@Override
    protected Void doInBackground() {
        final int BUFFER_SIZE = 2048;

        BufferedInputStream bis = null;
        ByteArrayOutputStream baos;

        String prefix = ConfigManager.getInstance().getClientPrefix();
        String addr = ConfigManager.getInstance().getProperties().getProperty("updateurl");
        addr = addr.replace("%PREFIX%", prefix);
        addr = addr.replace("%FILE%", this.path);

        try {
            URL url = new URL(addr);
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setRequestProperty("User-Agent", "User-Agent: Kubach v" + Constants.VERSION);

            this.totalProgressValue = connection.getContentLength();

            int totalDataRead = 0;
            bis = new BufferedInputStream(connection.getInputStream());
            baos = new ByteArrayOutputStream();
            try (BufferedOutputStream bos = new BufferedOutputStream(baos, BUFFER_SIZE)) {
                byte[] data = new byte[BUFFER_SIZE];
                int i = 0;

                while ((i = bis.read(data)) != -1) {
                    totalDataRead = totalDataRead + i;
                    baos.write(data, 0, i);

                    publish(new SyncTaskState(addr, "Downloading (" + String.format("%.2f", totalDataRead / (float) this.totalProgressValue * 100) + "%)", totalDataRead));
                }

                // Write file to disk
                File f = new File(this.pathToFile);
                writeBytesToFile(f, baos.toByteArray());

                publish(new SyncTaskState(addr, "Finished", this.totalProgressValue, f));
            }
        } catch (IOException ex) {
            ex.printStackTrace();
            if (--numTries > 0) {
                publish(new SyncTaskState(addr, "Retrying...", 0));

                this.doInBackground();
            } else {
                publish(new SyncTaskState(addr, "FAILED", 0));
            }
        } finally {
            try {
                bis.close();
            } catch (IOException ex) {
                ex.printStackTrace();
                if (--numTries > 0) {
                    publish(new SyncTaskState(addr, "Retrying...", 0));

                    this.doInBackground();
                } else {
                    publish(new SyncTaskState(addr, "FAILED", 0));
                }
            }
        }

        return null;
    }