docs: function BpmnQuestionnaire(options) {
  
    // Check if options was provided
    if (!options) {
      throw new Error('No options provided');
    }
  
    if (has(options, 'questionnaireJson')) {
      this.questionnaireJson = options.questionnaireJson;
    } else {
  
      // Report error
      throw new Error('No questionnaire specified');
    }
  
    // Events
    this.events = new EventEmitter();
  
    // Services
    this.services = {
      translator: (function(){
        var translator;
  
        if(has(options, 'plugins.translator')) {
          // translator = new Translator(options.plugins.translator)
          translator = new Translator(options.plugins.translator);
        } else {
          translator = new Translator();
        }
  
        return translator.translate.bind(translator);
      }())
    }
  
    // Check if types were provided
    if (options.types) {
      this.types = options.types;
    }
  
    // Check if questions were provided
    if (this.questionnaireJson.questions.length) {
      this.questions = [];
      var that = this;
  
      // Create questions
      this.questionnaireJson.questions.forEach(function(question, index) {
  
        // Check if type of question was provided
        if (!typeof that.types[question.type] === 'function') {
  
          // Report error
          throw new Error('Type not specified');
        } else {
  
          // Add instance of question to array of questions
          that.questions.push(
            new that.types[question.type](index, question, that)
          );
        }
      });
    } else {
  
      // Report error
      throw new Error('No questions specified');
    }
  
    // Initial state is immutable
    this.initState = Immutable({
      currentQuestion: 0,
      progress:        0,
      view:            'intro'
    });
  
    // Set state to mutable copy of initial state
    this.state = this.initState.asMutable({deep: true});
  
    // Set up loop
    this.loop = mainLoop(this.state, this.render.bind(this), {
      create: require("virtual-dom/create-element"),
      diff:   require("virtual-dom/diff"),
      patch:  require("virtual-dom/patch")
    });
  
    // Check if container element was specified
    if (!options.container) {
      throw new Error('No container element specified');
    }
  
    // Append questionnaire to container element
    if (typeof options.container === 'string') {
  
      // Search for element with given ID
      var container = document.getElementById(options.container);
  
      // Error handling
      if (!container) {
        throw new Error('Container element not found');
      }
  
      this.container = container;
    } else if (options.container.appendChild) {
  
      // Append questionnaire
      this.container = options.container;
    } else {
      throw new Error('Container element not found');
    }
  
    // Append questionnaire
    this.container.appendChild(this.loop.target);
  }