docs: function (input, readCallback) {
      if (compileStandard !== null) {
        return compileStandard(input, readCallback);
      }
  
      function formatFatalError (message) {
        return JSON.stringify({
          errors: [
            {
              'type': 'SOLCError',
              'component': 'dsolcjs',
              'severity': 'error',
              'message': message,
              'formattedMessage': 'Error: ' + message
            }
          ]
        });
      }
  
      if (readCallback !== undefined && typeof readCallback !== 'function') {
        return formatFatalError('Invalid import callback supplied');
      }
  
      try {
        input = JSON.parse(input);
      } catch (e) {
        return formatFatalError('Invalid JSON supplied: ' + e.message);
      }
  
      if (input['language'] !== 'Solidity') {
        return formatFatalError('Only Solidity sources are supported');
      }
  
      // NOTE: this is deliberately `== null`
      if (input['sources'] == null || input['sources'].length === 0) {
        return formatFatalError('No input specified');
      }
  
      // Bail out early
      if ((input['sources'].length > 1) && (compileJSONMulti === null)) {
        return formatFatalError('Multiple sources provided, but compiler only supports single input');
      }
  
      function isOptimizerEnabled (input) {
        return input['settings'] && input['settings']['optimizer'] && input['settings']['optimizer']['enabled'];
      }
  
      function translateSources (input) {
        var sources = {};
        for (var source in input['sources']) {
          if (input['sources'][source]['content'] !== null) {
            sources[source] = input['sources'][source]['content'];
          } else {
            // force failure
            return null;
          }
        }
        return sources;
      }
  
      function librariesSupplied (input) {
        if (input['settings'] !== null) {
          return input['settings']['libraries'];
        }
      }
  
      function translateOutput (output, libraries) {
        try {
          output = JSON.parse(output);
        } catch (e) {
          return formatFatalError('Compiler returned invalid JSON: ' + e.message);
        }
        output = translate.translateJsonCompilerOutput(output, libraries);
        if (output == null) {
          return formatFatalError('Failed to process output');
        }
        return JSON.stringify(output);
      }
  
      var sources = translateSources(input);
      if (sources === null || Object.keys(sources).length === 0) {
        return formatFatalError('Failed to process sources');
      }
  
      // Try linking if libraries were supplied
      var libraries = librariesSupplied(input);
  
      // Try to wrap around old versions
      if (compileJSONCallback !== null) {
        return translateOutput(compileJSONCallback(JSON.stringify({ 'sources': sources }), isOptimizerEnabled(input), readCallback), libraries);
      }
  
      if (compileJSONMulti !== null) {
        return translateOutput(compileJSONMulti(JSON.stringify({ 'sources': sources }), isOptimizerEnabled(input)), libraries);
      }
  
      // Try our luck with an ancient compiler
      if (compileJSON !== null) {
        return translateOutput(compileJSON(sources[Object.keys(sources)[0]], isOptimizerEnabled(input)), libraries);
      }
  
      return formatFatalError('Compiler does not support any known interface.');
    }