@Override
    public File download(URI uri) throws FileSizeLimitExceededException, FileDownloadException {
        InputStream input = null;
        OutputStream output = null;

        try {
            log.debug("Connecting to {}", uri);

            HttpClient client = new DefaultHttpClient();
            HttpGet get = new HttpGet(uri);
            HttpResponse response = client.execute(get);

            validateStatusCode(response);
            validateFileSize(response);

            File target = getTargetFile(uri);
            byte[] buffer = new byte[1024];

            log.debug("Downloading file {} from {}", target, uri);

            input = response.getEntity().getContent();
            output = new FileOutputStream(target.getAbsolutePath());
            if (!target.exists()) {
                target.createNewFile();
            }
            for (int length; (length = input.read(buffer)) > 0; ) {
                output.write(buffer, 0, length);
            }

            log.debug("File {} successfully downloaded from {}", target.getName(), uri);
            return target;

        } catch (FileNotFoundException e) {
            log.error("Target file not found:", e);
            throw new FileDownloadException(String.format("Failed to download due to an server IO error", uri), e);
        } catch (ClientProtocolException e) {
            throw new FileDownloadException(String.format("Failed to download file from '%s'", uri), e);
        } catch (IOException e) {
            throw new FileDownloadException(String.format("Failed to download file from '%s'", uri), e);
        } finally {
            if (output != null) try {
                output.close();
            } catch (IOException e) {
                log.error("Failed to close output stream", e);
            }
            if (input != null) try {
                input.close();
            } catch (IOException e) {
                log.error("Failed to close input stream", e);
            }
        }
    }