function PunkAveFileUploader(options)
{
  var self = this,
    uploadUrl = options.uploadUrl,
    viewUrl = options.viewUrl,
    $el = $(options.el),
    uploaderTemplate = _.template($('#file-uploader-template').html());
  $el.html(uploaderTemplate({}));

  var fileTemplate = _.template($('#file-uploader-file-template').html()),
    editor = $el.find('[data-files="1"]'),
    thumbnails = $el.find('[data-thumbnails="1"]');
  
  self.uploading = false;

  self.addExistingFiles = function(files)
  {
    _.each(files, function(file) {
      appendEditableImage({
        // cmsMediaUrl is a global variable set by the underscoreTemplates partial of MediaItems.html.twig
        'thumbnail_url': viewUrl + '/thumbnails/' + file,
        'url': uploadUrl + '/originals/' + file,
        'name': file
        });
    });
  };

  // Delay form submission until upload is complete.
  // Note that you are welcome to examine the
  // uploading property yourself if this isn't
  // quite right for you
  self.delaySubmitWhileUploading = function(sel)
  {
    $(sel).submit(function(e) {
        if (!self.uploading)
        {
            return true;
        }
        function attempt()
        {
            if (self.uploading)
            {
                setTimeout(attempt, 100);
            }
            else
            {
                $(sel).submit();
            }
        }
        attempt();
        return false;
    });
  }

  if (options.blockFormWhileUploading)
  {
    self.blockFormWhileUploading(options.blockFormWhileUploading);
  }

  if (options.existingFiles)
  {
    self.addExistingFiles(options.existingFiles);
  }

  editor.fileupload({
    dataType: 'json',
    url: uploadUrl,
    dropZone: $el.find('[data-dropzone="1"]'),
    done: function (e, data) {
      if (data)
      {
        _.each(data.result, function(item) {
          appendEditableImage(item);
        });
      }
    },
    start: function (e) {
      $el.find('[data-spinner="1"]').show();
      self.uploading = true;
    },
    stop: function (e) {
      $el.find('[data-spinner="1"]').hide();
      self.uploading = false;
    },
  });

  // Expects thumbnail_url, url, and name properties. thumbnail_url can be undefined if
  // url does not end in gif, jpg, jpeg or png. This is designed to work with the
  // result returned by the UploadHandler class on the PHP side
  function appendEditableImage(info)
  {
    // TODO: share the error's specifics
    if (info.error)
    {
      return;
    }
    var li = $(fileTemplate(info));
    li.find('[data-action="delete"]').click(function(event) {
      var file = $(this).closest('[data-name]');
      var name = file.attr('data-name');
      $.ajax({
        type: 'delete',
        url: setQueryParameter(uploadUrl, 'file', name),
        success: function() {
          file.remove();
        },
        dataType: 'json'
      });
      return false;
    });

    thumbnails.append(li);
  }

  function setQueryParameter(url, param, paramVal)
  {
    var newAdditionalURL = "";
    var tempArray = url.split("?");
    var baseURL = tempArray[0];
    var additionalURL = tempArray[1]; 
    var temp = "";
    if (additionalURL)
    {
        var tempArray = additionalURL.split("&");
        var i;
        for (i = 0; i < tempArray.length; i++)
        {
            if (tempArray[i].split('=')[0] != param )
            {
                newAdditionalURL += temp + tempArray[i];
                temp = "&";
            }
        }
    }
    var newTxt = temp + "" + param + "=" + encodeURIComponent(paramVal);
    var finalURL = baseURL + "?" + newAdditionalURL + newTxt;
    return finalURL;
  }
}



@@ -448,16 +448,136 @@
 = false;
+%0A  %0A  self.errorCallback = 'errorCallback' in options ? options.errorCallback : function( info ) %7B console.log(info); %7D,
 %0A%0A  self
@@ -677,16 +677,22 @@
 leImage(
+self, 
 %7B%0A      
@@ -865,22 +865,20 @@
  'url': 
-upload
+view
 Url + '/
@@ -1999,16 +1999,22 @@
 leImage(
+self, 
 item);%0A 
@@ -2251,17 +2251,16 @@
 e;%0A    %7D
-,
 %0A  %7D);%0A%0A
@@ -2524,16 +2524,25 @@
 leImage(
+punkave, 
 info)%0A  
@@ -2551,70 +2551,64 @@
     
-// TODO: share the error's specifics%0A    if (info.error)%0A    %7B
+if (info.error)%0A    %7B%0A      punkave.errorCallback(info);
 %0A   

fix a trailing comma for ie. allow a callback function 'errorCallback' in the options. change initial existing files to use the viewUrl.