docs: function Feedback(options) {
          var tmp;
  
          if ('undefined' !== typeof options.maxLength) {
              console.log('***Feedback constructor: maxLength is deprecated, ' +
                          'use maxChars instead***');
              options.maxChars = options.maxLength;
          }
          if ('undefined' !== typeof options.minLength) {
              console.log('***Feedback constructor: minLength is deprecated, ' +
                          'use minChars instead***');
              options.minChars = options.minLength;
          }
  
          /**
           * ### Feedback.mainText
           *
           * The main text introducing the choices
           *
           * @see Feedback.spanMainText
           */
          this.mainText = null;
  
          /**
           * ### Feedback.hint
           *
           * An additional text with information about how to select items
           *
           * If not specified, it may be auto-filled, e.g. '(pick 2)'.
           *
           * @see Feedback.texts.autoHint
           */
          this.hint = null;
  
          /**
           * ### Feedback.spanMainText
           *
           * The span containing the main text
           */
          this.spanMainText = null;
  
          /**
           * ### Feedback.maxChars
           *
           * The maximum character length for feedback to be submitted
           *
           * Default: 0
           */
          if ('undefined' === typeof options.maxChars) {
              this.maxChars = 0;
          }
          else {
              tmp = J.isInt(options.maxChars, 0);
              if (tmp !== false) {
                  this.maxChars = tmp;
              }
              else {
                  throw new TypeError('Feedback constructor: maxChars ' +
                                      'must be an integer >= 0 or undefined. ' +
                                      'Found: ' + options.maxChars);
              }
          }
  
          /**
           * ### Feedback.minChars
           *
           * The minimum character length for feedback to be submitted
           *
           * If minChars = 0, then there is no minimum length checked.
           *
           * Default: 0
           */
          if ('undefined' === typeof options.minChars) {
              this.minChars = 0;
          }
          else {
              tmp = J.isInt(options.minChars, 0, undefined, true);
              if (tmp !== false) {
                  if (this.maxChars && tmp > this.maxChars) {
                      throw new TypeError('Feedback constructor: minChars ' +
                                          'cannot be greater than maxChars. ' +
                                          'Found: ' + tmp + ' > ' +
                                          this.maxChars);
                  }
                  this.minChars = tmp;
              }
              else {
                  throw new TypeError('Feedback constructor: minChars ' +
                                      'must be an integer >= 0 or undefined. ' +
                                      'Found: ' + options.minChars);
              }
          }
  
          /**
           * ### Feedback.maxWords
           *
           * The maximum number of words for feedback to be submitted
           *
           * Set to 0 for no checks.
           *
           * Default: 0
           */
          if ('undefined' === typeof options.maxWords) {
              this.maxWords = 0;
          }
          else {
              tmp = J.isInt(options.maxWords, 0, undefined, true);
              if (tmp !== false) {
                  this.maxWords = options.maxWords;
              }
              else {
                  throw new TypeError('Feedback constructor: maxWords ' +
                                      'must be an integer >= 0 or undefined. ' +
                                      'Found: ' + options.maxWords);
              }
          }
  
          /**
           * ### Feedback.minWords
           *
           * The minimum number of words for feedback to be submitted
           *
           * If minWords = 0, then there is no minimum checked.
           *
           * Default: 0
           */
          if ('undefined' === typeof options.minWords) {
              this.minWords = 0;
          }
          else {
              tmp = J.isInt(options.minWords, 0, undefined, true);
              if (tmp  !== false) {
                  this.minWords = options.minWords;
  
                  // Checking if words and characters limit are compatible.
                  if (this.maxChars) {
                      tmp = (this.maxChars+1)/2;
                      if (this.minWords > tmp) {
  
                          throw new TypeError('Feedback constructor: minWords ' +
                                              'cannot be larger than ' +
                                              '(maxChars+1)/2. Found: ' +
                                              this.minWords + ' > ' + tmp);
                      }
                  }
              }
              else {
                  throw new TypeError('Feedback constructor: minWords ' +
                                      'must be an integer >= 0 or undefined. ' +
                                      'Found: ' + options.minWords);
              }
          }
  
          // Extra checks.
          if (this.maxWords) {
              if (this.maxChars && this.maxChars < this.maxWords) {
                  throw new TypeError('Feedback constructor: maxChars ' +
                                      'cannot be smaller than maxWords. ' +
                                      'Found: ' + this.maxChars + ' > ' +
                                      this.maxWords);
              }
              if (this.minChars > this.maxWords) {
                  throw new TypeError('Feedback constructor: minChars ' +
                                      'cannot be greater than maxWords. ' +
                                      'Found: ' + this.minChars + ' > ' +
                                      this.maxWords);
              }
          }
  
          /**
           * ### Feedback.rows
           *
           * The number of initial rows of the texarea
           *
           * Default: 3
           */
          if ('undefined' === typeof options.rows) {
              this.rows = 3;
          }
          else if (J.isInt(options.rows, 0) !== false) {
              this.rows = options.rows;
          }
          else {
              throw new TypeError('Feedback constructor: rows ' +
                                  'must be an integer > 0 or undefined. ' +
                                  'Found: ' + options.rows);
          }
  
          /**
           * ### Feedback.maxAttemptLength
           *
           * The maximum character length for an attempt to submit feedback
           *
           * Attempts are stored in the attempts array. You can store attempts
           * longer than valid feedbacks.
           *
           * Set to 0 for no limit.
           *
           * Default: 0
           */
          if ('undefined' === typeof options.maxAttemptLength) {
              this.maxAttemptLength = 0;
          }
          else {
              tmp = J.isNumber(options.maxAttemptLength, 0);
              if (tmp !== false) {
                  this.maxAttemptLength = tmp;
              }
              else {
                  throw new TypeError('Feedback constructor: ' +
                                  'options.maxAttemptLength must be a number ' +
                                  '> 0 or undefined. Found: ' +
                                  options.maxAttemptLength);
              }
          }
  
          /**
           * ### Feedback.showSubmit
           *
           * If TRUE, the submit button is shown
           *
           * Default: true
           *
           * @see Feedback.submitButton
           */
          this.showSubmit = 'undefined' === typeof options.showSubmit ?
              true : !!options.showSubmit;
  
          /**
           * ### Feedback.onsubmit
           *
           * Options passed to `getValues` when the submit button is pressed
           *
           * @see Feedback.getValues
           */
          if (!options.onsubmit) {
              this.onsubmit = { feedbackOnly: true, say: true, updateUI: true };
          }
          else if ('object' === typeof options.onsubmit) {
              this.onsubmit = options.onsubmit;
          }
          else {
              throw new TypeError('Feedback constructor: onsubmit ' +
                                  'must be string or object. Found: ' +
                                  options.onsubmit);
          }
  
          /**
           * ### Feedback._feedback
           *
           * Internal storage of the value of the feedback
           *
           * This value is used when the form has not been created yet
           */
          this._feedback = options.feedback || null;
  
          /**
           * ### Feedback.attempts
           *
           * Invalid feedbacks tried
           */
          this.attempts = [];
  
          /**
           * ### Feedback.timeInputBegin
           *
           * Time when feedback was inserted (first character, last attempt)
           */
          this.timeInputBegin = null;
  
          /**
           * ### Feedback.feedbackForm
           *
           * The HTML form element containing the textarea
           */
          this.feedbackForm = null;
  
          /**
           * ### Feedback.textareaElement
           *
           * The HTML textarea element containing the feedback
           */
          this.textareaElement = null;
  
          /**
           * ### Feedback.charCounter
           *
           * The HTML span element containing the characters count
           */
          this.charCounter = null;
  
          /**
           * ### Feedback.wordCounter
           *
           * The HTML span element containing the words count
           */
          this.wordCounter = null;
  
          /**
           * ### Feedback.submitButton
           *
           * The HTML submit button
           */
          this.submitButton = null;
  
          /**
           * ### Feedback.setMsg
           *
           * If TRUE, a set message is sent instead of a data msg
           *
           * Default: FALSE
           */
          this.setMsg = !!options.setMsg || false;
  
      }