setState("Broken download: " + track.getName());
setState(getResourceString("DownloadThread.Download_broken") + track.getName());
  public void download(final Track track) throws IOException {    final URL url = getProxyURL(track.getURL());    System.out.println(url);    final File file = getFileName(url);    setState(getResourceString("DownloadThread.Connecting_to")             + url.getHost());    try {      long timeout = 120000;            DownloadConnection connection = new DownloadConnection(url);      connection.connect(0, timeout);      // Get rid of the problem where tracks are downloaded but in reality      // they are 404 messages or some other html crud.      String contentType = connection.getContentType();      if (contentType == null)        throw new ProtocolException("Something went wrong talking to the "+                                    "download site");      if (contentType.indexOf("text") != -1)        throw new FileNotFoundException("Content type is Text");      int contentLength = connection.getContentLength();      long continueOffset = file.exists() ? file.length() : 0;      // If the file isn't already the right length, then we need to download      if (continueOffset != contentLength) {        boolean resume = false;        if (continueOffset > 0) {          resume = true;          DownloadConnection resumeConnection = null;          try {            resumeConnection = new DownloadConnection(url);            resumeConnection.connect(continueOffset, timeout);            System.out.println("Resuming download of "+track+" (offset="                               + continueOffset + ")");          }          catch (DownloadConnection.ResumeNotSupportedException exception) {            System.out.println("Server does not support resuming downloads");            resume = false;            continueOffset = 0;          }          if (resume) {            try {              connection.close(timeout);            }            catch (IOException e) {            }            connection = resumeConnection;          }        }        setState(getResourceString("DownloadThread.Downloading")                 + track.getName());        for (int i = 0; i < downloadListeners.size(); i++)          ((DownloadListener)downloadListeners.get(i)).downloadStarted(track);        final byte buf[] = new byte[128000];          // If we are resuming a download, then we must feed the already-downloaded          // part of the file to the download listeners.  They are only expected          // to deal with whole files.        if (resume && downloadListeners.size() != 0) {          FileInputStream is = new FileInputStream(file.toString());          try {            while (true) {              int nbytes = is.read(buf, 0, buf.length);              if (nbytes <= 0)                break;              for (int i = 0; i < downloadListeners.size(); i++)                ((DownloadListener)downloadListeners.get(i)).downloadData(track, buf, 0, nbytes);            }          }          finally {            is.close();          }        }        // If the continue offset is non-zero then we open the file in        // append mode. If the file on the server is shorter than the one         // we have on disk then we just start again.        OutputStream os = new FileOutputStream(file.toString(), resume);        boolean succeeded = false;        try {          int totalBytes = (int)continueOffset;                    while (true) {            int nbytes = connection.read(buf, timeout);            if (nbytes < 0)              break;            os.write(buf, 0, nbytes);              // Stephen Blackheath: I am in two minds as to whether this should be a separate              // listener, but it should be efficient enough as it is.            for (int i = 0; i < downloadListeners.size(); i++)              ((DownloadListener)downloadListeners.get(i)).downloadData(track, buf, 0, nbytes);            if (contentLength >= 0) {              totalBytes += nbytes;              int percent = totalBytes * 100 / contentLength;              if (percent != percentComplete) {                percentComplete = percent;                track.setPercentComplete(percent);                notifyUpdateListeners(track);                for (Iterator iter = downloadListeners.iterator(); iter.hasNext();) {                  DownloadListener d = (DownloadListener) iter.next();                  d.downloadProgressed(track, percent, Resources.getString("DownloadThread.Downloading_Tracks"));                }              }            }          }          succeeded = true;          exponentialBackoffManager.succeeded(track.getURL());        }        finally {          os.close();          try {            connection.close(timeout);          }          catch (IOException exception) {          }          for (int i = 0; i < downloadListeners.size(); i++)            ((DownloadListener)downloadListeners.get(i)).downloadFinished(track, succeeded);        }      }      track.setFile(file);      trackDatabase.save();    }    catch (Exception e) {      e.printStackTrace();      if (e instanceof FileNotFoundException) {        setState("Broken download: " + track.getName()); //$NON-NLS-1$        track.setBroken();      } else if (e instanceof IOException) {        exponentialBackoffManager.failed(track.getURL());        setState(getResourceString("DownloadThread.Download_failure")                 + track.getName());        track.increaseDownloadAttempts();      } else {        System.out.println("Exception not handled");      }     }    finally {      percentComplete = 0;    }  }