fix!: remove deprecated platforms (#270)

diff --git a/README.md b/README.md
index ae19ffe..55bd104 100644
--- a/README.md
+++ b/README.md
@@ -58,19 +58,11 @@
 
 ## Supported Platforms
 
-- Amazon Fire OS
 - Android
-- BlackBerry 10
 - Browser
-- Firefox OS**
 - iOS
-- Windows Phone 7 and 8*
 - Windows
 
-\* _Do not support `onprogress` nor `abort()`_
-
-\** _Do not support `onprogress`_
-
 # FileTransfer
 
 The `FileTransfer` object provides a way to upload files using an HTTP
@@ -259,10 +251,6 @@
 );
 ```
 
-### WP8 Quirks
-
-- Download requests is being cached by native implementation. To avoid caching, pass `if-Modified-Since` header to download method.
-
 ### Browser Quirks
 
 - __withCredentials__: _boolean_ that tells the browser to set the withCredentials flag on the XMLHttpRequest
diff --git a/package.json b/package.json
index a9788f9..993feca 100644
--- a/package.json
+++ b/package.json
@@ -7,15 +7,8 @@
     "id": "cordova-plugin-file-transfer",
     "platforms": [
       "android",
-      "amazon-fireos",
-      "ubuntu",
-      "blackberry10",
       "ios",
-      "wp7",
-      "wp8",
-      "windows8",
       "windows",
-      "firefoxos",
       "browser"
     ]
   },
@@ -37,15 +30,8 @@
     "transfer",
     "ecosystem:cordova",
     "cordova-android",
-    "cordova-amazon-fireos",
-    "cordova-ubuntu",
-    "cordova-blackberry10",
     "cordova-ios",
-    "cordova-wp7",
-    "cordova-wp8",
-    "cordova-windows8",
     "cordova-windows",
-    "cordova-firefoxos",
     "cordova-browser"
   ],
   "author": "Apache Software Foundation",
diff --git a/plugin.xml b/plugin.xml
index 41c7a91..1a1fd19 100644
--- a/plugin.xml
+++ b/plugin.xml
@@ -56,45 +56,6 @@
         <source-file src="src/android/FileUploadResult.java" target-dir="src/org/apache/cordova/filetransfer" />
     </platform>
 
-    <!-- amamzon-fireos -->
-    <platform name="amazon-fireos">
-        <config-file target="res/xml/config.xml" parent="/*">
-            <feature name="FileTransfer" >
-                <param name="android-package" value="org.apache.cordova.filetransfer.FileTransfer"/>
-            </feature>
-        </config-file>
-
-        <config-file target="AndroidManifest.xml" parent="/*">
-            <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
-        </config-file>
-
-        <source-file src="src/amazon/FileTransfer.java" target-dir="src/org/apache/cordova/filetransfer" />
-        <source-file src="src/android/FileProgressResult.java" target-dir="src/org/apache/cordova/filetransfer" />
-        <source-file src="src/android/FileUploadResult.java" target-dir="src/org/apache/cordova/filetransfer" />
-    </platform>
-
-    <!-- ubuntu -->
-    <platform name="ubuntu">
-        <header-file src="src/ubuntu/file-transfer.h" />
-        <source-file src="src/ubuntu/file-transfer.cpp" />
-    </platform>
-
-    <!-- blackberry10 -->
-    <platform name="blackberry10">
-        <config-file target="www/config.xml" parent="/widget">
-            <feature name="FileTransfer" value="FileTransfer"></feature>
-        </config-file>
-        <js-module src="www/blackberry10/FileTransferProxy.js" name="FileTransferProxy" >
-            <runs />
-        </js-module>
-        <js-module src="www/blackberry10/xhrFileTransfer.js" name="xhrFileTransfer" />
-        <!--
-        <js-module src="www/blackberry10/abort.js" name="abortProxy" />
-        <js-module src="www/blackberry10/download.js" name="downloadProxy" />
-        <js-module src="www/blackberry10/upload.js" name="uploadProxy" />
-        -->
-    </platform>
-
     <!-- ios -->
     <platform name="ios">
         <config-file target="config.xml" parent="/*">
@@ -108,41 +69,6 @@
         <framework src="AssetsLibrary.framework" />
     </platform>
 
-    <!-- wp7 -->
-    <platform name="wp7">
-        <config-file target="config.xml" parent="/*">
-            <feature name="FileTransfer">
-                <param name="wp-package" value="FileTransfer"/>
-            </feature>
-        </config-file>
-
-        <source-file src="src/wp/FileTransfer.cs" />
-
-        <js-module src="www/wp7/base64.js" name="base64">
-            <clobbers target="window.FileTransferBase64" />
-        </js-module>
-
-    </platform>
-
-    <!-- wp8 -->
-    <platform name="wp8">
-        <config-file target="config.xml" parent="/*">
-            <feature name="FileTransfer">
-                <param name="wp-package" value="FileTransfer"/>
-            </feature>
-        </config-file>
-
-        <source-file src="src/wp/FileTransfer.cs" />
-
-    </platform>
-
-    <!-- windows8 -->
-    <platform name="windows8">
-        <js-module src="src/windows/FileTransferProxy.js" name="FileTransferProxy">
-            <runs />
-        </js-module>
-    </platform>
-
     <!-- windows -->
     <platform name="windows">
         <js-module src="src/windows/FileTransferProxy.js" name="FileTransferProxy">
@@ -150,17 +76,6 @@
         </js-module>
     </platform>
 
-    <!-- firefoxOS -->
-    <platform name="firefoxos">
-        <config-file target="config.xml" parent="/*">
-            <permission name="systemXHR" privileged="true"/>
-        </config-file>
-
-        <js-module src="www/firefoxos/FileTransferProxy.js" name="FileTransferProxy">
-            <runs/>
-        </js-module>
-    </platform>
-
     <!-- browser -->
     <platform name="browser">
         <js-module src="www/browser/FileTransfer.js" name="BrowserFileTransfer">
diff --git a/src/amazon/FileTransfer.java b/src/amazon/FileTransfer.java
deleted file mode 100644
index 1563a39..0000000
--- a/src/amazon/FileTransfer.java
+++ /dev/null
@@ -1,898 +0,0 @@
-/*
-       Licensed to the Apache Software Foundation (ASF) under one
-       or more contributor license agreements.  See the NOTICE file
-       distributed with this work for additional information
-       regarding copyright ownership.  The ASF licenses this file
-       to you under the Apache License, Version 2.0 (the
-       "License"); you may not use this file except in compliance
-       with the License.  You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-       Unless required by applicable law or agreed to in writing,
-       software distributed under the License is distributed on an
-       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-       KIND, either express or implied.  See the License for the
-       specific language governing permissions and limitations
-       under the License.
-*/
-package org.apache.cordova.filetransfer;
-
-import java.io.BufferedReader;
-import java.io.ByteArrayOutputStream;
-import java.io.Closeable;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FilterInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.OutputStream;
-import java.io.UnsupportedEncodingException;
-import java.net.HttpURLConnection;
-import java.net.URLConnection;
-import java.net.URLDecoder;
-import java.security.cert.CertificateException;
-import java.security.cert.X509Certificate;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.zip.GZIPInputStream;
-import java.util.zip.Inflater;
-
-import javax.net.ssl.HostnameVerifier;
-import javax.net.ssl.HttpsURLConnection;
-import javax.net.ssl.SSLContext;
-import javax.net.ssl.SSLSession;
-import javax.net.ssl.SSLSocketFactory;
-import javax.net.ssl.TrustManager;
-import javax.net.ssl.X509TrustManager;
-
-import org.apache.cordova.Config;
-import org.apache.cordova.CallbackContext;
-import org.apache.cordova.CordovaPlugin;
-import org.apache.cordova.CordovaResourceApi;
-import org.apache.cordova.CordovaResourceApi.OpenForReadResult;
-import org.apache.cordova.PluginResult;
-import org.apache.cordova.file.FileUtils;
-import org.json.JSONArray;
-import org.json.JSONException;
-import org.json.JSONObject;
-
-import android.net.Uri;
-import android.os.Build;
-import android.util.Log;
-import com.amazon.android.webkit.AmazonCookieManager;
-
-public class FileTransfer extends CordovaPlugin {
-
-    private static final String LOG_TAG = "FileTransfer";
-    private static final String LINE_START = "--";
-    private static final String LINE_END = "\r\n";
-    private static final String BOUNDARY =  "+++++";
-
-    public static int FILE_NOT_FOUND_ERR = 1;
-    public static int INVALID_URL_ERR = 2;
-    public static int CONNECTION_ERR = 3;
-    public static int ABORTED_ERR = 4;
-
-    private static HashMap<String, RequestContext> activeRequests = new HashMap<String, RequestContext>();
-    private static final int MAX_BUFFER_SIZE = 16 * 1024;
-
-    private static final class RequestContext {
-        String source;
-        String target;
-        File targetFile;
-        CallbackContext callbackContext;
-        InputStream currentInputStream;
-        OutputStream currentOutputStream;
-        boolean aborted;
-        RequestContext(String source, String target, CallbackContext callbackContext) {
-            this.source = source;
-            this.target = target;
-            this.callbackContext = callbackContext;
-        }
-        void sendPluginResult(PluginResult pluginResult) {
-            synchronized (this) {
-                if (!aborted) {
-                    callbackContext.sendPluginResult(pluginResult);
-                }
-            }
-        }
-    }
-
-    /**
-     * Adds an interface method to an InputStream to return the number of bytes
-     * read from the raw stream. This is used to track total progress against
-     * the HTTP Content-Length header value from the server.
-     */
-    private static abstract class TrackingInputStream extends FilterInputStream {
-      public TrackingInputStream(final InputStream in) {
-        super(in);
-      }
-        public abstract long getTotalRawBytesRead();
-  }
-
-    private static class ExposedGZIPInputStream extends GZIPInputStream {
-      public ExposedGZIPInputStream(final InputStream in) throws IOException {
-        super(in);
-      }
-      public Inflater getInflater() {
-        return inf;
-      }
-  }
-
-    /**
-     * Provides raw bytes-read tracking for a GZIP input stream. Reports the
-     * total number of compressed bytes read from the input, rather than the
-     * number of uncompressed bytes.
-     */
-    private static class TrackingGZIPInputStream extends TrackingInputStream {
-      private ExposedGZIPInputStream gzin;
-      public TrackingGZIPInputStream(final ExposedGZIPInputStream gzin) throws IOException {
-        super(gzin);
-        this.gzin = gzin;
-      }
-      public long getTotalRawBytesRead() {
-        return gzin.getInflater().getBytesRead();
-      }
-  }
-
-    /**
-     * Provides simple total-bytes-read tracking for an existing InputStream
-     */
-    private static class SimpleTrackingInputStream extends TrackingInputStream {
-        private long bytesRead = 0;
-        public SimpleTrackingInputStream(InputStream stream) {
-            super(stream);
-        }
-
-        private int updateBytesRead(int newBytesRead) {
-          if (newBytesRead != -1) {
-            bytesRead += newBytesRead;
-          }
-          return newBytesRead;
-        }
-
-        @Override
-        public int read() throws IOException {
-            return updateBytesRead(super.read());
-        }
-
-        // Note: FilterInputStream delegates read(byte[] bytes) to the below method,
-        // so we don't override it or else double count (CB-5631).
-        @Override
-        public int read(byte[] bytes, int offset, int count) throws IOException {
-            return updateBytesRead(super.read(bytes, offset, count));
-        }
-
-        public long getTotalRawBytesRead() {
-          return bytesRead;
-        }
-    }
-
-    @Override
-    public boolean execute(String action, JSONArray args, final CallbackContext callbackContext) throws JSONException {
-        if (action.equals("upload") || action.equals("download")) {
-            String source = args.getString(0);
-            String target = args.getString(1);
-
-            if (action.equals("upload")) {
-                try {
-                    source = URLDecoder.decode(source, "UTF-8");
-                    upload(source, target, args, callbackContext);
-                } catch (UnsupportedEncodingException e) {
-                    callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.MALFORMED_URL_EXCEPTION, "UTF-8 error."));
-                }
-            } else {
-                download(source, target, args, callbackContext);
-            }
-            return true;
-        } else if (action.equals("abort")) {
-            String objectId = args.getString(0);
-            abort(objectId);
-            callbackContext.success();
-            return true;
-        }
-        return false;
-    }
-
-    private static void addHeadersToRequest(URLConnection connection, JSONObject headers) {
-        try {
-            for (Iterator<?> iter = headers.keys(); iter.hasNext(); ) {
-                String headerKey = iter.next().toString();
-                JSONArray headerValues = headers.optJSONArray(headerKey);
-                if (headerValues == null) {
-                    headerValues = new JSONArray();
-                    headerValues.put(headers.getString(headerKey));
-                }
-                connection.setRequestProperty(headerKey, headerValues.getString(0));
-                for (int i = 1; i < headerValues.length(); ++i) {
-                    connection.addRequestProperty(headerKey, headerValues.getString(i));
-                }
-            }
-        } catch (JSONException e1) {
-          // No headers to be manipulated!
-        }
-    }
-
-    /**
-     * Uploads the specified file to the server URL provided using an HTTP multipart request.
-     * @param source        Full path of the file on the file system
-     * @param target        URL of the server to receive the file
-     * @param args          JSON Array of args
-     * @param callbackContext    callback id for optional progress reports
-     *
-     * args[2] fileKey       Name of file request parameter
-     * args[3] fileName      File name to be used on server
-     * args[4] mimeType      Describes file content type
-     * args[5] params        key:value pairs of user-defined parameters
-     * @return FileUploadResult containing result of upload request
-     */
-    private void upload(final String source, final String target, JSONArray args, CallbackContext callbackContext) throws JSONException {
-        Log.d(LOG_TAG, "upload " + source + " to " +  target);
-
-        // Setup the options
-        final String fileKey = getArgument(args, 2, "file");
-        final String fileName = getArgument(args, 3, "image.jpg");
-        final String mimeType = getArgument(args, 4, "image/jpeg");
-        final JSONObject params = args.optJSONObject(5) == null ? new JSONObject() : args.optJSONObject(5);
-        final boolean trustEveryone = args.optBoolean(6);
-        // Always use chunked mode unless set to false as per API
-        final boolean chunkedMode = args.optBoolean(7) || args.isNull(7);
-        // Look for headers on the params map for backwards compatibility with older Cordova versions.
-        final JSONObject headers = args.optJSONObject(8) == null ? params.optJSONObject("headers") : args.optJSONObject(8);
-        final String objectId = args.getString(9);
-        final String httpMethod = getArgument(args, 10, "POST");
-        
-        final CordovaResourceApi resourceApi = webView.getResourceApi();
-
-        Log.d(LOG_TAG, "fileKey: " + fileKey);
-        Log.d(LOG_TAG, "fileName: " + fileName);
-        Log.d(LOG_TAG, "mimeType: " + mimeType);
-        Log.d(LOG_TAG, "params: " + params);
-        Log.d(LOG_TAG, "trustEveryone: " + trustEveryone);
-        Log.d(LOG_TAG, "chunkedMode: " + chunkedMode);
-        Log.d(LOG_TAG, "headers: " + headers);
-        Log.d(LOG_TAG, "objectId: " + objectId);
-        Log.d(LOG_TAG, "httpMethod: " + httpMethod);
-        
-        final Uri targetUri = resourceApi.remapUri(Uri.parse(target));
-        // Accept a path or a URI for the source.
-        Uri tmpSrc = Uri.parse(source);
-        final Uri sourceUri = resourceApi.remapUri(
-            tmpSrc.getScheme() != null ? tmpSrc : Uri.fromFile(new File(source)));
-
-        int uriType = CordovaResourceApi.getUriType(targetUri);
-        final boolean useHttps = uriType == CordovaResourceApi.URI_TYPE_HTTPS;
-        if (uriType != CordovaResourceApi.URI_TYPE_HTTP && !useHttps) {
-            JSONObject error = createFileTransferError(INVALID_URL_ERR, source, target, null, 0);
-            Log.e(LOG_TAG, "Unsupported URI: " + targetUri);
-            callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.IO_EXCEPTION, error));
-            return;
-        }
-
-        final RequestContext context = new RequestContext(source, target, callbackContext);
-        synchronized (activeRequests) {
-            activeRequests.put(objectId, context);
-        }
-        
-        cordova.getThreadPool().execute(new Runnable() {
-            public void run() {
-                if (context.aborted) {
-                    return;
-                }
-                HttpURLConnection conn = null;
-                HostnameVerifier oldHostnameVerifier = null;
-                SSLSocketFactory oldSocketFactory = null;
-                int totalBytes = 0;
-                int fixedLength = -1;
-                try {
-                    // Create return object
-                    FileUploadResult result = new FileUploadResult();
-                    FileProgressResult progress = new FileProgressResult();
-
-                    //------------------ CLIENT REQUEST
-                    // Open a HTTP connection to the URL based on protocol
-                    conn = resourceApi.createHttpConnection(targetUri);
-                    if (useHttps && trustEveryone) {
-                        // Setup the HTTPS connection class to trust everyone
-                        HttpsURLConnection https = (HttpsURLConnection)conn;
-                        oldSocketFactory  = trustAllHosts(https);
-                        // Save the current hostnameVerifier
-                        oldHostnameVerifier = https.getHostnameVerifier();
-                        // Setup the connection not to verify hostnames
-                        https.setHostnameVerifier(DO_NOT_VERIFY);
-                    }
-
-                    // Allow Inputs
-                    conn.setDoInput(true);
-
-                    // Allow Outputs
-                    conn.setDoOutput(true);
-
-                    // Don't use a cached copy.
-                    conn.setUseCaches(false);
-
-                    // Use a post method.
-                    conn.setRequestMethod(httpMethod);
-
-                    // if we specified a Content-Type header, don't do multipart form upload
-                    boolean multipartFormUpload = (headers == null) || !headers.has("Content-Type");
-                    if (multipartFormUpload) {
-                        conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + BOUNDARY);
-                    }
-                    // Set the cookies on the response
-                    String cookie = AmazonCookieManager.getInstance().getCookie(target);
-                    if (cookie != null) {
-                        conn.setRequestProperty("Cookie", cookie);
-                    }
-
-                    // Handle the other headers
-                    if (headers != null) {
-                        addHeadersToRequest(conn, headers);
-                    }
-
-                    /*
-                        * Store the non-file portions of the multipart data as a string, so that we can add it
-                        * to the contentSize, since it is part of the body of the HTTP request.
-                        */
-                    StringBuilder beforeData = new StringBuilder();
-                    try {
-                        for (Iterator<?> iter = params.keys(); iter.hasNext();) {
-                            Object key = iter.next();
-                            if(!String.valueOf(key).equals("headers"))
-                            {
-                              beforeData.append(LINE_START).append(BOUNDARY).append(LINE_END);
-                              beforeData.append("Content-Disposition: form-data; name=\"").append(key.toString()).append('"');
-                              beforeData.append(LINE_END).append(LINE_END);
-                              beforeData.append(params.getString(key.toString()));
-                              beforeData.append(LINE_END);
-                            }
-                        }
-                    } catch (JSONException e) {
-                        Log.e(LOG_TAG, e.getMessage(), e);
-                    }
-
-                    beforeData.append(LINE_START).append(BOUNDARY).append(LINE_END);
-                    beforeData.append("Content-Disposition: form-data; name=\"").append(fileKey).append("\";");
-                    beforeData.append(" filename=\"").append(fileName).append('"').append(LINE_END);
-                    beforeData.append("Content-Type: ").append(mimeType).append(LINE_END).append(LINE_END);
-                    byte[] beforeDataBytes = beforeData.toString().getBytes("UTF-8");
-                    byte[] tailParamsBytes = (LINE_END + LINE_START + BOUNDARY + LINE_START + LINE_END).getBytes("UTF-8");
-
-                    
-                    // Get a input stream of the file on the phone
-                    OpenForReadResult readResult = resourceApi.openForRead(sourceUri);
-                    
-                    int stringLength = beforeDataBytes.length + tailParamsBytes.length;
-                    if (readResult.length >= 0) {
-                        fixedLength = (int)readResult.length;
-                        if (multipartFormUpload)
-                            fixedLength += stringLength;
-                        progress.setLengthComputable(true);
-                        progress.setTotal(fixedLength);
-                    }
-                    Log.d(LOG_TAG, "Content Length: " + fixedLength);
-                    // setFixedLengthStreamingMode causes and OutOfMemoryException on pre-Froyo devices.
-                    // http://code.google.com/p/android/issues/detail?id=3164
-                    // It also causes OOM if HTTPS is used, even on newer devices.
-                    boolean useChunkedMode = chunkedMode && (Build.VERSION.SDK_INT < Build.VERSION_CODES.FROYO || useHttps);
-                    useChunkedMode = useChunkedMode || (fixedLength == -1);
-
-                    if (useChunkedMode) {
-                        conn.setChunkedStreamingMode(MAX_BUFFER_SIZE);
-                        // Although setChunkedStreamingMode sets this header, setting it explicitly here works
-                        // around an OutOfMemoryException when using https.
-                        conn.setRequestProperty("Transfer-Encoding", "chunked");
-                    } else {
-                        conn.setFixedLengthStreamingMode(fixedLength);
-                    }
-
-                    conn.connect();
-                    
-                    OutputStream sendStream = null;
-                    try {
-                        sendStream = conn.getOutputStream();
-                        synchronized (context) {
-                            if (context.aborted) {
-                                return;
-                            }
-                            context.currentOutputStream = sendStream;
-                        }
-                        
-                        if (multipartFormUpload) {
-                            //We don't want to change encoding, we just want this to write for all Unicode.
-                            sendStream.write(beforeDataBytes);
-                            totalBytes += beforeDataBytes.length;
-                        }
-                        // create a buffer of maximum size
-                        int bytesAvailable = readResult.inputStream.available();
-                        int bufferSize = Math.min(bytesAvailable, MAX_BUFFER_SIZE);
-                        byte[] buffer = new byte[bufferSize];
-    
-                        // read file and write it into form...
-                        int bytesRead = readResult.inputStream.read(buffer, 0, bufferSize);
-    
-                        long prevBytesRead = 0;
-                        while (bytesRead > 0) {
-                            result.setBytesSent(totalBytes);
-                            sendStream.write(buffer, 0, bytesRead);
-                            totalBytes += bytesRead;
-                            if (totalBytes > prevBytesRead + 102400) {
-                                prevBytesRead = totalBytes;
-                                Log.d(LOG_TAG, "Uploaded " + totalBytes + " of " + fixedLength + " bytes");
-                            }
-                            bytesAvailable = readResult.inputStream.available();
-                            bufferSize = Math.min(bytesAvailable, MAX_BUFFER_SIZE);
-                            bytesRead = readResult.inputStream.read(buffer, 0, bufferSize);
-
-                            // Send a progress event.
-                            progress.setLoaded(totalBytes);
-                            PluginResult progressResult = new PluginResult(PluginResult.Status.OK, progress.toJSONObject());
-                            progressResult.setKeepCallback(true);
-                            context.sendPluginResult(progressResult);
-                        }
-    
-                        if (multipartFormUpload) {
-                            // send multipart form data necessary after file data...
-                            sendStream.write(tailParamsBytes);
-                            totalBytes += tailParamsBytes.length;
-                        }
-                        sendStream.flush();
-                    } finally {
-                        safeClose(readResult.inputStream);
-                        safeClose(sendStream);
-                    }
-                    context.currentOutputStream = null;
-                    Log.d(LOG_TAG, "Sent " + totalBytes + " of " + fixedLength);
-
-                    //------------------ read the SERVER RESPONSE
-                    String responseString;
-                    int responseCode = conn.getResponseCode();
-                    Log.d(LOG_TAG, "response code: " + responseCode);
-                    Log.d(LOG_TAG, "response headers: " + conn.getHeaderFields());
-                    TrackingInputStream inStream = null;
-                    try {
-                        inStream = getInputStream(conn);
-                        synchronized (context) {
-                            if (context.aborted) {
-                                return;
-                            }
-                            context.currentInputStream = inStream;
-                        }
-                        
-                        ByteArrayOutputStream out = new ByteArrayOutputStream(Math.max(1024, conn.getContentLength()));
-                        byte[] buffer = new byte[1024];
-                        int bytesRead = 0;
-                        // write bytes to file
-                        while ((bytesRead = inStream.read(buffer)) > 0) {
-                            out.write(buffer, 0, bytesRead);
-                        }
-                        responseString = out.toString("UTF-8");
-                    } finally {
-                        context.currentInputStream = null;
-                        safeClose(inStream);
-                    }
-                    
-                    Log.d(LOG_TAG, "got response from server");
-                    Log.d(LOG_TAG, responseString.substring(0, Math.min(256, responseString.length())));
-                    
-                    // send request and retrieve response
-                    result.setResponseCode(responseCode);
-                    result.setResponse(responseString);
-
-                    context.sendPluginResult(new PluginResult(PluginResult.Status.OK, result.toJSONObject()));
-                } catch (FileNotFoundException e) {
-                    JSONObject error = createFileTransferError(FILE_NOT_FOUND_ERR, source, target, conn);
-                    Log.e(LOG_TAG, error.toString(), e);
-                    context.sendPluginResult(new PluginResult(PluginResult.Status.IO_EXCEPTION, error));
-                } catch (IOException e) {
-                    JSONObject error = createFileTransferError(CONNECTION_ERR, source, target, conn);
-                    Log.e(LOG_TAG, error.toString(), e);
-                    Log.e(LOG_TAG, "Failed after uploading " + totalBytes + " of " + fixedLength + " bytes.");
-                    context.sendPluginResult(new PluginResult(PluginResult.Status.IO_EXCEPTION, error));
-                } catch (JSONException e) {
-                    Log.e(LOG_TAG, e.getMessage(), e);
-                    context.sendPluginResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
-                } catch (Throwable t) {
-                    // Shouldn't happen, but will
-                    JSONObject error = createFileTransferError(CONNECTION_ERR, source, target, conn);
-                    Log.e(LOG_TAG, error.toString(), t);
-                    context.sendPluginResult(new PluginResult(PluginResult.Status.IO_EXCEPTION, error));
-                } finally {
-                    synchronized (activeRequests) {
-                        activeRequests.remove(objectId);
-                    }
-
-                    if (conn != null) {
-                        // Revert back to the proper verifier and socket factories
-                        // Revert back to the proper verifier and socket factories
-                        if (trustEveryone && useHttps) {
-                            HttpsURLConnection https = (HttpsURLConnection) conn;
-                            https.setHostnameVerifier(oldHostnameVerifier);
-                            https.setSSLSocketFactory(oldSocketFactory);
-                        }
-                    }
-                }                
-            }
-        });
-    }
-
-    private static void safeClose(Closeable stream) {
-        if (stream != null) {
-            try {
-                stream.close();
-            } catch (IOException e) {
-            }
-        }
-    }
-
-    private static TrackingInputStream getInputStream(URLConnection conn) throws IOException {
-        String encoding = conn.getContentEncoding();
-        if (encoding != null && encoding.equalsIgnoreCase("gzip")) {
-          return new TrackingGZIPInputStream(new ExposedGZIPInputStream(conn.getInputStream()));
-        }
-        return new SimpleTrackingInputStream(conn.getInputStream());
-    }
-
-    // always verify the host - don't check for certificate
-    private static final HostnameVerifier DO_NOT_VERIFY = new HostnameVerifier() {
-        public boolean verify(String hostname, SSLSession session) {
-            return true;
-        }
-    };
-    // Create a trust manager that does not validate certificate chains
-    private static final TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
-        public java.security.cert.X509Certificate[] getAcceptedIssuers() {
-            return new java.security.cert.X509Certificate[] {};
-        }
-        
-        public void checkClientTrusted(X509Certificate[] chain,
-                String authType) throws CertificateException {
-        }
-        
-        public void checkServerTrusted(X509Certificate[] chain,
-                String authType) throws CertificateException {
-        }
-    } };
-
-    /**
-     * This function will install a trust manager that will blindly trust all SSL
-     * certificates.  The reason this code is being added is to enable developers
-     * to do development using self signed SSL certificates on their web server.
-     *
-     * The standard HttpsURLConnection class will throw an exception on self
-     * signed certificates if this code is not run.
-     */
-    private static SSLSocketFactory trustAllHosts(HttpsURLConnection connection) {
-        // Install the all-trusting trust manager
-        SSLSocketFactory oldFactory = connection.getSSLSocketFactory();
-        try {
-            // Install our all trusting manager
-            SSLContext sc = SSLContext.getInstance("TLS");
-            sc.init(null, trustAllCerts, new java.security.SecureRandom());
-            SSLSocketFactory newFactory = sc.getSocketFactory();
-            connection.setSSLSocketFactory(newFactory);
-        } catch (Exception e) {
-            Log.e(LOG_TAG, e.getMessage(), e);
-        }
-        return oldFactory;
-    }
-
-    private static JSONObject createFileTransferError(int errorCode, String source, String target, URLConnection connection) {
-
-        int httpStatus = 0;
-        StringBuilder bodyBuilder = new StringBuilder();
-        String body = null;
-        if (connection != null) {
-            try {
-                if (connection instanceof HttpURLConnection) {
-                    httpStatus = ((HttpURLConnection)connection).getResponseCode();
-                    InputStream err = ((HttpURLConnection) connection).getErrorStream();
-                    if(err != null)
-                    {
-                        BufferedReader reader = new BufferedReader(new InputStreamReader(err, "UTF-8"));
-                        try {
-                            String line = reader.readLine();
-                            while(line != null) {
-                                bodyBuilder.append(line);
-                                line = reader.readLine();
-                                if(line != null) {
-                                    bodyBuilder.append('\n');
-                                }
-                            }
-                            body = bodyBuilder.toString();
-                        } finally {
-                            reader.close();
-                        }
-                    }
-                }
-            // IOException can leave connection object in a bad state, so catch all exceptions.
-            } catch (Throwable e) {
-                Log.w(LOG_TAG, "Error getting HTTP status code from connection.", e);
-            }
-        }
-
-        return createFileTransferError(errorCode, source, target, body, httpStatus);
-    }
-
-        /**
-        * Create an error object based on the passed in errorCode
-        * @param errorCode      the error
-        * @return JSONObject containing the error
-        */
-    private static JSONObject createFileTransferError(int errorCode, String source, String target, String body, Integer httpStatus) {
-        JSONObject error = null;
-        try {
-            error = new JSONObject();
-            error.put("code", errorCode);
-            error.put("source", source);
-            error.put("target", target);
-            if(body != null)
-            {
-                error.put("body", body);
-            }   
-            if (httpStatus != null) {
-                error.put("http_status", httpStatus);
-            }
-        } catch (JSONException e) {
-            Log.e(LOG_TAG, e.getMessage(), e);
-        }
-        return error;
-    }
-
-    /**
-     * Convenience method to read a parameter from the list of JSON args.
-     * @param args                      the args passed to the Plugin
-     * @param position          the position to retrieve the arg from
-     * @param defaultString the default to be used if the arg does not exist
-     * @return String with the retrieved value
-     */
-    private static String getArgument(JSONArray args, int position, String defaultString) {
-        String arg = defaultString;
-        if (args.length() > position) {
-            arg = args.optString(position);
-            if (arg == null || "null".equals(arg)) {
-                arg = defaultString;
-            }
-        }
-        return arg;
-    }
-
-    /**
-     * Downloads a file form a given URL and saves it to the specified directory.
-     *
-     * @param source        URL of the server to receive the file
-     * @param target            Full path of the file on the file system
-     */
-    private void download(final String source, final String target, JSONArray args, CallbackContext callbackContext) throws JSONException {
-        Log.d(LOG_TAG, "download " + source + " to " +  target);
-
-        final CordovaResourceApi resourceApi = webView.getResourceApi();
-
-        final boolean trustEveryone = args.optBoolean(2);
-        final String objectId = args.getString(3);
-        final JSONObject headers = args.optJSONObject(4);
-        
-        final Uri sourceUri = resourceApi.remapUri(Uri.parse(source));
-        // Accept a path or a URI for the source.
-        Uri tmpTarget = Uri.parse(target);
-        final Uri targetUri = resourceApi.remapUri(
-            tmpTarget.getScheme() != null ? tmpTarget : Uri.fromFile(new File(target)));
-
-        int uriType = CordovaResourceApi.getUriType(sourceUri);
-        final boolean useHttps = uriType == CordovaResourceApi.URI_TYPE_HTTPS;
-        final boolean isLocalTransfer = !useHttps && uriType != CordovaResourceApi.URI_TYPE_HTTP;
-        if (uriType == CordovaResourceApi.URI_TYPE_UNKNOWN) {
-            JSONObject error = createFileTransferError(INVALID_URL_ERR, source, target, null, 0);
-            Log.e(LOG_TAG, "Unsupported URI: " + targetUri);
-            callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.IO_EXCEPTION, error));
-            return;
-        }
-        
-        // TODO: refactor to also allow resources & content:
-        if (!isLocalTransfer && !Config.isUrlWhiteListed(source)) {
-            Log.w(LOG_TAG, "Source URL is not in white list: '" + source + "'");
-            JSONObject error = createFileTransferError(CONNECTION_ERR, source, target, null, 401);
-            callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.IO_EXCEPTION, error));
-            return;
-        }
-
-        
-        final RequestContext context = new RequestContext(source, target, callbackContext);
-        synchronized (activeRequests) {
-            activeRequests.put(objectId, context);
-        }
-        
-        cordova.getThreadPool().execute(new Runnable() {
-            public void run() {
-                if (context.aborted) {
-                    return;
-                }
-                HttpURLConnection connection = null;
-                HostnameVerifier oldHostnameVerifier = null;
-                SSLSocketFactory oldSocketFactory = null;
-                File file = null;
-                PluginResult result = null;
-                TrackingInputStream inputStream = null;
-
-                OutputStream outputStream = null;
-                try {
-                    OpenForReadResult readResult = null;
-                    outputStream = resourceApi.openOutputStream(targetUri);
-
-                    file = resourceApi.mapUriToFile(targetUri);
-                    context.targetFile = file;
-                    
-                    Log.d(LOG_TAG, "Download file:" + sourceUri);
-
-                    FileProgressResult progress = new FileProgressResult();
-
-                    if (isLocalTransfer) {
-                        readResult = resourceApi.openForRead(sourceUri);
-                        if (readResult.length != -1) {
-                            progress.setLengthComputable(true);
-                            progress.setTotal(readResult.length);
-                        }
-                        inputStream = new SimpleTrackingInputStream(readResult.inputStream);
-                    } else {
-                        // connect to server
-                        // Open a HTTP connection to the URL based on protocol
-                        connection = resourceApi.createHttpConnection(sourceUri);
-                        if (useHttps && trustEveryone) {
-                            // Setup the HTTPS connection class to trust everyone
-                            HttpsURLConnection https = (HttpsURLConnection)connection;
-                            oldSocketFactory = trustAllHosts(https);
-                            // Save the current hostnameVerifier
-                            oldHostnameVerifier = https.getHostnameVerifier();
-                            // Setup the connection not to verify hostnames
-                            https.setHostnameVerifier(DO_NOT_VERIFY);
-                        }
-        
-                        connection.setRequestMethod("GET");
-        
-                        // TODO: Make OkHttp use this AmazonCookieManager by default.
-                        String cookie = AmazonCookieManager.getInstance().getCookie(sourceUri.toString());
-                        if(cookie != null)
-                        {
-                            connection.setRequestProperty("cookie", cookie);
-                        }
-                        
-                        // This must be explicitly set for gzip progress tracking to work.
-                        connection.setRequestProperty("Accept-Encoding", "gzip");
-    
-                        // Handle the other headers
-                        if (headers != null) {
-                            addHeadersToRequest(connection, headers);
-                        }
-        
-                        connection.connect();
-    
-                        if (connection.getContentEncoding() == null || connection.getContentEncoding().equalsIgnoreCase("gzip")) {
-                            // Only trust content-length header if we understand
-                            // the encoding -- identity or gzip
-                            if (connection.getContentLength() != -1) {
-                                progress.setLengthComputable(true);
-                                progress.setTotal(connection.getContentLength());
-                            }
-                        }
-                        inputStream = getInputStream(connection);
-                    }
-                    
-                    try {
-                        synchronized (context) {
-                            if (context.aborted) {
-                                return;
-                            }
-                            context.currentInputStream = inputStream;
-                        }
-                        
-                        // write bytes to file
-                        byte[] buffer = new byte[MAX_BUFFER_SIZE];
-                        int bytesRead = 0;
-                        while ((bytesRead = inputStream.read(buffer)) > 0) {
-                            outputStream.write(buffer, 0, bytesRead);
-                            // Send a progress event.
-                            progress.setLoaded(inputStream.getTotalRawBytesRead());
-                            PluginResult progressResult = new PluginResult(PluginResult.Status.OK, progress.toJSONObject());
-                            progressResult.setKeepCallback(true);
-                            context.sendPluginResult(progressResult);
-                        }
-                    } finally {
-                        context.currentInputStream = null;
-                        safeClose(inputStream);
-                        safeClose(outputStream);
-                    }
-    
-                    Log.d(LOG_TAG, "Saved file: " + target);
-    
-                    // create FileEntry object
-                    FileUtils filePlugin = (FileUtils)webView.pluginManager.getPlugin("File");
-                    if (filePlugin != null) {
-                        JSONObject fileEntry = filePlugin.getEntryForFile(file);
-                        if (fileEntry != null) {
-                            result = new PluginResult(PluginResult.Status.OK, fileEntry);
-                        } else {
-                            JSONObject error = createFileTransferError(CONNECTION_ERR, source, target, connection);
-                            Log.e(LOG_TAG, "File plugin cannot represent download path");
-                            result = new PluginResult(PluginResult.Status.IO_EXCEPTION, error);
-                        }
-                    } else {
-                        Log.e(LOG_TAG, "File plugin not found; cannot save downloaded file");
-                        result = new PluginResult(PluginResult.Status.ERROR, "File plugin not found; cannot save downloaded file");
-                    }
-
-                } catch (FileNotFoundException e) {
-                    JSONObject error = createFileTransferError(FILE_NOT_FOUND_ERR, source, target, connection);
-                    Log.e(LOG_TAG, error.toString(), e);
-                    result = new PluginResult(PluginResult.Status.IO_EXCEPTION, error);
-                } catch (IOException e) {
-                    JSONObject error = createFileTransferError(CONNECTION_ERR, source, target, connection);
-                    Log.e(LOG_TAG, error.toString(), e);
-                    result = new PluginResult(PluginResult.Status.IO_EXCEPTION, error);
-                } catch (JSONException e) {
-                    Log.e(LOG_TAG, e.getMessage(), e);
-                    result = new PluginResult(PluginResult.Status.JSON_EXCEPTION);
-                } catch (Throwable e) {
-                    JSONObject error = createFileTransferError(CONNECTION_ERR, source, target, connection);
-                    Log.e(LOG_TAG, error.toString(), e);
-                    result = new PluginResult(PluginResult.Status.IO_EXCEPTION, error);
-                } finally {
-                    safeClose(outputStream);
-                    synchronized (activeRequests) {
-                        activeRequests.remove(objectId);
-                    }
-
-                    if (connection != null) {
-                        // Revert back to the proper verifier and socket factories
-                        if (trustEveryone && useHttps) {
-                            HttpsURLConnection https = (HttpsURLConnection) connection;
-                            https.setHostnameVerifier(oldHostnameVerifier);
-                            https.setSSLSocketFactory(oldSocketFactory);
-                        }
-                    }
-
-                    if (result == null) {
-                        result = new PluginResult(PluginResult.Status.ERROR, createFileTransferError(CONNECTION_ERR, source, target, connection));
-                    }
-                    // Remove incomplete download.
-                    if (result.getStatus() != PluginResult.Status.OK.ordinal() && file != null) {
-                        file.delete();
-                    }
-                    context.sendPluginResult(result);
-                }
-            }
-        });
-    }
-
-    /**
-     * Abort an ongoing upload or download.
-     */
-    private void abort(String objectId) {
-        final RequestContext context;
-        synchronized (activeRequests) {
-            context = activeRequests.remove(objectId);
-        }
-        if (context != null) {
-            File file = context.targetFile;
-            if (file != null) {
-                file.delete();
-            }
-            // Trigger the abort callback immediately to minimize latency between it and abort() being called.
-            JSONObject error = createFileTransferError(ABORTED_ERR, context.source, context.target, null, -1);
-            synchronized (context) {
-                context.sendPluginResult(new PluginResult(PluginResult.Status.ERROR, error));
-                context.aborted = true;
-            }
-            // Closing the streams can block, so execute on a background thread.
-            cordova.getThreadPool().execute(new Runnable() {
-                public void run() {
-                    synchronized (context) {
-                        safeClose(context.currentInputStream);
-                        safeClose(context.currentOutputStream);
-                    }
-                }
-            });
-        }
-    }
-}
diff --git a/src/ubuntu/file-transfer.cpp b/src/ubuntu/file-transfer.cpp
deleted file mode 100644
index 5b1adea..0000000
--- a/src/ubuntu/file-transfer.cpp
+++ /dev/null
@@ -1,265 +0,0 @@
-/*
- *
- * Copyright 2013 Canonical Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
-*/
-
-#include "file-transfer.h"
-#include <plugins/cordova-plugin-file/file.h>
-#include <cassert>
-
-static void SetHeaders(QNetworkRequest &request, const QVariantMap &headers) {
-    for (const QString &key: headers.keys()) {
-        QVariant val = *headers.find(key);
-        QString value = val.toString();
-        if (val.userType() == QMetaType::QVariantList || val.userType() == QMetaType::QStringList) {
-            QList<QVariant> list = val.toList();
-            for (QVariant v: list) {
-                if (value.size())
-                    value += ", ";
-                value += v.toString();
-            }
-        }
-        request.setRawHeader(key.toUtf8(), value.toUtf8());
-    }
-}
-
-void FileTransfer::download(int scId, int ecId, const QString& url, const QString &target, bool /*trustAllHost*/, int id, const QVariantMap &headers) {
-    QSharedPointer<FileTransferRequest> request(new FileTransferRequest(_manager, scId, ecId, id, this));
-
-    assert(_id2request.find(id) == _id2request.end());
-
-    _id2request.insert(id, request);
-
-    request->connect(request.data(), &FileTransferRequest::done, [&]() {
-        auto it = _id2request.find(id);
-        while (it != _id2request.end() && it.key() == id) {
-            if (it.value().data() == request.data()) {
-                _id2request.erase(it);
-                break;
-            }
-            it++;
-        }
-    });
-    request->download(url, target, headers);
-}
-
-void FileTransfer::upload(int scId, int ecId, const QString &fileURI, const QString& url, const QString& fileKey, const QString& fileName, const QString& mimeType,
-                          const QVariantMap & params, bool /*trustAllHosts*/, bool /*chunkedMode*/, const QVariantMap &headers, int id, const QString &/*httpMethod*/) {
-    QSharedPointer<FileTransferRequest> request(new FileTransferRequest(_manager, scId, ecId, id, this));
-
-    assert(_id2request.find(id) == _id2request.end());
-
-    _id2request.insert(id, request);
-
-    request->connect(request.data(), &FileTransferRequest::done, [&]() {
-        auto it = _id2request.find(id);
-        while (it != _id2request.end() && it.key() == id) {
-            if (it.value().data() == request.data()) {
-                _id2request.erase(it);
-                break;
-            }
-            it++;
-        }
-    });
-    request->upload(url, fileURI, fileKey, fileName, mimeType, params, headers);
-}
-
-void FileTransfer::abort(int scId, int ecId, int id) {
-    Q_UNUSED(scId)
-    Q_UNUSED(ecId)
-
-    auto it = _id2request.find(id);
-    while (it != _id2request.end() && it.key() == id) {
-        (*it)->abort();
-        it++;
-    }
-}
-
-void FileTransferRequest::download(const QString& uri, const QString &targetURI, const QVariantMap &headers) {
-    QUrl url(uri);
-    QNetworkRequest request;
-
-    QSharedPointer<CPlugin> filePlugin(_plugin->cordova()->getPlugin<File>());
-
-    if (!filePlugin.data())
-        return;
-
-    if (!url.isValid()) {
-        QVariantMap map;
-        map.insert("code", INVALID_URL_ERR);
-        map.insert("source", uri);
-        map.insert("target", targetURI);
-        _plugin->cb(_ecId, map);
-        emit done();
-        return;
-    }
-
-    request.setUrl(url);
-    if (url.password().size() || url.userName().size()) {
-        QString headerData = "Basic " + (url.userName() + ":" + url.password()).toLocal8Bit().toBase64();
-        request.setRawHeader("Authorization", headerData.toLocal8Bit());
-    }
-    SetHeaders(request, headers);
-    _reply = QSharedPointer<QNetworkReply>(_manager.get(request));
-
-    _reply->connect(_reply.data(), &QNetworkReply::finished, [this, targetURI, uri, filePlugin]() {
-        if (!_scId || _reply->error() != QNetworkReply::NoError)
-            return;
-
-        QPair<bool, QFileInfo> f1(dynamic_cast<File*>(filePlugin.data())->resolveURI(targetURI));
-
-        QFile res(f1.second.absoluteFilePath());
-        if (!f1.first || !res.open(QIODevice::WriteOnly)) {
-            QVariantMap map;
-            map.insert("code", INVALID_URL_ERR);
-            map.insert("source", uri);
-            map.insert("target", targetURI);
-            _plugin->cb(_ecId, map);
-            emit done();
-            return;
-        }
-        res.write(_reply->readAll());
-
-        _plugin->cb(_scId, dynamic_cast<File*>(filePlugin.data())->file2map(f1.second));
-
-        emit done();
-    });
-    _reply->connect(_reply.data(), SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(error(QNetworkReply::NetworkError)));
-    _reply->connect(_reply.data(), SIGNAL(downloadProgress(qint64, qint64)), this, SLOT(progress(qint64, qint64)));
-}
-
-void FileTransferRequest::upload(const QString& _url, const QString& fileURI, QString fileKey, QString fileName, QString mimeType, const QVariantMap &params, const QVariantMap &headers) {
-    QUrl url(_url);
-    QNetworkRequest request;
-
-    QSharedPointer<CPlugin> filePlugin(_plugin->cordova()->getPlugin<File>());
-
-    if (!filePlugin.data())
-        return;
-
-    if (!url.isValid()) {
-        QVariantMap map;
-        map.insert("code", INVALID_URL_ERR);
-        map.insert("source", fileURI);
-        map.insert("target", _url);
-        _plugin->cb(_ecId, map);
-        emit done();
-        return;
-    }
-
-    QPair<bool, QFileInfo> f1(dynamic_cast<File*>(filePlugin.data())->resolveURI(fileURI));
-    QFile file(f1.second.absoluteFilePath());
-    if (!f1.first || !file.open(QIODevice::ReadOnly)) {
-        QVariantMap map;
-        map.insert("code", FILE_NOT_FOUND_ERR);
-        map.insert("source", fileURI);
-        map.insert("target", _url);
-        _plugin->cb(_ecId, map);
-        emit done();
-        return;
-    }
-    QString content{file.readAll()};
-
-    request.setUrl(url);
-    if (url.password().size() || url.userName().size()) {
-        QString headerData = "Basic " + (url.userName() + ":" + url.password()).toLocal8Bit().toBase64();
-        request.setRawHeader("Authorization", headerData.toLocal8Bit());
-    }
-    SetHeaders(request, headers);
-
-    QString boundary = QString("CORDOVA-QT-%1A").arg(qrand());
-    while (content.contains(boundary)) {
-        boundary += QString("B%1A").arg(qrand());
-    }
-
-    request.setHeader(QNetworkRequest::ContentTypeHeader, QString("multipart/form-data; boundary=") + boundary);
-
-    fileKey.replace("\"", "");
-    fileName.replace("\"", "");
-    mimeType.replace("\"", "");
-    QString part = "--" + boundary + "\r\n";
-
-    part += "Content-Disposition: form-data; name=\"" + fileKey +"\"; filename=\"" + fileName + "\"\r\n";
-    part += "Content-Type: " + mimeType + "\r\n\r\n";
-    part += content + "\r\n";
-
-    for (QString key: params.keys()) {
-        part += "--" + boundary + "\r\n";
-        part += "Content-Disposition: form-data; name=\"" +  key + "\";\r\n\r\n";
-        part += params.find(key)->toString();
-        part += "\r\n";
-    }
-
-    part += QString("--") + boundary + "--" + "\r\n";
-
-    _reply = QSharedPointer<QNetworkReply>(_manager.post(request, QByteArray(part.toUtf8())));
-
-    _reply->connect(_reply.data(), &QNetworkReply::finished, [this, content]() {
-        if (_reply->error() != QNetworkReply::NoError)
-            return;
-        int status = 200;
-        QVariant statusCode = _reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
-
-        if (statusCode.isValid()) {
-            status = statusCode.toInt();
-        }
-
-        QVariantMap map;
-        map.insert("responseCode", status);
-        map.insert("response", QString(_reply->readAll()));
-        map.insert("bytesSent", content.size());
-        _plugin->cb(_scId, map);
-        emit done();
-    });
-    _reply->connect(_reply.data(), SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(error(QNetworkReply::NetworkError)));
-    _reply->connect(_reply.data(), SIGNAL(uploadProgress(qint64, qint64)), this, SLOT(progress(qint64, qint64)));
-}
-
-void FileTransferRequest::abort() {
-    QVariantMap map;
-    map.insert("code", ABORT_ERR);
-    _plugin->cb(_ecId, map);
-    _scId = 0;
-    emit done();
-}
-
-void FileTransferRequest::error(QNetworkReply::NetworkError code) {
-    Q_UNUSED(code);
-
-    int status = 404;
-    QVariant statusCode = _reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
-    if (statusCode.isValid()) {
-        status = statusCode.toInt();
-    }
-
-    QVariantMap map;
-    map.insert("http_status", status);
-    map.insert("body", QString(_reply->readAll()));
-    map.insert("code", CONNECTION_ERR);
-    _plugin->cb(_ecId, map);
-    emit done();
-}
-
-void FileTransferRequest::progress(qint64 bytesReceived, qint64 bytesTotal) {
-    QVariantMap map;
-    map.insert("lengthComputable", true);
-    map.insert("total", bytesTotal);
-    map.insert("loaded", bytesReceived);
-
-    if (bytesReceived && bytesTotal && _scId)
-        _plugin->callbackWithoutRemove(_scId, CordovaInternal::format(map));
-}
diff --git a/src/ubuntu/file-transfer.h b/src/ubuntu/file-transfer.h
deleted file mode 100644
index 75822cb..0000000
--- a/src/ubuntu/file-transfer.h
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- *
- * Copyright 2013 Canonical Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
-*/
-
-#ifndef FILE_TRANSFER_H_SDASDASDAS
-#define FILE_TRANSFER_H_SDASDASDAS
-
-#include <QtCore>
-#include <QtNetwork>
-
-#include <cplugin.h>
-
-class FileTransfer;
-
-class FileTransferRequest: public QObject {
-    Q_OBJECT
-
-    QNetworkAccessManager &_manager;
-    int _scId, _ecId;
-    int _id;
-    QSharedPointer<QNetworkReply> _reply;
-
-    enum FileTransferError {
-        FILE_NOT_FOUND_ERR = 1,
-        INVALID_URL_ERR = 2,
-        CONNECTION_ERR = 3,
-        ABORT_ERR = 4
-    };
-
-public:
-    FileTransferRequest(QNetworkAccessManager &manager, int scId, int ecId, int id, FileTransfer *plugin):
-        _manager(manager),
-        _scId(scId),
-        _ecId(ecId),
-        _id(id),
-        _plugin(plugin) {
-    }
-
-    void download(const QString& url, const QString &targetURI, const QVariantMap &headers);
-    void upload(const QString& _url, const QString& fileURI, QString fileKey, QString fileName, QString mimeType, const QVariantMap &params, const QVariantMap &headers);
-    void abort();
-
-signals:
-    void done();
-
-private slots:
-    void progress(qint64 bytesReceived, qint64 bytesTotal);
-    void error(QNetworkReply::NetworkError code);
-private:
-    FileTransfer *_plugin;
-    Q_DISABLE_COPY(FileTransferRequest);
-};
-
-class FileTransfer : public CPlugin {
-    Q_OBJECT
-public:
-    explicit FileTransfer(Cordova *cordova): CPlugin(cordova) {
-    }
-
-    Cordova* cordova() {
-        return m_cordova;
-    }
-
-    virtual const QString fullName() override {
-        return FileTransfer::fullID();
-    }
-
-    virtual const QString shortName() override {
-        return "FileTransfer";
-    }
-
-    static const QString fullID() {
-        return "FileTransfer";
-    }
-
-public slots:
-    void abort(int scId, int ecId, int id);
-    void download(int scId, int ecId, const QString& url, const QString &target, bool /*trustAllHost*/, int id, const QVariantMap &/*headers*/);
-    void upload(int scId, int ecId, const QString &filePath, const QString& url, const QString& fileKey, const QString& fileName, const QString& mimeType,
-                const QVariantMap & params, bool /*trustAllHosts*/, bool /*chunkedMode*/, const QVariantMap &headers, int id, const QString &httpMethod);
-
-private:
-    QNetworkAccessManager _manager;
-    QMultiMap<int, QSharedPointer<FileTransferRequest> > _id2request;
-    int lastRequestId;
-};
-
-#endif
diff --git a/src/wp/FileTransfer.cs b/src/wp/FileTransfer.cs
deleted file mode 100644
index 4be46e8..0000000
--- a/src/wp/FileTransfer.cs
+++ /dev/null
@@ -1,994 +0,0 @@
-/*
-	Licensed under the Apache License, Version 2.0 (the "License");
-	you may not use this file except in compliance with the License.
-	You may obtain a copy of the License at
-
-	http://www.apache.org/licenses/LICENSE-2.0
-
-	Unless required by applicable law or agreed to in writing, software
-	distributed under the License is distributed on an "AS IS" BASIS,
-	WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-	See the License for the specific language governing permissions and
-	limitations under the License.
-*/
-
-using Microsoft.Phone.Controls;
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.IO.IsolatedStorage;
-using System.Linq;
-using System.Net;
-using System.Runtime.Serialization;
-using System.Windows;
-using System.Security;
-using System.Diagnostics;
-using System.Threading.Tasks;
-using WPCordovaClassLib.Cordova.JSON;
-using System.Reflection;
-
-namespace WPCordovaClassLib.Cordova.Commands
-{
-    public class FileTransfer : BaseCommand
-    {
-        public class DownloadRequestState
-        {
-            // This class stores the State of the request.
-            public HttpWebRequest request;
-            public TransferOptions options;
-            public bool isCancelled;
-
-            public DownloadRequestState()
-            {
-                request = null;
-                options = null;
-                isCancelled = false;
-            }
-        }
-
-        public class TransferOptions
-        {
-            /// File path to upload  OR File path to download to
-            public string FilePath { get; set; }
-
-            public string Url { get; set; }
-            /// Flag to recognize if we should trust every host (only in debug environments)
-            public bool TrustAllHosts { get; set; }
-            public string Id { get; set; }
-            public string Headers { get; set; }
-            public string CallbackId { get; set; }
-            public bool ChunkedMode { get; set; }
-            /// Server address
-            public string Server { get; set; }
-            /// File key
-            public string FileKey { get; set; }
-            /// File name on the server
-            public string FileName { get; set; }
-            /// File Mime type
-            public string MimeType { get; set; }
-            /// Additional options
-            public string Params { get; set; }
-            public string Method { get; set; }
-
-            public TransferOptions()
-            {
-                FileKey = "file";
-                FileName = "image.jpg";
-                MimeType = "image/jpeg";
-            }
-        }
-
-        /// <summary>
-        /// Boundary symbol
-        /// </summary>
-        private string Boundary = "----------------------------" + DateTime.Now.Ticks.ToString("x");
-
-        // Error codes
-        public const int FileNotFoundError = 1;
-        public const int InvalidUrlError = 2;
-        public const int ConnectionError = 3;
-        public const int AbortError = 4; // not really an error, but whatevs
-
-        private static Dictionary<string, DownloadRequestState> InProcDownloads = new Dictionary<string,DownloadRequestState>();
-
-        // Private instance of the main WebBrowser instance
-        // NOTE: Any access to this object needs to occur on the UI thread via the Dispatcher
-        private WebBrowser browser;
-
-
-
-        /// <summary>
-        /// Uploading response info
-        /// </summary>
-        [DataContract]
-        public class FileUploadResult
-        {
-            /// <summary>
-            /// Amount of sent bytes
-            /// </summary>
-            [DataMember(Name = "bytesSent")]
-            public long BytesSent { get; set; }
-
-            /// <summary>
-            /// Server response code
-            /// </summary>
-            [DataMember(Name = "responseCode")]
-            public long ResponseCode { get; set; }
-
-            /// <summary>
-            /// Server response
-            /// </summary>
-            [DataMember(Name = "response", EmitDefaultValue = false)]
-            public string Response { get; set; }
-
-            /// <summary>
-            /// Creates FileUploadResult object with response values
-            /// </summary>
-            /// <param name="bytesSent">Amount of sent bytes</param>
-            /// <param name="responseCode">Server response code</param>
-            /// <param name="response">Server response</param>
-            public FileUploadResult(long bytesSent, long responseCode, string response)
-            {
-                this.BytesSent = bytesSent;
-                this.ResponseCode = responseCode;
-                this.Response = response;
-            }
-        }
-        /// <summary>
-        /// Represents transfer error codes for callback
-        /// </summary>
-        [DataContract]
-        public class FileTransferError
-        {
-            /// <summary>
-            /// Error code
-            /// </summary>
-            [DataMember(Name = "code", IsRequired = true)]
-            public int Code { get; set; }
-
-            /// <summary>
-            /// The source URI
-            /// </summary>
-            [DataMember(Name = "source", IsRequired = true)]
-            public string Source { get; set; }
-
-            /// <summary>
-            /// The target URI
-            /// </summary>
-            ///
-            [DataMember(Name = "target", IsRequired = true)]
-            public string Target { get; set; }
-
-            [DataMember(Name = "body", IsRequired = true)]
-            public string Body { get; set; }
-
-            /// <summary>
-            /// The http status code response from the remote URI
-            /// </summary>
-            [DataMember(Name = "http_status", IsRequired = true)]
-            public int HttpStatus { get; set; }
-
-            /// <summary>
-            /// Creates FileTransferError object
-            /// </summary>
-            /// <param name="errorCode">Error code</param>
-            public FileTransferError(int errorCode)
-            {
-                this.Code = errorCode;
-                this.Source = null;
-                this.Target = null;
-                this.HttpStatus = 0;
-                this.Body = "";
-            }
-            public FileTransferError(int errorCode, string source, string target, int status, string body = "")
-            {
-                this.Code = errorCode;
-                this.Source = source;
-                this.Target = target;
-                this.HttpStatus = status;
-                this.Body = body;
-            }
-        }
-
-        /// <summary>
-        /// Represents a singular progress event to be passed back to javascript
-        /// </summary>
-        [DataContract]
-        public class FileTransferProgress
-        {
-            /// <summary>
-            /// Is the length of the response known?
-            /// </summary>
-            [DataMember(Name = "lengthComputable", IsRequired = true)]
-            public bool LengthComputable { get; set; }
-            /// <summary>
-            /// amount of bytes loaded
-            /// </summary>
-            [DataMember(Name = "loaded", IsRequired = true)]
-            public long BytesLoaded { get; set; }
-            /// <summary>
-            /// Total bytes
-            /// </summary>
-            [DataMember(Name = "total", IsRequired = false)]
-            public long BytesTotal { get; set; }
-
-            public FileTransferProgress(long bTotal = 0, long bLoaded = 0)
-            {
-                LengthComputable = bTotal > 0;
-                BytesLoaded = bLoaded;
-                BytesTotal = bTotal;
-            }
-        }
-
-        /// <summary>
-        /// Represents a request header passed from Javascript to upload/download operations
-        /// </summary>
-        [DataContract]
-        protected struct Header
-        {
-            [DataMember(Name = "name")]
-            public string Name;
-
-            [DataMember(Name = "value")]
-            public string Value;
-        }
-
-        private static MethodInfo JsonDeserializeUsingJsonNet;
-
-        public FileTransfer()
-        {
-            if (JsonDeserializeUsingJsonNet == null)
-            {
-                var method = typeof(JsonHelper).GetMethod("Deserialize", new Type[] { typeof(string), typeof(bool) });
-                if (method != null) 
-                {
-                    JsonDeserializeUsingJsonNet = method.MakeGenericMethod(new Type[] { typeof(Header[]) });
-                }
-            }
-        }
-
-        /// Helper method to copy all relevant cookies from the WebBrowser control into a header on
-        /// the HttpWebRequest
-        /// </summary>
-        /// <param name="browser">The source browser to copy the cookies from</param>
-        /// <param name="webRequest">The destination HttpWebRequest to add the cookie header to</param>
-        /// <returns>Nothing</returns>
-        private async Task CopyCookiesFromWebBrowser(HttpWebRequest webRequest)
-        {
-            var tcs = new TaskCompletionSource<object>();
-
-            // Accessing WebBrowser needs to happen on the UI thread
-            Deployment.Current.Dispatcher.BeginInvoke(() =>
-            {
-                // Get the WebBrowser control
-                if (this.browser == null)
-                {
-                    PhoneApplicationFrame frame = Application.Current.RootVisual as PhoneApplicationFrame;
-                    if (frame != null)
-                    {
-                        PhoneApplicationPage page = frame.Content as PhoneApplicationPage;
-                        if (page != null)
-                        {
-                            CordovaView cView = page.FindName("CordovaView") as CordovaView;
-                            if (cView != null)
-                            {
-                                this.browser = cView.Browser;
-                            }
-                        }
-                    }
-                }
-
-                try
-                {
-                    // Only copy the cookies if the scheme and host match (to avoid any issues with secure/insecure cookies)
-                    // NOTE: since the returned CookieCollection appears to munge the original cookie's domain value in favor of the actual Source domain,
-                    // we can't know for sure whether the cookies would be applicable to any other hosts, so best to play it safe and skip for now.
-                    if (this.browser != null && this.browser.Source.IsAbsoluteUri == true &&
-                        this.browser.Source.Scheme == webRequest.RequestUri.Scheme && this.browser.Source.Host == webRequest.RequestUri.Host)
-                    {
-                        string cookieHeader = "";
-                        string requestPath = webRequest.RequestUri.PathAndQuery;
-                        CookieCollection cookies = this.browser.GetCookies();
-
-                        // Iterate over the cookies and add to the header
-                        foreach (Cookie cookie in cookies)
-                        {
-                            // Check that the path is allowed, first
-                            // NOTE: Path always seems to be empty for now, even if the cookie has a path set by the server.
-                            if (cookie.Path.Length == 0 || requestPath.IndexOf(cookie.Path, StringComparison.InvariantCultureIgnoreCase) == 0)
-                            {
-                                cookieHeader += cookie.Name + "=" + cookie.Value + "; ";
-                            }
-                        }
-
-                        // Finally, set the header if we found any cookies
-                        if (cookieHeader.Length > 0)
-                        {
-                            webRequest.Headers["Cookie"] = cookieHeader;
-                        }
-                    }
-                }
-                catch (Exception)
-                {
-                    // Swallow the exception
-                }
-
-                // Complete the task
-                tcs.SetResult(Type.Missing);
-            });
-
-            await tcs.Task;
-        }
-
-        /// <summary>
-        /// Upload options
-        /// </summary>
-        //private TransferOptions uploadOptions;
-
-        /// <summary>
-        /// Bytes sent
-        /// </summary>
-        private long bytesSent;
-
-        /// <summary>
-        /// sends a file to a server
-        /// </summary>
-        /// <param name="options">Upload options</param>
-        /// exec(win, fail, 'FileTransfer', 'upload', [filePath, server, fileKey, fileName, mimeType, params, trustAllHosts, chunkedMode, headers, this._id, httpMethod]);
-        public void upload(string options)
-        {
-            options = options.Replace("{}", ""); // empty objects screw up the Deserializer
-            string callbackId = "";
-
-            TransferOptions uploadOptions = null;
-            HttpWebRequest webRequest = null;
-
-            try
-            {
-                try
-                {
-                    string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
-                    uploadOptions = new TransferOptions();
-                    uploadOptions.FilePath = args[0];
-                    uploadOptions.Server = args[1];
-                    uploadOptions.FileKey = args[2];
-                    uploadOptions.FileName = args[3];
-                    uploadOptions.MimeType = args[4];
-                    uploadOptions.Params = args[5];
-
-                    bool trustAll = false;
-                    bool.TryParse(args[6],out trustAll);
-                    uploadOptions.TrustAllHosts = trustAll;
-
-                    bool doChunked = false;
-                    bool.TryParse(args[7], out doChunked);
-                    uploadOptions.ChunkedMode = doChunked;
-
-                    //8 : Headers
-                    //9 : id
-                    //10: method
-
-                    uploadOptions.Headers = args[8];
-                    uploadOptions.Id = args[9];
-                    uploadOptions.Method = args[10];
-
-                    uploadOptions.CallbackId = callbackId = args[11];
-                }
-                catch (Exception)
-                {
-                    DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
-                    return;
-                }
-
-                Uri serverUri;
-                try
-                {
-                    serverUri = new Uri(uploadOptions.Server);
-                }
-                catch (Exception)
-                {
-                    DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new FileTransferError(InvalidUrlError, uploadOptions.Server, null, 0)));
-                    return;
-                }
-                webRequest = (HttpWebRequest)WebRequest.Create(serverUri);
-                webRequest.ContentType = "multipart/form-data; boundary=" + Boundary;
-                webRequest.Method = uploadOptions.Method;
-
-                DownloadRequestState reqState = new DownloadRequestState();
-                InProcDownloads[uploadOptions.Id] = reqState;
-                reqState.options = uploadOptions;
-                reqState.request = webRequest;
-
-                try
-                {
-                    // Associate cookies with the request
-                    // This is an async call, so we need to await it in order to preserve proper control flow
-                    Task cookieTask = CopyCookiesFromWebBrowser(webRequest);
-                    cookieTask.Wait();
-                }
-                catch (AggregateException ae)
-                {
-                    DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR,
-                        new FileTransferError(FileTransfer.ConnectionError, uploadOptions.FilePath, uploadOptions.Server, 0, ae.InnerException.Message)));
-                    return;
-                }
-
-                if (!string.IsNullOrEmpty(uploadOptions.Headers))
-                {
-                    Dictionary<string, string> headers = parseHeaders(uploadOptions.Headers);
-                    if (headers != null)
-                    {
-                        foreach (string key in headers.Keys)
-                        {
-                            webRequest.Headers[key] = headers[key];
-                        }
-                    }
-                }
-
-                webRequest.BeginGetRequestStream(uploadCallback, reqState);
-            }
-            catch (Exception /*ex*/)
-            {
-                DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new FileTransferError(ConnectionError)),callbackId);
-            }
-        }
-
-        // example : "{\"Authorization\":\"Basic Y29yZG92YV91c2VyOmNvcmRvdmFfcGFzc3dvcmQ=\"}"
-        protected Dictionary<string,string> parseHeaders(string jsonHeaders)
-        {
-            try
-            {
-                if (FileTransfer.JsonDeserializeUsingJsonNet != null)
-                {
-                    return ((Header[])FileTransfer.JsonDeserializeUsingJsonNet.Invoke(null, new object[] { jsonHeaders, true }))
-                         .ToDictionary(header => header.Name, header => header.Value);
-                }
-                else
-                {
-                    return JsonHelper.Deserialize<Header[]>(jsonHeaders)
-                        .ToDictionary(header => header.Name, header => header.Value);
-                }
-            }
-            catch (Exception)
-            {
-                Debug.WriteLine("Failed to parseHeaders from string :: " + jsonHeaders);
-            }
-            return new Dictionary<string, string>();
-        }
-
-        public void download(string options)
-        {
-            TransferOptions downloadOptions = null;
-            HttpWebRequest webRequest = null;
-            string callbackId;
-
-            try
-            {
-                // source, target, trustAllHosts, this._id, headers
-                string[] optionStrings = JSON.JsonHelper.Deserialize<string[]>(options);
-
-                downloadOptions = new TransferOptions();
-                downloadOptions.Url = optionStrings[0];
-                downloadOptions.FilePath = optionStrings[1];
-
-                bool trustAll = false;
-                bool.TryParse(optionStrings[2],out trustAll);
-                downloadOptions.TrustAllHosts = trustAll;
-
-                downloadOptions.Id = optionStrings[3];
-                downloadOptions.Headers = optionStrings[4];
-                downloadOptions.CallbackId = callbackId = optionStrings[5];
-            }
-            catch (Exception)
-            {
-                DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
-                return;
-            }
-
-            try
-            {
-                // is the URL a local app file?
-                if (downloadOptions.Url.StartsWith("x-wmapp0") || downloadOptions.Url.StartsWith("file:"))
-                {
-                    using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
-                    {
-                        string cleanUrl = downloadOptions.Url.Replace("x-wmapp0:", "").Replace("file:", "").Replace("//","");
-
-                        // pre-emptively create any directories in the FilePath that do not exist
-                        string directoryName = getDirectoryName(downloadOptions.FilePath);
-                        if (!string.IsNullOrEmpty(directoryName) && !isoFile.DirectoryExists(directoryName))
-                        {
-                            isoFile.CreateDirectory(directoryName);
-                        }
-
-                        // just copy from one area of iso-store to another ...
-                        if (isoFile.FileExists(downloadOptions.Url))
-                        {
-                            isoFile.CopyFile(downloadOptions.Url, downloadOptions.FilePath);
-                        }
-                        else
-                        {
-                            // need to unpack resource from the dll
-                            Uri uri = new Uri(cleanUrl, UriKind.Relative);
-                            var resource = Application.GetResourceStream(uri);
-
-                            if (resource != null)
-                            {
-                                // create the file destination
-                                if (!isoFile.FileExists(downloadOptions.FilePath))
-                                {
-                                    var destFile = isoFile.CreateFile(downloadOptions.FilePath);
-                                    destFile.Close();
-                                }
-
-                                using (FileStream fileStream = new IsolatedStorageFileStream(downloadOptions.FilePath, FileMode.Open, FileAccess.Write, isoFile))
-                                {
-                                    long totalBytes = resource.Stream.Length;
-                                    int bytesRead = 0;
-                                    using (BinaryReader reader = new BinaryReader(resource.Stream))
-                                    {
-                                        using (BinaryWriter writer = new BinaryWriter(fileStream))
-                                        {
-                                            int BUFFER_SIZE = 1024;
-                                            byte[] buffer;
-
-                                            while (true)
-                                            {
-                                                buffer = reader.ReadBytes(BUFFER_SIZE);
-                                                // fire a progress event ?
-                                                bytesRead += buffer.Length;
-                                                if (buffer.Length > 0)
-                                                {
-                                                    writer.Write(buffer);
-                                                    DispatchFileTransferProgress(bytesRead, totalBytes, callbackId);
-                                                }
-                                                else
-                                                {
-                                                    writer.Close();
-                                                    reader.Close();
-                                                    fileStream.Close();
-                                                    break;
-                                                }
-                                            }
-                                        }
-                                    }
-                                }
-                            }
-                        }
-                    }
-
-                    File.FileEntry entry = File.FileEntry.GetEntry(downloadOptions.FilePath);
-                    if (entry != null)
-                    {
-                        DispatchCommandResult(new PluginResult(PluginResult.Status.OK, entry), callbackId);
-                    }
-                    else
-                    {
-                        DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, File.NOT_FOUND_ERR), callbackId);
-                    }
-
-                    return;
-                }
-                else
-                {
-                    // otherwise it is web-bound, we will actually download it
-                    //Debug.WriteLine("Creating WebRequest for url : " + downloadOptions.Url);
-                    webRequest = (HttpWebRequest)WebRequest.Create(downloadOptions.Url);
-                }
-            }
-            catch (Exception /*ex*/)
-            {
-                DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR,
-                                      new FileTransferError(InvalidUrlError, downloadOptions.Url, null, 0)));
-                return;
-            }
-
-            if (downloadOptions != null && webRequest != null)
-            {
-                DownloadRequestState state = new DownloadRequestState();
-                state.options = downloadOptions;
-                state.request = webRequest;
-                InProcDownloads[downloadOptions.Id] = state;
-
-                try
-                {
-                    // Associate cookies with the request
-                    // This is an async call, so we need to await it in order to preserve proper control flow
-                    Task cookieTask = CopyCookiesFromWebBrowser(webRequest);
-                    cookieTask.Wait();
-                }
-                catch (AggregateException ae) 
-                {
-                    DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR,
-                        new FileTransferError(FileTransfer.ConnectionError, downloadOptions.Url, downloadOptions.FilePath, 0, ae.InnerException.Message)));
-                    return;
-                }
-
-                if (!string.IsNullOrEmpty(downloadOptions.Headers))
-                {
-                    Dictionary<string, string> headers = parseHeaders(downloadOptions.Headers);
-                    foreach (string key in headers.Keys)
-                    {
-                        webRequest.Headers[key] = headers[key];
-                    }
-                }
-
-                try
-                {
-                    webRequest.BeginGetResponse(new AsyncCallback(downloadCallback), state);
-                }
-                catch (WebException)
-                {
-                    // eat it
-                }
-                // dispatch an event for progress ( 0 )
-                lock (state)
-                {
-                    if (!state.isCancelled)
-                    {
-                        var plugRes = new PluginResult(PluginResult.Status.OK, new FileTransferProgress());
-                        plugRes.KeepCallback = true;
-                        plugRes.CallbackId = callbackId;
-                        DispatchCommandResult(plugRes, callbackId);
-                    }
-                }
-            }
-        }
-
-        public void abort(string options)
-        {
-            Debug.WriteLine("Abort :: " + options);
-            string[] optionStrings = JSON.JsonHelper.Deserialize<string[]>(options);
-            string id = optionStrings[0];
-            string callbackId = optionStrings[1];
-
-            if (id != null && InProcDownloads.ContainsKey(id))
-            {
-                DownloadRequestState state = InProcDownloads[id];
-                if (!state.isCancelled)
-                { // prevent multiple callbacks for the same abort
-                    state.isCancelled = true;
-                    if (!state.request.HaveResponse)
-                    {
-                        state.request.Abort();
-                        InProcDownloads.Remove(id);
-                        //callbackId = state.options.CallbackId;
-                        //state = null;
-                        DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR,
-                                                               new FileTransferError(FileTransfer.AbortError)),
-                                                               state.options.CallbackId);
-                    }
-                }
-            }
-            else
-            {
-                DispatchCommandResult(new PluginResult(PluginResult.Status.IO_EXCEPTION), callbackId); // TODO: is it an IO exception?
-            }
-        }
-
-        private void DispatchFileTransferProgress(long bytesLoaded, long bytesTotal, string callbackId, bool keepCallback = true)
-        {
-            Debug.WriteLine("DispatchFileTransferProgress : " + callbackId);
-            // send a progress change event
-            FileTransferProgress progEvent = new FileTransferProgress(bytesTotal);
-            progEvent.BytesLoaded = bytesLoaded;
-            PluginResult plugRes = new PluginResult(PluginResult.Status.OK, progEvent);
-            plugRes.KeepCallback = keepCallback;
-            plugRes.CallbackId = callbackId;
-            DispatchCommandResult(plugRes, callbackId);
-        }
-
-        /// <summary>
-        ///
-        /// </summary>
-        /// <param name="asynchronousResult"></param>
-        private void downloadCallback(IAsyncResult asynchronousResult)
-        {
-            DownloadRequestState reqState = (DownloadRequestState)asynchronousResult.AsyncState;
-            HttpWebRequest request = reqState.request;
-
-            string callbackId = reqState.options.CallbackId;
-            try
-            {
-                HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(asynchronousResult);
-
-                // send a progress change event
-                DispatchFileTransferProgress(0, response.ContentLength, callbackId);
-
-                using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
-                {
-                    // create any directories in the path that do not exist
-                    string directoryName = getDirectoryName(reqState.options.FilePath);
-                    if (!string.IsNullOrEmpty(directoryName) && !isoFile.DirectoryExists(directoryName))
-                    {
-                        isoFile.CreateDirectory(directoryName);
-                    }
-
-                    // create the file if not exists
-                    if (!isoFile.FileExists(reqState.options.FilePath))
-                    {
-                        var file = isoFile.CreateFile(reqState.options.FilePath);
-                        file.Close();
-                    }
-
-                    using (FileStream fileStream = new IsolatedStorageFileStream(reqState.options.FilePath, FileMode.Open, FileAccess.Write, isoFile))
-                    {
-                        long totalBytes = response.ContentLength;
-                        int bytesRead = 0;
-                        using (BinaryReader reader = new BinaryReader(response.GetResponseStream()))
-                        {
-                            using (BinaryWriter writer = new BinaryWriter(fileStream))
-                            {
-                                int BUFFER_SIZE = 1024;
-                                byte[] buffer;
-
-                                while (true)
-                                {
-                                    buffer = reader.ReadBytes(BUFFER_SIZE);
-                                    // fire a progress event ?
-                                    bytesRead += buffer.Length;
-                                    if (buffer.Length > 0 && !reqState.isCancelled)
-                                    {
-                                        writer.Write(buffer);
-                                        DispatchFileTransferProgress(bytesRead, totalBytes, callbackId);
-                                    }
-                                    else
-                                    {
-                                        writer.Close();
-                                        reader.Close();
-                                        fileStream.Close();
-                                        break;
-                                    }
-                                    System.Threading.Thread.Sleep(1);
-                                }
-                            }
-                        }
-                    }
-                    if (reqState.isCancelled)
-                    {
-                        isoFile.DeleteFile(reqState.options.FilePath);
-                    }
-                }
-
-                if (reqState.isCancelled)
-                {
-                    DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new FileTransferError(AbortError)),
-                  callbackId);
-                }
-                else
-                {
-                    File.FileEntry entry = new File.FileEntry(reqState.options.FilePath);
-                    DispatchCommandResult(new PluginResult(PluginResult.Status.OK, entry), callbackId);
-                }
-            }
-            catch (IsolatedStorageException)
-            {
-                // Trying to write the file somewhere within the IsoStorage.
-                DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new FileTransferError(FileNotFoundError)),
-                                      callbackId);
-            }
-            catch (SecurityException)
-            {
-                // Trying to write the file somewhere not allowed.
-                DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new FileTransferError(FileNotFoundError)),
-                                      callbackId);
-            }
-            catch (WebException webex)
-            {
-                // TODO: probably need better work here to properly respond with all http status codes back to JS
-                // Right now am jumping through hoops just to detect 404.
-                HttpWebResponse response = (HttpWebResponse)webex.Response;
-                if ((webex.Status == WebExceptionStatus.ProtocolError && response.StatusCode == HttpStatusCode.NotFound)
-                    || webex.Status == WebExceptionStatus.UnknownError)
-                {
-                    // Weird MSFT detection of 404... seriously... just give us the f(*&#$@ status code as a number ffs!!!
-                    // "Numbers for HTTP status codes? Nah.... let's create our own set of enums/structs to abstract that stuff away."
-                    // FACEPALM
-                    // Or just cast it to an int, whiner ... -jm
-                    int statusCode = (int)response.StatusCode;
-                    string body = "";
-
-                    using (Stream streamResponse = response.GetResponseStream())
-                    {
-                        using (StreamReader streamReader = new StreamReader(streamResponse))
-                        {
-                            body = streamReader.ReadToEnd();
-                        }
-                    }
-                    FileTransferError ftError = new FileTransferError(ConnectionError, null, null, statusCode, body);
-                    DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, ftError),
-                                          callbackId);
-                }
-                else
-                {
-                    lock (reqState)
-                    {
-                        if (!reqState.isCancelled)
-                        {
-                            DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR,
-                                                                   new FileTransferError(ConnectionError)),
-                                                  callbackId);
-                        }
-                        else
-                        {
-                            Debug.WriteLine("It happened");
-                        }
-                    }
-                }
-            }
-            catch (Exception)
-            {
-                DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR,
-                                                        new FileTransferError(FileNotFoundError)),
-                                      callbackId);
-            }
-
-            //System.Threading.Thread.Sleep(1000);
-            if (InProcDownloads.ContainsKey(reqState.options.Id))
-            {
-                InProcDownloads.Remove(reqState.options.Id);
-            }
-        }
-
-        /// <summary>
-        /// Read file from Isolated Storage and sends it to server
-        /// </summary>
-        /// <param name="asynchronousResult"></param>
-        private void uploadCallback(IAsyncResult asynchronousResult)
-        {
-            DownloadRequestState reqState = (DownloadRequestState)asynchronousResult.AsyncState;
-            HttpWebRequest webRequest = reqState.request;
-            string callbackId = reqState.options.CallbackId;
-
-            try
-            {
-                using (Stream requestStream = (webRequest.EndGetRequestStream(asynchronousResult)))
-                {
-                    string lineStart = "--";
-                    string lineEnd = Environment.NewLine;
-                    byte[] boundaryBytes = System.Text.Encoding.UTF8.GetBytes(lineStart + Boundary + lineEnd);
-                    string formdataTemplate = "Content-Disposition: form-data; name=\"{0}\"" + lineEnd + lineEnd + "{1}" + lineEnd;
-
-                    if (!string.IsNullOrEmpty(reqState.options.Params))
-                    {
-                        Dictionary<string, string> paramMap = parseHeaders(reqState.options.Params);
-                        foreach (string key in paramMap.Keys)
-                        {
-                            requestStream.Write(boundaryBytes, 0, boundaryBytes.Length);
-                            string formItem = string.Format(formdataTemplate, key, paramMap[key]);
-                            byte[] formItemBytes = System.Text.Encoding.UTF8.GetBytes(formItem);
-                            requestStream.Write(formItemBytes, 0, formItemBytes.Length);
-                        }
-                    }
-                    using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
-                    {
-                        if (!isoFile.FileExists(reqState.options.FilePath))
-                        {
-                            DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new FileTransferError(FileNotFoundError, reqState.options.Server, reqState.options.FilePath, 0)));
-                            return;
-                        }
-
-                        byte[] endRequest = System.Text.Encoding.UTF8.GetBytes(lineEnd + lineStart + Boundary + lineStart + lineEnd);
-                        long totalBytesToSend = 0;
-
-                        using (FileStream fileStream = new IsolatedStorageFileStream(reqState.options.FilePath, FileMode.Open, isoFile))
-                        {
-                            string headerTemplate = "Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"" + lineEnd + "Content-Type: {2}" + lineEnd + lineEnd;
-                            string header = string.Format(headerTemplate, reqState.options.FileKey, reqState.options.FileName, reqState.options.MimeType);
-                            byte[] headerBytes = System.Text.Encoding.UTF8.GetBytes(header);
-
-                            byte[] buffer = new byte[4096];
-                            int bytesRead = 0;
-                            //sent bytes needs to be reseted before new upload
-                            bytesSent = 0;
-                            totalBytesToSend = fileStream.Length;
-
-                            requestStream.Write(boundaryBytes, 0, boundaryBytes.Length);
-
-                            requestStream.Write(headerBytes, 0, headerBytes.Length);
-
-                            while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0)
-                            {
-                                if (!reqState.isCancelled)
-                                {
-                                    requestStream.Write(buffer, 0, bytesRead);
-                                    bytesSent += bytesRead;
-                                    DispatchFileTransferProgress(bytesSent, totalBytesToSend, callbackId);
-                                    System.Threading.Thread.Sleep(1);
-                                }
-                                else
-                                {
-                                    throw new Exception("UploadCancelledException");
-                                }
-                            }
-                        }
-
-                        requestStream.Write(endRequest, 0, endRequest.Length);
-                    }
-                }
-                // webRequest
-
-                webRequest.BeginGetResponse(ReadCallback, reqState);
-            }
-            catch (Exception /*ex*/)
-            {
-                if (!reqState.isCancelled)
-                {
-                    DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new FileTransferError(ConnectionError)), callbackId);
-                }
-            }
-        }
-
-        /// <summary>
-        /// Reads response into FileUploadResult
-        /// </summary>
-        /// <param name="asynchronousResult"></param>
-        private void ReadCallback(IAsyncResult asynchronousResult)
-        {
-            DownloadRequestState reqState = (DownloadRequestState)asynchronousResult.AsyncState;
-            try
-            {
-                HttpWebRequest webRequest = reqState.request;
-                string callbackId = reqState.options.CallbackId;
-
-                if (InProcDownloads.ContainsKey(reqState.options.Id))
-                {
-                    InProcDownloads.Remove(reqState.options.Id);
-                }
-
-                using (HttpWebResponse response = (HttpWebResponse)webRequest.EndGetResponse(asynchronousResult))
-                {
-                    using (Stream streamResponse = response.GetResponseStream())
-                    {
-                        using (StreamReader streamReader = new StreamReader(streamResponse))
-                        {
-                            string responseString = streamReader.ReadToEnd();
-                            Deployment.Current.Dispatcher.BeginInvoke(() =>
-                            {
-                                DispatchCommandResult(new PluginResult(PluginResult.Status.OK, new FileUploadResult(bytesSent, (long)response.StatusCode, responseString)));
-                            });
-                        }
-                    }
-                }
-            }
-            catch (WebException webex)
-            {
-                // TODO: probably need better work here to properly respond with all http status codes back to JS
-                // Right now am jumping through hoops just to detect 404.
-                if ((webex.Status == WebExceptionStatus.ProtocolError && ((HttpWebResponse)webex.Response).StatusCode == HttpStatusCode.NotFound)
-                    || webex.Status == WebExceptionStatus.UnknownError)
-                {
-                    int statusCode = (int)((HttpWebResponse)webex.Response).StatusCode;
-                    FileTransferError ftError = new FileTransferError(ConnectionError, null, null, statusCode);
-                    DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, ftError), reqState.options.CallbackId);
-                }
-                else
-                {
-                    DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR,
-                                                           new FileTransferError(ConnectionError)),
-                                          reqState.options.CallbackId);
-                }
-            }
-            catch (Exception /*ex*/)
-            {
-                FileTransferError transferError = new FileTransferError(ConnectionError, reqState.options.Server, reqState.options.FilePath, 403);
-                DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, transferError), reqState.options.CallbackId);
-            }
-        }
-
-        // Gets the full path without the filename
-        private string getDirectoryName(String filePath)
-        {
-            string directoryName;
-            try
-            {
-                directoryName = filePath.Substring(0, filePath.LastIndexOf('/'));
-            }
-            catch
-            {
-                directoryName = "";
-            }
-            return directoryName;
-        }
-    }
-}
diff --git a/tests/tests.js b/tests/tests.js
index c8d9ef3..63c9c1c 100644
--- a/tests/tests.js
+++ b/tests/tests.js
@@ -53,10 +53,9 @@
     var SERVER_WITH_CREDENTIALS = "";
 
     // flags
-    var isWindows = cordova.platformId === "windows8" || cordova.platformId === "windows";
-    var isWindowsPhone81 = isWindows && WinJS.Utilities.isPhone;
-    var isWP8 = cordova.platformId === "windowsphone";
+    var isWindows = cordova.platformId === "windows";
     var isBrowser = cordova.platformId === "browser";
+    var isWindowsPhone = isWindows && WinJS.Utilities.isPhone;
     var isIE = isBrowser && navigator.userAgent.indexOf("Trident") >= 0;
     var isIos = cordova.platformId === "ios";
     var isIot = cordova.platformId === "android" && navigator.userAgent.indexOf("iot") >= 0;
@@ -177,10 +176,6 @@
             );
         };
 
-        // according to documentation, wp8 does not support onProgress:
-        // https://github.com/apache/cordova-plugin-file-transfer/blob/master/doc/index.md#supported-platforms
-        var wp8OnProgressHandler = function () {};
-
         var defaultOnProgressHandler = function (event) {
             if (event.lengthComputable) {
                 expect(event.loaded).toBeGreaterThan(1);
@@ -199,7 +194,7 @@
         };
 
         var getMalformedUrl = function () {
-            if (cordova.platformId === "android" || cordova.platformId === "amazon-fireos") {
+            if (cordova.platformId === "android") {
                 // bad protocol causes a MalformedUrlException on Android
                 return "httpssss://example.com";
             } else {
@@ -330,7 +325,7 @@
                 this.transfer = new FileTransfer();
 
                 // assign onprogress handler
-                this.transfer.onprogress = isWP8 ? wp8OnProgressHandler : defaultOnProgressHandler;
+                this.transfer.onprogress = defaultOnProgressHandler;
 
                 // spy on the onprogress handler, but still call through to it
                 spyOn(this.transfer, "onprogress").and.callThrough();
@@ -491,10 +486,7 @@
                     var fileURL = window.location.protocol + "//" + window.location.pathname.replace(/ /g, "%20");
                     var specContext = this;
 
-                    if (!/^file:/.exec(fileURL) && cordova.platformId !== "blackberry10") {
-                        if (cordova.platformId === "windowsphone") {
-                            expect(fileURL).toMatch(/^x-wmapp0:/);
-                        }
+                    if (!/^file:/.exec(fileURL)) {
                         done();
                         return;
                     }
@@ -645,12 +637,7 @@
                         expect(error.http_status).not.toBe(401, "Ensure " + fileURL + " is in the white list");
                         expect(error.http_status).toBe(404);
 
-                        // wp8 does not make difference between 404 and unknown host
-                        if (isWP8) {
-                            expect(error.code).toBe(FileTransferError.CONNECTION_ERR);
-                        } else {
-                            expect(error.code).toBe(FileTransferError.FILE_NOT_FOUND_ERR);
-                        }
+                        expect(error.code).toBe(FileTransferError.FILE_NOT_FOUND_ERR);
 
                         done();
                     };
@@ -738,13 +725,6 @@
                 });
 
                 it("filetransfer.spec.17 progress should work with gzip encoding", function (done) {
-
-                    // lengthComputable false on bb10 when downloading gzip
-                    if (cordova.platformId === "blackberry10") {
-                        pending();
-                        return;
-                    }
-
                     var fileURL = "http://www.apache.org/";
                     var specContext = this;
 
@@ -781,8 +761,6 @@
 
                         if (isWindows) {
                             expect(nativeURL.substring(0, 14)).toBe("ms-appdata:///");
-                        } else if (isWP8) {
-                            expect(nativeURL.substring(0, 1)).toBe("/");
                         } else {
                             expect(nativeURL.substring(0, 7)).toBe("file://");
                         }
@@ -834,11 +812,6 @@
                 });
 
                 it("filetransfer.spec.33 should properly handle 304", function (done) {
-                    if (isWP8) {
-                        pending();
-                        return;
-                    }
-
                     var downloadFail = function (error) {
                         expect(error.http_status).toBe(304);
                         expect(error.code).toBe(FileTransferError.NOT_MODIFIED_ERR);
@@ -854,11 +827,6 @@
                 }, DOWNLOAD_TIMEOUT);
 
                 it("filetransfer.spec.35 304 should not result in the deletion of a cached file", function (done) {
-                    if (isWP8) {
-                        pending();
-                        return;
-                    }
-
                     var specContext = this;
 
                     var fileOperationFail = function() {
@@ -1103,7 +1071,7 @@
 
                     // windows store and ios are too fast, win is called before we have a chance to abort
                     // so let's get them busy - while not providing an extra load to the slow Android emulators
-                    var arrayLength = ((isWindows && !isWindowsPhone81) || isIos) ? 3000000 : isIot ? 150000 : 200000;
+                    var arrayLength = ((isWindows && !isWindowsPhone) || isIos) ? 3000000 : isIot ? 150000 : 200000;
                     writeFile(specContext.root, specContext.fileName, new Array(arrayLength).join("aborttest!"), fileWin, done);
                 }, UPLOAD_TIMEOUT);
 
diff --git a/www/blackberry10/.jshintrc b/www/blackberry10/.jshintrc
deleted file mode 100644
index 85ccb32..0000000
--- a/www/blackberry10/.jshintrc
+++ /dev/null
@@ -1,5 +0,0 @@
-{
-    "globals": {
-        "requestAnimationFrame": true
-    }
-}
diff --git a/www/blackberry10/FileTransfer.js b/www/blackberry10/FileTransfer.js
deleted file mode 100644
index 76e1682..0000000
--- a/www/blackberry10/FileTransfer.js
+++ /dev/null
@@ -1,190 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
-*/
-
-var argscheck = require('cordova/argscheck'),
-    FileTransferError = require('./FileTransferError'),
-    xhrImpl = require('./BB10XHRImplementation');
-
-
-function getBasicAuthHeader(urlString) {
-    var header =  null;
-
-    if (window.btoa) {
-        // parse the url using the Location object
-        var url = document.createElement('a');
-        url.href = urlString;
-
-        var credentials = null;
-        var protocol = url.protocol + "//";
-        var origin = protocol + url.host;
-
-        // check whether there are the username:password credentials in the url
-        if (url.href.indexOf(origin) !== 0) { // credentials found
-            var atIndex = url.href.indexOf("@");
-            credentials = url.href.substring(protocol.length, atIndex);
-        }
-
-        if (credentials) {
-            var authHeader = "Authorization";
-            var authHeaderValue = "Basic " + window.btoa(credentials);
-
-            header = {
-                name : authHeader,
-                value : authHeaderValue
-            };
-        }
-    }
-
-    return header;
-}
-
-var idCounter = 0;
-
-/**
- * FileTransfer uploads a file to a remote server.
- * @constructor
- */
-var FileTransfer = function() {
-    this._id = ++idCounter;
-    this.onprogress = null; // optional callback
-};
-
-/**
-* Given an absolute file path, uploads a file on the device to a remote server
-* using a multipart HTTP request.
-* @param filePath {String}           Full path of the file on the device
-* @param server {String}             URL of the server to receive the file
-* @param successCallback (Function}  Callback to be invoked when upload has completed
-* @param errorCallback {Function}    Callback to be invoked upon error
-* @param options {FileUploadOptions} Optional parameters such as file name and mimetype
-* @param trustAllHosts {Boolean} Optional trust all hosts (e.g. for self-signed certs), defaults to false
-*/
-FileTransfer.prototype.upload = function(filePath, server, successCallback, errorCallback, options, trustAllHosts) {
-    argscheck.checkArgs('ssFFO*', 'FileTransfer.upload', arguments);
-    // check for options
-    var fileKey = null;
-    var fileName = null;
-    var mimeType = null;
-    var params = null;
-    var chunkedMode = true;
-    var headers = null;
-    var httpMethod = null;
-    var basicAuthHeader = getBasicAuthHeader(server);
-    if (basicAuthHeader) {
-        options = options || {};
-        options.headers = options.headers || {};
-        options.headers[basicAuthHeader.name] = basicAuthHeader.value;
-    }
-
-    if (options) {
-        fileKey = options.fileKey;
-        fileName = options.fileName;
-        mimeType = options.mimeType;
-        headers = options.headers;
-        httpMethod = options.httpMethod || "POST";
-        if (httpMethod.toUpperCase() == "PUT"){
-            httpMethod = "PUT";
-        } else {
-            httpMethod = "POST";
-        }
-        if (options.chunkedMode !== null || typeof options.chunkedMode != "undefined") {
-            chunkedMode = options.chunkedMode;
-        }
-        if (options.params) {
-            params = options.params;
-        }
-        else {
-            params = {};
-        }
-    }
-
-    var fail = errorCallback && function(e) {
-        var error = new FileTransferError(e.code, e.source, e.target, e.http_status, e.body);
-        errorCallback(error);
-    };
-
-    var self = this;
-    var win = function(result) {
-        if (typeof result.lengthComputable != "undefined") {
-            if (self.onprogress) {
-                self.onprogress(result);
-            }
-        } else {
-            if (successCallback) {
-                successCallback(result);
-            }
-        }
-    };
-    xhrImpl.upload(win, fail, [filePath, server, fileKey, fileName, mimeType, params, trustAllHosts, chunkedMode, headers, this._id, httpMethod]);
-};
-
-/**
- * Downloads a file form a given URL and saves it to the specified directory.
- * @param source {String}          URL of the server to receive the file
- * @param target {String}         Full path of the file on the device
- * @param successCallback (Function}  Callback to be invoked when upload has completed
- * @param errorCallback {Function}    Callback to be invoked upon error
- * @param trustAllHosts {Boolean} Optional trust all hosts (e.g. for self-signed certs), defaults to false
- * @param options {FileDownloadOptions} Optional parameters such as headers
- */
-FileTransfer.prototype.download = function(source, target, successCallback, errorCallback, trustAllHosts, options) {
-    argscheck.checkArgs('ssFF*', 'FileTransfer.download', arguments);
-    var self = this;
-
-    var basicAuthHeader = getBasicAuthHeader(source);
-    if (basicAuthHeader) {
-        options = options || {};
-        options.headers = options.headers || {};
-        options.headers[basicAuthHeader.name] = basicAuthHeader.value;
-    }
-
-    var headers = null;
-    if (options) {
-        headers = options.headers || null;
-    }
-
-    var win = function(result) {
-        if (typeof result.lengthComputable != "undefined") {
-            if (self.onprogress) {
-                return self.onprogress(result);
-            }
-        } else if (successCallback) {
-            successCallback(result);
-        }
-    };
-
-    var fail = errorCallback && function(e) {
-        var error = new FileTransferError(e.code, e.source, e.target, e.http_status, e.body);
-        errorCallback(error);
-    };
-
-    xhrImpl.download(win, fail, [source, target, trustAllHosts, this._id, headers]);
-};
-
-/**
- * Aborts the ongoing file transfer on this object. The original error
- * callback for the file transfer will be called if necessary.
- */
-FileTransfer.prototype.abort = function() {
-    xhrImpl.abort(null, null, [this._id]);
-};
-
-module.exports = FileTransfer;
diff --git a/www/blackberry10/FileTransferProxy.js b/www/blackberry10/FileTransferProxy.js
deleted file mode 100644
index a363f07..0000000
--- a/www/blackberry10/FileTransferProxy.js
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
-*/
-
-/*
- * FileTransferProxy
- *
- * Register all FileTransfer exec calls to be handled by proxy
- */
-
-var xhrFileTransfer = require('cordova-plugin-file-transfer.xhrFileTransfer');
-
-module.exports = {
-    abort: xhrFileTransfer.abort,
-    download: xhrFileTransfer.download,
-    upload: xhrFileTransfer.upload
-};
-
-require('cordova/exec/proxy').add('FileTransfer', module.exports);
diff --git a/www/blackberry10/xhrFileTransfer.js b/www/blackberry10/xhrFileTransfer.js
deleted file mode 100644
index 53d0d36..0000000
--- a/www/blackberry10/xhrFileTransfer.js
+++ /dev/null
@@ -1,260 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
-*/
-
-/* global Blob:false */
-
-var cordova = require('cordova'),
-    resolve = cordova.require('cordova-plugin-file.resolveLocalFileSystemURIProxy'),
-    requestAnimationFrame = cordova.require('cordova-plugin-file.bb10RequestAnimationFrame'),
-    xhr = {};
-
-function getParentPath(filePath) {
-    var pos = filePath.lastIndexOf('/');
-    return filePath.substring(0, pos + 1);
-}
-
-function getFileName(filePath) {
-    var pos = filePath.lastIndexOf('/');
-    return filePath.substring(pos + 1);
-}
-
-function checkURL(url) {
-    return url.indexOf(' ') === -1 ?  true : false;
-}
-
-module.exports = {
-    abort: function (win, fail, args) {
-        var id = args[0];
-        if (xhr[id]) {
-            xhr[id].abort();
-            if (typeof(win) === 'function') {
-                win();
-            }
-        } else if (typeof(fail) === 'function') {
-            fail();
-        }
-    },
-
-    upload: function(win, fail, args) {
-        var filePath = args[0],
-            server = args[1],
-            fileKey = args[2],
-            fileName = args[3],
-            mimeType = args[4],
-            params = args[5],
-            /*trustAllHosts = args[6],*/
-            chunkedMode = args[7],
-            headers = args[8],
-            onSuccess = function (data) {
-                if (typeof(win) === 'function') {
-                    win(data);
-                }
-            },
-            onFail = function (code) {
-                delete xhr[fileKey];
-                if (typeof(fail) === 'function') {
-                    fail(code);
-                }
-            };
-
-        if (!checkURL(server)) {
-            onFail(new FileTransferError(FileTransferError.INVALID_URL_ERR, server, filePath));
-        }
-
-        xhr[fileKey] = new XMLHttpRequest();
-        xhr[fileKey].onabort = function () {
-            onFail(new FileTransferError(FileTransferError.ABORT_ERR, server, filePath, this.status, xhr[fileKey].response));
-        };
-
-        resolve(function(entry) {
-            requestAnimationFrame(function () {
-                entry.nativeEntry.file(function(file) {
-                    function uploadFile(blobFile) {
-                        var fd = new FormData();
-
-                        fd.append(fileKey, blobFile, fileName);
-                        for (var prop in params) {
-                            if(params.hasOwnProperty(prop)) {
-                                fd.append(prop, params[prop]);
-                            }
-                        }
-
-                        xhr[fileKey].open("POST", server);
-                        xhr[fileKey].onload = function(evt) {
-                            if (xhr[fileKey].status === 200) {
-                                var result = new FileUploadResult();
-                                result.bytesSent = file.size;
-                                result.responseCode = xhr[fileKey].status;
-                                result.response = xhr[fileKey].response;
-                                delete xhr[fileKey];
-                                onSuccess(result);
-                            } else if (xhr[fileKey].status === 404) {
-                                onFail(new FileTransferError(FileTransferError.INVALID_URL_ERR, server, filePath, xhr[fileKey].status, xhr[fileKey].response));
-                            } else {
-                                onFail(new FileTransferError(FileTransferError.CONNECTION_ERR, server, filePath, xhr[fileKey].status, xhr[fileKey].response));
-                            }
-                        };
-                        xhr[fileKey].ontimeout = function(evt) {
-                            onFail(new FileTransferError(FileTransferError.CONNECTION_ERR, server, filePath, xhr[fileKey].status, xhr[fileKey].response));
-                        };
-                        xhr[fileKey].onerror = function () {
-                            onFail(new FileTransferError(FileTransferError.CONNECTION_ERR, server, filePath, this.status, xhr[fileKey].response));
-                        };
-                        xhr[fileKey].upload.onprogress = function (evt) {
-                            if (evt.loaded > 0) {
-                                onSuccess(evt);
-                            }
-                        };
-
-                        for (var header in headers) {
-                            if (headers.hasOwnProperty(header)) {
-                                xhr[fileKey].setRequestHeader(header, headers[header]);
-                            }
-                        }
-
-                        requestAnimationFrame(function () {
-                            xhr[fileKey].send(fd);
-                        });
-                    }
-
-                    var bytesPerChunk;
-                    if (chunkedMode === true) {
-                        bytesPerChunk = 1024 * 1024; // 1MB chunk sizes.
-                    } else {
-                        bytesPerChunk = file.size;
-                    }
-                    var start = 0;
-                    var end = bytesPerChunk;
-                    while (start < file.size) {
-                        var chunk = file.slice(start, end, mimeType);
-                        uploadFile(chunk);
-                        start = end;
-                        end = start + bytesPerChunk;
-                    }
-                }, function(error) {
-                    onFail(new FileTransferError(FileTransferError.FILE_NOT_FOUND_ERR, server, filePath));
-                });
-            });
-        }, function(error) {
-            onFail(new FileTransferError(FileTransferError.FILE_NOT_FOUND_ERR, server, filePath));
-        }, [filePath]);
-    },
-
-    download: function (win, fail, args) {
-        var source = args[0],
-            target = args[1],
-            id = args[3],
-            headers = args[4],
-            fileWriter,
-            onSuccess = function (entry) {
-                if (typeof(win) === 'function') {
-                    win(entry);
-                }
-            },
-            onFail = function (error) {
-                var reader;
-                delete xhr[id];
-                if (typeof(fail) === 'function') {
-                    if (error && error.body && typeof(error.body) === 'object') {
-                        reader = new FileReader()._realReader;
-                        reader.onloadend = function () {
-                            error.body = this.result;
-                            fail(error);
-                        };
-                        reader.onerror = function () {
-                            fail(error);
-                        };
-                        reader.readAsText(error.body);
-                    } else {
-                        fail(error);
-                    }
-                }
-            };
-
-        if (!checkURL(source)) {
-            onFail(new FileTransferError(FileTransferError.INVALID_URL_ERR, source, target));
-        }
-
-        xhr[id] = new XMLHttpRequest();
-
-        function writeFile(entry) {
-            entry.createWriter(function (writer) {
-                fileWriter = writer;
-                fileWriter.onwriteend = function (evt) {
-                    if (!evt.target.error) {
-                        entry.filesystemName = entry.filesystem.name;
-                        delete xhr[id];
-                        onSuccess(entry);
-                    } else {
-                        onFail(evt.target.error);
-                    }
-                };
-                fileWriter.onerror = function (evt) {
-                    onFail(evt.target.error);
-                };
-                fileWriter.write(new Blob([xhr[id].response]));
-            }, function (error) {
-                onFail(error);
-            });
-        }
-
-        xhr[id].onerror = function (e) {
-            onFail(new FileTransferError(FileTransferError.CONNECTION_ERR, source, target, xhr[id].status, xhr[id].response));
-        };
-
-        xhr[id].onabort = function (e) {
-            onFail(new FileTransferError(FileTransferError.ABORT_ERR, source, target, xhr[id].status, xhr[id].response));
-        };
-
-        xhr[id].onload = function () {
-            if (xhr[id].readyState === xhr[id].DONE) {
-                if (xhr[id].status === 200 && xhr[id].response) {
-                    resolveLocalFileSystemURI(getParentPath(target), function (dir) {
-                        dir.getFile(getFileName(target), {create: true}, writeFile, function (error) {
-                            onFail(new FileTransferError(FileTransferError.FILE_NOT_FOUND_ERR, source, target, xhr[id].status, xhr[id].response));
-                        });
-                    }, function (error) {
-                        onFail(new FileTransferError(FileTransferError.FILE_NOT_FOUND_ERR, source, target, xhr[id].status, xhr[id].response));
-                    });
-                } else if (xhr[id].status === 404) {
-                    onFail(new FileTransferError(FileTransferError.INVALID_URL_ERR, source, target, xhr[id].status, xhr[id].response));
-                } else {
-                    onFail(new FileTransferError(FileTransferError.CONNECTION_ERR, source, target, xhr[id].status, xhr[id].response));
-                }
-            }
-        };
-        xhr[id].onprogress = function (evt) {
-            onSuccess(evt);
-        };
-        xhr[id].open("GET", source, true);
-        for (var header in headers) {
-            if (headers.hasOwnProperty(header)) {
-                xhr[id].setRequestHeader(header, headers[header]);
-            }
-        }
-        xhr[id].responseType = "blob";
-        requestAnimationFrame(function () {
-            if (xhr[id]) {
-                xhr[id].send();
-            }
-        });
-    }
-};
diff --git a/www/firefoxos/FileTransferProxy.js b/www/firefoxos/FileTransferProxy.js
deleted file mode 100644
index 86c46be..0000000
--- a/www/firefoxos/FileTransferProxy.js
+++ /dev/null
@@ -1,222 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
-*/
-
-var FileTransferError = require('./FileTransferError'),
-    xhr = {};
-
-function getParentPath(filePath) {
-    var pos = filePath.lastIndexOf('/');
-    return filePath.substring(0, pos + 1);
-}
-
-function getFileName(filePath) {
-    var pos = filePath.lastIndexOf('/');
-    return filePath.substring(pos + 1);
-}
-
-module.exports = {
-    abort: function (successCallback, errorCallback, args) {
-        var id = args[0];
-        if (xhr[id]) {
-            xhr[id].abort();
-            if (typeof(successCallback) === 'function') {
-                successCallback();
-            }
-        } else if (typeof(errorCallback) === 'function') {
-            errorCallback();
-        }
-    },
-
-    upload: function(successCallback, errorCallback, args) {
-        var filePath = args[0],
-            server = args[1],
-            fileKey = args[2],
-            fileName = args[3],
-            mimeType = args[4],
-            params = args[5],
-            /*trustAllHosts = args[6],*/
-            /*chunkedMode = args[7],*/
-            headers = args[8];
-
-        xhr[fileKey] = new XMLHttpRequest({mozSystem: true});
-        xhr[fileKey].onabort = function() {
-            onFail(new FileTransferError(FileTransferError.ABORT_ERR, server, filePath, this.status, xhr[fileKey].response));
-        };
-
-        window.resolveLocalFileSystemURL(filePath, function(entry) {
-            entry.file(function(file) {
-                var reader = new FileReader();
-
-                reader.onloadend = function() {
-                    var blob = new Blob([this.result], {type: mimeType});
-                    var fd = new FormData();
-
-                    fd.append(fileKey, blob, fileName);
-
-                    for (var prop in params) {
-                        if (params.hasOwnProperty(prop)) {
-                            fd.append(prop, params[prop]);
-                        }
-                    }
-
-                    xhr[fileKey].open("POST", server);
-
-                    xhr[fileKey].onload = function(evt) {
-                        if (xhr[fileKey].status === 200) {
-                            var result = new FileUploadResult();
-                            result.bytesSent = blob.size;
-                            result.responseCode = xhr[fileKey].status;
-                            result.response = xhr[fileKey].response;
-                            delete xhr[fileKey];
-                            onSuccess(result);
-                        } else if (xhr[fileKey].status === 404) {
-                            onFail(new FileTransferError(FileTransferError.INVALID_URL_ERR, server, filePath, xhr[fileKey].status, xhr[fileKey].response));
-                        } else {
-                            onFail(new FileTransferError(FileTransferError.CONNECTION_ERR, server, filePath, xhr[fileKey].status, xhr[fileKey].response));
-                        }
-                    };
-
-                    xhr[fileKey].ontimeout = function() {
-                        onFail(new FileTransferError(FileTransferError.CONNECTION_ERR, server, filePath, xhr[fileKey].status, xhr[fileKey].response));
-                    };
-
-                    xhr[fileKey].onerror = function() {
-                        onFail(new FileTransferError(FileTransferError.CONNECTION_ERR, server, filePath, this.status, xhr[fileKey].response));
-                    };
-
-                    for (var header in headers) {
-                        if (headers.hasOwnProperty(header)) {
-                            xhr[fileKey].setRequestHeader(header, headers[header]);
-                        }
-                    }
-
-                    xhr[fileKey].send(fd);
-                };
-
-                reader.readAsArrayBuffer(file);
-
-            }, function() {
-                onFail(new FileTransferError(FileTransferError.FILE_NOT_FOUND_ERR, server, filePath));
-            });
-        }, function() {
-            onFail(new FileTransferError(FileTransferError.FILE_NOT_FOUND_ERR, server, filePath));
-        });
-
-        function onSuccess(data) {
-            if (typeof(successCallback) === 'function') {
-                successCallback(data);
-            }
-        }
-
-        function onFail(code) {
-            delete xhr[fileKey];
-            if (typeof(errorCallback) === 'function') {
-                errorCallback(code);
-            }
-        }
-    },
-
-    download: function (successCallback, errorCallback, args) {
-        var source = args[0],
-            target = args[1],
-            id = args[3],
-            headers = args[4];
-
-        xhr[id] = new XMLHttpRequest({mozSystem: true});
-
-        xhr[id].onload = function () {
-            if (xhr[id].readyState === xhr[id].DONE) {
-                if (xhr[id].status === 200 && xhr[id].response) {
-                    window.resolveLocalFileSystemURL(getParentPath(target), function (dir) {
-                        dir.getFile(getFileName(target), {create: true}, writeFile, function (error) {
-                            onFail(new FileTransferError(FileTransferError.FILE_NOT_FOUND_ERR, source, target, xhr[id].status, xhr[id].response));
-                        });
-                    }, function () {
-                        onFail(new FileTransferError(FileTransferError.FILE_NOT_FOUND_ERR, source, target, xhr[id].status, xhr[id].response));
-                    });
-                } else if (xhr[id].status === 404) {
-                    onFail(new FileTransferError(FileTransferError.INVALID_URL_ERR, source, target, xhr[id].status, xhr[id].response));
-                } else {
-                    onFail(new FileTransferError(FileTransferError.CONNECTION_ERR, source, target, xhr[id].status, xhr[id].response));
-                }
-            }
-        };
-
-        function writeFile(entry) {
-            entry.createWriter(function (fileWriter) {
-                fileWriter.onwriteend = function (evt) {
-                    if (!evt.target.error) {
-                        entry.filesystemName = entry.filesystem.name;
-                        delete xhr[id];
-                        onSuccess(entry);
-                    } else {
-                        onFail(evt.target.error);
-                    }
-                };
-                fileWriter.onerror = function (evt) {
-                    onFail(evt.target.error);
-                };
-                fileWriter.write(new Blob([xhr[id].response]));
-            }, function (error) {
-                onFail(error);
-            });
-        }
-
-        xhr[id].onerror = function (e) {
-            onFail(new FileTransferError(FileTransferError.CONNECTION_ERR, source, target, xhr[id].status, xhr[id].response));
-        };
-
-        xhr[id].onabort = function (e) {
-            onFail(new FileTransferError(FileTransferError.ABORT_ERR, source, target, xhr[id].status, xhr[id].response));
-        };
-
-        xhr[id].open("GET", source, true);
-
-        for (var header in headers) {
-            if (headers.hasOwnProperty(header)) {
-                xhr[id].setRequestHeader(header, headers[header]);
-            }
-        }
-
-        xhr[id].responseType = "blob";
-
-        setTimeout(function () {
-            if (xhr[id]) {
-                xhr[id].send();
-            }
-        }, 0);
-
-        function onSuccess(entry) {
-            if (typeof(successCallback) === 'function') {
-                successCallback(entry);
-            }
-        }
-
-        function onFail(error) {
-            delete xhr[id];
-            if (typeof(errorCallback) === 'function') {
-                errorCallback(error);
-            }
-        }
-    }
-};
-
-require('cordova/exec/proxy').add('FileTransfer', module.exports);
diff --git a/www/wp7/base64.js b/www/wp7/base64.js
deleted file mode 100644
index 221e30a..0000000
--- a/www/wp7/base64.js
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
-*/
-
-// jshint ignore: start
-
-var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=',
-    INVALID_CHARACTER_ERR = (function () {
-        // fabricate a suitable error object
-        try { document.createElement('$'); }
-        catch (error) { return error; }
-    }());
-
-    // encoder
-    // [https://gist.github.com/999166] by [https://github.com/nignag]
-    window.btoa || (
-    window.btoa = function (input) {
-        for (
-            // initialize result and counter
-          var block, charCode, idx = 0, map = chars, output = '';
-            // if the next input index does not exist:
-            //   change the mapping table to "="
-            //   check if d has no fractional digits
-          input.charAt(idx | 0) || (map = '=', idx % 1) ;
-            // "8 - idx % 1 * 8" generates the sequence 2, 4, 6, 8
-          output += map.charAt(63 & block >> 8 - idx % 1 * 8)
-        ) {
-            charCode = input.charCodeAt(idx += 3 / 4);
-            if (charCode > 0xFF) throw INVALID_CHARACTER_ERR;
-            block = block << 8 | charCode;
-        }
-        return output;
-    });
-
-    // decoder
-    // [https://gist.github.com/1020396] by [https://github.com/atk]
-    window.atob || (
-    window.atob = function (input) {
-        input = input.replace(/=+$/, '')
-        if (input.length % 4 == 1) throw INVALID_CHARACTER_ERR;
-        for (
-            // initialize result and counters
-          var bc = 0, bs, buffer, idx = 0, output = '';
-            // get next character
-          buffer = input.charAt(idx++) ;
-            // character found in table? initialize bit storage and add its ascii value;
-          ~buffer && (bs = bc % 4 ? bs * 64 + buffer : buffer,
-            // and if not first of each 4 characters,
-            // convert the first 8 bits to one ascii character
-            bc++ % 4) ? output += String.fromCharCode(255 & bs >> (-2 * bc & 6)) : 0
-        ) {
-            // try to find character in table (0-63, not found => -1)
-            buffer = chars.indexOf(buffer);
-        }
-        return output;
-    });
\ No newline at end of file