getReply = async function getReply(messageObject, options, callback) {
  if (options.depth) {
    debug.verbose('Called recursively', options.depth);
    if (options.depth >= 20) {
      console.error('getReply was called recursively 20 times - returning null reply.');
      return callback(null, null);
    }
  }

  let matches = [];
  try {
    const pendingTopics = await getPendingTopics(messageObject, options);
    matches = await findMatches(pendingTopics, messageObject, options);
  } catch (err) {
    console.error(err);
  }

  const data = afterHandle(matches);
  // One day, everything will be async/await and everything will be happy. Until
  // then, catch exceptions in the callback and throw them at top-level on next tick.
  try {
    return callback(null, data);
  } catch (err) {
    process.nextTick(() => { throw err; });
  }
}
The real craziness to retreive a reply.
@param {Object} messageObject - The instance of the Message class for the user input.
@param {Object} options.system - The system.
@param {Object} options.user - The user.
@param {Number} options.depth - The depth of how many times this function has been recursively called.
@param {Array} options.pendingTopics - A list of topics that have been specified to specifically search (usually via topicRedirect etc).
@param {Function} callback - Callback function once the reply has been found.