         # TODO: Is this too naive?  coffee-script nodes have a `isStatement(o)` function, which
         # really only cares about `o.level`.  Should we be working out the level and calling
         # this function?
-        @isStatement = @parent? and @parent.type is 'Block' and @childAttr is 'expressions' and @type isnt 'Comment'
+        @isStatement = @parent? and @parent.type is 'Block' and @childName is 'expressions' and @type isnt 'Comment'
 
     # Run `fn(node)` for each child of this node.  Child nodes will be automatically wrapped in a
     # `NodeWrapper`.
     #
     forEachChild: (fn) ->
         if @node.children?
-            @node.children.forEach (attr) => @forEachChildOfType attr, fn
+            @node.children.forEach (childName) => @forEachChildOfType childName, fn
 
     # Like `forEachChild`, but only
-    forEachChildOfType: (attr, fn) ->
-        childAttr = @node[attr]
-        if childAttr?
-            attrs = _.flatten [childAttr], true
+    forEachChildOfType: (childName, fn) ->
+        children = @node[childName]
+        if children?
+            childNodes = _.flatten [children], true
 
             index = 0
-            while index < attrs.length
-                child = attrs[index]
+            while index < childNodes.length
+                child = childNodes[index]
                 if child.constructor.name?
-                    fn new NodeWrapper(child, this, attr, index, @depth + 1)
+                    fn new NodeWrapper(child, this, childName, index, @depth + 1)
 
                 # Bump index up in case we inserted nodes
                 # TODO: Guard against incrementing forever?
-                index++ while (child != attrs[index])
+                index++ while (child != childNodes[index])
                 index++
+
+    # Returns a NodeWrapper for the given child.  This only works if the child is not an array
+    # (e.g. `Block.expressions`)
+    child: (name, index=null) ->
+        child = @node[name]
+        if !child then return null
+
+        if !index?
+            assert !_.isArray child
+            return new NodeWrapper child, this, name, 0, @depth + 1
+        else
+            assert _.isArray child
+            if !child[index] then return null
+            return new NodeWrapper child[index], this, name, index, @depth + 1
+
 
     # Insert a new node before this node (only works if this node is in an array-based attribute,
     # like `Block.expressions`.)

    # and will be skipped when instrumenting code.
    #
    insertBefore: (csSource) ->
        assert _.isArray @parent.node[@childAttr]

        compiled = compile csSource, @node

        # childIndex is more of a hint, since nodes can move around.
        if @parent.node[@childAttr][@childIndex] isnt @node
            childIndex = _.indexOf @parent.node[@childAttr], @node
            if childIndex is -1 then throw new Error "Can't find node in parent"
            @childIndex = childIndex

        @parent.node[@childAttr].splice(@childIndex, 0, compiled)

    # Insert a chunk of code at the start of a child of this node.  E.g. if this is a Block,
    # then `insertAtStart('expressions', 'console.log "foo"'')` would add a `console.log`

# Properties:
# * `node` - The original coffee-script node.
# * `parent` - A `NodeWrapper` object for the parent of the coffee-script node.
# * `childName` - A coffee-script node has multiple named children.  This is the name of the
#   attribute which contains this node in `@parent.node`.  Note that `@parent.node[childName]`
#   may be a single Node or it may be an array of nodes, depending on the implementation of the
#   specific node type.
# * `childIndex` - Where `@parent.node[childName]` is an array, this is the index of `@node`
#   in `@parent.node[childName]`.  Note that inserting new nodes will obviously invalidate this
#   value, so this is more of a "hint" than a hard and fast truism.
# * `depth` - The depth in the AST from the root node.
# * `type` - Copy of @node.constructor.name.
