whole_func_string: function() {
      // The `solution` markup is built by distributing correct values
      // across the controls and disabling them
      var $ = cheerio.load(this.form.html.template);
      this.form.controls.forEach(function(ctl) {
        switch(ctl.type) {
          case 'checkboxGroup':
          case 'radioGroup':
            ctl.items.forEach(function(item) {
              var input = $('input#' + item.id);
              input.attr('disabled', 'disabled');
              if (item.value)
                input.attr('checked', 'checked');
            });
            break;
          case 'selectMenu':
            var select = $('select#' + ctl.id);
            select.attr('disabled', 'disabled');
            ctl.items.forEach(function(item) {
              if (item.value)
                select.val(item.id);
            });
            break;
          case 'inputText':
            var input = $('input#' + ctl.id);
            input.val(ctl.value);
            input.attr('disabled', 'disabled');
            break;
          case 'associativeGroup':
            var ag = $('fieldset#' + ctl.id);
            ag.addClass('disabled');
            utils.associativeGroupCategories(ctl).forEach(function(category) {
              var $dropTarget = ag
                .find('#category-' + category.item.id)
                .find('.dropTarget');
              category.items.forEach(function(item) {
                var $item = ag.find('#item-' + item.id);
                $dropTarget.append($item);
              });
            });
            break;
        }
      }, this);
      this.form.html.solution = $.html();
      // The `prompt` markup
      $ = cheerio.load(this.form.html.template);
      // Solution blocks are removed
      $('.solution').remove();
      // Sortable items are shuffled
      utils.shuffle($, '.sortableGroup');
      utils.shuffle($, '.associativeGroup .items');
      this.form.html.prompt = $.html();
    }
func_code_string: function() {
      // The `solution` markup is built by distributing correct values
      // across the controls and disabling them
      var $ = cheerio.load(this.form.html.template);
      this.form.controls.forEach(function(ctl) {
        switch(ctl.type) {
          case 'checkboxGroup':
          case 'radioGroup':
            ctl.items.forEach(function(item) {
              var input = $('input#' + item.id);
              input.attr('disabled', 'disabled');
              if (item.value)
                input.attr('checked', 'checked');
            });
            break;
          case 'selectMenu':
            var select = $('select#' + ctl.id);
            select.attr('disabled', 'disabled');
            ctl.items.forEach(function(item) {
              if (item.value)
                select.val(item.id);
            });
            break;
          case 'inputText':
            var input = $('input#' + ctl.id);
            input.val(ctl.value);
            input.attr('disabled', 'disabled');
            break;
          case 'associativeGroup':
            var ag = $('fieldset#' + ctl.id);
            ag.addClass('disabled');
            utils.associativeGroupCategories(ctl).forEach(function(category) {
              var $dropTarget = ag
                .find('#category-' + category.item.id)
                .find('.dropTarget');
              category.items.forEach(function(item) {
                var $item = ag.find('#item-' + item.id);
                $dropTarget.append($item);
              });
            });
            break;
        }
      }, this);
      this.form.html.solution = $.html();
      // The `prompt` markup
      $ = cheerio.load(this.form.html.template);
      // Solution blocks are removed
      $('.solution').remove();
      // Sortable items are shuffled
      utils.shuffle($, '.sortableGroup');
      utils.shuffle($, '.associativeGroup .items');
      this.form.html.prompt = $.html();
    }
func_documentation_string: Generates `prompt` and `solution` markup by applying modifications
  to `template` markup.