text: // namespaces
  var dwv = dwv || {};
  dwv.io = dwv.io || {};
  
  /**
   * DICOM data loader.
   * @constructor
   */
  dwv.io.DicomDataLoader = function ()
  {
      // closure to self
      var self = this;
  
      /**
       * Loader options.
       * @private
       * @type Object
       */
      var options = {};
  
      /**
       * Loading flag.
       * @private
       * @type Boolean
       */
      var isLoading = false;
  
      /**
       * Set the loader options.
       * @param {Object} opt The input options.
       */
      this.setOptions = function (opt) {
          options = opt;
      };
  
      /**
       * Is the load ongoing?
       * @return {Boolean} True if loading.
       */
      this.isLoading = function () {
          return isLoading;
      };
  
      /**
       * DICOM buffer to dwv.image.View (asynchronous)
       * @private
       */
      var db2v = new dwv.image.DicomBufferToView();
  
      /**
       * Load data.
       * @param {Object} buffer The DICOM buffer.
       * @param {String} origin The data origin.
       * @param {Number} index The data index.
       */
      this.load = function (buffer, origin, index) {
          // setup db2v ony once
          if (!isLoading) {
              // set character set
              if (typeof options.defaultCharacterSet !== "undefined") {
                  db2v.setDefaultCharacterSet(options.defaultCharacterSet);
              }
              // connect handlers
              db2v.onloadstart = self.onloadstart;
              db2v.onprogress = self.onprogress;
              db2v.onloaditem = self.onloaditem;
              db2v.onload = self.onload;
              db2v.onloadend = function (event) {
                  // reset loading flag
                  isLoading = false;
                  // call listeners
                  self.onloadend(event);
              };
              db2v.onerror = self.onerror;
              db2v.onabort = self.onabort;
          }
  
          // set loading flag
          isLoading = true;
          // convert
          db2v.convert(buffer, origin, index);
      };
  
      /**
       * Abort load.
       */
      this.abort = function () {
          // reset loading flag
          isLoading = false;
          // abort conversion, will trigger db2v.onabort
          db2v.abort();
      };
  
  }; // class DicomDataLoader
  
  /**
   * Check if the loader can load the provided file.
   * @param {Object} file The file to check.
   * @return True if the file can be loaded.
   */
  dwv.io.DicomDataLoader.prototype.canLoadFile = function (file) {
      var ext = dwv.utils.getFileExtension(file.name);
      var hasNoExt = (ext === null);
      var hasDcmExt = (ext === "dcm");
      return hasNoExt || hasDcmExt;
  };
  
  /**
   * Check if the loader can load the provided url.
   * True if:
   *  - the url has a 'contentType' and it is 'application/dicom' (as in wado urls)
   *  - the url has no 'contentType' and no extension or the extension is 'dcm'
   * @param {String} url The url to check.
   * @return True if the url can be loaded.
   */
  dwv.io.DicomDataLoader.prototype.canLoadUrl = function (url) {
      var urlObjext = dwv.utils.getUrlFromUri(url);
      // extension
      var ext = dwv.utils.getFileExtension(urlObjext.pathname);
      var hasNoExt = (ext === null);
      var hasDcmExt = (ext === "dcm");
      // content type (for wado url)
      var contentType = urlObjext.searchParams.get("contentType");
      var hasContentType = contentType !== null &&
          typeof contentType !== "undefined";
      var hasDicomContentType = (contentType === "application/dicom");
  
      return hasContentType ? hasDicomContentType : (hasNoExt || hasDcmExt);
  };
  
  /**
   * Get the file content type needed by the loader.
   * @return One of the 'dwv.io.fileContentTypes'.
   */
  dwv.io.DicomDataLoader.prototype.loadFileAs = function () {
      return dwv.io.fileContentTypes.ArrayBuffer;
  };
  
  /**
   * Get the url content type needed by the loader.
   * @return One of the 'dwv.io.urlContentTypes'.
   */
  dwv.io.DicomDataLoader.prototype.loadUrlAs = function () {
      return dwv.io.urlContentTypes.ArrayBuffer;
  };
  
  /**
   * Handle a load start event.
   * @param {Object} event The load start event.
   * Default does nothing.
   */
  dwv.io.DicomDataLoader.prototype.onloadstart = function (/*event*/) {};
  /**
   * Handle a progress event.
   * @param {Object} event The load progress event.
   * Default does nothing.
   */
  dwv.io.DicomDataLoader.prototype.onprogress = function (/*event*/) {};
  /**
   * Handle a load item event.
   * @param {Object} event The load item event fired
   *   when a file item has been loaded successfully.
   * Default does nothing.
   */
  dwv.io.DicomDataLoader.prototype.onloaditem = function (/*event*/) {};
  /**
   * Handle a load event.
   * @param {Object} event The load event fired
   *   when a file has been loaded successfully.
   * Default does nothing.
   */
  dwv.io.DicomDataLoader.prototype.onload = function (/*event*/) {};
  /**
   * Handle an load end event.
   * @param {Object} event The load end event fired
   *  when a file load has completed, successfully or not.
   * Default does nothing.
   */
  dwv.io.DicomDataLoader.prototype.onloadend = function (/*event*/) {};
  /**
   * Handle an error event.
   * @param {Object} event The error event.
   * Default does nothing.
   */
  dwv.io.DicomDataLoader.prototype.onerror = function (/*event*/) {};
  /**
   * Handle an abort event.
   * @param {Object} event The abort event.
   * Default does nothing.
   */
  dwv.io.DicomDataLoader.prototype.onabort = function (/*event*/) {};
  
  /**
   * Add to Loader list.
   */
  dwv.io.loaderList = dwv.io.loaderList || [];
  dwv.io.loaderList.push( "DicomDataLoader" );
  