(function() {
  if(typeof Promise === 'undefined') {
    throw "old browser without Promise object. Please load a polyfill before loading dbc_openplatform.min.js, if you want to make it work";
  }
  var cycle = require('cycle');
  var sc;
  sc = false;
  var apiToken;
  var endpoints = [
    "availability",
    "events",
    "facets",
    "libraries",
    "news",
    "order",
    "rank",
    "recommend",
    "renew",
    "search",
    "suggest",
    "user",
    "work"];

  dbcOpenPlatform = {};
  function endpoint(name) {
    return function(params) {
      params = Object.assign({access_token: apiToken}, params);
      var envelope = params.envelope;
      delete params.envelope;
      if(!this.connected()) {
        return Promise.reject('need to connect before calling endpoint');
      }
      return new Promise(function(resolve, reject) {
        sc.emit(name, params, function(err, result) {
          if(err) {
            return reject(err);
          }
          result = cycle.retrocycle(result);
          if(!result.statusCode || result.statusCode !== 200) {
            reject(result);
          } else {
            resolve(envelope ? result : result.data);
          }
        });
      });
    };
  }
  for(var i = 0; i < endpoints.length; ++i) {
    dbcOpenPlatform[endpoints[i]] = endpoint(endpoints[i]);
  }

  /**
   * Connect to the DBC open platform.
   * takes token, or client_id,client_secret 
   * or client_id,client_secret,user_id,user_passed
   * as parameters.
   */
  dbcOpenPlatform.connect = function() {
    var promise, args, clientId, clientSecret, user, password;

    args = Array.prototype.slice.call(arguments);
    if(!args.length === 0 && !apiToken) {
      if(!apiToken) {
        throw "missing token to connect";
      }
      promise = Promise.resolve(apiToken);
    } else if(args.length === 1) {
      promise = Promise.resolve(args[0]);
    } else {
      clientId = args[0];
      clientSecret = args[1];
      if(args.length === 2) {
        user = '@';
        password = '@';
      } else if(args.length === 4) {
        user = args[2];
        password = args[3];
      } else {
        throw "dbcOpenPlatform.connect takes 0, 1, 2 or 4 parameters"
      }
      promise = getToken(clientId, clientSecret, user, password);
    }
    return promise.then(function(token) {
      apiToken = token;
      return new Promise(function(resolve, reject) {
        if(sc) {
          sc.on('connectAbort', function() {
            sc = undefined;
            resolve(dbcServiceProvider.connect(token));
          });
          sc.on('connect', function() {
            resolve(token);
          });
          sc.connect();
          return;
        } 
        sc = require('socketcluster-client').connect({
            hostname: 'openplatform.dbc.dk', 
            port: 443,
            secure: true,
            path: '/v0/socketcluster/?access_token=' + token
          });
        sc.on('connectAbort', function(result) {
          reject(result);
        });
        sc.on('connect', function() {
          resolve(token);
        });
      });
    });
  };
  dbcOpenPlatform.disconnect = function() {
    if(sc) {
      sc.disconnect();
    }
    return Promise.resolve();
  };
  dbcOpenPlatform.connected = function() {
    return sc && sc.state === 'open';
  };
  function getToken(clientId, clientSecret, user, passwd) {
    var xhr = new XMLHttpRequest();

    xhr.open('POST', 'https://auth.dbc.dk/oauth/token');

    xhr.setRequestHeader('Authorization', 'Basic ' + 
        btoa(client_id() + ':' + client_secret()));

    xhr.setRequestHeader('Content-Type',
        'application/x-www-form-urlencoded');

    xhr.send('grant_type=password' +
        '&username=' + user_id() +
        '&password=' + user_password());

    return new Promise(function(resolve, reject) {
      xhr.onreadystatechange = function() {
        if(xhr.readyState === 4) {
          if(xhr.status === 200) {
            var result = xhr.response;
            result = JSON.parse(result).access_token;
            resolve(result);
          } else {
            reject(xhr);
          }
        }
      }
    });

  }
})();

@@ -56,17 +56,17 @@
   throw 
-%22
+'
 old brow
@@ -183,17 +183,17 @@
  it work
-%22
+'
 ;%0A  %7D%0A  
@@ -286,17 +286,17 @@
 = %5B%0A    
-%22
+'
 availabi
@@ -303,44 +303,44 @@
 lity
-%22
+'
 ,%0A    
-%22
+'
 events
-%22
+'
 ,%0A    
-%22
+'
 facets
-%22
+'
 ,%0A    
-%22
+'
 libr
@@ -348,53 +348,53 @@
 ries
-%22
+'
 ,%0A    
-%22
+'
 news
-%22
+'
 ,%0A    
-%22
+'
 order
-%22
+'
 ,%0A    
-%22
+'
 rank
-%22
+'
 ,%0A    
-%22
+'
 reco
@@ -402,75 +402,75 @@
 mend
-%22
+'
 ,%0A    
-%22
+'
 renew
-%22
+'
 ,%0A    
-%22
+'
 search
-%22
+'
 ,%0A    
-%22
+'
 suggest
-%22
+'
 ,%0A    
-%22
+'
 user
-%22
+'
 ,%0A    
-%22
+'
 work
-%22
+'
 %5D;%0A%0A
@@ -1734,17 +1734,17 @@
   throw 
-%22
+'
 missing 
@@ -1759,17 +1759,17 @@
  connect
-%22
+'
 ;%0A      
@@ -2151,17 +2151,17 @@
   throw 
-%22
+'
 dbcOpenP
@@ -2209,9 +2209,133 @@
 ters
-%22
+'%0A      %7D%0A      if(user.indexOf('@') === -1) %7B%0A        throw 'id should be the concatenation of user-id, %22@%22, and agency-id';
 %0A   

check for @ in user-id, fixes #420 (plus use quotes in the same way) (#421)