       match = @regexCommentText.exec commentBlock
     text
 
+  # Return the array of other control classes required by this class.
+  requiresClasses: ( source ) ->
+    match = @regexRequiresClasses.exec source
+    if match?
+      JSON.parse match[1] # Return the parsed array as an array
+
 
 # Extracts docs from CoffeeScript controls
 coffeeDocsExtractor = new DocsExtractor
+  baseClassName: ///
+    \r?\n                     # Start of line (no indentation)
+    class                     # "class" keyword
+    \s+                       # Whitespace
+    [\w\.]+                   # Class name (handled separately)
+    \s+                       # Whitespace
+    extends                   # "extends" keyword
+    \s+                       # Whitespace
+    (                         # Group captures base class name
+      [a-zA-Z0-9\$][\w]+      # JavaScript identifier
+    )
+  ///
   className: ///
     \r?\n                     # Start of line (no indentation)
     class                     # "class" keyword
     \s+                       # Whitespace
-    (?:window.)?              # optional "window."
+    (?:window.)?              # Optional "window."
     (                         # Group captures class name
       [a-zA-Z0-9\$][\w]+      # JavaScript identifier
     )

    extractor = extractors[ extension ]
    if extractor?
      source = fs.readFileSync filePath, "utf8"
      { className: className, comments: comments } = extractor.extract source
      if className? and comments?
        docs[ className ] = comments
  docs



class DocsExtractor

  constructor: ( regexes ) ->
    @regexBaseClassName = regexes.baseClassName
    @regexClassName = regexes.className
    @regexComments = regexes.comments
    @regexCommentText = regexes.commentText
    @regexRequiresClasses = regexes.requiresClasses

  extract: ( source ) ->
    baseClassName: @baseClassName source
    className: @controlClassName source
    members: @memberComments source
    requiresClasses: @requiresClasses source

  # Return the name for the control class defined in the source text.
  baseClassName: ( source ) ->
    match = @regexBaseClassName.exec source
    match?[1]

  # Return the name for the control class defined in the source text.
  controlClassName: ( source ) ->
    match = @regexClassName.exec source
    match?[1]

  # Return the comments found for members defined in the source text.
  memberComments: ( source ) ->
    comments = null
    match = @regexComments.exec source
    while match != null
