 
   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
 

    idt   = o.indent
    code  = 'function'
    code  += ' ' + @name if @ctor
    code  += '(' + vars.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

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

    o.scope.shared  = del(o, 'sharedScope')
    o.indent        += TAB
    delete o.bare
    params     = []
    exprs      = []
    for name in @paramNames() # this step must be performed before the others
      unless o.scope.check name then o.scope.parameter name
    for param in @params when param.splat
      o.scope.add p.name.value, 'var', yes for p in @params when p.name.value
      splats = new Assign new Value(new Arr(p.asReference o for p in @params)),
