Add note about double-dash bindings with camelCased arguments to docs

# /api/App Components/Batman.View/Batman.View Bindings

See the [guide](/docs/bindings.html) for an overview of view bindings. All bindings take a keypath as an attribute value unless otherwise specified.

Binding | Description | Example
-----|----|----
`data-bind`| Binds `innerHTML` or input value. Great for all kinds of inputs. | `<input type="checkbox" data-bind="user.isAuthorized" />`
`data-bind-#{attr}`| Binds node's `attr` to the keypath | `data-bind-id='post.id'`
`data-source`| `innerHTML` or value will get value from the keypath, but not set it | `<p data-source="post.content"></p>`
`data-source-#{attr}`| Node's `attr` will get its value from the keypath | `<h1 data-source-id='post.id'></h1>`
`data-target`| Changes to the node will set the keypath, but not get from the keypath |`<input data-target='user.name' />`
`data-context-#{name}`| Makes keypath value accessible as `name` inside node | `data-context-lastcomment='mostRecentPost.comments.last'`
`data-context`| Makes attributes of keypath directly accessible inside node|
`data-showif`| Shows node if keypath returns truthy | `data-showif='user.isAuthorized'`
`data-hideif`| Hides node if keypath returns truthy | `data-hideif='post.alreadyPublished'`
`data-insertif`| The node will be present in the DOM if the keypath returns truthy | `data-insertif='post.isPublished'`
`data-removeif`| The node will be removed from the DOM if the keypath returns truthy | `data-removeif='comment.isNotAppropriate'`
`data-renderif`| Node's contents will only be rendered if the keypath returns truthy |
`data-deferif`| Node's contents will only be rendered if the keypath returns falsey|
`data-route`| Takes a `Batman.NamedRouteQuery`. Clicking this node will route to the keypath. | `data-route='routes.posts[post].edit'`
`data-route-params` | Appends the keypath the route generated by a `data-route` on the node | `data-route-params='myParamString'
`data-view`| Wraps the node in the view specified | `data-view='NavigatorView'`
`data-view-#{optionName}`| Passes keypath value to `data-view` as `optionName` (see `View.option`) | `data-view-user='currentUser'`
`data-partial`| Takes a __string__, renders the template with that path | `data-partial='posts/_form'`
`data-defineview`| Wraps HTML which should be stored by `Batman.View` | `data-defineview='posts/index'`
`data-yield`| Creates a named yield for the application | `data-yield='modal'`
`data-contentfor`| Wraps content for a non-default yield | `data-contentfor='modal'`
`data-debug`| Calls `debugger` when instantiating the binding | `data-debug="true"`
`data-event-#{eventName}`| Binds keypath value to `eventName` on this node | `data-event-click='notifyAllUsers'`
`data-addclass-#{className}`| Adds class `className` if keypath returns truthy | `data-addclass-selected='item.selected'`
`data-removeclass-#{className}`| Removes class `className` if keypath returns truthy | `data-removeclass-highlight='item.isPast'`
`data-foreach-#{itemName}`| Make a copy of this node for each member in keypath; children accessible as `itemName` | `data-foreach-item='myCollection'`
`data-formfor-#{name}`| Inputs for keypath value will observe errors; keypath value aliased as `name`| `data-formfor-comment='newComment'`
`data-style-#{styleAttrName}`| Bind the node's style attribute `styleAttrName` to the keypath value| `data-style-float='leftOrRight'`
`data-track-#{clickOrView}`| Track clicks or views on this node. | `data-track-view='logView'`

**Note:** Since HTML is technically case insensitive, bindings using the double-dash syntax (e.g. `data-context-#{name}`) should use lowercase names as arguments. See [Issue #957](https://github.com/batmanjs/batman/issues/957) for more information.

#### Keypath Filters

Binding keypaths may be passed through view filters. See the [`Batman.View Filters` documentation](/docs/api/batman.view_filters.html) for more information.

## Custom Bindings

To add a custom binding,

- Extend an existing batman.js binding class
- Create a binding hook as a property of  `Batman.DOM.readers` or `Batman.DOM.attrReaders` (for bindings like `data-binding-#{attr}`).

For example, a `data-permission` binding:

```coffeescript
# Usage:
# <div data-permission='administrator'>
#   <!-- equal to `data-showif='isAdministrator'` -->
# </div>

# Binding class
class Batman.DOM.PermissionBinding extends Batman.DOM.ShowHideBinding
  constructor: (definition) ->
    permissionName = definition.keyPath
    permissionKeyPath = "is#{Batman.helpers.titleize(permissionName)}"
    definition.keyPath = permissionKeyPath
    super(definition)

# Binding hook:
Batman.DOM.readers.permission = (definition) ->
  new Batman.DOM.PermissionBinding(definition)

```

## data-bind

`data-bind` creates a two way binding between a property on a `Batman.Object` and an HTML element. Bindings created via `data-bind` will update the HTML element with the value of the JS land property as soon as they are created and each time the property changes after, and if the HTML element can be observed for changes, it will update the JS land property with the value from the HTML.

`data-bind` will change its behaviour depending on what kind of tag it is attached to:

 + `<input type="checkbox">`: the binding will edit the `checked` property of the checkbox and populate the keypath with a boolean.
 + `<input type="text">` and similar, `<textarea`>: the binding will edit the `value` property of the input and populate the keypath with the string found at `value`.
 + `<input type="file">`: the binding will _not_ edit the `value` property of the input, but it will update the keypath with a host `File` object or objects if the node has the `multiple` attribute.
 + `<select>`: the binding will edit the `selected` property of each `<option>` tag within the `<select>` matching the property at the keypath. If the `<select>` has the multiple attribute, the value at the keypath can be an array of selected `<option>` values. You can also use `data-bind-selected` bindings on the individual options to toggle option selectedness.
 + All other tags: the binding will edit the `innerHTML` property of the tag and will not populate the keypath.

`data-bind` can also be used to bind an attribute of a node to a JavaScript property. Since attributes can't be observed for changes, this is a one way binding which will never update the JavaScript land property. Specify which attribute to bind using the "double dash" syntax like so: `data-bind-attribute="some.keypath"`. For example, to bind the `placeholder` attribute of an input, use `data-bind-placeholder`.

```html
<input type="text" data-bind-placeholder="'Specify a subtitle for product ' | append product.name">
```

_Note_: `data-bind` will not update a JavaScript property if filters are used in the keypath.

## data-source

`data-source` creates a one way binding which propagates only changes from JavaScript land to the DOM, and never vice versa. `data-source` has the same semantics with regards to how it operates on different tags as `data-bind`, but it will only ever update the DOM and never the JavaScript land property.

For example, the HTML below will never update the `title` property on the product, even if the user changes it. Each time the `title` attribute changes from a `set` in JavaScript land, the value of the input will be updated to the new value of `title`, erasing any potential changes that have been made to the value of the input by the user.

```html
<input type="text" data-source="product.title">
```

_Note_: `data-source-attribute` is equivalent to `data-bind-attribute`, since the former is defined as never making JS land changes, and the latter is unable to.

## data-target

`data-target` creates a one way binding which propagates only changes from the DOM to JavaScript land, and never vice versa. `data-target` has the same semantics with regards to how it operates on different tags as `data-bind`, but it will never update the DOM even if the JavaScript land value changes.

_Note_: `data-target-attribute` is unavailable, because DOM changes to node attributes can't be monitored.

## data-showif / data-hideif

`data-showif` and `data-hideif` bind to keypaths and show or hide the node they appear on based on the truthiness of the result. `data-showif` will show a node if the given keypath evaluates to something truthy, and `data-hideif` will leave a node visible until its given keypath becomes truthy, at which point the node will be hidden. `data-showif` and `data-hideif` show and hide nodes by adding `display: none !important;` to the node's `style` attribute.

For example, if the HTML below is rendered where the keypath `product.published` evaluated to true, the `<button>` will be visible.

```html
<button data-showif="product.published">Unpublish Product</button>
```

This is the Batman equivalent of a templating language's `if` construct, where else branches are implemented using the opposite binding.

```html
<button data-showif="product.published">Unpublish Product</button>
<button data-hideif="product.published">Publish Product</button>
```

## data-addclass / data-removeclass

`data-addclass` and `data-removeclass` bindings can be used to conditionally add or remove a class from a node based on a boolean keypath. Specify the class to add using the "double dash" syntax; for example,`data-addclass-big="some.keypath"` on a node will add the "big" class to that node's classes if `some.keypath` is truthy. `data-removeclass` will remove a class (usually one which is present in the HTML) if the keypath passed to it is truthy.

The outer span in the HTML below will have an "error" class when the `product.errors.length` keypath evaluates to anything other than 0, since 0 is falsy and other numbers are truthy.

```html
<p data-addclass-error="product.errors.length">
  This product has <span data-bind="product.errors.length"></span> errors.
</p>
```

## data-foreach

`data-foreach` is used to loop over an iterable object in Batman views. `data-foreach` duplicates the node it occurs on for each item in the collection found at the keypath given to it, and renders each duplicated node with that node's object from the collection by putting it in the context under a name passed to it using the "double dash" syntax.

The `<option>` node below will be duplicated for each item in the `Set` at the `products` keypath.

```html
<select>
  <option data-foreach-product="products" data-bind="product.name"></option>
</select>
```

Batman will execute the `data-foreach` binding before the `data-bind` on the `<option>` node, which means that the `data-bind` will be processed for each duplicated node with each separate Product in the `products` Set in scope for each separate node. If there were say 3 Products in the `products` set, the HTML would look similar to this once rendered:

```html
<select>
  <option data-bind="product.name">Product A</option>
  <option data-bind="product.name">Product B</option>
  <option data-bind="product.name">Product C</option>
  <!-- end products -->
</select>
```

`data-foreach` can be used to iterate over `Batman.Set`s, and most often should be, because it observes any Sets and will update the DOM with new nodes if items are added to the set, or remove nodes from the DOM if their corresponding nodes are removed from the set. `data-foreach`, like every other binding, is keypath aware, such that if the `Set` instance at the keypath changes, or any previous segment of the keypath changes, `data-foreach` will remove all the nodes currently in the DOM, and add new nodes for each new item in the incoming `Set`.

Sometimes you'll need to add some custom logic to the iteration nodes. For example, a custom `viewDidAppear` handler so you can know whenever a new iteration node appears in the DOM. You can do this by specifying a custom subclass of `Batman.IterationView`.

```html
<ul>
  <li data-foreach-product="products" data-view="ProductIterationView">
    <span data-bind="product.name"></span>
  </li>
</ul>
```

```coffeescript
class MyApp.ProductIterationView extends Batman.IterationView
  viewDidAppear: ->
    $(@get('node')).draggable()
```

_Note_: `data-foreach` expects to find an iterable object at the keypath given to it, and will emit a warning if it finds `undefined`.

_Note_: `data-foreach` expects the passed enumerable to be unique. It creates a map of nodes to items, so every node needs to be able to reference exactly one object. If you simply have a set of values that you're iterating over, you should wrap your values in objects, e.g. `[{value: true}, {value: true}]`.

## data-formfor

`data-formfor` creates a special addition to the context stack to represent an object under edit within a form. Usually this object is a model. Using the double dash syntax, the name for the model to reside under can be specified.

__Automatic Validation Display__

`data-formfor` also has some handy functionality for displaying the result of validating the object under edit in the form. This will only be enabled if the object has an `errors` Set, like `Batman.Models` do.

If a tag matching the relative selector `.errors` is found, it will populate this element with a list of the errors found during validation on the object. The selector for the errors container can be changed by adding a `data-errors-list` attribute with the value of the selector to the form with the `data-formfor` binding on it, or editing `Batman.DOM.FormBinding::defaultErrorsListSelector`.

If value bindings are made using `data-bind` to attributes on the model within the form, automatic `data-addclass-error` bindings will be added to the elements on which the `data-bind` occurs to add the "error" class when the model has errors on the attribute which `data-bind` binds to.

In the HTML below, an automatic `data-addclass-error` will be added to the `<input>` which activates when the `product` model has validation errors on the `name` attribute.

```html
<form data-formfor-product="currentProduct">
  <input type="text" data-bind="product.name"></input>
</form>
```

The class which gets automatically added to inputs binding to invalid attributes can be customized by editing `Batman.DOM.FormBinding::errorClass`.

## data-context

`data-context` bindings add the object found at the key to the context stack, optionally under a key using the double dash syntax.

For example, if a `product` object exists in the current context, the `data-context` binding below will expose its attributes at the root level of the context:

```html
<div data-context="product">
  <span data-bind="name"></span>
  <span data-bind="cost"></span>
</div>
```

Contexts added to the stack can also be scoped under a key using `data-context-`:

```html
<div data-context-currentProduct="product">
  <span data-bind="currentProduct"></span>
  <span data-bind="currentProduct"></span>
</div>
```

This is a useful mechanism for passing local variables to partial views.

## data-event

`data-event` bindings add DOM event listeners to the nodes they exist on which call the function found at the passed keypath. `data-event` bindings use the double dash syntax to specify the name of the event to listen for.

In the HTML below, if the keypath `myFunction` resolves to a function, that function will be executed each time the `<button>` element is clicked.

```html
<button data-event-click="myFunction">Execute myFunction!</button>
```

You can use `data-event` to execute controller actions without routing:

```html
<!-- with beforeAction & afterAction filters: -->
<a data-event-click='controllers.items.executeAction | withArguments "new"'>Create a new item</a>
<!-- or, skipping beforeAction & afterAction filters: -->
<a data-event-click="controllers.items.new">Create a new item</a>
```

Functions which `data-event` calls will be passed the node and the `DOMEvent` object: `(node, event) ->`.

`data-event` supports the following types of events formally and should "do the right thing" when attached to elements which fire these events:

 + click
 + doubleclick
 + change
 + submit

If the event name used doesn't match the above events, the event name used will just fall through and be passed to `window.addEventListener`.

## data-route

`data-route` bindings are used to dispatch a new controller action upon the clicking of the node they bind to. `data-route` expects to find either a string or a `NamedRouteQuery` at the keypath passed to it. With this route, it will add an event handler to the `click` action of the element which dispatches the route and prevents the default action of the DOMEvent. `data-route` will also populate the `href` attribute if it occurs on an `<a>` tag so that other functions like "Copy Link Address" and Alt+Click continue to work on the link.

The first way to use `data-route` is by passing it a string, which can be built using filters or an accessor, but the preferred way is to use the `NamedRouteQuery`. These objects are generated for you by starting keypaths at the `App.routes` property. All `Batman.App`s have a `routes` property which holds a nested list of all the routes, which you descend into by passing various key segments and objects. Since the `App` object is present in the default context stack, `data-route` keypaths can just start with `routes`.

For example, assume the following routes definition in the current `Batman.App`:

```coffeescript
class Alfred extends Batman.App
  @resources 'todos'
```

This means that routes like `/todos` and `/todos/:id` exist. To route to the collection action, use the plural name of the resource:

```html
<a data-route="routes.todos"></a>
```

To route to an individual todo things get a bit more complicated. If we have a Todo model with ID# `42` in the context as `todo`, use the `get` filter shorthand on the `NamedRouteQuery` returned by `routes.todos` to generate a member route:

```html
<a data-route="routes.todos[todo]"></a>
```

Underneath, this is calling `Alfred.get('routes.todos').get(todo)`; the todo object is being passed as a key to the `NamedRouteQuery`, which knows how to generate a member route when given a record. The above HTML when rendered will look like this:

```html
<a data-route="routes.todos[todo]" href="/todos/42"></a>
```

This syntax can be extended to nested routes. If we have nested routes, we can use chained gets to generated nested routes

```coffeescript
class Tracker extends Batman.App
  @resources 'villains', ->
    @resources 'crimes'
```

Routes for collection and member crimes should look like `/villains/:villain_id/crimes` and `/villains/:villain_id/crimes/:id` respectively. Assuming the presence of a `villain` and a `crime` in the context, chained `get`s on `NamedRouteQuery`s achieve this:

```html
<!-- Collection of crimes for a particular villain -->
<a data-route="routes.villains[villain].crimes"></a>
<!-- One crime of a particular villain -->
<a data-route="routes.villains[villain].crimes[crime]"></a>
```

_Note_: `data-route` bindings route only to internal dispatch, and not external links. Use a regular `<a>` tag to link away from the application.

## data-route-params

Adds the provided keypath or literal value to the route provided to `data-route`. For example:

```html
<a data-route='routes.villians.new' data-route-params='"mastermind=true"'>Mastermind</a>
```

will route to `/villians/new?mastermind=true` and

```
<a data-route='routes.villians.new' data-route-params='otherRouteParams'>Other</a>
```

will look up `otherRouteParams` and append it to `/villains/new`, adding a `?` if necessary.

## data-view

`data-view` bindings attach custom `Batman.View` instances or instantiate custom `View` subclasses to / on a node. `data-view` expects either a `Batman.View` instance or subclass at the keypath passed to it. If an instance is passed, it will `set` the `node` property of the view to the node the `data-view` occurs on. If a class is passed, that class will be instantiated with the context the `data-view` binding executed in and with the node it occurred upon. See `Batman.View` for more information on custom Views and their uses.

_Note_: `data-view` bindings will bind to the passed keypath until it exists, that is to say until the value of it is not `undefined`. After the `View` has been set up, the `data-view` binding will remove itself and stop observing the keypath.

## data-partial

`data-partial` pulls in a partial template and renders it in the current context of the node the `data-partial` occurs in. `data-partial` expects the name of the view to render in the value of the HTML attribute. __Warning__: This value is not a keypath. The HTML attribute's value is interpreted as a string, and the template which resides at that view path will be rendered.

If we have this HTML at `views/villains/_stub.html` in our app:

```html
<span data-bind="villain.name"></span>
```

and in `views/villains/show.html` we have this HTML:

```html
<h1>A villain!</h1>
<div data-partial="villains/_stub"></div>
```

the contents of the `stub` partial will be inserted and rendered in the `<div>` above.

## data-defineview
`data-defineview` specifies that the content of the node defines the template for a particular view.

The binding value should be a regular view path, i.e. "#{resource_name}/#{controller_action}". For example:

```html
<div data-defineview="crimes/index">
  <ul class="crimes">
    <li class="crime" data-foreach-crime="crimes">
      <span data-bind="crime.name" data-addclass-heinous="crime.heinous" />
    </li>
  </ul>
</div>
```

will be used by the `CrimesController`'s  `index` action.

## data-renderif / data-deferif

`data-renderif` (and `data-deferif`) defers parsing of a node's child bindings until its keypath updates to true (or false, respectively). Note that this does not prevent the node from being inserted into the DOM. These bindings should generally be combined with a `data-showif` or `data-insertif` to prevent it from being visible until it is ready.

Deferring rendering can help prevent portions of the page updating many times while data is being loaded. It can also allow you to prevent features that are not yet ready from being used.

## data-yield

`data-yield` specifies that this node should be a render target for any view renderings that specify they should be rendered into a yield with this name. For example, `data-yield="myYieldNode"` can be rendered into by using `new Batman.View(contentFor: 'myYieldNode')`. The special case of `data-yield="main"` will be the render target for any view rendered by a controller action. This can mean the implicit render that happens by default at the end of a controller action or by explicitly calling `@render` inside a controller.

You can also specify a render target inside your HTML using `data-contentfor`.

```html
<div data-yield="main"></div>
```

## data-contentfor

`data-contentfor` specifies that the content of this node should be rendered into a `yield` with the corresponding name.

```html
<div data-contentfor="header"><h1 data-bind="title"></h1></div>
<div data-yield="header"></div>
```

## data-track

`data-track-#{viewOrClick}` fires events on an internal instance of a user-defined `MyApp.EventTracker` class. An `EventTracker` must respond to `track(viewOrClick, keypathValue, node)`, where:

- `viewOrClick` is the binding attribute argument
- `keypathValue` is the value of the keypath passed to the binding
- `node` is the bound node.

The node is considered _viewed_ when the binding is initialized.

Under the hood, batman.js will instantiate `MyApp.EventTracker` once, storing it at `Batman.Tracking.tracker`.

## data-debug

Calls `debugger` when instantiating the binding. `DebuggerBinding` is removed from production builds of batman.js.

# /api/App Components/Batman.View/Batman.View Bindings

See the [guide](/docs/bindings.html) for an overview of view bindings. All bindings take a keypath as an attribute value unless otherwise specified.

Binding | Description | Example
-----|----|----
`data-bind`| Binds `innerHTML` or input value. Great for all kinds of inputs. | `<input type="checkbox" data-bind="user.isAuthorized" />`
`data-bind-#{attr}`| Binds node's `attr` to the keypath | `data-bind-id='post.id'`
`data-source`| `innerHTML` or value will get value from the keypath, but not set it | `<p data-source="post.content"></p>`
`data-source-#{attr}`| Node's `attr` will get its value from the keypath | `<h1 data-source-id='post.id'></h1>`
`data-target`| Changes to the node will set the keypath, but not get from the keypath |`<input data-target='user.name' />`
`data-context-#{name}`| Makes keypath value accessible as `name` inside node | `data-context-lastcomment='mostRecentPost.comments.last'`
`data-context`| Makes attributes of keypath directly accessible inside node|
`data-showif`| Shows node if keypath returns truthy | `data-showif='user.isAuthorized'`
`data-hideif`| Hides node if keypath returns truthy | `data-hideif='post.alreadyPublished'`
`data-insertif`| The node will be present in the DOM if the keypath returns truthy | `data-insertif='post.isPublished'`
`data-removeif`| The node will be removed from the DOM if the keypath returns truthy | `data-removeif='comment.isNotAppropriate'`
`data-renderif`| Node's contents will only be rendered if the keypath returns truthy |
`data-deferif`| Node's contents will only be rendered if the keypath returns falsey|
`data-route`| Takes a `Batman.NamedRouteQuery`. Clicking this node will route to the keypath. | `data-route='routes.posts[post].edit'`
`data-route-params` | Appends the keypath the route generated by a `data-route` on the node | `data-route-params='myParamString'
`data-view`| Wraps the node in the view specified | `data-view='NavigatorView'`
`data-view-#{optionName}`| Passes keypath value to `data-view` as `optionName` (see `View.option`) | `data-view-user='currentUser'`
`data-partial`| Takes a __string__, renders the template with that path | `data-partial='posts/_form'`
`data-defineview`| Wraps HTML which should be stored by `Batman.View` | `data-defineview='posts/index'`
`data-yield`| Creates a named yield for the application | `data-yield='modal'`
`data-contentfor`| Wraps content for a non-default yield | `data-contentfor='modal'`
`data-debug`| Calls `debugger` when instantiating the binding | `data-debug="true"`
`data-event-#{eventName}`| Binds keypath value to `eventName` on this node | `data-event-click='notifyAllUsers'`
`data-addclass-#{className}`| Adds class `className` if keypath returns truthy | `data-addclass-selected='item.selected'`
`data-removeclass-#{className}`| Removes class `className` if keypath returns truthy | `data-removeclass-highlight='item.isPast'`
`data-foreach-#{itemName}`| Make a copy of this node for each member in keypath; children accessible as `itemName` | `data-foreach-item='myCollection'`
`data-formfor-#{name}`| Inputs for keypath value will observe errors; keypath value aliased as `name`| `data-formfor-comment='newComment'`
`data-style-#{styleAttrName}`| Bind the node's style attribute `styleAttrName` to the keypath value| `data-style-float='leftOrRight'`
`data-track-#{clickOrView}`| Track clicks or views on this node. | `data-track-view='logView'`

#### Keypath Filters

Binding keypaths may be passed through view filters. See the [`Batman.View Filters` documentation](/docs/api/batman.view_filters.html) for more information.

## Custom Bindings

To add a custom binding,

- Extend an existing batman.js binding class
- Create a binding hook as a property of  `Batman.DOM.readers` or `Batman.DOM.attrReaders` (for bindings like `data-binding-#{attr}`).

For example, a `data-permission` binding:

```coffeescript
# Usage:
# <div data-permission='administrator'>
#   <!-- equal to `data-showif='isAdministrator'` -->
# </div>

# Binding class
class Batman.DOM.PermissionBinding extends Batman.DOM.ShowHideBinding
  constructor: (definition) ->
    permissionName = definition.keyPath
    permissionKeyPath = "is#{Batman.helpers.titleize(permissionName)}"
    definition.keyPath = permissionKeyPath
    super(definition)

# Binding hook:
Batman.DOM.readers.permission = (definition) ->
  new Batman.DOM.PermissionBinding(definition)

```

## data-bind

`data-bind` creates a two way binding between a property on a `Batman.Object` and an HTML element. Bindings created via `data-bind` will update the HTML element with the value of the JS land property as soon as they are created and each time the property changes after, and if the HTML element can be observed for changes, it will update the JS land property with the value from the HTML.

`data-bind` will change its behaviour depending on what kind of tag it is attached to:

 + `<input type="checkbox">`: the binding will edit the `checked` property of the checkbox and populate the keypath with a boolean.
 + `<input type="text">` and similar, `<textarea`>: the binding will edit the `value` property of the input and populate the keypath with the string found at `value`.
 + `<input type="file">`: the binding will _not_ edit the `value` property of the input, but it will update the keypath with a host `File` object or objects if the node has the `multiple` attribute.
 + `<select>`: the binding will edit the `selected` property of each `<option>` tag within the `<select>` matching the property at the keypath. If the `<select>` has the multiple attribute, the value at the keypath can be an array of selected `<option>` values. You can also use `data-bind-selected` bindings on the individual options to toggle option selectedness.
 + All other tags: the binding will edit the `innerHTML` property of the tag and will not populate the keypath.

`data-bind` can also be used to bind an attribute of a node to a JavaScript property. Since attributes can't be observed for changes, this is a one way binding which will never update the JavaScript land property. Specify which attribute to bind using the "double dash" syntax like so: `data-bind-attribute="some.keypath"`. For example, to bind the `placeholder` attribute of an input, use `data-bind-placeholder`.

```html
<input type="text" data-bind-placeholder="'Specify a subtitle for product ' | append product.name">
```

_Note_: `data-bind` will not update a JavaScript property if filters are used in the keypath.

## data-source

`data-source` creates a one way binding which propagates only changes from JavaScript land to the DOM, and never vice versa. `data-source` has the same semantics with regards to how it operates on different tags as `data-bind`, but it will only ever update the DOM and never the JavaScript land property.

For example, the HTML below will never update the `title` property on the product, even if the user changes it. Each time the `title` attribute changes from a `set` in JavaScript land, the value of the input will be updated to the new value of `title`, erasing any potential changes that have been made to the value of the input by the user.

```html
<input type="text" data-source="product.title">
```

_Note_: `data-source-attribute` is equivalent to `data-bind-attribute`, since the former is defined as never making JS land changes, and the latter is unable to.

## data-target

`data-target` creates a one way binding which propagates only changes from the DOM to JavaScript land, and never vice versa. `data-target` has the same semantics with regards to how it operates on different tags as `data-bind`, but it will never update the DOM even if the JavaScript land value changes.

_Note_: `data-target-attribute` is unavailable, because DOM changes to node attributes can't be monitored.

## data-showif / data-hideif

`data-showif` and `data-hideif` bind to keypaths and show or hide the node they appear on based on the truthiness of the result. `data-showif` will show a node if the given keypath evaluates to something truthy, and `data-hideif` will leave a node visible until its given keypath becomes truthy, at which point the node will be hidden. `data-showif` and `data-hideif` show and hide nodes by adding `display: none !important;` to the node's `style` attribute.

For example, if the HTML below is rendered where the keypath `product.published` evaluated to true, the `<button>` will be visible.

```html
<button data-showif="product.published">Unpublish Product</button>
```

This is the Batman equivalent of a templating language's `if` construct, where else branches are implemented using the opposite binding.

```html
<button data-showif="product.published">Unpublish Product</button>
<button data-hideif="product.published">Publish Product</button>
```

## data-addclass / data-removeclass

`data-addclass` and `data-removeclass` bindings can be used to conditionally add or remove a class from a node based on a boolean keypath. Specify the class to add using the "double dash" syntax; for example,`data-addclass-big="some.keypath"` on a node will add the "big" class to that node's classes if `some.keypath` is truthy. `data-removeclass` will remove a class (usually one which is present in the HTML) if the keypath passed to it is truthy.

The outer span in the HTML below will have an "error" class when the `product.errors.length` keypath evaluates to anything other than 0, since 0 is falsy and other numbers are truthy.

```html
<p data-addclass-error="product.errors.length">
  This product has <span data-bind="product.errors.length"></span> errors.
</p>
```

## data-foreach

`data-foreach` is used to loop over an iterable object in Batman views. `data-foreach` duplicates the node it occurs on for each item in the collection found at the keypath given to it, and renders each duplicated node with that node's object from the collection by putting it in the context under a name passed to it using the "double dash" syntax.

The `<option>` node below will be duplicated for each item in the `Set` at the `products` keypath.

```html
<select>
  <option data-foreach-product="products" data-bind="product.name"></option>
</select>
```

Batman will execute the `data-foreach` binding before the `data-bind` on the `<option>` node, which means that the `data-bind` will be processed for each duplicated node with each separate Product in the `products` Set in scope for each separate node. If there were say 3 Products in the `products` set, the HTML would look similar to this once rendered:

```html
<select>
  <option data-bind="product.name">Product A</option>
  <option data-bind="product.name">Product B</option>
  <option data-bind="product.name">Product C</option>
  <!-- end products -->
</select>
```

`data-foreach` can be used to iterate over `Batman.Set`s, and most often should be, because it observes any Sets and will update the DOM with new nodes if items are added to the set, or remove nodes from the DOM if their corresponding nodes are removed from the set. `data-foreach`, like every other binding, is keypath aware, such that if the `Set` instance at the keypath changes, or any previous segment of the keypath changes, `data-foreach` will remove all the nodes currently in the DOM, and add new nodes for each new item in the incoming `Set`.

Sometimes you'll need to add some custom logic to the iteration nodes. For example, a custom `viewDidAppear` handler so you can know whenever a new iteration node appears in the DOM. You can do this by specifying a custom subclass of `Batman.IterationView`.

```html
<ul>
  <li data-foreach-product="products" data-view="ProductIterationView">
    <span data-bind="product.name"></span>
  </li>
</ul>
```

```coffeescript
class MyApp.ProductIterationView extends Batman.IterationView
  viewDidAppear: ->
    $(@get('node')).draggable()
```

_Note_: `data-foreach` expects to find an iterable object at the keypath given to it, and will emit a warning if it finds `undefined`.

_Note_: `data-foreach` expects the passed enumerable to be unique. It creates a map of nodes to items, so every node needs to be able to reference exactly one object. If you simply have a set of values that you're iterating over, you should wrap your values in objects, e.g. `[{value: true}, {value: true}]`.

## data-formfor

`data-formfor` creates a special addition to the context stack to represent an object under edit within a form. Usually this object is a model. Using the double dash syntax, the name for the model to reside under can be specified.

__Automatic Validation Display__

`data-formfor` also has some handy functionality for displaying the result of validating the object under edit in the form. This will only be enabled if the object has an `errors` Set, like `Batman.Models` do.

If a tag matching the relative selector `.errors` is found, it will populate this element with a list of the errors found during validation on the object. The selector for the errors container can be changed by adding a `data-errors-list` attribute with the value of the selector to the form with the `data-formfor` binding on it, or editing `Batman.DOM.FormBinding::defaultErrorsListSelector`.

If value bindings are made using `data-bind` to attributes on the model within the form, automatic `data-addclass-error` bindings will be added to the elements on which the `data-bind` occurs to add the "error" class when the model has errors on the attribute which `data-bind` binds to.

In the HTML below, an automatic `data-addclass-error` will be added to the `<input>` which activates when the `product` model has validation errors on the `name` attribute.

```html
<form data-formfor-product="currentProduct">
  <input type="text" data-bind="product.name"></input>
</form>
```

The class which gets automatically added to inputs binding to invalid attributes can be customized by editing `Batman.DOM.FormBinding::errorClass`.

## data-context

`data-context` bindings add the object found at the key to the context stack, optionally under a key using the double dash syntax.

For example, if a `product` object exists in the current context, the `data-context` binding below will expose its attributes at the root level of the context:

```html
<div data-context="product">
  <span data-bind="name"></span>
  <span data-bind="cost"></span>
</div>
```

Contexts added to the stack can also be scoped under a key using `data-context-`:

```html
<div data-context-currentProduct="product">
  <span data-bind="currentProduct"></span>
  <span data-bind="currentProduct"></span>
</div>
```

This is a useful mechanism for passing local variables to partial views.

## data-event

`data-event` bindings add DOM event listeners to the nodes they exist on which call the function found at the passed keypath. `data-event` bindings use the double dash syntax to specify the name of the event to listen for.

In the HTML below, if the keypath `myFunction` resolves to a function, that function will be executed each time the `<button>` element is clicked.

```html
<button data-event-click="myFunction">Execute myFunction!</button>
```

You can use `data-event` to execute controller actions without routing:

```html
<!-- with beforeAction & afterAction filters: -->
<a data-event-click='controllers.items.executeAction | withArguments "new"'>Create a new item</a>
<!-- or, skipping beforeAction & afterAction filters: -->
<a data-event-click="controllers.items.new">Create a new item</a>
```

Functions which `data-event` calls will be passed the node and the `DOMEvent` object: `(node, event) ->`.

`data-event` supports the following types of events formally and should "do the right thing" when attached to elements which fire these events:

 + click
 + doubleclick
 + change
 + submit

If the event name used doesn't match the above events, the event name used will just fall through and be passed to `window.addEventListener`.

## data-route

`data-route` bindings are used to dispatch a new controller action upon the clicking of the node they bind to. `data-route` expects to find either a string or a `NamedRouteQuery` at the keypath passed to it. With this route, it will add an event handler to the `click` action of the element which dispatches the route and prevents the default action of the DOMEvent. `data-route` will also populate the `href` attribute if it occurs on an `<a>` tag so that other functions like "Copy Link Address" and Alt+Click continue to work on the link.

The first way to use `data-route` is by passing it a string, which can be built using filters or an accessor, but the preferred way is to use the `NamedRouteQuery`. These objects are generated for you by starting keypaths at the `App.routes` property. All `Batman.App`s have a `routes` property which holds a nested list of all the routes, which you descend into by passing various key segments and objects. Since the `App` object is present in the default context stack, `data-route` keypaths can just start with `routes`.

For example, assume the following routes definition in the current `Batman.App`:

```coffeescript
class Alfred extends Batman.App
  @resources 'todos'
```

This means that routes like `/todos` and `/todos/:id` exist. To route to the collection action, use the plural name of the resource:

```html
<a data-route="routes.todos"></a>
```

To route to an individual todo things get a bit more complicated. If we have a Todo model with ID# `42` in the context as `todo`, use the `get` filter shorthand on the `NamedRouteQuery` returned by `routes.todos` to generate a member route:

```html
<a data-route="routes.todos[todo]"></a>
```

Underneath, this is calling `Alfred.get('routes.todos').get(todo)`; the todo object is being passed as a key to the `NamedRouteQuery`, which knows how to generate a member route when given a record. The above HTML when rendered will look like this:

```html
<a data-route="routes.todos[todo]" href="/todos/42"></a>
```

This syntax can be extended to nested routes. If we have nested routes, we can use chained gets to generated nested routes

```coffeescript
class Tracker extends Batman.App
  @resources 'villains', ->
    @resources 'crimes'
```

Routes for collection and member crimes should look like `/villains/:villain_id/crimes` and `/villains/:villain_id/crimes/:id` respectively. Assuming the presence of a `villain` and a `crime` in the context, chained `get`s on `NamedRouteQuery`s achieve this:

```html
<!-- Collection of crimes for a particular villain -->
<a data-route="routes.villains[villain].crimes"></a>
<!-- One crime of a particular villain -->
<a data-route="routes.villains[villain].crimes[crime]"></a>
```

_Note_: `data-route` bindings route only to internal dispatch, and not external links. Use a regular `<a>` tag to link away from the application.

## data-route-params

Adds the provided keypath or literal value to the route provided to `data-route`. For example:

```html
<a data-route='routes.villians.new' data-route-params='"mastermind=true"'>Mastermind</a>
```

will route to `/villians/new?mastermind=true` and

```
<a data-route='routes.villians.new' data-route-params='otherRouteParams'>Other</a>
```

will look up `otherRouteParams` and append it to `/villains/new`, adding a `?` if necessary.

## data-view

`data-view` bindings attach custom `Batman.View` instances or instantiate custom `View` subclasses to / on a node. `data-view` expects either a `Batman.View` instance or subclass at the keypath passed to it. If an instance is passed, it will `set` the `node` property of the view to the node the `data-view` occurs on. If a class is passed, that class will be instantiated with the context the `data-view` binding executed in and with the node it occurred upon. See `Batman.View` for more information on custom Views and their uses.

_Note_: `data-view` bindings will bind to the passed keypath until it exists, that is to say until the value of it is not `undefined`. After the `View` has been set up, the `data-view` binding will remove itself and stop observing the keypath.

## data-partial

`data-partial` pulls in a partial template and renders it in the current context of the node the `data-partial` occurs in. `data-partial` expects the name of the view to render in the value of the HTML attribute. __Warning__: This value is not a keypath. The HTML attribute's value is interpreted as a string, and the template which resides at that view path will be rendered.

If we have this HTML at `views/villains/_stub.html` in our app:

```html
<span data-bind="villain.name"></span>
```

and in `views/villains/show.html` we have this HTML:

```html
<h1>A villain!</h1>
<div data-partial="villains/_stub"></div>
```

the contents of the `stub` partial will be inserted and rendered in the `<div>` above.

## data-defineview
`data-defineview` specifies that the content of the node defines the template for a particular view.

The binding value should be a regular view path, i.e. "#{resource_name}/#{controller_action}". For example:

```html
<div data-defineview="crimes/index">
  <ul class="crimes">
    <li class="crime" data-foreach-crime="crimes">
      <span data-bind="crime.name" data-addclass-heinous="crime.heinous" />
    </li>
  </ul>
</div>
```

will be used by the `CrimesController`'s  `index` action.

## data-renderif / data-deferif

`data-renderif` (and `data-deferif`) defers parsing of a node's child bindings until its keypath updates to true (or false, respectively). Note that this does not prevent the node from being inserted into the DOM. These bindings should generally be combined with a `data-showif` or `data-insertif` to prevent it from being visible until it is ready.

Deferring rendering can help prevent portions of the page updating many times while data is being loaded. It can also allow you to prevent features that are not yet ready from being used.

## data-yield

`data-yield` specifies that this node should be a render target for any view renderings that specify they should be rendered into a yield with this name. For example, `data-yield="myYieldNode"` can be rendered into by using `new Batman.View(contentFor: 'myYieldNode')`. The special case of `data-yield="main"` will be the render target for any view rendered by a controller action. This can mean the implicit render that happens by default at the end of a controller action or by explicitly calling `@render` inside a controller.

You can also specify a render target inside your HTML using `data-contentfor`.

```html
<div data-yield="main"></div>
```

## data-contentfor

`data-contentfor` specifies that the content of this node should be rendered into a `yield` with the corresponding name.

```html
<div data-contentfor="header"><h1 data-bind="title"></h1></div>
<div data-yield="header"></div>
```

## data-track

`data-track-#{viewOrClick}` fires events on an internal instance of a user-defined `MyApp.EventTracker` class. An `EventTracker` must respond to `track(viewOrClick, keypathValue, node)`, where:

- `viewOrClick` is the binding attribute argument
- `keypathValue` is the value of the keypath passed to the binding
- `node` is the bound node.

The node is considered _viewed_ when the binding is initialized.

Under the hood, batman.js will instantiate `MyApp.EventTracker` once, storing it at `Batman.Tracking.tracker`.

## data-debug

Calls `debugger` when instantiating the binding. `DebuggerBinding` is removed from production builds of batman.js.


average times

average times

# Super secret queue methods

    @QueueMethods =
      popAndServeNextTicket: ->

Move the current connection to the processed queue

TODO: get postID

        queueMeta = QueueMeta.findOne()

Save `currentlyServingTicketNumber` for potential updating if we bump the queue

        currentlyServingTicketNumber = queueMeta.currentlyServingTicketNumber

Update object, extended at various point for updating the QueueMeta

        update =
          $set: {}

If the currentlyServingTicketNumber is 0, skip attempting to archive the conneciton to ProcessedQueue

        if queueMeta.theOnlyConnectionAllowedIn isnt undefined

Return if there is no connection to pop or the timeCurrentTicketExpires hasn't expired

          hasntExpired = queueMeta.timeCurrentTicketExpires > moment.utc().toDate()
          return if hasntExpired

Insert the processed connection into the ProcessedQueue

          try
            waitTimeSeconds = moment.utc().diff (moment.utc queueMeta.theOnlyConnectionAllowedIn.timeEnqueued), 'seconds'
            processed =
              connection: queueMeta.theOnlyConnectionAllowedIn
              waitTimeSeconds: waitTimeSeconds
            QueueProcessed.insert processed
          catch err
            console.log err

Remove the connection

          criteria =
            connectionId: queueMeta.theOnlyConnectionAllowedIn.connectionId

          Queue.remove criteria

Now serving the next ticket number, and this ticket hasn't posted

          try
            averageWaitTimeSeconds = Math.round (((currentlyServingTicketNumber - 1) * queueMeta.averageWaitTimeSeconds) + waitTimeSeconds) / currentlyServingTicketNumber
            totalWaitTimeSeconds = queueMeta.totalWaitTimeSeconds + waitTimeSeconds
            currentlyServingTicketNumber += 1
            _.extend update.$set,
              currentlyServingTicketNumber: currentlyServingTicketNumber
              hasCurrentConnectionPosted: no
              averageWaitTimeSeconds: averageWaitTimeSeconds
              totalWaitTimeSeconds: totalWaitTimeSeconds
          catch err
            console.log err

Try to serve the next connection

        criteria = ticketNumber: currentlyServingTicketNumber
        nextConnection = Queue.findOne criteria

Set the allowed connection and expireTime if one exists

If there is a nextConnection (i.e. someone waiting in line), then serve them.
Otherwise clear out theOnlyConnectionAllowedIn.

        if nextConnection?
          timeCurrentTicketExpires = moment.utc()
          timeCurrentTicketExpires.add 1, 'minutes'
          _.extend update.$set,
            theOnlyConnectionAllowedIn: nextConnection
            timeCurrentTicketExpires: timeCurrentTicketExpires.toDate()

Set up timeout function to pop queue

          delayPop = Meteor.setTimeout QueueMethods.popAndServeNextTicket, 1000

If there is no nextConnection, unset theOnlyConnectionAllowedIn.
Note, fake data is filled in to pass schema, even though we're $unset'ing

        else
          update.$unset = theOnlyConnectionAllowedIn: ""

        criteria = _id: queueMeta._id

        QueueMeta.update criteria, update

TODO: keep it DRY; logic isn't exactly shared and want to keep update atomic to
avoid extraneous DDP messages.

      serveCurrentTicket: ->

Lookup the queue (only one for now)

        queueMeta = QueueMeta.findOne()

Get the next connection.

        criteria =
          ticketNumber: queueMeta.currentlyServingTicketNumber

        nextConnection = Queue.findOne criteria

Set the allowed connection and expireTime if one exists

        if nextConnection?
          timeCurrentTicketExpires = moment.utc()
          timeCurrentTicketExpires.add 1, 'minutes'
          update =
            $set:
              theOnlyConnectionAllowedIn: nextConnection
              timeCurrentTicketExpires: timeCurrentTicketExpires.toDate()
          criteria = _id: queueMeta._id

Set up timeout function to pop queue

          delayPop = Meteor.setTimeout QueueMethods.popAndServeNextTicket, 1000

          QueueMeta.update criteria, update

# Super secret queue methods

    @QueueMethods =
      popAndServeNextTicket: ->

Move the current connection to the processed queue

TODO: get postID

        queueMeta = QueueMeta.findOne()

Save `currentlyServingTicketNumber` for potential updating if we bump the queue

        currentlyServingTicketNumber = queueMeta.currentlyServingTicketNumber

Update object, extended at various point for updating the QueueMeta

        update =
          $set: {}

If the currentlyServingTicketNumber is 0, skip attempting to archive the conneciton to ProcessedQueue

        if queueMeta.theOnlyConnectionAllowedIn isnt undefined

Return if there is no connection to pop or the timeCurrentTicketExpires hasn't expired

          hasntExpired = queueMeta.timeCurrentTicketExpires > moment.utc().toDate()
          return if hasntExpired

Insert the processed connection into the ProcessedQueue

          processed =
            connection: queueMeta.theOnlyConnectionAllowedIn
            waitTimeSeconds: (moment.utc()).seconds() - (moment.utc queueMeta.theOnlyConnectionAllowedIn.timeEnqueued).seconds()

          QueueProcessed.insert processed

Remove the connection

          criteria =
            connectionId: queueMeta.theOnlyConnectionAllowedIn.connectionId

          Queue.remove criteria

Now serving the next ticket number, and this ticket hasn't posted

          currentlyServingTicketNumber += 1
          _.extend update.$set,
            currentlyServingTicketNumber: currentlyServingTicketNumber
            hasCurrentConnectionPosted: no

Try to serve the next connection

        criteria = ticketNumber: currentlyServingTicketNumber
        nextConnection = Queue.findOne criteria

Set the allowed connection and expireTime if one exists

If there is a nextConnection (i.e. someone waiting in line), then serve them.
Otherwise clear out theOnlyConnectionAllowedIn.

        if nextConnection?
          timeCurrentTicketExpires = moment.utc()
          timeCurrentTicketExpires.add 1, 'minutes'
          _.extend update.$set,
            theOnlyConnectionAllowedIn: nextConnection
            timeCurrentTicketExpires: timeCurrentTicketExpires.toDate()

Set up timeout function to pop queue

          delayPop = Meteor.setTimeout QueueMethods.popAndServeNextTicket, 1000

If there is no nextConnection, unset theOnlyConnectionAllowedIn.
Note, fake data is filled in to pass schema, even though we're $unset'ing

        else
          update.$unset = theOnlyConnectionAllowedIn: ""

        criteria = _id: queueMeta._id

        QueueMeta.update criteria, update

TODO: keep it DRY; logic isn't exactly shared and want to keep update atomic to
avoid extraneous DDP messages.

      serveCurrentTicket: ->

Lookup the queue (only one for now)

        queueMeta = QueueMeta.findOne()

Get the next connection.

        criteria =
          ticketNumber: queueMeta.currentlyServingTicketNumber

        nextConnection = Queue.findOne criteria

Set the allowed connection and expireTime if one exists

        if nextConnection?
          timeCurrentTicketExpires = moment.utc()
          timeCurrentTicketExpires.add 1, 'minutes'
          update =
            $set:
              theOnlyConnectionAllowedIn: nextConnection
              timeCurrentTicketExpires: timeCurrentTicketExpires.toDate()
          criteria = _id: queueMeta._id

Set up timeout function to pop queue

          delayPop = Meteor.setTimeout QueueMethods.popAndServeNextTicket, 1000

          QueueMeta.update criteria, update


on call error, clear calls before calling fail

    _self = this

    if console?.log?
     LOG = console.log.bind console
    else
     LOG = -> null

    if console?.error?
     ERROR_LOG = console.error.bind console
    else
     ERROR_LOG = -> null

    POLL_TYPE =
     progress: true

##Response class

    class Response
     constructor: (data, port, options) ->
      @id = data.id
      @port = port
      @options = options
      @queue = []
      @fresh = true

     progress: (progress, data, callback) ->
      @queue.push
       method: 'progress'
       data: data
       options: {progress: progress}
       callback: callback
      @_handleQueue()

     success: (data) ->
      @queue.push method: 'success', data: data, options: {}
      @_handleQueue()

     fail: (data) ->
      @queue.push method: 'fail', data: data, options: {}
      @_handleQueue()

     setOptions: (options) ->
      @options = options
      @fresh = true
      @_handleQueue()

     _multipleResponse: ->
      responseList = []
      callbacks = []
      for d in @queue
       responseList.push
        status: d.method
        data: d.data
        options: d.options
       if d.callback?
        callbacks.push d.callback

      done = ->
       for callback in callbacks
        callback()

      if @port.isStreaming
       @port.respondMultiple this, responseList, @options, done
      else if @fresh
       @port.respondMultiple this, responseList, @options, done
       @fresh = false

      @queue = []

     _handleQueue: ->
      return unless @queue.length > 0
      return if not @queue.isStreaming and not @fresh

      if @queue.length > 1
       return @_multipleResponse()

      d = @queue[0]

      if @port.isStreaming
       @port.respond this, d.method, d.data, d.options, @options, d.callback
      else if @fresh
       @port.respond this, d.method, d.data, d.options, @options, d.callback
       @fresh = false

      @queue = []

##Call class

    class Call
     constructor: (@id, @method, @data, @callbacks, @options) -> null

     handle: (data, options) ->
      if not @callbacks[options.status]?
       return if options.status is 'progress'
       #Handled by caller
       throw new Error "No callback registered #{@method} #{options.status}"
      self = this
      setTimeout (-> self.callbacks[options.status] data, options), 0

      if POLL_TYPE[options.status]?
       return false
      else
       return true

##Port base class

    class Port
     constructor: ->
      @handlers = {}
      @callsCache = {}
      @callsCounter = 0
      @id = parseInt Math.random() * 1000
      @responses = {}
      @wrappers =
       send: []
       respond: []
       handleCall: []
       handleResponse: []

     isStreaming: true

     onCallError: (msg, options) ->
      callsCache = @callsCache
      @callsCache = {}
      for id, call of callsCache
       if not call.callbacks.fail?
        ERROR_LOG 'fail callback not registered', call.method, call.data
       else
        call.callbacks.fail error: 'connectionError', msg: msg, options: options, {}

      @errorCallback msg, options

     onHandleError: (msg, data, options) ->
      @errorCallback msg, data
      response = new Response data, this, options
      response.fail msg

     errorCallback: (msg, options) ->
      ERROR_LOG msg, options

     wrap: (wrapper) ->
      for key, f of wrapper
       if @wrappers[key]?
        @wrappers[key].push f
       else
        this[key] = f

###Send RPC call

     send: (method, data, callbacks, options = {}) ->
      if (typeof callbacks) is 'function'
       callbacks =
        success: callbacks

      for f in @wrappers.send
       return unless f.apply this, [method, data, callbacks, options]

      params = @_createCall method, data, callbacks, options
      @_send params, callbacks

###Respond to a RPC call

     respond: (response, status, data, options = {}, portOptions = {}, callback = null) ->
      if not POLL_TYPE[status]?
       delete @responses[response.id]

      for f in @wrappers.respond
       return unless f.apply this, [response, status, data, options, portOptions]

      @_respond (@_createResponse response, status, data, options), portOptions, callback

     respondMultiple: (response, list, portOptions = {}, callback = null) ->
      for d in list
       if not POLL_TYPE[d.status]?
        delete @responses[response.id]
        break

      data = []
      for d in list
       cancel = false
       d.options ?= {}
       for f in @wrappers.respond
        r = f.apply this, [response, d.status, d.data, d.options, portOptions]
        if not r
         cancel = true
         break

        continue if cancel

       data.push @_createResponse response, d.status, d.data, d.options

      return if data.length is 0

      data =
       type: 'list'
       list: data

      @_respond data, portOptions, callback

###Create Call object
This is a private function

     _createCall: (method, data, callbacks, options) ->
      call = new Call "#{@id}-#{@callsCounter}", method, data, callbacks, options
      @callsCounter++
      @callsCache[call.id] = call

      params =
       type: 'call'
       id: call.id
       method: call.method
       data: call.data

      params[k] = v for k, v of options
      return params

###Create Response object

     _createResponse: (response, status, data, options) ->
      params =
       type: 'response'
       id: response.id
       status: status
       data: data

      params[k] = v for k, v of options

      return params

###Add handler

     on: (method, callback) ->
      @handlers[method] = callback

###Handle incoming message

     _handleMessage: (data, options, last = true) ->
      switch data.type
       when 'list'
        for d, i in data.list
         @_handleMessage d, options, (last and i + 1 is data.list.length)
       when 'response'
        @_handleResponse data, options, last
       when 'call'
        @_handleCall data, options, last
       when 'poll'
        @_handlePoll data, options, last

     _handleCall: (data, options) ->
      for f in @wrappers.handleCall
       return unless f.apply this, arguments
      if not @handlers[data.method]?
       @onHandleError "Unknown method: #{data.method}", data, options
       return
      @responses[data.id] = new Response data, this, options
      @handlers[data.method] data.data, data, @responses[data.id]

     _handleResponse: (data, options) ->
      for f in @wrappers.handleResponse
       return unless f.apply this, arguments
      if not @callsCache[data.id]?
       #Cannot reply
       @errorCallback "Response without call: #{data.id}", data
       return
      try
       if @callsCache[data.id].handle data.data, data
        delete @callsCache[data.id]
      catch e
       @errorCallback e.message, data
       delete @callsCache[data.id]

     _handlePoll: (data, options) ->
      @onHandleError "Poll not implemented", data, options

##WorkerPort class
Used for browser and worker

    class WorkerPort extends Port
     constructor: (worker) ->
      super()
      @worker = worker
      @worker.onmessage = @_onMessage.bind this
      #@worker.onerror = @onCallError.bind this

     _send: (data) ->
      @worker.postMessage data

     _respond: (data, options, callback) ->
      @worker.postMessage data
      callback?()

     _onMessage: (e) ->
      data = e.data
      @_handleMessage data

##SocketPort class

    class SocketPort extends Port
     constructor: (socket) ->
      super()
      @socket = socket
      @socket.on 'message', @_onMessage.bind this

     _send: (data) ->  @socket.emit 'message', data
     _respond: (data, options, callback) ->
      @worker.emit 'message', data
      callback?()

     _onMessage: (e) ->
      data = e.data
      @_handleMessage data

##ServerSocketPort class

    class ServerSocketPort extends Port
     constructor: (server) ->
      super()
      @server = server
      @server.on 'connection', @_onConnection.bind this

     _onConnection: (socket) ->
      new SocketPort handlers: @handlers, socket

##AJAX class

    class AjaxHttpPort extends Port
     constructor: (options) ->
      super()
      @protocol = options.protocol
      @host = options.host
      @port = options.port
      @path = options.path ? '/'
      @url = @path
      if @protocol?
       if @host? and not @port?
        @url = "#{@protocol}://#{@host}#{@path}"
       else if @host? and @port?
        @url = "#{@protocol}://#{@host}:#{@port}#{@path}"
      else
       if @host? and not @port?
        @url = "//#{@host}#{@path}"
       else if @host? and @port?
        @url = "//#{@host}:#{@port}#{@path}"

     isStreaming: false

     _onRequest: (xhr) ->
      return unless xhr.readyState is 4
      status = xhr.status
      if ((not status and xhr.responseText? and xhr.responseText != '') or
          (status >= 200 and status < 300) or
          (status is 304))
       try
        jsonData = JSON.parse xhr.responseText
       catch e
        @onCallError 'ParseError', e
        return

       @_handleMessage jsonData, xhr: xhr
      else
       @onCallError 'Cannot connect to server'

     _respond: (data, options, callback) ->
      @errorCallback 'AJAX cannot respond', data
      callback?()

     _send: (data) ->
      data = JSON.stringify data
      xhr = new XMLHttpRequest
      xhr.open 'POST', @url
      xhr.onreadystatechange = =>
       @_onRequest xhr
      xhr.setRequestHeader 'Accept', 'application/json'
      #xhr.setRequestHeader 'Content-Type', 'application/json'
      xhr.send data

     _handleResponse: (data, options, last = true) ->
      for f in @wrappers.handleResponse
       return unless f.apply this, arguments
      if not @callsCache[data.id]?
       @errorCallback "Response without call: #{data.id}", data
       return
      call = @callsCache[data.id]
      try
       if call.handle data.data, data
        delete @callsCache[data.id]
       else if last
        params =
         type: 'poll'
         id: call.id
        params[k] = v for k, v of call.options
        @_send params
      catch e
       @errorCallback e.message, data
       delete @callsCache[data.id]

##NodeHttpPort class

    class NodeHttpPort extends Port
     constructor: (options, http) ->
      super()
      @host = options.host ? 'localhost'
      @port = options.port ? 80
      @path = options.path ? '/'
      @http = http
      @_createHttpOptions()

     isStreaming: false

     _createHttpOptions: ->
      @httpOptions =
       hostname: @host
       port: @port
       path: @path
       method: 'POST'
       agent: false
       headers:
        accept: 'application/json'
       'content-type': 'application/json'

     _onRequest: (res) ->
      data = ''
      #LOG 'STATUS: ' + res.statusCode
      #LOG 'HEADERS: ' + JSON.stringify res.headers
      res.setEncoding 'utf8'
      res.on 'data', (chunk) ->
       data += chunk
      #LOG 'result', res
      res.on 'end', =>
       try
        jsonData = JSON.parse data
       catch e
        @onCallError 'ParseError', e
        return

       @_handleMessage jsonData, response: res

     _respond: (data, options, callback) ->
      data = JSON.stringify data
      res = options.response
      res.setHeader 'content-length', Buffer.byteLength data, 'utf8'
      if callback?
       res.once 'finish', ->
        callback()
       res.once 'close', ->
        callback()

      res.write data
      res.end()

     _send: (data, callbacks) ->
      data = JSON.stringify data
      options = @httpOptions
      options.headers['content-length'] = Buffer.byteLength data, 'utf8'

      req = @http.request options, @_onRequest.bind this
      delete options.headers['content-length']
      req.on 'error', (e) ->
       callbacks.fail? e

      req.write data
      req.end()

     _handleResponse: (data, options, last = true) ->
      for f in @wrappers.handleResponse
       return unless f.apply this, arguments
      if not @callsCache[data.id]?
       @errorCallback "Response without call: #{data.id}", data
       return
      call = @callsCache[data.id]
      if not call.handle data.data, data
       return if not last
       params =
        type: 'poll'
        id: call.id
       params[k] = v for k, v of call.options
       @_send params, call.callbacks

##NodeHttpServerPort class

    class NodeHttpServerPort extends Port
     constructor: (options, http, zlib = null) ->
      super()
      @port = options.port
      @http = http
      @zlib = zlib
      @allowOrigin = options.allowOrigin

     isStreaming: false

     _onRequest: (req, res) ->
      data = ''
      res.setHeader 'content-type', 'application/json'

      req.on 'data', (chunk) ->
       data += chunk
      req.on 'end', =>
       try
        jsonData = JSON.parse data
       catch e
        @errorCallback 'ParseError', e
        return

       @_handleMessage jsonData, response: res, request: req

     _respond: (data, options, callback) ->
      if @allowOrigin?
       options.response.setHeader 'Access-Control-Allow-Origin', @allowOrigin

      accept = options.request.headers['accept-encoding']
      accept ?= ''
      if not @zlib?
       accept = ''

      data = JSON.stringify data
      buffer = new Buffer data, 'utf8'
      if accept.match /\bdeflate\b/
       options.response.setHeader 'content-encoding', 'deflate'
       @zlib.deflate buffer, (err, result) =>
        if err?
         return @errorCallback 'DeflateError', e
        @_sendBuffer result, options.response, callback
      else if accept.match /\bgzip\b/
       options.response.setHeader 'content-encoding', 'gzip'
       @zlib.gzip buffer, (err, result) =>
        if err?
         return @errorCallback 'GZipeError', e
        @_sendBuffer result, options.response, callback
      else
       @_sendBuffer buffer, options.response, callback

     _sendBuffer: (buf, res, callback) ->
       res.setHeader 'content-length', buf.length
       if callback?
        res.once 'finish', ->
         callback()
        res.once 'close', ->
         callback()

       res.write buf
       res.end()

     listen: ->
      @server = @http.createServer @_onRequest.bind this
      @server.listen @port

     _handlePoll: (data, options) ->
      for f in @wrappers.handleCall
       return unless f.apply this, arguments
      if not @responses[data.id]?
       @onHandleError "Poll without response: #{data.id}", data, options
       return
      @responses[data.id].setOptions options

##NodeHttpsServerPort class

    class NodeHttpsServerPort extends NodeHttpServerPort
     constructor: (options, http) ->
      super options, http
      @_key = options.key
      @_cert = options.cert

     listen: ->
      options =
       key: @_key
       cert: @_cert

      @server = @http.createServer options, @_onRequest.bind this
      @server.listen @port

#IO Module

    IO =
     addPort: (name, port) ->
      IO[name] = port

     ports:
      WorkerPort: WorkerPort
      SocketPort: SocketPort
      AjaxHttpPort: AjaxHttpPort
      NodeHttpPort: NodeHttpPort
      NodeHttpServerPort: NodeHttpServerPort
      NodeHttpsServerPort: NodeHttpsServerPort
      ServerSocketPort: ServerSocketPort

     Helpers:
      progress: (from, to, func) ->
       (progress, data) ->
        func? progress * (to - from) + from, data

     setup_____: (options) ->
      options.workers ?= []
      switch options.platform
       when 'ui'
        for worker in options.workers
         IO.addPort worker.name, new WorkerPort worker.js
        for socket in options.sockets
         IO.addPort socket.name, new SocketPort socket.url
       when 'node'
        for socket in options.listenSockets
         IO.addPort socket.name, new SocketListenPort socket.port
        for socket in options.sockets
         IO.addPort socket.name, new SocketPort socket.url
       when 'worker'
        IO.addPort 'UI', new WorkerListenPort _self

    if exports?
     module.exports = IO
    else
     _self.IO = IO

    _self = this

    if console?.log?
     LOG = console.log.bind console
    else
     LOG = -> null

    if console?.error?
     ERROR_LOG = console.error.bind console
    else
     ERROR_LOG = -> null

    POLL_TYPE =
     progress: true

##Response class

    class Response
     constructor: (data, port, options) ->
      @id = data.id
      @port = port
      @options = options
      @queue = []
      @fresh = true

     progress: (progress, data, callback) ->
      @queue.push
       method: 'progress'
       data: data
       options: {progress: progress}
       callback: callback
      @_handleQueue()

     success: (data) ->
      @queue.push method: 'success', data: data, options: {}
      @_handleQueue()

     fail: (data) ->
      @queue.push method: 'fail', data: data, options: {}
      @_handleQueue()

     setOptions: (options) ->
      @options = options
      @fresh = true
      @_handleQueue()

     _multipleResponse: ->
      responseList = []
      callbacks = []
      for d in @queue
       responseList.push
        status: d.method
        data: d.data
        options: d.options
       if d.callback?
        callbacks.push d.callback

      done = ->
       for callback in callbacks
        callback()

      if @port.isStreaming
       @port.respondMultiple this, responseList, @options, done
      else if @fresh
       @port.respondMultiple this, responseList, @options, done
       @fresh = false

      @queue = []

     _handleQueue: ->
      return unless @queue.length > 0
      return if not @queue.isStreaming and not @fresh

      if @queue.length > 1
       return @_multipleResponse()

      d = @queue[0]

      if @port.isStreaming
       @port.respond this, d.method, d.data, d.options, @options, d.callback
      else if @fresh
       @port.respond this, d.method, d.data, d.options, @options, d.callback
       @fresh = false

      @queue = []

##Call class

    class Call
     constructor: (@id, @method, @data, @callbacks, @options) -> null

     handle: (data, options) ->
      if not @callbacks[options.status]?
       return if options.status is 'progress'
       #Handled by caller
       throw new Error "No callback registered #{@method} #{options.status}"
      self = this
      setTimeout (-> self.callbacks[options.status] data, options), 0

      if POLL_TYPE[options.status]?
       return false
      else
       return true

##Port base class

    class Port
     constructor: ->
      @handlers = {}
      @callsCache = {}
      @callsCounter = 0
      @id = parseInt Math.random() * 1000
      @responses = {}
      @wrappers =
       send: []
       respond: []
       handleCall: []
       handleResponse: []

     isStreaming: true

     onCallError: (msg, options) ->
      for id, call of @callsCache
       if not call.callbacks.fail?
        ERROR_LOG 'fail callback not registered', call.method, call.data
       else
        call.callbacks.fail error: 'connectionError', msg: msg, options: options, {}

      @callsCache = {}

      @errorCallback msg, options

     onHandleError: (msg, data, options) ->
      @errorCallback msg, data
      response = new Response data, this, options
      response.fail msg

     errorCallback: (msg, options) ->
      ERROR_LOG msg, options

     wrap: (wrapper) ->
      for key, f of wrapper
       if @wrappers[key]?
        @wrappers[key].push f
       else
        this[key] = f

###Send RPC call

     send: (method, data, callbacks, options = {}) ->
      if (typeof callbacks) is 'function'
       callbacks =
        success: callbacks

      for f in @wrappers.send
       return unless f.apply this, [method, data, callbacks, options]

      params = @_createCall method, data, callbacks, options
      @_send params, callbacks

###Respond to a RPC call

     respond: (response, status, data, options = {}, portOptions = {}, callback = null) ->
      if not POLL_TYPE[status]?
       delete @responses[response.id]

      for f in @wrappers.respond
       return unless f.apply this, [response, status, data, options, portOptions]

      @_respond (@_createResponse response, status, data, options), portOptions, callback

     respondMultiple: (response, list, portOptions = {}, callback = null) ->
      for d in list
       if not POLL_TYPE[d.status]?
        delete @responses[response.id]
        break

      data = []
      for d in list
       cancel = false
       d.options ?= {}
       for f in @wrappers.respond
        r = f.apply this, [response, d.status, d.data, d.options, portOptions]
        if not r
         cancel = true
         break

        continue if cancel

       data.push @_createResponse response, d.status, d.data, d.options

      return if data.length is 0

      data =
       type: 'list'
       list: data

      @_respond data, portOptions, callback

###Create Call object
This is a private function

     _createCall: (method, data, callbacks, options) ->
      call = new Call "#{@id}-#{@callsCounter}", method, data, callbacks, options
      @callsCounter++
      @callsCache[call.id] = call

      params =
       type: 'call'
       id: call.id
       method: call.method
       data: call.data

      params[k] = v for k, v of options
      return params

###Create Response object

     _createResponse: (response, status, data, options) ->
      params =
       type: 'response'
       id: response.id
       status: status
       data: data

      params[k] = v for k, v of options

      return params

###Add handler

     on: (method, callback) ->
      @handlers[method] = callback

###Handle incoming message

     _handleMessage: (data, options, last = true) ->
      switch data.type
       when 'list'
        for d, i in data.list
         @_handleMessage d, options, (last and i + 1 is data.list.length)
       when 'response'
        @_handleResponse data, options, last
       when 'call'
        @_handleCall data, options, last
       when 'poll'
        @_handlePoll data, options, last

     _handleCall: (data, options) ->
      for f in @wrappers.handleCall
       return unless f.apply this, arguments
      if not @handlers[data.method]?
       @onHandleError "Unknown method: #{data.method}", data, options
       return
      @responses[data.id] = new Response data, this, options
      @handlers[data.method] data.data, data, @responses[data.id]

     _handleResponse: (data, options) ->
      for f in @wrappers.handleResponse
       return unless f.apply this, arguments
      if not @callsCache[data.id]?
       #Cannot reply
       @errorCallback "Response without call: #{data.id}", data
       return
      try
       if @callsCache[data.id].handle data.data, data
        delete @callsCache[data.id]
      catch e
       @errorCallback e.message, data
       delete @callsCache[data.id]

     _handlePoll: (data, options) ->
      @onHandleError "Poll not implemented", data, options

##WorkerPort class
Used for browser and worker

    class WorkerPort extends Port
     constructor: (worker) ->
      super()
      @worker = worker
      @worker.onmessage = @_onMessage.bind this
      #@worker.onerror = @onCallError.bind this

     _send: (data) ->
      @worker.postMessage data

     _respond: (data, options, callback) ->
      @worker.postMessage data
      callback?()

     _onMessage: (e) ->
      data = e.data
      @_handleMessage data

##SocketPort class

    class SocketPort extends Port
     constructor: (socket) ->
      super()
      @socket = socket
      @socket.on 'message', @_onMessage.bind this

     _send: (data) ->  @socket.emit 'message', data
     _respond: (data, options, callback) ->
      @worker.emit 'message', data
      callback?()

     _onMessage: (e) ->
      data = e.data
      @_handleMessage data

##ServerSocketPort class

    class ServerSocketPort extends Port
     constructor: (server) ->
      super()
      @server = server
      @server.on 'connection', @_onConnection.bind this

     _onConnection: (socket) ->
      new SocketPort handlers: @handlers, socket

##AJAX class

    class AjaxHttpPort extends Port
     constructor: (options) ->
      super()
      @protocol = options.protocol
      @host = options.host
      @port = options.port
      @path = options.path ? '/'
      @url = @path
      if @protocol?
       if @host? and not @port?
        @url = "#{@protocol}://#{@host}#{@path}"
       else if @host? and @port?
        @url = "#{@protocol}://#{@host}:#{@port}#{@path}"
      else
       if @host? and not @port?
        @url = "//#{@host}#{@path}"
       else if @host? and @port?
        @url = "//#{@host}:#{@port}#{@path}"

     isStreaming: false

     _onRequest: (xhr) ->
      return unless xhr.readyState is 4
      status = xhr.status
      if ((not status and xhr.responseText? and xhr.responseText != '') or
          (status >= 200 and status < 300) or
          (status is 304))
       try
        jsonData = JSON.parse xhr.responseText
       catch e
        @onCallError 'ParseError', e
        return

       @_handleMessage jsonData, xhr: xhr
      else
       @onCallError 'Cannot connect to server'

     _respond: (data, options, callback) ->
      @errorCallback 'AJAX cannot respond', data
      callback?()

     _send: (data) ->
      data = JSON.stringify data
      xhr = new XMLHttpRequest
      xhr.open 'POST', @url
      xhr.onreadystatechange = =>
       @_onRequest xhr
      xhr.setRequestHeader 'Accept', 'application/json'
      #xhr.setRequestHeader 'Content-Type', 'application/json'
      xhr.send data

     _handleResponse: (data, options, last = true) ->
      for f in @wrappers.handleResponse
       return unless f.apply this, arguments
      if not @callsCache[data.id]?
       @errorCallback "Response without call: #{data.id}", data
       return
      call = @callsCache[data.id]
      try
       if call.handle data.data, data
        delete @callsCache[data.id]
       else if last
        params =
         type: 'poll'
         id: call.id
        params[k] = v for k, v of call.options
        @_send params
      catch e
       @errorCallback e.message, data
       delete @callsCache[data.id]

##NodeHttpPort class

    class NodeHttpPort extends Port
     constructor: (options, http) ->
      super()
      @host = options.host ? 'localhost'
      @port = options.port ? 80
      @path = options.path ? '/'
      @http = http
      @_createHttpOptions()

     isStreaming: false

     _createHttpOptions: ->
      @httpOptions =
       hostname: @host
       port: @port
       path: @path
       method: 'POST'
       agent: false
       headers:
        accept: 'application/json'
       'content-type': 'application/json'

     _onRequest: (res) ->
      data = ''
      #LOG 'STATUS: ' + res.statusCode
      #LOG 'HEADERS: ' + JSON.stringify res.headers
      res.setEncoding 'utf8'
      res.on 'data', (chunk) ->
       data += chunk
      #LOG 'result', res
      res.on 'end', =>
       try
        jsonData = JSON.parse data
       catch e
        @onCallError 'ParseError', e
        return

       @_handleMessage jsonData, response: res

     _respond: (data, options, callback) ->
      data = JSON.stringify data
      res = options.response
      res.setHeader 'content-length', Buffer.byteLength data, 'utf8'
      if callback?
       res.once 'finish', ->
        callback()
       res.once 'close', ->
        callback()

      res.write data
      res.end()

     _send: (data, callbacks) ->
      data = JSON.stringify data
      options = @httpOptions
      options.headers['content-length'] = Buffer.byteLength data, 'utf8'

      req = @http.request options, @_onRequest.bind this
      delete options.headers['content-length']
      req.on 'error', (e) ->
       callbacks.fail? e

      req.write data
      req.end()

     _handleResponse: (data, options, last = true) ->
      for f in @wrappers.handleResponse
       return unless f.apply this, arguments
      if not @callsCache[data.id]?
       @errorCallback "Response without call: #{data.id}", data
       return
      call = @callsCache[data.id]
      if not call.handle data.data, data
       return if not last
       params =
        type: 'poll'
        id: call.id
       params[k] = v for k, v of call.options
       @_send params, call.callbacks

##NodeHttpServerPort class

    class NodeHttpServerPort extends Port
     constructor: (options, http, zlib = null) ->
      super()
      @port = options.port
      @http = http
      @zlib = zlib
      @allowOrigin = options.allowOrigin

     isStreaming: false

     _onRequest: (req, res) ->
      data = ''
      res.setHeader 'content-type', 'application/json'

      req.on 'data', (chunk) ->
       data += chunk
      req.on 'end', =>
       try
        jsonData = JSON.parse data
       catch e
        @errorCallback 'ParseError', e
        return

       @_handleMessage jsonData, response: res, request: req

     _respond: (data, options, callback) ->
      if @allowOrigin?
       options.response.setHeader 'Access-Control-Allow-Origin', @allowOrigin

      accept = options.request.headers['accept-encoding']
      accept ?= ''
      if not @zlib?
       accept = ''

      data = JSON.stringify data
      buffer = new Buffer data, 'utf8'
      if accept.match /\bdeflate\b/
       options.response.setHeader 'content-encoding', 'deflate'
       @zlib.deflate buffer, (err, result) =>
        if err?
         return @errorCallback 'DeflateError', e
        @_sendBuffer result, options.response, callback
      else if accept.match /\bgzip\b/
       options.response.setHeader 'content-encoding', 'gzip'
       @zlib.gzip buffer, (err, result) =>
        if err?
         return @errorCallback 'GZipeError', e
        @_sendBuffer result, options.response, callback
      else
       @_sendBuffer buffer, options.response, callback

     _sendBuffer: (buf, res, callback) ->
       res.setHeader 'content-length', buf.length
       if callback?
        res.once 'finish', ->
         callback()
        res.once 'close', ->
         callback()

       res.write buf
       res.end()

     listen: ->
      @server = @http.createServer @_onRequest.bind this
      @server.listen @port

     _handlePoll: (data, options) ->
      for f in @wrappers.handleCall
       return unless f.apply this, arguments
      if not @responses[data.id]?
       @onHandleError "Poll without response: #{data.id}", data, options
       return
      @responses[data.id].setOptions options

##NodeHttpsServerPort class

    class NodeHttpsServerPort extends NodeHttpServerPort
     constructor: (options, http) ->
      super options, http
      @_key = options.key
      @_cert = options.cert

     listen: ->
      options =
       key: @_key
       cert: @_cert

      @server = @http.createServer options, @_onRequest.bind this
      @server.listen @port

#IO Module

    IO =
     addPort: (name, port) ->
      IO[name] = port

     ports:
      WorkerPort: WorkerPort
      SocketPort: SocketPort
      AjaxHttpPort: AjaxHttpPort
      NodeHttpPort: NodeHttpPort
      NodeHttpServerPort: NodeHttpServerPort
      NodeHttpsServerPort: NodeHttpsServerPort
      ServerSocketPort: ServerSocketPort

     Helpers:
      progress: (from, to, func) ->
       (progress, data) ->
        func? progress * (to - from) + from, data

     setup_____: (options) ->
      options.workers ?= []
      switch options.platform
       when 'ui'
        for worker in options.workers
         IO.addPort worker.name, new WorkerPort worker.js
        for socket in options.sockets
         IO.addPort socket.name, new SocketPort socket.url
       when 'node'
        for socket in options.listenSockets
         IO.addPort socket.name, new SocketListenPort socket.port
        for socket in options.sockets
         IO.addPort socket.name, new SocketPort socket.url
       when 'worker'
        IO.addPort 'UI', new WorkerListenPort _self

    if exports?
     module.exports = IO
    else
     _self.IO = IO