 
   isComplex: ->
     @name.isComplex()
+
+  # Finds the name or names of a `Param`; useful for detecting duplicates.
+  # In a sense, a destructured parameter represents multiple JS parameters,
+  # thus this method returns an `Array` of names. 
+  # Reserved words used as param names, as well as the Object and Array 
+  # literals used for destructured params, get a compiler generated name 
+  # during the `Code` compilation step, so this is necessarily an incomplete
+  # list of a parameter's names.
+  names: (name = @name)->
+    atParam = (obj) ->
+      {value} = obj.properties[0].name
+      return if value.reserved then [] else [value]
+    # * simple literals `foo`
+    return [name.value] if name instanceof Literal
+    # * at-params `@foo`
+    return atParam(name) if name instanceof Value
+    names = []
+    for obj in name.objects
+      # * assignments within destructured parameters `{foo:bar}`
+      if obj instanceof Assign
+        names.push obj.variable.base.value
+      # * destructured parameters within destructured parameters `[{a}]`
+      else if obj.isArray() or obj.isObject()
+        names.push @names(obj.base)...
+      # * at-params within destructured parameters `{@foo}`
+      else if obj.this
+        names.push atParam(obj)...
+      # * simple destructured parameters {foo}
+      else names.push obj.base.value 
+    names
 
 #### Splat
 

          lit = new Literal ref.name.value + ' == null'
          val = new Assign new Value(param.name), param.value, '='
          exprs.push new If lit, val
      vars.push ref unless splats
    wasEmpty = @body.isEmpty()
    exprs.unshift splats if splats
    @body.expressions.unshift exprs... if exprs.length
    o.scope.parameter vars[i] = v.compile o for v, i in vars unless splats
    @body.makeReturn() unless wasEmpty or @noReturn
    if @bound
      if o.scope.parent.method?.bound

    idt   = o.indent
    code  = 'function'
    code  += ' ' + @name if @ctor
    code  += '(' + params.join(', ') + ') {'
    code  += "\n#{ @body.compileWithDeclarations o }\n#{@tab}" unless @body.isEmpty()
    code  += '}'
    return @tab + code if @ctor
    if @front or (o.level >= LEVEL_ACCESS) then "(#{code})" else code

  # A list of parameter names, excluding those generated by the compiler.
  paramNames: ->
    names = []
    names.push param.names()... for param in @params
    names

  # Short-circuit `traverseChildren` method to prevent it from crossing scope boundaries
  # unless `crossScope` is `true`.
