             assignee = if issue.assignee then " (#{issue.assignee.login})" else ""
             msg.send "[#{issue.number}] #{issue.title} #{labels}#{assignee} = #{issue.html_url}"
 
+
+# TODO: Move this once `make test` works again.
+test = ->
+  is_defined = (x)  -> x?
+  one_of     = (xs) -> xs[Math.floor Math.random() * xs.length]
+  maybe      = (x)  -> one_of [x, undefined]
+  pp         = (o)  -> "{ " + ("#{k}: '#{v}'" for k, v of o).join(', ') + " }"
+
+  # Get criteria for random ask string.
+  random_criteria = ->
+    me: (maybe 'me'),
+    limit: (maybe one_of [1..100]),
+    assignee: (maybe one_of ["my", "@fred", "julia_roberts"]),
+    label: (maybe one_of ["ui", "show-stopper"]),
+    repo: (maybe one_of ["github/hubot", "hubot-scripts", "janky"]),
+    query: (maybe one_of ["firefox", "internet explorer"])
+
+  # Create the string for the robot to receive from criteria. We create this
+  # string from randomized criteria, then parse the string and compare the
+  # results to the randomized criteria to test the `parse_criteria` function.
+  show_criteria = ({me, limit, assignee, label, repo, query}) -> [
+    'show', me,
+    limit, 'of' if limit? and assignee?,
+    (if assignee? and assignee isnt "my" then "#{assignee}'s" else assignee),
+    label,
+    'issues',
+    'for' if repo?, repo,
+    'about' if query?, query
+  ].filter(is_defined).join ' '
+
+  # QuickCheck-inspired randomized test cases.
+  _.times 100, ->
+    criteria_expected = random_criteria()
+    ask = show_criteria criteria_expected
+    criteria_parsed = parse_criteria ask
+    unless _.isEqual criteria_expected, criteria_parsed
+      console.log "Counterexample: \"#{ask}\"\n\tExpected: #{pp criteria_expected}\n\tGot:      #{pp criteria_parsed}" 
+
+#test()

# Show open issues from a Github repository.
#
# You need to set the following variables:
#   HUBOT_GITHUB_TOKEN ="<oauth token>"
#   HUBOT_GITHUB_USER ="<user name>"
#
# HUBOT_GITHUB_USER is optional, but if you set it, you can ask `show me issues
# for hubot` instead of `show me issues for github/hubot`.
#
# HUBOT_GITHUB_REPO is optional, but if you set it, you can ask `show me issues`
# instead of `show me issues for github/hubot`.
#
# show me issues for <user/repo> -- Shows open issues for that project.

_  = require("underscore")
_s = require("underscore.string")

get_username = (name) ->
  name = name.replace("@", "").replace("'s", "")
  resolve = (n) -> process.env["HUBOT_GITHUB_USER_#{n.replace(/\s/g, '_').toUpperCase()}"]
  # Try resolving the name to a GitHub username using full, then first name:
  resolved = resolve(name) or resolve(_s.words(name)[0])
  if resolved? then resolved else name

get_repo = (repo) ->
  repo = process.env.HUBOT_GITHUB_REPO unless repo?
  repo = repo.replace "for ", ""
  repo = "#{process.env.HUBOT_GITHUB_USER}/#{repo}" unless _s.include repo, "/"
  repo

module.exports = (robot) ->
  robot.respond /show (me)?\s*(\d+|\d+ of)?\s*(@?\w+'s|my)?\s*(\S+)?\s*issues\s*(for \S+)?\s*(about .+)?/i, (msg) ->
    oauth_token = process.env.HUBOT_GITHUB_TOKEN
    [limit, assignee, issue_label, repo, query] = msg.match[2..]

    repo = get_repo repo

    msg.http("https://api.github.com/repos/#{repo}/issues")
      .headers(Authorization: "token #{oauth_token}", Accept: "application/json")
      .query(state: "open", sort: "created")
      .get() (err, res, body) ->

          return

        issues = JSON.parse(body)
        issues = filter_issues issues, criteria
       
        if _.isEmpty issues
            msg.send "No issues found."
        else
          for issue in issues
