// Type definitions for Angular v2.0.0-local_sha.aaf41fc
// Project: http://angular.io/
// Definitions by: angular team <https://github.com/angular/>
// Definitions: https://github.com/borisyankov/DefinitelyTyped

// ***********************************************************
// This file is generated by the Angular build process.
// Please do not create manual edits or send pull requests
// modifying this file.
// ***********************************************************






interface Map<K,V> {}


declare module ng {
  // See https://github.com/Microsoft/TypeScript/issues/1168
  class BaseException /* extends Error */ {
    message: string;
    stack: string;
    toString(): string;
  }
  interface InjectableReference {}
}

declare module ngWorker {
  // See https://github.com/Microsoft/TypeScript/issues/1168
  class BaseException /* extends Error */ {
    message: string;
    stack: string;
    toString(): string;
  }
  interface InjectableReference {}
}

declare module ngUi {
  // See https://github.com/Microsoft/TypeScript/issues/1168
  class BaseException /* extends Error */ {
    message: string;
    stack: string;
    toString(): string;
  }
  interface InjectableReference {}
}




declare module ng {  
  /**
   * Declares an injectable parameter to be a live list of directives or variable
   * bindings from the content children of a directive.
   * 
   * ### Example ([live demo](http://plnkr.co/edit/lY9m8HLy7z06vDoUaSN2?p=preview))
   * 
   * Assume that `<tabs>` component would like to get a list its children `<pane>`
   * components as shown in this example:
   * 
   * ```html
   * <tabs>
   *   <pane title="Overview">...</pane>
   *   <pane *ng-for="#o of objects" [title]="o.title">{{o.text}}</pane>
   * </tabs>
   * ```
   * 
   * The preferred solution is to query for `Pane` directives using this decorator.
   * 
   * ```javascript
   * @Component({
   *   selector: 'pane',
   *   inputs: ['title']
   * })
   * class Pane {
   *   title:string;
   * }
   * 
   * @Component({
   *  selector: 'tabs',
   *  template: `
   *    <ul>
   *      <li *ng-for="#pane of panes">{{pane.title}}</li>
   *    </ul>
   *    <content></content>
   *  `
   * })
   * class Tabs {
   *   panes: QueryList<Pane>;
   *   constructor(@Query(Pane) panes:QueryList<Pane>) {
   *    this.panes = panes;
   *  }
   * }
   * ```
   * 
   * A query can look for variable bindings by passing in a string with desired binding symbol.
   * 
   * ### Example ([live demo](http://plnkr.co/edit/sT2j25cH1dURAyBRCKx1?p=preview))
   * ```html
   * <seeker>
   *   <div #findme>...</div>
   * </seeker>
   * 
   * @Component({ selector: 'seeker' })
   * class Seeker {
   *   constructor(@Query('findme') elList: QueryList<ElementRef>) {...}
   * }
   * ```
   * 
   * In this case the object that is injected depend on the type of the variable
   * binding. It can be an ElementRef, a directive or a component.
   * 
   * Passing in a comma separated list of variable bindings will query for all of them.
   * 
   * ```html
   * <seeker>
   *   <div #find-me>...</div>
   *   <div #find-me-too>...</div>
   * </seeker>
   * 
   *  @Component({
   *   selector: 'seeker'
   * })
   * class Seeker {
   *   constructor(@Query('findMe, findMeToo') elList: QueryList<ElementRef>) {...}
   * }
   * ```
   * 
   * Configure whether query looks for direct children or all descendants
   * of the querying element, by using the `descendants` parameter.
   * It is set to `false` by default.
   * 
   * ### Example ([live demo](http://plnkr.co/edit/wtGeB977bv7qvA5FTYl9?p=preview))
   * ```html
   * <container #first>
   *   <item>a</item>
   *   <item>b</item>
   *   <container #second>
   *     <item>c</item>
   *   </container>
   * </container>
   * ```
   * 
   * When querying for items, the first container will see only `a` and `b` by default,
   * but with `Query(TextDirective, {descendants: true})` it will see `c` too.
   * 
   * The queried directives are kept in a depth-first pre-order with respect to their
   * positions in the DOM.
   * 
   * Query does not look deep into any subcomponent views.
   * 
   * Query is updated as part of the change-detection cycle. Since change detection
   * happens after construction of a directive, QueryList will always be empty when observed in the
   * constructor.
   * 
   * The injected object is an unmodifiable live list.
   * See {@link QueryList} for more details.
   */
  class QueryMetadata extends DependencyMetadata {
    
    constructor(_selector: Type | string, {descendants, first}?: {descendants?: boolean, first?: boolean});
    
    /**
     * whether we want to query only direct children (false) or all
     * children (true).
     */
    descendants: boolean;
    
    first: boolean;
    
    /**
     * always `false` to differentiate it with {@link ViewQueryMetadata}.
     */
    isViewQuery: boolean;
    
    /**
     * what this is querying for.
     */
    selector: any;
    
    /**
     * whether this is querying for a variable binding or a directive.
     */
    isVarBindingQuery: boolean;
    
    /**
     * returns a list of variable bindings this is querying for.
     * Only applicable if this is a variable bindings query.
     */
    varBindings: string[];
    
    toString(): string;
    
  }

    
  /**
   * Configures a content query.
   * 
   * Content queries are set before the `afterContentInit` callback is called.
   * 
   * ### Example
   * 
   * ```
   * @Directive({
   *   selector: 'someDir'
   * })
   * class SomeDir {
   *   @ContentChildren(ChildDirective) contentChildren: QueryList<ChildDirective>;
   * 
   *   afterContentInit() {
   *     // contentChildren is set
   *   }
   * }
   * ```
   */
  class ContentChildrenMetadata extends QueryMetadata {
    
    constructor(_selector: Type | string, {descendants}?: {descendants?: boolean});
    
  }

    
  /**
   * Configures a content query.
   * 
   * Content queries are set before the `afterContentInit` callback is called.
   * 
   * ### Example
   * 
   * ```
   * @Directive({
   *   selector: 'someDir'
   * })
   * class SomeDir {
   *   @ContentChild(ChildDirective) contentChild;
   * 
   *   afterContentInit() {
   *     // contentChild is set
   *   }
   * }
   * ```
   */
  class ContentChildMetadata extends QueryMetadata {
    
    constructor(_selector: Type | string);
    
  }

    
  /**
   * Configures a view query.
   * 
   * View queries are set before the `afterViewInit` callback is called.
   * 
   * ### Example
   * 
   * ```
   * @Component({
   *   selector: 'someDir',
   *   templateUrl: 'someTemplate',
   *   directives: [ItemDirective]
   * })
   * class SomeDir {
   *   @ViewChildren(ItemDirective) viewChildren: QueryList<ItemDirective>;
   * 
   *   afterViewInit() {
   *     // viewChildren is set
   *   }
   * }
   * ```
   */
  class ViewChildrenMetadata extends ViewQueryMetadata {
    
    constructor(_selector: Type | string);
    
  }

    
  /**
   * Similar to {@link QueryMetadata}, but querying the component view, instead of
   * the content children.
   * 
   * ### Example ([live demo](http://plnkr.co/edit/eNsFHDf7YjyM6IzKxM1j?p=preview))
   * 
   * ```javascript
   * @Component({...})
   * @View({
   *   template: `
   *     <item> a </item>
   *     <item> b </item>
   *     <item> c </item>
   *   `
   * })
   * class MyComponent {
   *   shown: boolean;
   * 
   *   constructor(private @Query(Item) items:QueryList<Item>) {
   *     items.onChange(() => console.log(items.length));
   *   }
   * }
   * ```
   * 
   * Supports the same querying parameters as {@link QueryMetadata}, except
   * `descendants`. This always queries the whole view.
   * 
   * As `shown` is flipped between true and false, items will contain zero of one
   * items.
   * 
   * Specifies that a {@link QueryList} should be injected.
   * 
   * The injected object is an iterable and observable live list.
   * See {@link QueryList} for more details.
   */
  class ViewQueryMetadata extends QueryMetadata {
    
    constructor(_selector: Type | string, {descendants, first}?: {descendants?: boolean, first?: boolean});
    
    /**
     * always `true` to differentiate it with {@link QueryMetadata}.
     */
    isViewQuery: any;
    
    toString(): string;
    
  }

    
  /**
   * Configures a view query.
   * 
   * View queries are set before the `afterViewInit` callback is called.
   * 
   * ### Example
   * 
   * ```
   * @Component({
   *   selector: 'someDir',
   *   templateUrl: 'someTemplate',
   *   directives: [ItemDirective]
   * })
   * class SomeDir {
   *   @ViewChild(ItemDirective) viewChild:ItemDirective;
   * 
   *   afterViewInit() {
   *     // viewChild is set
   *   }
   * }
   * ```
   */
  class ViewChildMetadata extends ViewQueryMetadata {
    
    constructor(_selector: Type | string);
    
  }

    
  /**
   * Specifies that a constant attribute value should be injected.
   * 
   * The directive can inject constant string literals of host element attributes.
   * 
   * ### Example
   * 
   * Suppose we have an `<input>` element and want to know its `type`.
   * 
   * ```html
   * <input type="text">
   * ```
   * 
   * A decorator can inject string literal `text` like so:
   * 
   * ```javascript
   * @Directive({
   *   selector: `input'
   * })
   * class InputDirective {
   *   constructor(@Attribute('type') type) {
   *     // type would be `text` in this example
   *   }
   * }
   * ```
   */
  class AttributeMetadata extends DependencyMetadata {
    
    constructor(attributeName: string);
    
    attributeName: string;
    
    token: any;
    
    toString(): string;
    
  }

    
  /**
   * Declare reusable UI building blocks for an application.
   * 
   * Each Angular component requires a single `@Component` and at least one `@View` annotation. The
   * `@Component`
   * annotation specifies when a component is instantiated, and which properties and hostListeners it
   * binds to.
   * 
   * When a component is instantiated, Angular
   * - creates a shadow DOM for the component.
   * - loads the selected template into the shadow DOM.
   * - creates all the injectable objects configured with `providers` and `viewProviders`.
   * 
   * All template expressions and statements are then evaluated against the component instance.
   * 
   * For details on the `@View` annotation, see {@link ViewMetadata}.
   * 
   * ## Lifecycle hooks
   * 
   * When the component class implements some {@link angular2/lifecycle_hooks} the callbacks are
   * called by the change detection at defined points in time during the life of the component.
   * 
   * ### Example
   * 
   * ```
   * @Component({
   *   selector: 'greet',
   *   template: 'Hello {{name}}!'
   * })
   * class Greet {
   *   name: string;
   * 
   *   constructor() {
   *     this.name = 'World';
   *   }
   * }
   * ```
   */
  class ComponentMetadata extends DirectiveMetadata {
    
    constructor({selector, inputs, outputs, properties, events, host, exportAs, moduleId, bindings,
                   providers, viewBindings, viewProviders,
                   changeDetection, queries, templateUrl, template,
                   styleUrls, styles, directives, pipes, encapsulation}?: {
        selector?: string,
        inputs?: string[],
        outputs?: string[],
        properties?: string[],
        events?: string[],
        host?: {[key: string]: string},
        /** @deprecated */ bindings?: any[],
        providers?: any[],
        exportAs?: string,
        moduleId?: string,
        /** @deprecated */ viewBindings?: any[],
        viewProviders?: any[],
        queries?: {[key: string]: any},
        changeDetection?: ChangeDetectionStrategy,
        templateUrl?: string,
        template?: string,
        styleUrls?: string[],
        styles?: string[],
        directives?: Array<Type | any[]>,
        pipes?: Array<Type | any[]>,
        encapsulation?: ViewEncapsulation
      });
    
    /**
     * Defines the used change detection strategy.
     * 
     * When a component is instantiated, Angular creates a change detector, which is responsible for
     * propagating the component's bindings.
     * 
     * The `changeDetection` property defines, whether the change detection will be checked every time
     * or only when the component tells it to do so.
     */
    changeDetection: ChangeDetectionStrategy;
    
    /**
     * Defines the set of injectable objects that are visible to its view DOM children.
     * 
     * ## Simple Example
     * 
     * Here is an example of a class that can be injected:
     * 
     * ```
     * class Greeter {
     *    greet(name:string) {
     *      return 'Hello ' + name + '!';
     *    }
     * }
     * 
     * @Directive({
     *   selector: 'needs-greeter'
     * })
     * class NeedsGreeter {
     *   greeter:Greeter;
     * 
     *   constructor(greeter:Greeter) {
     *     this.greeter = greeter;
     *   }
     * }
     * 
     * @Component({
     *   selector: 'greet',
     *   viewProviders: [
     *     Greeter
     *   ],
     *   template: `<needs-greeter></needs-greeter>`,
     *   directives: [NeedsGreeter]
     * })
     * class HelloWorld {
     * }
     * 
     * ```
     */
    viewProviders: any[];
    
    viewBindings: any[];
    
    templateUrl: string;
    
    template: string;
    
    styleUrls: string[];
    
    styles: string[];
    
    directives: Array<Type | any[]>;
    
    pipes: Array<Type | any[]>;
    
    encapsulation: ViewEncapsulation;
    
  }

    
  /**
   * Directives allow you to attach behavior to elements in the DOM.
   * 
   * {@link DirectiveMetadata}s with an embedded view are called {@link ComponentMetadata}s.
   * 
   * A directive consists of a single directive annotation and a controller class. When the
   * directive's `selector` matches
   * elements in the DOM, the following steps occur:
   * 
   * 1. For each directive, the `ElementInjector` attempts to resolve the directive's constructor
   * arguments.
   * 2. Angular instantiates directives for each matched element using `ElementInjector` in a
   * depth-first order,
   *    as declared in the HTML.
   * 
   * ## Understanding How Injection Works
   * 
   * There are three stages of injection resolution.
   * - *Pre-existing Injectors*:
   *   - The terminal {@link Injector} cannot resolve dependencies. It either throws an error or, if
   * the dependency was
   *     specified as `@Optional`, returns `null`.
   *   - The platform injector resolves browser singleton resources, such as: cookies, title,
   * location, and others.
   * - *Component Injectors*: Each component instance has its own {@link Injector}, and they follow
   * the same parent-child hierarchy
   *     as the component instances in the DOM.
   * - *Element Injectors*: Each component instance has a Shadow DOM. Within the Shadow DOM each
   * element has an `ElementInjector`
   *     which follow the same parent-child hierarchy as the DOM elements themselves.
   * 
   * When a template is instantiated, it also must instantiate the corresponding directives in a
   * depth-first order. The
   * current `ElementInjector` resolves the constructor dependencies for each directive.
   * 
   * Angular then resolves dependencies as follows, according to the order in which they appear in the
   * {@link ViewMetadata}:
   * 
   * 1. Dependencies on the current element
   * 2. Dependencies on element injectors and their parents until it encounters a Shadow DOM boundary
   * 3. Dependencies on component injectors and their parents until it encounters the root component
   * 4. Dependencies on pre-existing injectors
   * 
   * 
   * The `ElementInjector` can inject other directives, element-specific special objects, or it can
   * delegate to the parent
   * injector.
   * 
   * To inject other directives, declare the constructor parameter as:
   * - `directive:DirectiveType`: a directive on the current element only
   * - `@Host() directive:DirectiveType`: any directive that matches the type between the current
   * element and the
   *    Shadow DOM root.
   * - `@Query(DirectiveType) query:QueryList<DirectiveType>`: A live collection of direct child
   * directives.
   * - `@QueryDescendants(DirectiveType) query:QueryList<DirectiveType>`: A live collection of any
   * child directives.
   * 
   * To inject element-specific special objects, declare the constructor parameter as:
   * - `element: ElementRef` to obtain a reference to logical element in the view.
   * - `viewContainer: ViewContainerRef` to control child template instantiation, for
   * {@link DirectiveMetadata} directives only
   * - `bindingPropagation: BindingPropagation` to control change detection in a more granular way.
   * 
   * ### Example
   * 
   * The following example demonstrates how dependency injection resolves constructor arguments in
   * practice.
   * 
   * 
   * Assume this HTML template:
   * 
   * ```
   * <div dependency="1">
   *   <div dependency="2">
   *     <div dependency="3" my-directive>
   *       <div dependency="4">
   *         <div dependency="5"></div>
   *       </div>
   *       <div dependency="6"></div>
   *     </div>
   *   </div>
   * </div>
   * ```
   * 
   * With the following `dependency` decorator and `SomeService` injectable class.
   * 
   * ```
   * @Injectable()
   * class SomeService {
   * }
   * 
   * @Directive({
   *   selector: '[dependency]',
   *   inputs: [
   *     'id: dependency'
   *   ]
   * })
   * class Dependency {
   *   id:string;
   * }
   * ```
   * 
   * Let's step through the different ways in which `MyDirective` could be declared...
   * 
   * 
   * ### No injection
   * 
   * Here the constructor is declared with no arguments, therefore nothing is injected into
   * `MyDirective`.
   * 
   * ```
   * @Directive({ selector: '[my-directive]' })
   * class MyDirective {
   *   constructor() {
   *   }
   * }
   * ```
   * 
   * This directive would be instantiated with no dependencies.
   * 
   * 
   * ### Component-level injection
   * 
   * Directives can inject any injectable instance from the closest component injector or any of its
   * parents.
   * 
   * Here, the constructor declares a parameter, `someService`, and injects the `SomeService` type
   * from the parent
   * component's injector.
   * ```
   * @Directive({ selector: '[my-directive]' })
   * class MyDirective {
   *   constructor(someService: SomeService) {
   *   }
   * }
   * ```
   * 
   * This directive would be instantiated with a dependency on `SomeService`.
   * 
   * 
   * ### Injecting a directive from the current element
   * 
   * Directives can inject other directives declared on the current element.
   * 
   * ```
   * @Directive({ selector: '[my-directive]' })
   * class MyDirective {
   *   constructor(dependency: Dependency) {
   *     expect(dependency.id).toEqual(3);
   *   }
   * }
   * ```
   * This directive would be instantiated with `Dependency` declared at the same element, in this case
   * `dependency="3"`.
   * 
   * ### Injecting a directive from any ancestor elements
   * 
   * Directives can inject other directives declared on any ancestor element (in the current Shadow
   * DOM), i.e. on the current element, the
   * parent element, or its parents.
   * ```
   * @Directive({ selector: '[my-directive]' })
   * class MyDirective {
   *   constructor(@Host() dependency: Dependency) {
   *     expect(dependency.id).toEqual(2);
   *   }
   * }
   * ```
   * 
   * `@Host` checks the current element, the parent, as well as its parents recursively. If
   * `dependency="2"` didn't
   * exist on the direct parent, this injection would
   * have returned
   * `dependency="1"`.
   * 
   * 
   * ### Injecting a live collection of direct child directives
   * 
   * 
   * A directive can also query for other child directives. Since parent directives are instantiated
   * before child directives, a directive can't simply inject the list of child directives. Instead,
   * the directive injects a {@link QueryList}, which updates its contents as children are added,
   * removed, or moved by a directive that uses a {@link ViewContainerRef} such as a `ng-for`, an
   * `ng-if`, or an `ng-switch`.
   * 
   * ```
   * @Directive({ selector: '[my-directive]' })
   * class MyDirective {
   *   constructor(@Query(Dependency) dependencies:QueryList<Dependency>) {
   *   }
   * }
   * ```
   * 
   * This directive would be instantiated with a {@link QueryList} which contains `Dependency` 4 and
   * 6. Here, `Dependency` 5 would not be included, because it is not a direct child.
   * 
   * ### Injecting a live collection of descendant directives
   * 
   * By passing the descendant flag to `@Query` above, we can include the children of the child
   * elements.
   * 
   * ```
   * @Directive({ selector: '[my-directive]' })
   * class MyDirective {
   *   constructor(@Query(Dependency, {descendants: true}) dependencies:QueryList<Dependency>) {
   *   }
   * }
   * ```
   * 
   * This directive would be instantiated with a Query which would contain `Dependency` 4, 5 and 6.
   * 
   * ### Optional injection
   * 
   * The normal behavior of directives is to return an error when a specified dependency cannot be
   * resolved. If you
   * would like to inject `null` on unresolved dependency instead, you can annotate that dependency
   * with `@Optional()`.
   * This explicitly permits the author of a template to treat some of the surrounding directives as
   * optional.
   * 
   * ```
   * @Directive({ selector: '[my-directive]' })
   * class MyDirective {
   *   constructor(@Optional() dependency:Dependency) {
   *   }
   * }
   * ```
   * 
   * This directive would be instantiated with a `Dependency` directive found on the current element.
   * If none can be
   * found, the injector supplies `null` instead of throwing an error.
   * 
   * ### Example
   * 
   * Here we use a decorator directive to simply define basic tool-tip behavior.
   * 
   * ```
   * @Directive({
   *   selector: '[tooltip]',
   *   inputs: [
   *     'text: tooltip'
   *   ],
   *   host: {
   *     '(mouseenter)': 'onMouseEnter()',
   *     '(mouseleave)': 'onMouseLeave()'
   *   }
   * })
   * class Tooltip{
   *   text:string;
   *   overlay:Overlay; // NOT YET IMPLEMENTED
   *   overlayManager:OverlayManager; // NOT YET IMPLEMENTED
   * 
   *   constructor(overlayManager:OverlayManager) {
   *     this.overlay = overlay;
   *   }
   * 
   *   onMouseEnter() {
   *     // exact signature to be determined
   *     this.overlay = this.overlayManager.open(text, ...);
   *   }
   * 
   *   onMouseLeave() {
   *     this.overlay.close();
   *     this.overlay = null;
   *   }
   * }
   * ```
   * In our HTML template, we can then add this behavior to a `<div>` or any other element with the
   * `tooltip` selector,
   * like so:
   * 
   * ```
   * <div tooltip="some text here"></div>
   * ```
   * 
   * Directives can also control the instantiation, destruction, and positioning of inline template
   * elements:
   * 
   * A directive uses a {@link ViewContainerRef} to instantiate, insert, move, and destroy views at
   * runtime.
   * The {@link ViewContainerRef} is created as a result of `<template>` element, and represents a
   * location in the current view
   * where these actions are performed.
   * 
   * Views are always created as children of the current {@link ViewMetadata}, and as siblings of the
   * `<template>` element. Thus a
   * directive in a child view cannot inject the directive that created it.
   * 
   * Since directives that create views via ViewContainers are common in Angular, and using the full
   * `<template>` element syntax is wordy, Angular
   * also supports a shorthand notation: `<li *foo="bar">` and `<li template="foo: bar">` are
   * equivalent.
   * 
   * Thus,
   * 
   * ```
   * <ul>
   *   <li *foo="bar" title="text"></li>
   * </ul>
   * ```
   * 
   * Expands in use to:
   * 
   * ```
   * <ul>
   *   <template [foo]="bar">
   *     <li title="text"></li>
   *   </template>
   * </ul>
   * ```
   * 
   * Notice that although the shorthand places `*foo="bar"` within the `<li>` element, the binding for
   * the directive
   * controller is correctly instantiated on the `<template>` element rather than the `<li>` element.
   * 
   * ## Lifecycle hooks
   * 
   * When the directive class implements some {@link angular2/lifecycle_hooks} the callbacks are
   * called by the change detection at defined points in time during the life of the directive.
   * 
   * ### Example
   * 
   * Let's suppose we want to implement the `unless` behavior, to conditionally include a template.
   * 
   * Here is a simple directive that triggers on an `unless` selector:
   * 
   * ```
   * @Directive({
   *   selector: '[unless]',
   *   inputs: ['unless']
   * })
   * export class Unless {
   *   viewContainer: ViewContainerRef;
   *   templateRef: TemplateRef;
   *   prevCondition: boolean;
   * 
   *   constructor(viewContainer: ViewContainerRef, templateRef: TemplateRef) {
   *     this.viewContainer = viewContainer;
   *     this.templateRef = templateRef;
   *     this.prevCondition = null;
   *   }
   * 
   *   set unless(newCondition) {
   *     if (newCondition && (isBlank(this.prevCondition) || !this.prevCondition)) {
   *       this.prevCondition = true;
   *       this.viewContainer.clear();
   *     } else if (!newCondition && (isBlank(this.prevCondition) || this.prevCondition)) {
   *       this.prevCondition = false;
   *       this.viewContainer.create(this.templateRef);
   *     }
   *   }
   * }
   * ```
   * 
   * We can then use this `unless` selector in a template:
   * ```
   * <ul>
   *   <li *unless="expr"></li>
   * </ul>
   * ```
   * 
   * Once the directive instantiates the child view, the shorthand notation for the template expands
   * and the result is:
   * 
   * ```
   * <ul>
   *   <template [unless]="exp">
   *     <li></li>
   *   </template>
   *   <li></li>
   * </ul>
   * ```
   * 
   * Note also that although the `<li></li>` template still exists inside the `<template></template>`,
   * the instantiated
   * view occurs on the second `<li></li>` which is a sibling to the `<template>` element.
   */
  class DirectiveMetadata extends InjectableMetadata {
    
    constructor({selector, inputs, outputs, properties, events, host, bindings, providers, exportAs,
                   moduleId, queries}?: {
        selector?: string,
        inputs?: string[],
        outputs?: string[],
        properties?: string[],
        events?: string[],
        host?: {[key: string]: string},
        providers?: any[],
        /** @deprecated */ bindings?: any[],
        exportAs?: string,
        moduleId?: string,
        queries?: {[key: string]: any}
      });
    
    /**
     * The CSS selector that triggers the instantiation of a directive.
     * 
     * Angular only allows directives to trigger on CSS selectors that do not cross element
     * boundaries.
     * 
     * `selector` may be declared as one of the following:
     * 
     * - `element-name`: select by element name.
     * - `.class`: select by class name.
     * - `[attribute]`: select by attribute name.
     * - `[attribute=value]`: select by attribute name and value.
     * - `:not(sub_selector)`: select only if the element does not match the `sub_selector`.
     * - `selector1, selector2`: select if either `selector1` or `selector2` matches.
     * 
     * 
     * ### Example
     * 
     * Suppose we have a directive with an `input[type=text]` selector.
     * 
     * And the following HTML:
     * 
     * ```html
     * <form>
     *   <input type="text">
     *   <input type="radio">
     * <form>
     * ```
     * 
     * The directive would only be instantiated on the `<input type="text">` element.
     */
    selector: string;
    
    /**
     * Enumerates the set of data-bound input properties for a directive
     * 
     * Angular automatically updates input properties during change detection.
     * 
     * The `inputs` property defines a set of `directiveProperty` to `bindingProperty`
     * configuration:
     * 
     * - `directiveProperty` specifies the component property where the value is written.
     * - `bindingProperty` specifies the DOM property where the value is read from.
     * 
     * When `bindingProperty` is not provided, it is assumed to be equal to `directiveProperty`.
     * 
     * ### Example ([live demo](http://plnkr.co/edit/ivhfXY?p=preview))
     * 
     * The following example creates a component with two data-bound properties.
     * 
     * ```typescript
     * @Component({
     *   selector: 'bank-account',
     *   inputs: ['bankName', 'id: account-id'],
     *   template: `
     *     Bank Name: {{bankName}}
     *     Account Id: {{id}}
     *   `
     * })
     * class BankAccount {
     *   bankName: string;
     *   id: string;
     * 
     *   // this property is not bound, and won't be automatically updated by Angular
     *   normalizedBankName: string;
     * }
     * 
     * @Component({
     *   selector: 'app',
     *   template: `
     *     <bank-account bank-name="RBC" account-id="4747"></bank-account>
     *   `,
     *   directives: [BankAccount]
     * })
     * class App {}
     * 
     * bootstrap(App);
     * ```
     */
    inputs: string[];
    
    properties: string[];
    
    /**
     * Enumerates the set of event-bound output properties.
     * 
     * When an output property emits an event, an event handler attached to that event
     * the template is invoked.
     * 
     * The `outputs` property defines a set of `directiveProperty` to `bindingProperty`
     * configuration:
     * 
     * - `directiveProperty` specifies the component property that emits events.
     * - `bindingProperty` specifies the DOM property the event handler is attached to.
     * 
     * ### Example ([live demo](http://plnkr.co/edit/d5CNq7?p=preview))
     * 
     * ```typescript
     * @Directive({
     *   selector: 'interval-dir',
     *   outputs: ['everySecond', 'five5Secs: everyFiveSeconds']
     * })
     * class IntervalDir {
     *   everySecond = new EventEmitter();
     *   five5Secs = new EventEmitter();
     * 
     *   constructor() {
     *     setInterval(() => this.everySecond.next("event"), 1000);
     *     setInterval(() => this.five5Secs.next("event"), 5000);
     *   }
     * }
     * 
     * @Component({
     *   selector: 'app',
     *   template: `
     *     <interval-dir (every-second)="everySecond()" (every-five-seconds)="everyFiveSeconds()">
     *     </interval-dir>
     *   `,
     *   directives: [IntervalDir]
     * })
     * class App {
     *   everySecond() { console.log('second'); }
     *   everyFiveSeconds() { console.log('five seconds'); }
     * }
     * bootstrap(App);
     * ```
     */
    outputs: string[];
    
    events: string[];
    
    /**
     * Specify the events, actions, properties and attributes related to the host element.
     * 
     * ## Host Listeners
     * 
     * Specifies which DOM events a directive listens to via a set of `(event)` to `method`
     * key-value pairs:
     * 
     * - `event1`: the DOM event that the directive listens to.
     * - `statement`: the statement to execute when the event occurs.
     * If the evaluation of the statement returns `false`, then `preventDefault`is applied on the DOM
     * event.
     * 
     * To listen to global events, a target must be added to the event name.
     * The target can be `window`, `document` or `body`.
     * 
     * When writing a directive event binding, you can also refer to the $event local variable.
     * 
     * ### Example ([live demo](http://plnkr.co/edit/DlA5KU?p=preview))
     * 
     * The following example declares a directive that attaches a click listener to the button and
     * counts clicks.
     * 
     * ```typescript
     * @Directive({
     *   selector: 'button[counting]',
     *   host: {
     *     '(click)': 'onClick($event.target)'
     *   }
     * })
     * class CountClicks {
     *   numberOfClicks = 0;
     * 
     *   onClick(btn) {
     *     console.log("button", btn, "number of clicks:", this.numberOfClicks++);
     *   }
     * }
     * 
     * @Component({
     *   selector: 'app',
     *   template: `<button counting>Increment</button>`,
     *   directives: [CountClicks]
     * })
     * class App {}
     * 
     * bootstrap(App);
     * ```
     * 
     * ## Host Property Bindings
     * 
     * Specifies which DOM properties a directive updates.
     * 
     * Angular automatically checks host property bindings during change detection.
     * If a binding changes, it will update the host element of the directive.
     * 
     * ### Example ([live demo](http://plnkr.co/edit/gNg0ED?p=preview))
     * 
     * The following example creates a directive that sets the `valid` and `invalid` classes
     * on the DOM element that has ng-model directive on it.
     * 
     * ```typescript
     * @Directive({
     *   selector: '[ng-model]',
     *   host: {
     *     '[class.valid]': 'valid',
     *     '[class.invalid]': 'invalid'
     *   }
     * })
     * class NgModelStatus {
     *   constructor(public control:NgModel) {}
     *   get valid { return this.control.valid; }
     *   get invalid { return this.control.invalid; }
     * }
     * 
     * @Component({
     *   selector: 'app',
     *   template: `<input [(ng-model)]="prop">`,
     *   directives: [FORM_DIRECTIVES, NgModelStatus]
     * })
     * class App {
     *   prop;
     * }
     * 
     * bootstrap(App);
     * ```
     * 
     * ## Attributes
     * 
     * Specifies static attributes that should be propagated to a host element.
     * 
     * ### Example
     * 
     * In this example using `my-button` directive (ex.: `<div my-button></div>`) on a host element
     * (here: `<div>` ) will ensure that this element will get the "button" role.
     * 
     * ```typescript
     * @Directive({
     *   selector: '[my-button]',
     *   host: {
     *     'role': 'button'
     *   }
     * })
     * class MyButton {
     * }
     * ```
     */
    host: {[key: string]: string};
    
    /**
     * Defines the set of injectable objects that are visible to a Directive and its light DOM
     * children.
     * 
     * ## Simple Example
     * 
     * Here is an example of a class that can be injected:
     * 
     * ```
     * class Greeter {
     *    greet(name:string) {
     *      return 'Hello ' + name + '!';
     *    }
     * }
     * 
     * @Directive({
     *   selector: 'greet',
     *   bindings: [
     *     Greeter
     *   ]
     * })
     * class HelloWorld {
     *   greeter:Greeter;
     * 
     *   constructor(greeter:Greeter) {
     *     this.greeter = greeter;
     *   }
     * }
     * ```
     */
    providers: any[];
    
    /**
     * @deprecated
     */
    bindings: any[];
    
    /**
     * Defines the name that can be used in the template to assign this directive to a variable.
     * 
     * ## Simple Example
     * 
     * ```
     * @Directive({
     *   selector: 'child-dir',
     *   exportAs: 'child'
     * })
     * class ChildDir {
     * }
     * 
     * @Component({
     *   selector: 'main',
     *   template: `<child-dir #c="child"></child-dir>`,
     *   directives: [ChildDir]
     * })
     * class MainComponent {
     * }
     * 
     * ```
     */
    exportAs: string;
    
    /**
     * The module id of the module that contains the directive.
     * Needed to be able to resolve relative urls for templates and styles.
     * In Dart, this can be determined automatically and does not need to be set.
     * In CommonJS, this can always be set to `module.id`.
     * 
     * ## Simple Example
     * 
     * ```
     * @Directive({
     *   selector: 'someDir',
     *   moduleId: module.id
     * })
     * class SomeDir {
     * }
     * 
     * ```
     */
    moduleId: string;
    
    /**
     * Configures the queries that will be injected into the directive.
     * 
     * Content queries are set before the `afterContentInit` callback is called.
     * View queries are set before the `afterViewInit` callback is called.
     * 
     * ### Example
     * 
     * ```
     * @Component({
     *   selector: 'someDir',
     *   queries: {
     *     contentChildren: new ContentChildren(ChildDirective),
     *     viewChildren: new ViewChildren(ChildDirective)
     *   },
     *   template: '<child-directive></child-directive>',
     *   directives: [ChildDirective]
     * })
     * class SomeDir {
     *   contentChildren: QueryList<ChildDirective>,
     *   viewChildren: QueryList<ChildDirective>
     * 
     *   afterContentInit() {
     *     // contentChildren is set
     *   }
     * 
     *   afterViewInit() {
     *     // viewChildren is set
     *   }
     * }
     * ```
     */
    queries: {[key: string]: any};
    
  }

    
  /**
   * Declare reusable pipe function.
   * 
   * ### Example
   * 
   * ```
   * @Pipe({
   *   name: 'lowercase'
   * })
   * class Lowercase {
   *   transform(v, args) { return v.toLowerCase(); }
   * }
   * ```
   */
  class PipeMetadata extends InjectableMetadata {
    
    constructor({name, pure}: {name: string, pure: boolean});
    
    name: string;
    
    pure: boolean;
    
  }

    
  /**
   * Declares a data-bound input property.
   * 
   * Angular automatically updates data-bound properties during change detection.
   * 
   * `InputMetadata` takes an optional parameter that specifies the name
   * used when instantiating a component in the template. When not provided,
   * the name of the decorated property is used.
   * 
   * ### Example
   * 
   * The following example creates a component with two input properties.
   * 
   * ```typescript
   * @Component({
   *   selector: 'bank-account',
   *   template: `
   *     Bank Name: {{bankName}}
   *     Account Id: {{id}}
   *   `
   * })
   * class BankAccount {
   *   @Input() bankName: string;
   *   @Input('account-id') id: string;
   * 
   *   // this property is not bound, and won't be automatically updated by Angular
   *   normalizedBankName: string;
   * }
   * 
   * @Component({
   *   selector: 'app',
   *   template: `
   *     <bank-account bank-name="RBC" account-id="4747"></bank-account>
   *   `,
   *   directives: [BankAccount]
   * })
   * class App {}
   * 
   * bootstrap(App);
   * ```
   */
  class InputMetadata {
    
    constructor(bindingPropertyName?: string);
    
    /**
     * Name used when instantiating a component in the temlate.
     */
    bindingPropertyName: string;
    
  }

    
  /**
   * Declares an event-bound output property.
   * 
   * When an output property emits an event, an event handler attached to that event
   * the template is invoked.
   * 
   * `OutputMetadata` takes an optional parameter that specifies the name
   * used when instantiating a component in the template. When not provided,
   * the name of the decorated property is used.
   * 
   * ### Example
   * 
   * ```typescript
   * @Directive({
   *   selector: 'interval-dir',
   * })
   * class IntervalDir {
   *   @Output() everySecond = new EventEmitter();
   *   @Output('everyFiveSeconds') five5Secs = new EventEmitter();
   * 
   *   constructor() {
   *     setInterval(() => this.everySecond.next("event"), 1000);
   *     setInterval(() => this.five5Secs.next("event"), 5000);
   *   }
   * }
   * 
   * @Component({
   *   selector: 'app',
   *   template: `
   *     <interval-dir (every-second)="everySecond()" (every-five-seconds)="everyFiveSeconds()">
   *     </interval-dir>
   *   `,
   *   directives: [IntervalDir]
   * })
   * class App {
   *   everySecond() { console.log('second'); }
   *   everyFiveSeconds() { console.log('five seconds'); }
   * }
   * bootstrap(App);
   * ```
   */
  class OutputMetadata {
    
    constructor(bindingPropertyName?: string);
    
    bindingPropertyName: string;
    
  }

    
  /**
   * Declares a host property binding.
   * 
   * Angular automatically checks host property bindings during change detection.
   * If a binding changes, it will update the host element of the directive.
   * 
   * `HostBindingMetadata` takes an optional parameter that specifies the property
   * name of the host element that will be updated. When not provided,
   * the class property name is used.
   * 
   * ### Example
   * 
   * The following example creates a directive that sets the `valid` and `invalid` classes
   * on the DOM element that has ng-model directive on it.
   * 
   * ```typescript
   * @Directive({selector: '[ng-model]'})
   * class NgModelStatus {
   *   constructor(public control:NgModel) {}
   *   @HostBinding('[class.valid]') get valid { return this.control.valid; }
   *   @HostBinding('[class.invalid]') get invalid { return this.control.invalid; }
   * }
   * 
   * @Component({
   *   selector: 'app',
   *   template: `<input [(ng-model)]="prop">`,
   *   directives: [FORM_DIRECTIVES, NgModelStatus]
   * })
   * class App {
   *   prop;
   * }
   * 
   * bootstrap(App);
   * ```
   */
  class HostBindingMetadata {
    
    constructor(hostPropertyName?: string);
    
    hostPropertyName: string;
    
  }

    
  /**
   * Declares a host listener.
   * 
   * Angular will invoke the decorated method when the host element emits the specified event.
   * 
   * If the decorated method returns `false`, then `preventDefault` is applied on the DOM
   * event.
   * 
   * ### Example
   * 
   * The following example declares a directive that attaches a click listener to the button and
   * counts clicks.
   * 
   * ```typescript
   * @Directive({selector: 'button[counting]'})
   * class CountClicks {
   *   numberOfClicks = 0;
   * 
   *   @HostListener('click', ['$event.target'])
   *   onClick(btn) {
   *     console.log("button", btn, "number of clicks:", this.numberOfClicks++);
   *   }
   * }
   * 
   * @Component({
   *   selector: 'app',
   *   template: `<button counting>Increment</button>`,
   *   directives: [CountClicks]
   * })
   * class App {}
   * 
   * bootstrap(App);
   * ```
   */
  class HostListenerMetadata {
    
    constructor(eventName: string, args?: string[]);
    
    eventName: string;
    
    args: string[];
    
  }

    
  /**
   * Metadata properties available for configuring Views.
   * 
   * Each Angular component requires a single `@Component` and at least one `@View` annotation. The
   * `@View` annotation specifies the HTML template to use, and lists the directives that are active
   * within the template.
   * 
   * When a component is instantiated, the template is loaded into the component's shadow root, and
   * the expressions and statements in the template are evaluated against the component.
   * 
   * For details on the `@Component` annotation, see {@link ComponentMetadata}.
   * 
   * ### Example
   * 
   * ```
   * @Component({
   *   selector: 'greet',
   *   template: 'Hello {{name}}!',
   *   directives: [GreetUser, Bold]
   * })
   * class Greet {
   *   name: string;
   * 
   *   constructor() {
   *     this.name = 'World';
   *   }
   * }
   * ```
   */
  class ViewMetadata {
    
    constructor({templateUrl, template, directives, pipes, encapsulation, styles, styleUrls}?: {
        templateUrl?: string,
        template?: string,
        directives?: Array<Type | any[]>,
        pipes?: Array<Type | any[]>,
        encapsulation?: ViewEncapsulation,
        styles?: string[],
        styleUrls?: string[],
      });
    
    /**
     * Specifies a template URL for an Angular component.
     * 
     * NOTE: Only one of `templateUrl` or `template` can be defined per View.
     * 
     * <!-- TODO: what's the url relative to? -->
     */
    templateUrl: string;
    
    /**
     * Specifies an inline template for an Angular component.
     * 
     * NOTE: Only one of `templateUrl` or `template` can be defined per View.
     */
    template: string;
    
    /**
     * Specifies stylesheet URLs for an Angular component.
     * 
     * <!-- TODO: what's the url relative to? -->
     */
    styleUrls: string[];
    
    /**
     * Specifies an inline stylesheet for an Angular component.
     */
    styles: string[];
    
    /**
     * Specifies a list of directives that can be used within a template.
     * 
     * Directives must be listed explicitly to provide proper component encapsulation.
     * 
     * ### Example
     * 
     * ```javascript
     * @Component({
     *   selector: 'my-component',
     *   directives: [NgFor]
     *   template: '
     *   <ul>
     *     <li *ng-for="#item of items">{{item}}</li>
     *   </ul>'
     * })
     * class MyComponent {
     * }
     * ```
     */
    directives: Array<Type | any[]>;
    
    pipes: Array<Type | any[]>;
    
    /**
     * Specify how the template and the styles should be encapsulated.
     * The default is {@link ViewEncapsulation#Emulated `ViewEncapsulation.Emulated`} if the view
     * has styles,
     * otherwise {@link ViewEncapsulation#None `ViewEncapsulation.None`}.
     */
    encapsulation: ViewEncapsulation;
    
  }

    
  /**
   * Defines template and style encapsulation options available for Component's {@link View}.
   * 
   * See {@link ViewMetadata#encapsulation}.
   */
  enum ViewEncapsulation {
    
    /**
     * Emulate `Native` scoping of styles by adding an attribute containing surrogate id to the Host
     * Element and pre-processing the style rules provided via
     * {@link ViewMetadata#styles} or {@link ViewMetadata#stylesUrls}, and adding the new Host Element
     * attribute to all selectors.
     * 
     * This is the default option.
     */
    Emulated,
    
    /**
     * Use the native encapsulation mechanism of the renderer.
     * 
     * For the DOM this means using [Shadow DOM](https://w3c.github.io/webcomponents/spec/shadow/) and
     * creating a ShadowRoot for Component's Host Element.
     */
    Native,
    
    /**
     * Don't provide any template or style encapsulation.
     */
    None
  }
  

    
  /**
   * Interface for the {@link DirectiveMetadata} decorator function.
   * 
   * See {@link DirectiveFactory}.
   */
  interface DirectiveDecorator extends TypeDecorator {
    
  }

    
  /**
   * Interface for the {@link ComponentMetadata} decorator function.
   * 
   * See {@link ComponentFactory}.
   */
  interface ComponentDecorator extends TypeDecorator {
    
    /**
     * Chain {@link ViewMetadata} annotation.
     */
    View(obj: {
        templateUrl?: string,
        template?: string,
        directives?: Array<Type | any[]>,
        pipes?: Array<Type | any[]>,
        renderer?: string,
        styles?: string[],
        styleUrls?: string[],
      }): ViewDecorator;
    
  }

    
  /**
   * Interface for the {@link ViewMetadata} decorator function.
   * 
   * See {@link ViewFactory}.
   */
  interface ViewDecorator extends TypeDecorator {
    
    /**
     * Chain {@link ViewMetadata} annotation.
     */
    View(obj: {
        templateUrl?: string,
        template?: string,
        directives?: Array<Type | any[]>,
        pipes?: Array<Type | any[]>,
        renderer?: string,
        styles?: string[],
        styleUrls?: string[],
      }): ViewDecorator;
    
  }

    
  /**
   * {@link DirectiveMetadata} factory for creating annotations, decorators or DSL.
   * 
   * ### Example as TypeScript Decorator
   * 
   * ```
   * import {Directive} from "angular2/angular2";
   * 
   * @Directive({...})
   * class MyDirective {
   *   constructor() {
   *     ...
   *   }
   * }
   * ```
   * 
   * ### Example as ES5 DSL
   * 
   * ```
   * var MyDirective = ng
   *   .Directive({...})
   *   .Class({
   *     constructor: function() {
   *       ...
   *     }
   *   })
   * ```
   * 
   * ### Example as ES5 annotation
   * 
   * ```
   * var MyDirective = function() {
   *   ...
   * };
   * 
   * MyDirective.annotations = [
   *   new ng.Directive({...})
   * ]
   * ```
   */
  interface DirectiveFactory {
    
    new(obj: {
        selector?: string,
        inputs?: string[],
        outputs?: string[],
        properties?: string[],
        events?: string[],
        host?: {[key: string]: string},
        bindings?: any[],
        providers?: any[],
        exportAs?: string,
        moduleId?: string,
        queries?: {[key: string]: any}
      }): DirectiveMetadata;
    
    (obj: {
        selector?: string,
        inputs?: string[],
        outputs?: string[],
        properties?: string[],
        events?: string[],
        host?: {[key: string]: string},
        bindings?: any[],
        providers?: any[],
        exportAs?: string,
        moduleId?: string,
        queries?: {[key: string]: any}
      }): DirectiveDecorator;
    
  }

    
  /**
   * {@link ComponentMetadata} factory for creating annotations, decorators or DSL.
   * 
   * ### Example as TypeScript Decorator
   * 
   * ```
   * import {Component} from "angular2/angular2";
   * 
   * @Component({...})
   * class MyComponent {
   *   constructor() {
   *     ...
   *   }
   * }
   * ```
   * 
   * ### Example as ES5 DSL
   * 
   * ```
   * var MyComponent = ng
   *   .Component({...})
   *   .Class({
   *     constructor: function() {
   *       ...
   *     }
   *   })
   * ```
   * 
   * ### Example as ES5 annotation
   * 
   * ```
   * var MyComponent = function() {
   *   ...
   * };
   * 
   * MyComponent.annotations = [
   *   new ng.Component({...})
   * ]
   * ```
   */
  interface ComponentFactory {
    
    new(obj: {
        selector?: string,
        inputs?: string[],
        outputs?: string[],
        properties?: string[],
        events?: string[],
        host?: {[key: string]: string},
        /* @deprecated */
        bindings?: any[],
        providers?: any[],
        exportAs?: string,
        moduleId?: string,
        queries?: {[key: string]: any},
        /* @deprecated */
        viewBindings?: any[],
        viewProviders?: any[],
        changeDetection?: ChangeDetectionStrategy,
        templateUrl?: string,
        template?: string,
        styleUrls?: string[],
        styles?: string[],
        directives?: Array<Type | any[]>,
        pipes?: Array<Type | any[]>,
        encapsulation?: ViewEncapsulation
      }): ComponentMetadata;
    
    (obj: {
        selector?: string,
        inputs?: string[],
        outputs?: string[],
        properties?: string[],
        events?: string[],
        host?: {[key: string]: string},
        /* @deprecated */
        bindings?: any[],
        providers?: any[],
        exportAs?: string,
        moduleId?: string,
        queries?: {[key: string]: any},
        viewBindings?: any[],
        viewProviders?: any[],
        changeDetection?: ChangeDetectionStrategy,
        templateUrl?: string,
        template?: string,
        styleUrls?: string[],
        styles?: string[],
        directives?: Array<Type | any[]>,
        pipes?: Array<Type | any[]>,
        encapsulation?: ViewEncapsulation
      }): ComponentDecorator;
    
  }

    
  /**
   * {@link ViewMetadata} factory for creating annotations, decorators or DSL.
   * 
   * ### Example as TypeScript Decorator
   * 
   * ```
   * import {Component, View} from "angular2/angular2";
   * 
   * @Component({...})
   * @View({...})
   * class MyComponent {
   *   constructor() {
   *     ...
   *   }
   * }
   * ```
   * 
   * ### Example as ES5 DSL
   * 
   * ```
   * var MyComponent = ng
   *   .Component({...})
   *   .View({...})
   *   .Class({
   *     constructor: function() {
   *       ...
   *     }
   *   })
   * ```
   * 
   * ### Example as ES5 annotation
   * 
   * ```
   * var MyComponent = function() {
   *   ...
   * };
   * 
   * MyComponent.annotations = [
   *   new ng.Component({...}),
   *   new ng.View({...})
   * ]
   * ```
   */
  interface ViewFactory {
    
    new(obj: {
        templateUrl?: string,
        template?: string,
        directives?: Array<Type | any[]>,
        pipes?: Array<Type | any[]>,
        encapsulation?: ViewEncapsulation,
        styles?: string[],
        styleUrls?: string[],
      }): ViewMetadata;
    
    (obj: {
        templateUrl?: string,
        template?: string,
        directives?: Array<Type | any[]>,
        pipes?: Array<Type | any[]>,
        encapsulation?: ViewEncapsulation,
        styles?: string[],
        styleUrls?: string[],
      }): ViewDecorator;
    
  }

    
  /**
   * {@link AttributeMetadata} factory for creating annotations, decorators or DSL.
   * 
   * ### Example as TypeScript Decorator
   * 
   * ```
   * import {Attribute, Component} from "angular2/angular2";
   * 
   * @Component({...})
   * class MyComponent {
   *   constructor(@Attribute('title') title: string) {
   *     ...
   *   }
   * }
   * ```
   * 
   * ### Example as ES5 DSL
   * 
   * ```
   * var MyComponent = ng
   *   .Component({...})
   *   .Class({
   *     constructor: [new ng.Attribute('title'), function(title) {
   *       ...
   *     }]
   *   })
   * ```
   * 
   * ### Example as ES5 annotation
   * 
   * ```
   * var MyComponent = function(title) {
   *   ...
   * };
   * 
   * MyComponent.annotations = [
   *   new ng.Component({...})
   * ]
   * MyComponent.parameters = [
   *   [new ng.Attribute('title')]
   * ]
   * ```
   */
  interface AttributeFactory {
    
    new(name: string): AttributeMetadata;
    
    (name: string): TypeDecorator;
    
  }

    
  /**
   * {@link QueryMetadata} factory for creating annotations, decorators or DSL.
   * 
   * ### Example as TypeScript Decorator
   * 
   * ```
   * import {Query, QueryList, Component} from "angular2/angular2";
   * 
   * @Component({...})
   * class MyComponent {
   *   constructor(@Query(SomeType) queryList: QueryList<SomeType>) {
   *     ...
   *   }
   * }
   * ```
   * 
   * ### Example as ES5 DSL
   * 
   * ```
   * var MyComponent = ng
   *   .Component({...})
   *   .Class({
   *     constructor: [new ng.Query(SomeType), function(queryList) {
   *       ...
   *     }]
   *   })
   * ```
   * 
   * ### Example as ES5 annotation
   * 
   * ```
   * var MyComponent = function(queryList) {
   *   ...
   * };
   * 
   * MyComponent.annotations = [
   *   new ng.Component({...})
   * ]
   * MyComponent.parameters = [
   *   [new ng.Query(SomeType)]
   * ]
   * ```
   */
  interface QueryFactory {
    
    new(selector: Type | string, {descendants}?: {descendants?: boolean}): QueryMetadata;
    
    (selector: Type | string, {descendants}?: {descendants?: boolean}): ParameterDecorator;
    
  }

    
  interface ContentChildrenFactory {
    
    new(selector: Type | string, {descendants}?: {descendants?: boolean}): ContentChildrenMetadata;
    
    (selector: Type | string, {descendants}?: {descendants?: boolean}): any;
    
  }

    
  interface ContentChildFactory {
    
    new(selector: Type | string): ContentChildFactory;
    
    (selector: Type | string): any;
    
  }

    
  interface ViewChildrenFactory {
    
    new(selector: Type | string): ViewChildrenMetadata;
    
    (selector: Type | string): any;
    
  }

    
  interface ViewChildFactory {
    
    new(selector: Type | string): ViewChildFactory;
    
    (selector: Type | string): any;
    
  }

    
  /**
   * {@link PipeMetadata} factory for creating decorators.
   * 
   * ### Example as TypeScript Decorator
   * 
   * ```
   * import {Pipe} from "angular2/angular2";
   * 
   * @Pipe({...})
   * class MyPipe {
   *   constructor() {
   *     ...
   *   }
   * 
   *   transform(v, args) {}
   * }
   * ```
   */
  interface PipeFactory {
    
    new(obj: {name: string, pure?: boolean}): any;
    
    (obj: {name: string, pure?: boolean}): any;
    
  }

    
  /**
   * {@link InputMetadata} factory for creating decorators.
   * 
   * See {@link InputMetadata}.
   */
  interface InputFactory {
    
    new(bindingPropertyName?: string): any;
    
    (bindingPropertyName?: string): any;
    
  }

    
  /**
   * {@link OutputMetadata} factory for creating decorators.
   * 
   * See {@link OutputMetadata}.
   */
  interface OutputFactory {
    
    new(bindingPropertyName?: string): any;
    
    (bindingPropertyName?: string): any;
    
  }

    
  /**
   * {@link HostBindingMetadata} factory function.
   */
  interface HostBindingFactory {
    
    new(hostPropertyName?: string): any;
    
    (hostPropertyName?: string): any;
    
  }

    
  /**
   * {@link HostListenerMetadata} factory function.
   */
  interface HostListenerFactory {
    
    new(eventName: string, args?: string[]): any;
    
    (eventName: string, args?: string[]): any;
    
  }

    
  /**
   * Declare reusable UI building blocks for an application.
   * 
   * Each Angular component requires a single `@Component` and at least one `@View` annotation. The
   * `@Component`
   * annotation specifies when a component is instantiated, and which properties and hostListeners it
   * binds to.
   * 
   * When a component is instantiated, Angular
   * - creates a shadow DOM for the component.
   * - loads the selected template into the shadow DOM.
   * - creates all the injectable objects configured with `providers` and `viewProviders`.
   * 
   * All template expressions and statements are then evaluated against the component instance.
   * 
   * For details on the `@View` annotation, see {@link ViewMetadata}.
   * 
   * ## Lifecycle hooks
   * 
   * When the component class implements some {@link angular2/lifecycle_hooks} the callbacks are
   * called by the change detection at defined points in time during the life of the component.
   * 
   * ### Example
   * 
   * ```
   * @Component({
   *   selector: 'greet',
   *   template: 'Hello {{name}}!'
   * })
   * class Greet {
   *   name: string;
   * 
   *   constructor() {
   *     this.name = 'World';
   *   }
   * }
   * ```
   */
  var Component: ComponentFactory;
  

    
  /**
   * Directives allow you to attach behavior to elements in the DOM.
   * 
   * {@link DirectiveMetadata}s with an embedded view are called {@link ComponentMetadata}s.
   * 
   * A directive consists of a single directive annotation and a controller class. When the
   * directive's `selector` matches
   * elements in the DOM, the following steps occur:
   * 
   * 1. For each directive, the `ElementInjector` attempts to resolve the directive's constructor
   * arguments.
   * 2. Angular instantiates directives for each matched element using `ElementInjector` in a
   * depth-first order,
   *    as declared in the HTML.
   * 
   * ## Understanding How Injection Works
   * 
   * There are three stages of injection resolution.
   * - *Pre-existing Injectors*:
   *   - The terminal {@link Injector} cannot resolve dependencies. It either throws an error or, if
   * the dependency was
   *     specified as `@Optional`, returns `null`.
   *   - The platform injector resolves browser singleton resources, such as: cookies, title,
   * location, and others.
   * - *Component Injectors*: Each component instance has its own {@link Injector}, and they follow
   * the same parent-child hierarchy
   *     as the component instances in the DOM.
   * - *Element Injectors*: Each component instance has a Shadow DOM. Within the Shadow DOM each
   * element has an `ElementInjector`
   *     which follow the same parent-child hierarchy as the DOM elements themselves.
   * 
   * When a template is instantiated, it also must instantiate the corresponding directives in a
   * depth-first order. The
   * current `ElementInjector` resolves the constructor dependencies for each directive.
   * 
   * Angular then resolves dependencies as follows, according to the order in which they appear in the
   * {@link ViewMetadata}:
   * 
   * 1. Dependencies on the current element
   * 2. Dependencies on element injectors and their parents until it encounters a Shadow DOM boundary
   * 3. Dependencies on component injectors and their parents until it encounters the root component
   * 4. Dependencies on pre-existing injectors
   * 
   * 
   * The `ElementInjector` can inject other directives, element-specific special objects, or it can
   * delegate to the parent
   * injector.
   * 
   * To inject other directives, declare the constructor parameter as:
   * - `directive:DirectiveType`: a directive on the current element only
   * - `@Host() directive:DirectiveType`: any directive that matches the type between the current
   * element and the
   *    Shadow DOM root.
   * - `@Query(DirectiveType) query:QueryList<DirectiveType>`: A live collection of direct child
   * directives.
   * - `@QueryDescendants(DirectiveType) query:QueryList<DirectiveType>`: A live collection of any
   * child directives.
   * 
   * To inject element-specific special objects, declare the constructor parameter as:
   * - `element: ElementRef` to obtain a reference to logical element in the view.
   * - `viewContainer: ViewContainerRef` to control child template instantiation, for
   * {@link DirectiveMetadata} directives only
   * - `bindingPropagation: BindingPropagation` to control change detection in a more granular way.
   * 
   * ### Example
   * 
   * The following example demonstrates how dependency injection resolves constructor arguments in
   * practice.
   * 
   * 
   * Assume this HTML template:
   * 
   * ```
   * <div dependency="1">
   *   <div dependency="2">
   *     <div dependency="3" my-directive>
   *       <div dependency="4">
   *         <div dependency="5"></div>
   *       </div>
   *       <div dependency="6"></div>
   *     </div>
   *   </div>
   * </div>
   * ```
   * 
   * With the following `dependency` decorator and `SomeService` injectable class.
   * 
   * ```
   * @Injectable()
   * class SomeService {
   * }
   * 
   * @Directive({
   *   selector: '[dependency]',
   *   inputs: [
   *     'id: dependency'
   *   ]
   * })
   * class Dependency {
   *   id:string;
   * }
   * ```
   * 
   * Let's step through the different ways in which `MyDirective` could be declared...
   * 
   * 
   * ### No injection
   * 
   * Here the constructor is declared with no arguments, therefore nothing is injected into
   * `MyDirective`.
   * 
   * ```
   * @Directive({ selector: '[my-directive]' })
   * class MyDirective {
   *   constructor() {
   *   }
   * }
   * ```
   * 
   * This directive would be instantiated with no dependencies.
   * 
   * 
   * ### Component-level injection
   * 
   * Directives can inject any injectable instance from the closest component injector or any of its
   * parents.
   * 
   * Here, the constructor declares a parameter, `someService`, and injects the `SomeService` type
   * from the parent
   * component's injector.
   * ```
   * @Directive({ selector: '[my-directive]' })
   * class MyDirective {
   *   constructor(someService: SomeService) {
   *   }
   * }
   * ```
   * 
   * This directive would be instantiated with a dependency on `SomeService`.
   * 
   * 
   * ### Injecting a directive from the current element
   * 
   * Directives can inject other directives declared on the current element.
   * 
   * ```
   * @Directive({ selector: '[my-directive]' })
   * class MyDirective {
   *   constructor(dependency: Dependency) {
   *     expect(dependency.id).toEqual(3);
   *   }
   * }
   * ```
   * This directive would be instantiated with `Dependency` declared at the same element, in this case
   * `dependency="3"`.
   * 
   * ### Injecting a directive from any ancestor elements
   * 
   * Directives can inject other directives declared on any ancestor element (in the current Shadow
   * DOM), i.e. on the current element, the
   * parent element, or its parents.
   * ```
   * @Directive({ selector: '[my-directive]' })
   * class MyDirective {
   *   constructor(@Host() dependency: Dependency) {
   *     expect(dependency.id).toEqual(2);
   *   }
   * }
   * ```
   * 
   * `@Host` checks the current element, the parent, as well as its parents recursively. If
   * `dependency="2"` didn't
   * exist on the direct parent, this injection would
   * have returned
   * `dependency="1"`.
   * 
   * 
   * ### Injecting a live collection of direct child directives
   * 
   * 
   * A directive can also query for other child directives. Since parent directives are instantiated
   * before child directives, a directive can't simply inject the list of child directives. Instead,
   * the directive injects a {@link QueryList}, which updates its contents as children are added,
   * removed, or moved by a directive that uses a {@link ViewContainerRef} such as a `ng-for`, an
   * `ng-if`, or an `ng-switch`.
   * 
   * ```
   * @Directive({ selector: '[my-directive]' })
   * class MyDirective {
   *   constructor(@Query(Dependency) dependencies:QueryList<Dependency>) {
   *   }
   * }
   * ```
   * 
   * This directive would be instantiated with a {@link QueryList} which contains `Dependency` 4 and
   * 6. Here, `Dependency` 5 would not be included, because it is not a direct child.
   * 
   * ### Injecting a live collection of descendant directives
   * 
   * By passing the descendant flag to `@Query` above, we can include the children of the child
   * elements.
   * 
   * ```
   * @Directive({ selector: '[my-directive]' })
   * class MyDirective {
   *   constructor(@Query(Dependency, {descendants: true}) dependencies:QueryList<Dependency>) {
   *   }
   * }
   * ```
   * 
   * This directive would be instantiated with a Query which would contain `Dependency` 4, 5 and 6.
   * 
   * ### Optional injection
   * 
   * The normal behavior of directives is to return an error when a specified dependency cannot be
   * resolved. If you
   * would like to inject `null` on unresolved dependency instead, you can annotate that dependency
   * with `@Optional()`.
   * This explicitly permits the author of a template to treat some of the surrounding directives as
   * optional.
   * 
   * ```
   * @Directive({ selector: '[my-directive]' })
   * class MyDirective {
   *   constructor(@Optional() dependency:Dependency) {
   *   }
   * }
   * ```
   * 
   * This directive would be instantiated with a `Dependency` directive found on the current element.
   * If none can be
   * found, the injector supplies `null` instead of throwing an error.
   * 
   * ### Example
   * 
   * Here we use a decorator directive to simply define basic tool-tip behavior.
   * 
   * ```
   * @Directive({
   *   selector: '[tooltip]',
   *   inputs: [
   *     'text: tooltip'
   *   ],
   *   host: {
   *     '(mouseenter)': 'onMouseEnter()',
   *     '(mouseleave)': 'onMouseLeave()'
   *   }
   * })
   * class Tooltip{
   *   text:string;
   *   overlay:Overlay; // NOT YET IMPLEMENTED
   *   overlayManager:OverlayManager; // NOT YET IMPLEMENTED
   * 
   *   constructor(overlayManager:OverlayManager) {
   *     this.overlay = overlay;
   *   }
   * 
   *   onMouseEnter() {
   *     // exact signature to be determined
   *     this.overlay = this.overlayManager.open(text, ...);
   *   }
   * 
   *   onMouseLeave() {
   *     this.overlay.close();
   *     this.overlay = null;
   *   }
   * }
   * ```
   * In our HTML template, we can then add this behavior to a `<div>` or any other element with the
   * `tooltip` selector,
   * like so:
   * 
   * ```
   * <div tooltip="some text here"></div>
   * ```
   * 
   * Directives can also control the instantiation, destruction, and positioning of inline template
   * elements:
   * 
   * A directive uses a {@link ViewContainerRef} to instantiate, insert, move, and destroy views at
   * runtime.
   * The {@link ViewContainerRef} is created as a result of `<template>` element, and represents a
   * location in the current view
   * where these actions are performed.
   * 
   * Views are always created as children of the current {@link ViewMetadata}, and as siblings of the
   * `<template>` element. Thus a
   * directive in a child view cannot inject the directive that created it.
   * 
   * Since directives that create views via ViewContainers are common in Angular, and using the full
   * `<template>` element syntax is wordy, Angular
   * also supports a shorthand notation: `<li *foo="bar">` and `<li template="foo: bar">` are
   * equivalent.
   * 
   * Thus,
   * 
   * ```
   * <ul>
   *   <li *foo="bar" title="text"></li>
   * </ul>
   * ```
   * 
   * Expands in use to:
   * 
   * ```
   * <ul>
   *   <template [foo]="bar">
   *     <li title="text"></li>
   *   </template>
   * </ul>
   * ```
   * 
   * Notice that although the shorthand places `*foo="bar"` within the `<li>` element, the binding for
   * the directive
   * controller is correctly instantiated on the `<template>` element rather than the `<li>` element.
   * 
   * ## Lifecycle hooks
   * 
   * When the directive class implements some {@link angular2/lifecycle_hooks} the callbacks are
   * called by the change detection at defined points in time during the life of the directive.
   * 
   * ### Example
   * 
   * Let's suppose we want to implement the `unless` behavior, to conditionally include a template.
   * 
   * Here is a simple directive that triggers on an `unless` selector:
   * 
   * ```
   * @Directive({
   *   selector: '[unless]',
   *   inputs: ['unless']
   * })
   * export class Unless {
   *   viewContainer: ViewContainerRef;
   *   templateRef: TemplateRef;
   *   prevCondition: boolean;
   * 
   *   constructor(viewContainer: ViewContainerRef, templateRef: TemplateRef) {
   *     this.viewContainer = viewContainer;
   *     this.templateRef = templateRef;
   *     this.prevCondition = null;
   *   }
   * 
   *   set unless(newCondition) {
   *     if (newCondition && (isBlank(this.prevCondition) || !this.prevCondition)) {
   *       this.prevCondition = true;
   *       this.viewContainer.clear();
   *     } else if (!newCondition && (isBlank(this.prevCondition) || this.prevCondition)) {
   *       this.prevCondition = false;
   *       this.viewContainer.create(this.templateRef);
   *     }
   *   }
   * }
   * ```
   * 
   * We can then use this `unless` selector in a template:
   * ```
   * <ul>
   *   <li *unless="expr"></li>
   * </ul>
   * ```
   * 
   * Once the directive instantiates the child view, the shorthand notation for the template expands
   * and the result is:
   * 
   * ```
   * <ul>
   *   <template [unless]="exp">
   *     <li></li>
   *   </template>
   *   <li></li>
   * </ul>
   * ```
   * 
   * Note also that although the `<li></li>` template still exists inside the `<template></template>`,
   * the instantiated
   * view occurs on the second `<li></li>` which is a sibling to the `<template>` element.
   */
  var Directive: DirectiveFactory;
  

    
  /**
   * Metadata properties available for configuring Views.
   * 
   * Each Angular component requires a single `@Component` and at least one `@View` annotation. The
   * `@View` annotation specifies the HTML template to use, and lists the directives that are active
   * within the template.
   * 
   * When a component is instantiated, the template is loaded into the component's shadow root, and
   * the expressions and statements in the template are evaluated against the component.
   * 
   * For details on the `@Component` annotation, see {@link ComponentMetadata}.
   * 
   * ### Example
   * 
   * ```
   * @Component({
   *   selector: 'greet',
   *   template: 'Hello {{name}}!',
   *   directives: [GreetUser, Bold]
   * })
   * class Greet {
   *   name: string;
   * 
   *   constructor() {
   *     this.name = 'World';
   *   }
   * }
   * ```
   */
  var View: ViewFactory;
  

    
  /**
   * Metadata properties available for configuring Views.
   * 
   * Each Angular component requires a single `@Component` and at least one `@View` annotation. The
   * `@View` annotation specifies the HTML template to use, and lists the directives that are active
   * within the template.
   * 
   * When a component is instantiated, the template is loaded into the component's shadow root, and
   * the expressions and statements in the template are evaluated against the component.
   * 
   * For details on the `@Component` annotation, see {@link ComponentMetadata}.
   * 
   * ### Example
   * 
   * ```
   * @Component({
   *   selector: 'greet',
   *   template: 'Hello {{name}}!',
   *   directives: [GreetUser, Bold]
   * })
   * class Greet {
   *   name: string;
   * 
   *   constructor() {
   *     this.name = 'World';
   *   }
   * }
   * ```
   */
  var Attribute: AttributeFactory;
  

    
  /**
   * Declares an injectable parameter to be a live list of directives or variable
   * bindings from the content children of a directive.
   * 
   * ### Example ([live demo](http://plnkr.co/edit/lY9m8HLy7z06vDoUaSN2?p=preview))
   * 
   * Assume that `<tabs>` component would like to get a list its children `<pane>`
   * components as shown in this example:
   * 
   * ```html
   * <tabs>
   *   <pane title="Overview">...</pane>
   *   <pane *ng-for="#o of objects" [title]="o.title">{{o.text}}</pane>
   * </tabs>
   * ```
   * 
   * The preferred solution is to query for `Pane` directives using this decorator.
   * 
   * ```javascript
   * @Component({
   *   selector: 'pane',
   *   inputs: ['title']
   * })
   * class Pane {
   *   title:string;
   * }
   * 
   * @Component({
   *  selector: 'tabs',
   *  template: `
   *    <ul>
   *      <li *ng-for="#pane of panes">{{pane.title}}</li>
   *    </ul>
   *    <content></content>
   *  `
   * })
   * class Tabs {
   *   panes: QueryList<Pane>;
   *   constructor(@Query(Pane) panes:QueryList<Pane>) {
   *     this.panes = panes;
   *   }
   * }
   * ```
   * 
   * A query can look for variable bindings by passing in a string with desired binding symbol.
   * 
   * ### Example ([live demo](http://plnkr.co/edit/sT2j25cH1dURAyBRCKx1?p=preview))
   * ```html
   * <seeker>
   *   <div #findme>...</div>
   * </seeker>
   * 
   * @Component({ selector: 'foo' })
   * class seeker {
   *   constructor(@Query('findme') elList: QueryList<ElementRef>) {...}
   * }
   * ```
   * 
   * In this case the object that is injected depend on the type of the variable
   * binding. It can be an ElementRef, a directive or a component.
   * 
   * Passing in a comma separated list of variable bindings will query for all of them.
   * 
   * ```html
   * <seeker>
   *   <div #find-me>...</div>
   *   <div #find-me-too>...</div>
   * </seeker>
   * 
   *  @Component({
   *   selector: 'foo'
   * })
   * class Seeker {
   *   constructor(@Query('findMe, findMeToo') elList: QueryList<ElementRef>) {...}
   * }
   * ```
   * 
   * Configure whether query looks for direct children or all descendants
   * of the querying element, by using the `descendants` parameter.
   * It is set to `false` by default.
   * 
   * ### Example ([live demo](http://plnkr.co/edit/wtGeB977bv7qvA5FTYl9?p=preview))
   * ```html
   * <container #first>
   *   <item>a</item>
   *   <item>b</item>
   *   <container #second>
   *     <item>c</item>
   *   </container>
   * </container>
   * ```
   * 
   * When querying for items, the first container will see only `a` and `b` by default,
   * but with `Query(TextDirective, {descendants: true})` it will see `c` too.
   * 
   * The queried directives are kept in a depth-first pre-order with respect to their
   * positions in the DOM.
   * 
   * Query does not look deep into any subcomponent views.
   * 
   * Query is updated as part of the change-detection cycle. Since change detection
   * happens after construction of a directive, QueryList will always be empty when observed in the
   * constructor.
   * 
   * The injected object is an unmodifiable live list.
   * See {@link QueryList} for more details.
   */
  var Query: QueryFactory;
  

    
  /**
   * Configures a content query.
   * 
   * Content queries are set before the `afterContentInit` callback is called.
   * 
   * ### Example
   * 
   * ```
   * @Directive({
   *   selector: 'someDir'
   * })
   * class SomeDir {
   *   @ContentChildren(ChildDirective) contentChildren: QueryList<ChildDirective>;
   * 
   *   afterContentInit() {
   *     // contentChildren is set
   *   }
   * }
   * ```
   */
  var ContentChildren: ContentChildrenFactory;
  

    
  /**
   * Configures a content query.
   * 
   * Content queries are set before the `afterContentInit` callback is called.
   * 
   * ### Example
   * 
   * ```
   * @Directive({
   *   selector: 'someDir'
   * })
   * class SomeDir {
   *   @ContentChild(ChildDirective) contentChild;
   * 
   *   afterContentInit() {
   *     // contentChild is set
   *   }
   * }
   * ```
   */
  var ContentChild: ContentChildFactory;
  

    
  /**
   * Configures a view query.
   * 
   * View queries are set before the `afterViewInit` callback is called.
   * 
   * ### Example
   * 
   * ```
   * @Component({
   *   selector: 'someDir',
   *   templateUrl: 'someTemplate',
   *   directives: [ItemDirective]
   * })
   * class SomeDir {
   *   @ViewChildren(ItemDirective) viewChildren: QueryList<ItemDirective>;
   * 
   *   afterViewInit() {
   *     // viewChildren is set
   *   }
   * }
   * ```
   */
  var ViewChildren: ViewChildrenFactory;
  

    
  /**
   * Configures a view query.
   * 
   * View queries are set before the `afterViewInit` callback is called.
   * 
   * ### Example
   * 
   * ```
   * @Component({
   *   selector: 'someDir',
   *   templateUrl: 'someTemplate',
   *   directives: [ItemDirective]
   * })
   * class SomeDir {
   *   @ViewChild(ItemDirective) viewChild:ItemDirective;
   * 
   *   afterViewInit() {
   *     // viewChild is set
   *   }
   * }
   * ```
   */
  var ViewChild: ViewChildFactory;
  

    
  /**
   * Similar to {@link QueryMetadata}, but querying the component view, instead of
   * the content children.
   * 
   * ### Example ([live demo](http://plnkr.co/edit/eNsFHDf7YjyM6IzKxM1j?p=preview))
   * 
   * ```javascript
   * @Component({...})
   * @View({
   *   template: `
   *     <item> a </item>
   *     <item> b </item>
   *     <item> c </item>
   *   `
   * })
   * class MyComponent {
   *   shown: boolean;
   * 
   *   constructor(private @Query(Item) items:QueryList<Item>) {
   *     items.onChange(() => console.log(items.length));
   *   }
   * }
   * ```
   * 
   * Supports the same querying parameters as {@link QueryMetadata}, except
   * `descendants`. This always queries the whole view.
   * 
   * As `shown` is flipped between true and false, items will contain zero of one
   * items.
   * 
   * Specifies that a {@link QueryList} should be injected.
   * 
   * The injected object is an iterable and observable live list.
   * See {@link QueryList} for more details.
   */
  var ViewQuery: QueryFactory;
  

    
  /**
   * Declare reusable pipe function.
   * 
   * ### Example
   * 
   * ```
   * @Pipe({
   *   name: 'lowercase'
   * })
   * class Lowercase {
   *   transform(v, args) { return v.toLowerCase(); }
   * }
   * ```
   */
  var Pipe: PipeFactory;
  

    
  /**
   * Declares a data-bound input property.
   * 
   * Angular automatically updates data-bound properties during change detection.
   * 
   * `InputMetadata` takes an optional parameter that specifies the name
   * used when instantiating a component in the template. When not provided,
   * the name of the decorated property is used.
   * 
   * ### Example
   * 
   * The following example creates a component with two input properties.
   * 
   * ```typescript
   * @Component({
   *   selector: 'bank-account',
   *   template: `
   *     Bank Name: {{bankName}}
   *     Account Id: {{id}}
   *   `
   * })
   * class BankAccount {
   *   @Input() bankName: string;
   *   @Input('account-id') id: string;
   * 
   *   // this property is not bound, and won't be automatically updated by Angular
   *   normalizedBankName: string;
   * }
   * 
   * @Component({
   *   selector: 'app',
   *   template: `
   *     <bank-account bank-name="RBC" account-id="4747"></bank-account>
   *   `,
   *   directives: [BankAccount]
   * })
   * class App {}
   * 
   * bootstrap(App);
   * ```
   */
  var Input: InputFactory;
  

    
  /**
   * Declares an event-bound output property.
   * 
   * When an output property emits an event, an event handler attached to that event
   * the template is invoked.
   * 
   * `OutputMetadata` takes an optional parameter that specifies the name
   * used when instantiating a component in the template. When not provided,
   * the name of the decorated property is used.
   * 
   * ### Example
   * 
   * ```typescript
   * @Directive({
   *   selector: 'interval-dir',
   * })
   * class IntervalDir {
   *   @Output() everySecond = new EventEmitter();
   *   @Output('everyFiveSeconds') five5Secs = new EventEmitter();
   * 
   *   constructor() {
   *     setInterval(() => this.everySecond.next("event"), 1000);
   *     setInterval(() => this.five5Secs.next("event"), 5000);
   *   }
   * }
   * 
   * @Component({
   *   selector: 'app',
   *   template: `
   *     <interval-dir (every-second)="everySecond()" (every-five-seconds)="everyFiveSeconds()">
   *     </interval-dir>
   *   `,
   *   directives: [IntervalDir]
   * })
   * class App {
   *   everySecond() { console.log('second'); }
   *   everyFiveSeconds() { console.log('five seconds'); }
   * }
   * bootstrap(App);
   * ```
   */
  var Output: OutputFactory;
  

    
  /**
   * Declares a host property binding.
   * 
   * Angular automatically checks host property bindings during change detection.
   * If a binding changes, it will update the host element of the directive.
   * 
   * `HostBindingMetadata` takes an optional parameter that specifies the property
   * name of the host element that will be updated. When not provided,
   * the class property name is used.
   * 
   * ### Example
   * 
   * The following example creates a directive that sets the `valid` and `invalid` classes
   * on the DOM element that has ng-model directive on it.
   * 
   * ```typescript
   * @Directive({selector: '[ng-model]'})
   * class NgModelStatus {
   *   constructor(public control:NgModel) {}
   *   @HostBinding('[class.valid]') get valid { return this.control.valid; }
   *   @HostBinding('[class.invalid]') get invalid { return this.control.invalid; }
   * }
   * 
   * @Component({
   *   selector: 'app',
   *   template: `<input [(ng-model)]="prop">`,
   *   directives: [FORM_DIRECTIVES, NgModelStatus]
   * })
   * class App {
   *   prop;
   * }
   * 
   * bootstrap(App);
   * ```
   */
  var HostBinding: HostBindingFactory;
  

    
  /**
   * Declares a host listener.
   * 
   * Angular will invoke the decorated method when the host element emits the specified event.
   * 
   * If the decorated method returns `false`, then `preventDefault` is applied on the DOM
   * event.
   * 
   * ### Example
   * 
   * The following example declares a directive that attaches a click listener to the button and
   * counts clicks.
   * 
   * ```typescript
   * @Directive({selector: 'button[counting]'})
   * class CountClicks {
   *   numberOfClicks = 0;
   * 
   *   @HostListener('click', ['$event.target'])
   *   onClick(btn) {
   *     console.log("button", btn, "number of clicks:", this.numberOfClicks++);
   *   }
   * }
   * 
   * @Component({
   *   selector: 'app',
   *   template: `<button counting>Increment</button>`,
   *   directives: [CountClicks]
   * })
   * class App {}
   * 
   * bootstrap(App);
   * ```
   */
  var HostListener: HostListenerFactory;
  

    
  /**
   * Provides a way for expressing ES6 classes with parameter annotations in ES5.
   * 
   * ## Basic Example
   * 
   * ```
   * var Greeter = ng.Class({
   *   constructor: function(name) {
   *     this.name = name;
   *   },
   * 
   *   greet: function() {
   *     alert('Hello ' + this.name + '!');
   *   }
   * });
   * ```
   * 
   * is equivalent to ES6:
   * 
   * ```
   * class Greeter {
   *   constructor(name) {
   *     this.name = name;
   *   }
   * 
   *   greet() {
   *     alert('Hello ' + this.name + '!');
   *   }
   * }
   * ```
   * 
   * or equivalent to ES5:
   * 
   * ```
   * var Greeter = function (name) {
   *   this.name = name;
   * }
   * 
   * Greeter.prototype.greet = function () {
   *   alert('Hello ' + this.name + '!');
   * }
   * ```
   * 
   * ### Example with parameter annotations
   * 
   * ```
   * var MyService = ng.Class({
   *   constructor: [String, [new Query(), QueryList], function(name, queryList) {
   *     ...
   *   }]
   * });
   * ```
   * 
   * is equivalent to ES6:
   * 
   * ```
   * class MyService {
   *   constructor(name: string, @Query() queryList: QueryList) {
   *     ...
   *   }
   * }
   * ```
   * 
   * ### Example with inheritance
   * 
   * ```
   * var Shape = ng.Class({
   *   constructor: (color) {
   *     this.color = color;
   *   }
   * });
   * 
   * var Square = ng.Class({
   *   extends: Shape,
   *   constructor: function(color, size) {
   *     Shape.call(this, color);
   *     this.size = size;
   *   }
   * });
   * ```
   */
  function Class(clsDef: ClassDefinition): ConcreteType;
  

    
  /**
   * Declares the interface to be used with {@link Class}.
   */
  interface ClassDefinition {
    
    /**
     * Optional argument for specifying the superclass.
     */
    extends?: Type;
    
    /**
     * Required constructor function for a class.
     * 
     * The function may be optionally wrapped in an `Array`, in which case additional parameter
     * annotations may be specified.
     * The number of arguments and the number of parameter annotations must match.
     * 
     * See {@link Class} for example of usage.
     */
    constructor: Function | any[];
    
  }

    
  /**
   * An interface implemented by all Angular type decorators, which allows them to be used as ES7
   * decorators as well as
   * Angular DSL syntax.
   * 
   * DSL syntax:
   * 
   * ```
   * var MyClass = ng
   *   .Component({...})
   *   .View({...})
   *   .Class({...});
   * ```
   * 
   * ES7 syntax:
   * 
   * ```
   * @ng.Component({...})
   * @ng.View({...})
   * class MyClass {...}
   * ```
   */
  interface TypeDecorator {
    
    /**
     * Invoke as ES7 decorator.
     */
    <T extends Type>(type: T): T;
    
    /**
     * Storage for the accumulated annotations so far used by the DSL syntax.
     * 
     * Used by {@link Class} to annotate the generated class.
     */
    annotations: any[];
    
    /**
     * Generate a class from the definition and annotate it with {@link TypeDecorator#annotations}.
     */
    Class(obj: ClassDefinition): ConcreteType;
    
  }

    
  /**
   * A parameter metadata that specifies a dependency.
   * 
   * ### Example ([live demo](http://plnkr.co/edit/6uHYJK?p=preview))
   * 
   * ```typescript
   * class Engine {}
   * 
   * @Injectable()
   * class Car {
   *   engine;
   *   constructor(@Inject("MyEngine") engine:Engine) {
   *     this.engine = engine;
   *   }
   * }
   * 
   * var injector = Injector.resolveAndCreate([
   *  provide("MyEngine", {useClass: Engine}),
   *  Car
   * ]);
   * 
   * expect(injector.get(Car).engine instanceof Engine).toBe(true);
   * ```
   * 
   * When `@Inject()` is not present, {@link Injector} will use the type annotation of the parameter.
   * 
   * ### Example
   * 
   * ```typescript
   * class Engine {}
   * 
   * @Injectable()
   * class Car {
   *   constructor(public engine: Engine) {} //same as constructor(@Inject(Engine) engine:Engine)
   * }
   * 
   * var injector = Injector.resolveAndCreate([Engine, Car]);
   * expect(injector.get(Car).engine instanceof Engine).toBe(true);
   * ```
   */
  class InjectMetadata {
    
    constructor(token: any);
    
    token: any;
    
    toString(): string;
    
  }

    
  /**
   * A parameter metadata that marks a dependency as optional. {@link Injector} provides `null` if
   * the dependency is not found.
   * 
   * ### Example ([live demo](http://plnkr.co/edit/AsryOm?p=preview))
   * 
   * ```typescript
   * class Engine {}
   * 
   * @Injectable()
   * class Car {
   *   engine;
   *   constructor(@Optional() engine:Engine) {
   *     this.engine = engine;
   *   }
   * }
   * 
   * var injector = Injector.resolveAndCreate([Car]);
   * expect(injector.get(Car).engine).toBeNull();
   * ```
   */
  class OptionalMetadata {
    
    toString(): string;
    
  }

    
  /**
   * A marker metadata that marks a class as available to {@link Injector} for creation.
   * 
   * ### Example ([live demo](http://plnkr.co/edit/Wk4DMQ?p=preview))
   * 
   * ```typescript
   * @Injectable()
   * class UsefulService {}
   * 
   * @Injectable()
   * class NeedsService {
   *   constructor(public service:UsefulService) {}
   * }
   * 
   * var injector = Injector.resolveAndCreate([NeedsService, UsefulService]);
   * expect(injector.get(NeedsService).service instanceof UsefulService).toBe(true);
   * ```
   * {@link Injector} will throw {@link NoAnnotationError} when trying to instantiate a class that
   * does not have `@Injectable` marker, as shown in the example below.
   * 
   * ```typescript
   * class UsefulService {}
   * 
   * class NeedsService {
   *   constructor(public service:UsefulService) {}
   * }
   * 
   * var injector = Injector.resolveAndCreate([NeedsService, UsefulService]);
   * expect(() => injector.get(NeedsService)).toThrowError();
   * ```
   */
  class InjectableMetadata {
    
    constructor();
    
  }

    
  /**
   * Specifies that an {@link Injector} should retrieve a dependency only from itself.
   * 
   * ### Example ([live demo](http://plnkr.co/edit/NeagAg?p=preview))
   * 
   * ```typescript
   * class Dependency {
   * }
   * 
   * @Injectable()
   * class NeedsDependency {
   *   dependency;
   *   constructor(@Self() dependency:Dependency) {
   *     this.dependency = dependency;
   *   }
   * }
   * 
   * var inj = Injector.resolveAndCreate([Dependency, NeedsDependency]);
   * var nd = inj.get(NeedsDependency);
   * 
   * expect(nd.dependency instanceof Dependency).toBe(true);
   * 
   * var inj = Injector.resolveAndCreate([Dependency]);
   * var child = inj.resolveAndCreateChild([NeedsDependency]);
   * expect(() => child.get(NeedsDependency)).toThrowError();
   * ```
   */
  class SelfMetadata {
    
    toString(): string;
    
  }

    
  /**
   * Specifies that an injector should retrieve a dependency from any injector until reaching the
   * closest host.
   * 
   * In Angular, a component element is automatically declared as a host for all the injectors in
   * its view.
   * 
   * ### Example ([live demo](http://plnkr.co/edit/GX79pV?p=preview))
   * 
   * In the following example `App` contains `ParentCmp`, which contains `ChildDirective`.
   * So `ParentCmp` is the host of `ChildDirective`.
   * 
   * `ChildDirective` depends on two services: `HostService` and `OtherService`.
   * `HostService` is defined at `ParentCmp`, and `OtherService` is defined at `App`.
   * 
   * ```typescript
   * class OtherService {}
   * class HostService {}
   * 
   * @Directive({
   *   selector: 'child-directive'
   * })
   * class ChildDirective {
   *   constructor(@Optional() @Host() os:OtherService, @Optional() @Host() hs:HostService){
   *     console.log("os is null", os);
   *     console.log("hs is NOT null", hs);
   *   }
   * }
   * 
   * @Component({
   *   selector: 'parent-cmp',
   *   providers: [HostService],
   *   template: `
   *     Dir: <child-directive></child-directive>
   *   `,
   *   directives: [ChildDirective]
   * })
   * class ParentCmp {
   * }
   * 
   * @Component({
   *   selector: 'app',
   *   providers: [OtherService],
   *   template: `
   *     Parent: <parent-cmp></parent-cmp>
   *   `,
   *   directives: [ParentCmp]
   * })
   * class App {
   * }
   * 
   * bootstrap(App);
   * ```
   */
  class HostMetadata {
    
    toString(): string;
    
  }

    
  /**
   * Specifies that the dependency resolution should start from the parent injector.
   * 
   * ### Example ([live demo](http://plnkr.co/edit/Wchdzb?p=preview))
   * 
   * ```typescript
   * class Dependency {
   * }
   * 
   * @Injectable()
   * class NeedsDependency {
   *   dependency;
   *   constructor(@SkipSelf() dependency:Dependency) {
   *     this.dependency = dependency;
   *   }
   * }
   * 
   * var parent = Injector.resolveAndCreate([Dependency]);
   * var child = parent.resolveAndCreateChild([NeedsDependency]);
   * expect(child.get(NeedsDependency).dependency instanceof Depedency).toBe(true);
   * 
   * var inj = Injector.resolveAndCreate([Dependency, NeedsDependency]);
   * expect(() => inj.get(NeedsDependency)).toThrowError();
   * ```
   */
  class SkipSelfMetadata {
    
    toString(): string;
    
  }

    
  /**
   * `DependencyMetadata` is used by the framework to extend DI.
   * This is internal to Angular and should not be used directly.
   */
  class DependencyMetadata {
    
    token: any;
    
  }

    
  /**
   * Allows to refer to references which are not yet defined.
   * 
   * For instance, `forwardRef` is used when the `token` which we need to refer to for the purposes of
   * DI is declared,
   * but not yet defined. It is also used when the `token` which we use when creating a query is not
   * yet defined.
   * 
   * ### Example ([live demo](http://plnkr.co/edit/bRs0SX2OTQiJzqvjgl8P?p=preview))
   * 
   * ```typescript
   * class Door {
   *   lock: Lock;
   *   constructor(@Inject(forwardRef(() => Lock)) lock:Lock) {
   *     this.lock = lock;
   *   }
   * }
   * 
   * // Only at this point Lock is defined.
   * class Lock {
   * }
   * 
   * var injector = Injector.resolveAndCreate([Door, Lock]);
   * var door = injector.get(Door);
   * expect(door instanceof Door).toBe(true);
   * expect(door.lock instanceof Lock).toBe(true);
   * ```
   */
  function forwardRef(forwardRefFn: ForwardRefFn): Type;
  

    
  /**
   * Lazily retrieves the reference value from a forwardRef.
   * 
   * Acts as the identity function when given a non-forward-ref value.
   * 
   * ### Example ([live demo](http://plnkr.co/edit/GU72mJrk1fiodChcmiDR?p=preview))
   * 
   * ```typescript
   * var ref = forwardRef(() => "refValue");
   * expect(resolveForwardRef(ref)).toEqual("refValue");
   * expect(resolveForwardRef("regularValue")).toEqual("regularValue");
   * ```
   * 
   * See: {@link forwardRef}
   */
  function resolveForwardRef(type: any): any;
  

    
  /**
   * An interface that a function passed into {@link forwardRef} has to implement.
   * 
   * ### Example
   * 
   * ```typescript
   * var fn:ForwardRefFn = forwardRef(() => Lock);
   * ```
   */
  interface ForwardRefFn {
    
    (): any;
    
  }

    
  /**
   * A dependency injection container used for instantiating objects and resolving dependencies.
   * 
   * An `Injector` is a replacement for a `new` operator, which can automatically resolve the
   * constructor dependencies.
   * 
   * In typical use, application code asks for the dependencies in the constructor and they are
   * resolved by the `Injector`.
   * 
   * ### Example ([live demo](http://plnkr.co/edit/jzjec0?p=preview))
   * 
   * The following example creates an `Injector` configured to create `Engine` and `Car`.
   * 
   * ```typescript
   * @Injectable()
   * class Engine {
   * }
   * 
   * @Injectable()
   * class Car {
   *   constructor(public engine:Engine) {}
   * }
   * 
   * var injector = Injector.resolveAndCreate([Car, Engine]);
   * var car = injector.get(Car);
   * expect(car instanceof Car).toBe(true);
   * expect(car.engine instanceof Engine).toBe(true);
   * ```
   * 
   * Notice, we don't use the `new` operator because we explicitly want to have the `Injector`
   * resolve all of the object's dependencies automatically.
   */
  class Injector {
    
    /**
     * Private
     */
    constructor(_proto: any, _parent?: Injector, _depProvider?: any, _debugContext?: Function);
    
    /**
     * Turns an array of provider definitions into an array of resolved providers.
     * 
     * A resolution is a process of flattening multiple nested arrays and converting individual
     * providers into an array of {@link ResolvedProvider}s.
     * 
     * ### Example ([live demo](http://plnkr.co/edit/AiXTHi?p=preview))
     * 
     * ```typescript
     * @Injectable()
     * class Engine {
     * }
     * 
     * @Injectable()
     * class Car {
     *   constructor(public engine:Engine) {}
     * }
     * 
     * var providers = Injector.resolve([Car, [[Engine]]]);
     * 
     * expect(providers.length).toEqual(2);
     * 
     * expect(providers[0] instanceof ResolvedProvider).toBe(true);
     * expect(providers[0].key.displayName).toBe("Car");
     * expect(providers[0].dependencies.length).toEqual(1);
     * expect(providers[0].factory).toBeDefined();
     * 
     * expect(providers[1].key.displayName).toBe("Engine");
     * });
     * ```
     * 
     * See {@link Injector#fromResolvedProviders} for more info.
     */
    static resolve(providers: Array<Type | Provider | any[]>): ResolvedProvider[];
    
    /**
     * Resolves an array of providers and creates an injector from those providers.
     * 
     * The passed-in providers can be an array of `Type`, {@link Provider},
     * or a recursive array of more providers.
     * 
     * ### Example ([live demo](http://plnkr.co/edit/ePOccA?p=preview))
     * 
     * ```typescript
     * @Injectable()
     * class Engine {
     * }
     * 
     * @Injectable()
     * class Car {
     *   constructor(public engine:Engine) {}
     * }
     * 
     * var injector = Injector.resolveAndCreate([Car, Engine]);
     * expect(injector.get(Car) instanceof Car).toBe(true);
     * ```
     * 
     * This function is slower than the corresponding `fromResolvedProviders`
     * because it needs to resolve the passed-in providers first.
     * See {@link Injector#resolve} and {@link Injector#fromResolvedProviders}.
     */
    static resolveAndCreate(providers: Array<Type | Provider | any[]>): Injector;
    
    /**
     * Creates an injector from previously resolved providers.
     * 
     * This API is the recommended way to construct injectors in performance-sensitive parts.
     * 
     * ### Example ([live demo](http://plnkr.co/edit/KrSMci?p=preview))
     * 
     * ```typescript
     * @Injectable()
     * class Engine {
     * }
     * 
     * @Injectable()
     * class Car {
     *   constructor(public engine:Engine) {}
     * }
     * 
     * var providers = Injector.resolve([Car, Engine]);
     * var injector = Injector.fromResolvedProviders(providers);
     * expect(injector.get(Car) instanceof Car).toBe(true);
     * ```
     */
    static fromResolvedProviders(providers: ResolvedProvider[]): Injector;
    
    /**
     * @deprecated
     */
    static fromResolvedBindings(providers: ResolvedProvider[]): Injector;
    
    /**
     * Retrieves an instance from the injector based on the provided token.
     * Throws {@link NoProviderError} if not found.
     * 
     * ### Example ([live demo](http://plnkr.co/edit/HeXSHg?p=preview))
     * 
     * ```typescript
     * var injector = Injector.resolveAndCreate([
     *   provide("validToken", {useValue: "Value"})
     * ]);
     * expect(injector.get("validToken")).toEqual("Value");
     * expect(() => injector.get("invalidToken")).toThrowError();
     * ```
     * 
     * `Injector` returns itself when given `Injector` as a token.
     * 
     * ```typescript
     * var injector = Injector.resolveAndCreate([]);
     * expect(injector.get(Injector)).toBe(injector);
     * ```
     */
    get(token: any): any;
    
    /**
     * Retrieves an instance from the injector based on the provided token.
     * Returns null if not found.
     * 
     * ### Example ([live demo](http://plnkr.co/edit/tpEbEy?p=preview))
     * 
     * ```typescript
     * var injector = Injector.resolveAndCreate([
     *   provide("validToken", {useValue: "Value"})
     * ]);
     * expect(injector.getOptional("validToken")).toEqual("Value");
     * expect(injector.getOptional("invalidToken")).toBe(null);
     * ```
     * 
     * `Injector` returns itself when given `Injector` as a token.
     * 
     * ```typescript
     * var injector = Injector.resolveAndCreate([]);
     * expect(injector.getOptional(Injector)).toBe(injector);
     * ```
     */
    getOptional(token: any): any;
    
    /**
     * Parent of this injector.
     * 
     * <!-- TODO: Add a link to the section of the user guide talking about hierarchical injection.
     * -->
     * 
     * ### Example ([live demo](http://plnkr.co/edit/eosMGo?p=preview))
     * 
     * ```typescript
     * var parent = Injector.resolveAndCreate([]);
     * var child = parent.resolveAndCreateChild([]);
     * expect(child.parent).toBe(parent);
     * ```
     */
    parent: Injector;
    
    /**
     * Resolves an array of providers and creates a child injector from those providers.
     * 
     * <!-- TODO: Add a link to the section of the user guide talking about hierarchical injection.
     * -->
     * 
     * The passed-in providers can be an array of `Type`, {@link Provider},
     * or a recursive array of more providers.
     * 
     * ### Example ([live demo](http://plnkr.co/edit/opB3T4?p=preview))
     * 
     * ```typescript
     * class ParentProvider {}
     * class ChildProvider {}
     * 
     * var parent = Injector.resolveAndCreate([ParentProvider]);
     * var child = parent.resolveAndCreateChild([ChildProvider]);
     * 
     * expect(child.get(ParentProvider) instanceof ParentProvider).toBe(true);
     * expect(child.get(ChildProvider) instanceof ChildProvider).toBe(true);
     * expect(child.get(ParentProvider)).toBe(parent.get(ParentProvider));
     * ```
     * 
     * This function is slower than the corresponding `createChildFromResolved`
     * because it needs to resolve the passed-in providers first.
     * See {@link Injector#resolve} and {@link Injector#createChildFromResolved}.
     */
    resolveAndCreateChild(providers: Array<Type | Provider | any[]>): Injector;
    
    /**
     * Creates a child injector from previously resolved providers.
     * 
     * <!-- TODO: Add a link to the section of the user guide talking about hierarchical injection.
     * -->
     * 
     * This API is the recommended way to construct injectors in performance-sensitive parts.
     * 
     * ### Example ([live demo](http://plnkr.co/edit/VhyfjN?p=preview))
     * 
     * ```typescript
     * class ParentProvider {}
     * class ChildProvider {}
     * 
     * var parentProviders = Injector.resolve([ParentProvider]);
     * var childProviders = Injector.resolve([ChildProvider]);
     * 
     * var parent = Injector.fromResolvedProviders(parentProviders);
     * var child = parent.createChildFromResolved(childProviders);
     * 
     * expect(child.get(ParentProvider) instanceof ParentProvider).toBe(true);
     * expect(child.get(ChildProvider) instanceof ChildProvider).toBe(true);
     * expect(child.get(ParentProvider)).toBe(parent.get(ParentProvider));
     * ```
     */
    createChildFromResolved(providers: ResolvedProvider[]): Injector;
    
    /**
     * Resolves a provider and instantiates an object in the context of the injector.
     * 
     * The created object does not get cached by the injector.
     * 
     * ### Example ([live demo](http://plnkr.co/edit/yvVXoB?p=preview))
     * 
     * ```typescript
     * @Injectable()
     * class Engine {
     * }
     * 
     * @Injectable()
     * class Car {
     *   constructor(public engine:Engine) {}
     * }
     * 
     * var injector = Injector.resolveAndCreate([Engine]);
     * 
     * var car = injector.resolveAndInstantiate(Car);
     * expect(car.engine).toBe(injector.get(Engine));
     * expect(car).not.toBe(injector.resolveAndInstantiate(Car));
     * ```
     */
    resolveAndInstantiate(provider: Type | Provider): any;
    
    /**
     * Instantiates an object using a resolved provider in the context of the injector.
     * 
     * The created object does not get cached by the injector.
     * 
     * ### Example ([live demo](http://plnkr.co/edit/ptCImQ?p=preview))
     * 
     * ```typescript
     * @Injectable()
     * class Engine {
     * }
     * 
     * @Injectable()
     * class Car {
     *   constructor(public engine:Engine) {}
     * }
     * 
     * var injector = Injector.resolveAndCreate([Engine]);
     * var carProvider = Injector.resolve([Car])[0];
     * var car = injector.instantiateResolved(carProvider);
     * expect(car.engine).toBe(injector.get(Engine));
     * expect(car).not.toBe(injector.instantiateResolved(carProvider));
     * ```
     */
    instantiateResolved(provider: ResolvedProvider): any;
    
    displayName: string;
    
    toString(): string;
    
  }

    
  /**
   * @deprecated
   */
  class Binding extends Provider {
    
    constructor(token: any, {toClass, toValue, toAlias, toFactory, deps, multi}: {
        toClass?: Type,
        toValue?: any,
        toAlias?: any,
        toFactory: Function, deps?: Object[], multi?: boolean
      });
    
    /**
     * @deprecated
     */
    toClass: any;
    
    /**
     * @deprecated
     */
    toAlias: any;
    
    /**
     * @deprecated
     */
    toFactory: any;
    
    /**
     * @deprecated
     */
    toValue: any;
    
  }

    
  /**
   * Helper class for the {@link bind} function.
   */
  class ProviderBuilder {
    
    constructor(token: any);
    
    token: any;
    
    /**
     * Binds a DI token to a class.
     * 
     * ### Example ([live demo](http://plnkr.co/edit/ZpBCSYqv6e2ud5KXLdxQ?p=preview))
     * 
     * Because `toAlias` and `toClass` are often confused, the example contains
     * both use cases for easy comparison.
     * 
     * ```typescript
     * class Vehicle {}
     * 
     * class Car extends Vehicle {}
     * 
     * var injectorClass = Injector.resolveAndCreate([
     *   Car,
     *   provide(Vehicle, {useClass: Car})
     * ]);
     * var injectorAlias = Injector.resolveAndCreate([
     *   Car,
     *   provide(Vehicle, {useExisting: Car})
     * ]);
     * 
     * expect(injectorClass.get(Vehicle)).not.toBe(injectorClass.get(Car));
     * expect(injectorClass.get(Vehicle) instanceof Car).toBe(true);
     * 
     * expect(injectorAlias.get(Vehicle)).toBe(injectorAlias.get(Car));
     * expect(injectorAlias.get(Vehicle) instanceof Car).toBe(true);
     * ```
     */
    toClass(type: Type): Provider;
    
    /**
     * Binds a DI token to a value.
     * 
     * ### Example ([live demo](http://plnkr.co/edit/G024PFHmDL0cJFgfZK8O?p=preview))
     * 
     * ```typescript
     * var injector = Injector.resolveAndCreate([
     *   provide('message', {useValue: 'Hello'})
     * ]);
     * 
     * expect(injector.get('message')).toEqual('Hello');
     * ```
     */
    toValue(value: any): Provider;
    
    /**
     * Binds a DI token to an existing token.
     * 
     * Angular will return the same instance as if the provided token was used. (This is
     * in contrast to `useClass` where a separate instance of `useClass` will be returned.)
     * 
     * ### Example ([live demo](http://plnkr.co/edit/uBaoF2pN5cfc5AfZapNw?p=preview))
     * 
     * Because `toAlias` and `toClass` are often confused, the example contains
     * both use cases for easy comparison.
     * 
     * ```typescript
     * class Vehicle {}
     * 
     * class Car extends Vehicle {}
     * 
     * var injectorAlias = Injector.resolveAndCreate([
     *   Car,
     *   provide(Vehicle, {useExisting: Car})
     * ]);
     * var injectorClass = Injector.resolveAndCreate([
     *   Car,
     *   provide(Vehicle, {useClass: Car})
     * ]);
     * 
     * expect(injectorAlias.get(Vehicle)).toBe(injectorAlias.get(Car));
     * expect(injectorAlias.get(Vehicle) instanceof Car).toBe(true);
     * 
     * expect(injectorClass.get(Vehicle)).not.toBe(injectorClass.get(Car));
     * expect(injectorClass.get(Vehicle) instanceof Car).toBe(true);
     * ```
     */
    toAlias(aliasToken: /*Type*/ any): Provider;
    
    /**
     * Binds a DI token to a function which computes the value.
     * 
     * ### Example ([live demo](http://plnkr.co/edit/OejNIfTT3zb1iBxaIYOb?p=preview))
     * 
     * ```typescript
     * var injector = Injector.resolveAndCreate([
     *   provide(Number, {useFactory: () => { return 1+2; }}),
     *   provide(String, {useFactory: (v) => { return "Value: " + v; }, deps: [Number]})
     * ]);
     * 
     * expect(injector.get(Number)).toEqual(3);
     * expect(injector.get(String)).toEqual('Value: 3');
     * ```
     */
    toFactory(factory: Function, dependencies?: any[]): Provider;
    
  }

    
  /**
   * @deprecated
   */
  interface ResolvedBinding extends ResolvedProvider {
    
  }

    
  /**
   * An internal resolved representation of a factory function created by resolving {@link Provider}.
   */
  class ResolvedFactory {
    
    constructor(factory: Function, dependencies: Dependency[]);
    
    /**
     * Factory function which can return an instance of an object represented by a key.
     */
    factory: Function;
    
    /**
     * Arguments (dependencies) to the `factory` function.
     */
    dependencies: Dependency[];
    
  }

    
  class Dependency {
    
    constructor(key: Key, optional: boolean, lowerBoundVisibility: any, upperBoundVisibility: any, properties: any[]);
    
    static fromKey(key: Key): Dependency;
    
    key: Key;
    
    optional: boolean;
    
    lowerBoundVisibility: any;
    
    upperBoundVisibility: any;
    
    properties: any[];
    
  }

    
  /**
   * @deprecated
   * Creates a {@link Provider}.
   * 
   * To construct a {@link Provider}, bind a `token` to either a class, a value, a factory function,
   * or
   * to an existing `token`.
   * See {@link ProviderBuilder} for more details.
   * 
   * The `token` is most commonly a class or {@link angular2/di/OpaqueToken}.
   */
  function bind(token: any): ProviderBuilder;
  

    
  /**
   * Describes how the {@link Injector} should instantiate a given token.
   * 
   * See {@link provide}.
   * 
   * ### Example ([live demo](http://plnkr.co/edit/GNAyj6K6PfYg2NBzgwZ5?p%3Dpreview&p=preview))
   * 
   * ```javascript
   * var injector = Injector.resolveAndCreate([
   *   new Provider("message", { useValue: 'Hello' })
   * ]);
   * 
   * expect(injector.get("message")).toEqual('Hello');
   * ```
   */
  class Provider {
    
    constructor(token: any, {useClass, useValue, useExisting, useFactory, deps, multi}: {
        useClass?: Type,
        useValue?: any,
        useExisting?: any,
        useFactory?: Function,
        deps?: Object[],
        multi?: boolean
      });
    
    /**
     * Token used when retrieving this provider. Usually, it is a type {@link Type}.
     */
    token: any;
    
    /**
     * Binds a DI token to an implementation class.
     * 
     * ### Example ([live demo](http://plnkr.co/edit/RSTG86qgmoxCyj9SWPwY?p=preview))
     * 
     * Because `useExisting` and `useClass` are often confused, the example contains
     * both use cases for easy comparison.
     * 
     * ```typescript
     * class Vehicle {}
     * 
     * class Car extends Vehicle {}
     * 
     * var injectorClass = Injector.resolveAndCreate([
     *   Car,
     *   new Provider(Vehicle, { useClass: Car })
     * ]);
     * var injectorAlias = Injector.resolveAndCreate([
     *   Car,
     *   new Provider(Vehicle, { useExisting: Car })
     * ]);
     * 
     * expect(injectorClass.get(Vehicle)).not.toBe(injectorClass.get(Car));
     * expect(injectorClass.get(Vehicle) instanceof Car).toBe(true);
     * 
     * expect(injectorAlias.get(Vehicle)).toBe(injectorAlias.get(Car));
     * expect(injectorAlias.get(Vehicle) instanceof Car).toBe(true);
     * ```
     */
    useClass: Type;
    
    /**
     * Binds a DI token to a value.
     * 
     * ### Example ([live demo](http://plnkr.co/edit/UFVsMVQIDe7l4waWziES?p=preview))
     * 
     * ```javascript
     * var injector = Injector.resolveAndCreate([
     *   new Provider("message", { useValue: 'Hello' })
     * ]);
     * 
     * expect(injector.get("message")).toEqual('Hello');
     * ```
     */
    useValue: any;
    
    /**
     * Binds a DI token to an existing token.
     * 
     * {@link Injector} returns the same instance as if the provided token was used.
     * This is in contrast to `useClass` where a separate instance of `useClass` is returned.
     * 
     * ### Example ([live demo](http://plnkr.co/edit/QsatsOJJ6P8T2fMe9gr8?p=preview))
     * 
     * Because `useExisting` and `useClass` are often confused the example contains
     * both use cases for easy comparison.
     * 
     * ```typescript
     * class Vehicle {}
     * 
     * class Car extends Vehicle {}
     * 
     * var injectorAlias = Injector.resolveAndCreate([
     *   Car,
     *   new Provider(Vehicle, { useExisting: Car })
     * ]);
     * var injectorClass = Injector.resolveAndCreate([
     *   Car,
     *   new Provider(Vehicle, { useClass: Car })
     * ]);
     * 
     * expect(injectorAlias.get(Vehicle)).toBe(injectorAlias.get(Car));
     * expect(injectorAlias.get(Vehicle) instanceof Car).toBe(true);
     * 
     * expect(injectorClass.get(Vehicle)).not.toBe(injectorClass.get(Car));
     * expect(injectorClass.get(Vehicle) instanceof Car).toBe(true);
     * ```
     */
    useExisting: any;
    
    /**
     * Binds a DI token to a function which computes the value.
     * 
     * ### Example ([live demo](http://plnkr.co/edit/Scoxy0pJNqKGAPZY1VVC?p=preview))
     * 
     * ```typescript
     * var injector = Injector.resolveAndCreate([
     *   new Provider(Number, { useFactory: () => { return 1+2; }}),
     *   new Provider(String, { useFactory: (value) => { return "Value: " + value; },
     *                       deps: [Number] })
     * ]);
     * 
     * expect(injector.get(Number)).toEqual(3);
     * expect(injector.get(String)).toEqual('Value: 3');
     * ```
     * 
     * Used in conjuction with dependencies.
     */
    useFactory: Function;
    
    /**
     * Specifies a set of dependencies
     * (as `token`s) which should be injected into the factory function.
     * 
     * ### Example ([live demo](http://plnkr.co/edit/Scoxy0pJNqKGAPZY1VVC?p=preview))
     * 
     * ```typescript
     * var injector = Injector.resolveAndCreate([
     *   new Provider(Number, { useFactory: () => { return 1+2; }}),
     *   new Provider(String, { useFactory: (value) => { return "Value: " + value; },
     *                       deps: [Number] })
     * ]);
     * 
     * expect(injector.get(Number)).toEqual(3);
     * expect(injector.get(String)).toEqual('Value: 3');
     * ```
     * 
     * Used in conjunction with `useFactory`.
     */
    dependencies: Object[];
    
    /**
     * Creates multiple providers matching the same token (a multi-provider).
     * 
     * Multi-providers are used for creating pluggable service, where the system comes
     * with some default providers, and the user can register additonal providers.
     * The combination of the default providers and the additional providers will be
     * used to drive the behavior of the system.
     * 
     * ### Example
     * 
     * ```typescript
     * var injector = Injector.resolveAndCreate([
     *   new Provider("Strings", { useValue: "String1", multi: true}),
     *   new Provider("Strings", { useValue: "String2", multi: true})
     * ]);
     * 
     * expect(injector.get("Strings")).toEqual(["String1", "String2"]);
     * ```
     * 
     * Multi-providers and regular providers cannot be mixed. The following
     * will throw an exception:
     * 
     * ```typescript
     * var injector = Injector.resolveAndCreate([
     *   new Provider("Strings", { useValue: "String1", multi: true }),
     *   new Provider("Strings", { useValue: "String2"})
     * ]);
     * ```
     */
    multi: boolean;
    
  }

    
  /**
   * An internal resolved representation of a {@link Provider} used by the {@link Injector}.
   * 
   * It is usually created automatically by `Injector.resolveAndCreate`.
   * 
   * It can be created manually, as follows:
   * 
   * ### Example ([live demo](http://plnkr.co/edit/RfEnhh8kUEI0G3qsnIeT?p%3Dpreview&p=preview))
   * 
   * ```typescript
   * var resolvedProviders = Injector.resolve([new Provider('message', {useValue: 'Hello'})]);
   * var injector = Injector.fromResolvedProviders(resolvedProviders);
   * 
   * expect(injector.get('message')).toEqual('Hello');
   * ```
   */
  interface ResolvedProvider {
    
    /**
     * A key, usually a `Type`.
     */
    key: Key;
    
    /**
     * Factory function which can return an instance of an object represented by a key.
     */
    resolvedFactories: ResolvedFactory[];
    
    /**
     * Indicates if the provider is a multi-provider or a regular provider.
     */
    multiProvider: boolean;
    
  }

    
  /**
   * Creates a {@link Provider}.
   * 
   * See {@link Provider} for more details.
   * 
   * <!-- TODO: improve the docs -->
   */
  function provide(token: any, {useClass, useValue, useExisting, useFactory, deps, multi}: {
    useClass?: Type,
    useValue?: any,
    useExisting?: any,
    useFactory?: Function,
    deps?: Object[],
    multi?: boolean
  }): Provider;
  

    
  /**
   * A unique object used for retrieving items from the {@link Injector}.
   * 
   * Keys have:
   * - a system-wide unique `id`.
   * - a `token`.
   * 
   * `Key` is used internally by {@link Injector} because its system-wide unique `id` allows the
   * injector to store created objects in a more efficient way.
   * 
   * `Key` should not be created directly. {@link Injector} creates keys automatically when resolving
   * providers.
   */
  class Key {
    
    /**
     * Private
     */
    constructor(token: Object, id: number);
    
    /**
     * Retrieves a `Key` for a token.
     */
    static get(token: Object): Key;
    
    /**
     * @returns the number of keys registered in the system.
     */
    static numberOfKeys: number;
    
    token: Object;
    
    id: number;
    
    /**
     * Returns a stringified token.
     */
    displayName: string;
    
  }

    
  /**
   * Type literals is a Dart-only feature. This is here only so we can x-compile
   * to multiple languages.
   */
  class TypeLiteral {
    
    type: any;
    
  }

    
  /**
   * Thrown when trying to retrieve a dependency by `Key` from {@link Injector}, but the
   * {@link Injector} does not have a {@link Provider} for {@link Key}.
   * 
   * ### Example ([live demo](http://plnkr.co/edit/vq8D3FRB9aGbnWJqtEPE?p=preview))
   * 
   * ```typescript
   * class A {
   *   constructor(b:B) {}
   * }
   * 
   * expect(() => Injector.resolveAndCreate([A])).toThrowError();
   * ```
   */
  class NoProviderError extends AbstractProviderError {
    
    constructor(injector: Injector, key: Key);
    
  }

    
  /**
   * Base class for all errors arising from misconfigured providers.
   */
  class AbstractProviderError extends BaseException {
    
    constructor(injector: Injector, key: Key, constructResolvingMessage: Function);
    
    addKey(injector: Injector, key: Key): void;
    
    context: any;
    
  }

    
  /**
   * Thrown when dependencies form a cycle.
   * 
   * ### Example ([live demo](http://plnkr.co/edit/wYQdNos0Tzql3ei1EV9j?p=info))
   * 
   * ```typescript
   * var injector = Injector.resolveAndCreate([
   *   provide("one", {useFactory: (two) => "two", deps: [[new Inject("two")]]}),
   *   provide("two", {useFactory: (one) => "one", deps: [[new Inject("one")]]})
   * ]);
   * 
   * expect(() => injector.get("one")).toThrowError();
   * ```
   * 
   * Retrieving `A` or `B` throws a `CyclicDependencyError` as the graph above cannot be constructed.
   */
  class CyclicDependencyError extends AbstractProviderError {
    
    constructor(injector: Injector, key: Key);
    
  }

    
  /**
   * Thrown when a constructing type returns with an Error.
   * 
   * The `InstantiationError` class contains the original error plus the dependency graph which caused
   * this object to be instantiated.
   * 
   * ### Example ([live demo](http://plnkr.co/edit/7aWYdcqTQsP0eNqEdUAf?p=preview))
   * 
   * ```typescript
   * class A {
   *   constructor() {
   *     throw new Error('message');
   *   }
   * }
   * 
   * var injector = Injector.resolveAndCreate([A]);
   * 
   * try {
   *   injector.get(A);
   * } catch (e) {
   *   expect(e instanceof InstantiationError).toBe(true);
   *   expect(e.originalException.message).toEqual("message");
   *   expect(e.originalStack).toBeDefined();
   * }
   * ```
   */
  class InstantiationError extends WrappedException {
    
    constructor(injector: Injector, originalException: any, originalStack: any, key: Key);
    
    addKey(injector: Injector, key: Key): void;
    
    wrapperMessage: string;
    
    causeKey: Key;
    
    context: any;
    
  }

    
  /**
   * Thrown when an object other then {@link Provider} (or `Type`) is passed to {@link Injector}
   * creation.
   * 
   * ### Example ([live demo](http://plnkr.co/edit/YatCFbPAMCL0JSSQ4mvH?p=preview))
   * 
   * ```typescript
   * expect(() => Injector.resolveAndCreate(["not a type"])).toThrowError();
   * ```
   */
  class InvalidProviderError extends BaseException {
    
    constructor(provider: any);
    
  }

    
  /**
   * Thrown when the class has no annotation information.
   * 
   * Lack of annotation information prevents the {@link Injector} from determining which dependencies
   * need to be injected into the constructor.
   * 
   * ### Example ([live demo](http://plnkr.co/edit/rHnZtlNS7vJOPQ6pcVkm?p=preview))
   * 
   * ```typescript
   * class A {
   *   constructor(b) {}
   * }
   * 
   * expect(() => Injector.resolveAndCreate([A])).toThrowError();
   * ```
   * 
   * This error is also thrown when the class not marked with {@link Injectable} has parameter types.
   * 
   * ```typescript
   * class B {}
   * 
   * class A {
   *   constructor(b:B) {} // no information about the parameter types of A is available at runtime.
   * }
   * 
   * expect(() => Injector.resolveAndCreate([A,B])).toThrowError();
   * ```
   */
  class NoAnnotationError extends BaseException {
    
    constructor(typeOrFunc: any, params: any[][]);
    
  }

    
  /**
   * Thrown when getting an object by index.
   * 
   * ### Example ([live demo](http://plnkr.co/edit/bRs0SX2OTQiJzqvjgl8P?p=preview))
   * 
   * ```typescript
   * class A {}
   * 
   * var injector = Injector.resolveAndCreate([A]);
   * 
   * expect(() => injector.getAt(100)).toThrowError();
   * ```
   */
  class OutOfBoundsError extends BaseException {
    
    constructor(index: any);
    
  }

    
  /**
   * Creates a token that can be used in a DI Provider.
   * 
   * ### Example ([live demo](http://plnkr.co/edit/Ys9ezXpj2Mnoy3Uc8KBp?p=preview))
   * 
   * ```typescript
   * var t = new OpaqueToken("value");
   * 
   * var injector = Injector.resolveAndCreate([
   *   provide(t, {useValue: "providedValue"})
   * ]);
   * 
   * expect(injector.get(t)).toEqual("bindingValue");
   * ```
   * 
   * Using an `OpaqueToken` is preferable to using strings as tokens because of possible collisions
   * caused by multiple providers using the same string as two different tokens.
   * 
   * Using an `OpaqueToken` is preferable to using an `Object` as tokens because it provides better
   * error messages.
   */
  class OpaqueToken {
    
    constructor(_desc: string);
    
    toString(): string;
    
  }

    
  /**
   * Factory for creating {@link InjectMetadata}.
   */
  interface InjectFactory {
    
    new(token: any): InjectMetadata;
    
    (token: any): any;
    
  }

    
  /**
   * Factory for creating {@link OptionalMetadata}.
   */
  interface OptionalFactory {
    
    new(): OptionalMetadata;
    
    (): any;
    
  }

    
  /**
   * Factory for creating {@link InjectableMetadata}.
   */
  interface InjectableFactory {
    
    new(): InjectableMetadata;
    
    (): any;
    
  }

    
  /**
   * Factory for creating {@link SelfMetadata}.
   */
  interface SelfFactory {
    
    new(): SelfMetadata;
    
    (): any;
    
  }

    
  /**
   * Factory for creating {@link HostMetadata}.
   */
  interface HostFactory {
    
    new(): HostMetadata;
    
    (): any;
    
  }

    
  /**
   * Factory for creating {@link SkipSelfMetadata}.
   */
  interface SkipSelfFactory {
    
    new(): SkipSelfMetadata;
    
    (): any;
    
  }

    
  /**
   * Factory for creating {@link InjectMetadata}.
   */
  var Inject: InjectFactory;
  

    
  /**
   * Factory for creating {@link OptionalMetadata}.
   */
  var Optional: OptionalFactory;
  

    
  /**
   * Factory for creating {@link InjectableMetadata}.
   */
  var Injectable: InjectableFactory;
  

    
  /**
   * Factory for creating {@link SelfMetadata}.
   */
  var Self: SelfFactory;
  

    
  /**
   * Factory for creating {@link HostMetadata}.
   */
  var Host: HostFactory;
  

    
  /**
   * Factory for creating {@link SkipSelfMetadata}.
   */
  var SkipSelf: SkipSelfFactory;
  

    
  /**
   * The `async` pipe subscribes to an Observable or Promise and returns the latest value it has
   * emitted.
   * When a new value is emitted, the `async` pipe marks the component to be checked for changes.
   * 
   * ### Example
   * The example below binds the `time` Observable to the view. Every 500ms, the `time` Observable
   * updates the view with the current time.
   * 
   * ```
   * import {Observable} from 'angular2/core';
   * @Component({
   *   selector: "task-cmp",
   *   template: "Time: {{ time | async }}"
   * })
   * class Task {
   *   time = new Observable<number>(observer => {
   *     setInterval(_ =>
   *       observer.next(new Date().getTime()), 500);
   *   });
   * }
   * ```
   */
  class AsyncPipe implements PipeTransform,  PipeOnDestroy {
    
    constructor(_ref: ChangeDetectorRef);
    
    onDestroy(): void;
    
    transform(obj: Observable | Promise<any>, args?: any[]): any;
    
  }

    
  /**
   * WARNING: this pipe uses the Internationalization API.
   * Therefore it is only reliable in Chrome and Opera browsers.
   * 
   * Formats a date value to a string based on the requested format.
   * 
   * ##Usage
   * 
   *     expression | date[:format]
   * 
   * where `expression` is a date object or a number (milliseconds since UTC epoch) and
   * `format` indicates which date/time components to include:
   * 
   *  | Component | Symbol | Short Form   | Long Form         | Numeric   | 2-digit   |
   *  |-----------|:------:|--------------|-------------------|-----------|-----------|
   *  | era       |   G    | G (AD)       | GGGG (Anno Domini)| -         | -         |
   *  | year      |   y    | -            | -                 | y (2015)  | yy (15)   |
   *  | month     |   M    | MMM (Sep)    | MMMM (September)  | M (9)     | MM (09)   |
   *  | day       |   d    | -            | -                 | d (3)     | dd (03)   |
   *  | weekday   |   E    | EEE (Sun)    | EEEE (Sunday)     | -         | -         |
   *  | hour      |   j    | -            | -                 | j (13)    | jj (13)   |
   *  | hour12    |   h    | -            | -                 | h (1 PM)  | hh (01 PM)|
   *  | hour24    |   H    | -            | -                 | H (13)    | HH (13)   |
   *  | minute    |   m    | -            | -                 | m (5)     | mm (05)   |
   *  | second    |   s    | -            | -                 | s (9)     | ss (09)   |
   *  | timezone  |   z    | -            | z (Pacific Standard Time)| -  | -         |
   *  | timezone  |   Z    | Z (GMT-8:00) | -                 | -         | -         |
   * 
   * In javascript, only the components specified will be respected (not the ordering,
   * punctuations, ...) and details of the formatting will be dependent on the locale.
   * On the other hand in Dart version, you can also include quoted text as well as some extra
   * date/time components such as quarter. For more information see:
   * https://api.dartlang.org/apidocs/channels/stable/dartdoc-viewer/intl/intl.DateFormat.
   * 
   * `format` can also be one of the following predefined formats:
   * 
   *  - `'medium'`: equivalent to `'yMMMdjms'` (e.g. Sep 3, 2010, 12:05:08 PM for en-US)
   *  - `'short'`: equivalent to `'yMdjm'` (e.g. 9/3/2010, 12:05 PM for en-US)
   *  - `'fullDate'`: equivalent to `'yMMMMEEEEd'` (e.g. Friday, September 3, 2010 for en-US)
   *  - `'longDate'`: equivalent to `'yMMMMd'` (e.g. September 3, 2010)
   *  - `'mediumDate'`: equivalent to `'yMMMd'` (e.g. Sep 3, 2010 for en-US)
   *  - `'shortDate'`: equivalent to `'yMd'` (e.g. 9/3/2010 for en-US)
   *  - `'mediumTime'`: equivalent to `'jms'` (e.g. 12:05:08 PM for en-US)
   *  - `'shortTime'`: equivalent to `'jm'` (e.g. 12:05 PM for en-US)
   * 
   * Timezone of the formatted text will be the local system timezone of the end-users machine.
   * 
   * ### Examples
   * 
   * Assuming `dateObj` is (year: 2015, month: 6, day: 15, hour: 21, minute: 43, second: 11)
   * in the _local_ time and locale is 'en-US':
   * 
   *     {{ dateObj | date }}               // output is 'Jun 15, 2015'
   *     {{ dateObj | date:'medium' }}      // output is 'Jun 15, 2015, 9:43:11 PM'
   *     {{ dateObj | date:'shortTime' }}   // output is '9:43 PM'
   *     {{ dateObj | date:'mmss' }}        // output is '43:11'
   */
  class DatePipe implements PipeTransform {
    
    transform(value: any, args: any[]): string;
    
    supports(obj: any): boolean;
    
  }

    
  let DEFAULT_PIPES: Provider;
  

    
  let DEFAULT_PIPES_TOKEN: OpaqueToken;
  

    
  /**
   * Implements json transforms to any object.
   * 
   * ### Example
   * 
   * In this example we transform the user object to json.
   * 
   *  ```
   * @Component({
   *   selector: "user-cmp",
   *   template: "User: {{ user | json }}"
   * })
   * class Username {
   *  user:Object
   *  constructor() {
   *    this.user = { name: "PatrickJS" };
   *  }
   * }
   * 
   * ```
   */
  class JsonPipe implements PipeTransform {
    
    transform(value: any, args?: any[]): string;
    
  }

    
  /**
   * Creates a new List or String containing only a subset (slice) of the
   * elements.
   * 
   * The starting index of the subset to return is specified by the `start` parameter.
   * 
   * The ending index of the subset to return is specified by the optional `end` parameter.
   * 
   * ##Usage
   * 
   *     expression | slice:start[:end]
   * 
   * All behavior is based on the expected behavior of the JavaScript API
   * Array.prototype.slice() and String.prototype.slice()
   * 
   * Where the input expression is a [List] or [String], and `start` is:
   * 
   * - **a positive integer**: return the item at _start_ index and all items after
   * in the list or string expression.
   * - **a negative integer**: return the item at _start_ index from the end and all items after
   * in the list or string expression.
   * - **`|start|` greater than the size of the expression**: return an empty list or string.
   * - **`|start|` negative greater than the size of the expression**: return entire list or
   * string expression.
   * 
   * and where `end` is:
   * 
   * - **omitted**: return all items until the end of the input
   * - **a positive integer**: return all items before _end_ index of the list or string
   * expression.
   * - **a negative integer**: return all items before _end_ index from the end of the list
   * or string expression.
   * 
   * When operating on a [List], the returned list is always a copy even when all
   * the elements are being returned.
   * 
   * ### Examples
   * 
   * ## List Example
   * 
   * Assuming `var collection = ['a', 'b', 'c', 'd']`, this `ng-for` directive:
   * 
   *     <li *ng-for="var i of collection | slice:1:3">{{i}}</li>
   * 
   * produces the following:
   * 
   *     <li>b</li>
   *     <li>c</li>
   * 
   * ## String Examples
   * 
   *     {{ 'abcdefghij' | slice:0:4 }}       // output is 'abcd'
   *     {{ 'abcdefghij' | slice:4:0 }}       // output is ''
   *     {{ 'abcdefghij' | slice:-4 }}      // output is 'ghij'
   *     {{ 'abcdefghij' | slice:-4,-2 }}      // output is 'gh'
   *     {{ 'abcdefghij' | slice: -100 }}    // output is 'abcdefghij'
   *     {{ 'abcdefghij' | slice: 100 }}    // output is ''
   */
  class SlicePipe implements PipeTransform {
    
    transform(value: any, args?: any[]): any;
    
    supports(obj: any): boolean;
    
  }

    
  /**
   * Implements lowercase transforms to text.
   * 
   * ### Example
   * 
   * In this example we transform the user text lowercase.
   * 
   *  ```
   * @Component({
   *   selector: "username-cmp",
   *   template: "Username: {{ user | lowercase }}"
   * })
   * class Username {
   *   user:string;
   * }
   * 
   * ```
   */
  class LowerCasePipe implements PipeTransform {
    
    transform(value: string, args?: any[]): string;
    
  }

    
  class NumberPipe {
    
  }

    
  /**
   * WARNING: this pipe uses the Internationalization API.
   * Therefore it is only reliable in Chrome and Opera browsers.
   * 
   * Formats a number as local text. i.e. group sizing and separator and other locale-specific
   * configurations are based on the active locale.
   * 
   * ##Usage
   * 
   *     expression | number[:digitInfo]
   * 
   * where `expression` is a number and `digitInfo` has the following format:
   * 
   *     {minIntegerDigits}.{minFractionDigits}-{maxFractionDigits}
   * 
   * - minIntegerDigits is the minimum number of integer digits to use. Defaults to 1.
   * - minFractionDigits is the minimum number of digits after fraction. Defaults to 0.
   * - maxFractionDigits is the maximum number of digits after fraction. Defaults to 3.
   * 
   * For more information on the acceptable range for each of these numbers and other
   * details see your native internationalization library.
   * 
   * ### Examples
   * 
   *     {{ 123 | number }}              // output is 123
   *     {{ 123.1 | number: '.2-3' }}    // output is 123.10
   *     {{ 1 | number: '2.2' }}         // output is 01.00
   */
  class DecimalPipe extends NumberPipe implements PipeTransform {
    
    transform(value: any, args: any[]): string;
    
  }

    
  /**
   * WARNING: this pipe uses the Internationalization API.
   * Therefore it is only reliable in Chrome and Opera browsers.
   * 
   * Formats a number as local percent.
   * 
   * ##Usage
   * 
   *     expression | percent[:digitInfo]
   * 
   * For more information about `digitInfo` see {@link DecimalPipe}
   */
  class PercentPipe extends NumberPipe implements PipeTransform {
    
    transform(value: any, args: any[]): string;
    
  }

    
  /**
   * WARNING: this pipe uses the Internationalization API.
   * Therefore it is only reliable in Chrome and Opera browsers.
   * 
   * Formats a number as local currency.
   * 
   * ##Usage
   * 
   *     expression | currency[:currencyCode[:symbolDisplay[:digitInfo]]]
   * 
   * where `currencyCode` is the ISO 4217 currency code, such as "USD" for the US dollar and
   * "EUR" for the euro. `symbolDisplay` is a boolean indicating whether to use the currency
   * symbol (e.g. $) or the currency code (e.g. USD) in the output. The default for this value
   * is `false`.
   * For more information about `digitInfo` see {@link DecimalPipe}
   */
  class CurrencyPipe extends NumberPipe implements PipeTransform {
    
    transform(value: any, args: any[]): string;
    
  }

    
  /**
   * Implements uppercase transforms to text.
   * 
   * ### Example
   * 
   * In this example we transform the user text uppercase.
   * 
   *  ```
   * @Component({
   *   selector: "username-cmp",
   *   template: "Username: {{ user | uppercase }}"
   * })
   * class Username {
   *   user:string;
   * }
   * 
   * ```
   */
  class UpperCasePipe implements PipeTransform {
    
    transform(value: string, args?: any[]): string;
    
  }

    
  interface ConcreteType extends Type {
    
    new(...args: any[]): any;
    
  }

    
  /**
   * 
   * Runtime representation a type that a Component or other object is instances of.
   * 
   * An example of a `Type` is `MyCustomComponent` class, which in JavaScript is be represented by
   * the `MyCustomComponent` constructor function.
   */
  interface Type extends Function {
    
  }

    
  class Observable {
    
    observer(generator: any): Object;
    
  }

    
  /**
   * Use by directives and components to emit custom Events.
   * 
   * ### Examples
   * 
   * In the following example, `Zippy` alternatively emits `open` and `close` events when its
   * title gets clicked:
   * 
   * ```
   * @Component({
   *   selector: 'zippy',
   *   template: `
   *   <div class="zippy">
   *     <div (click)="toggle()">Toggle</div>
   *     <div [hidden]="!visible">
   *       <ng-content></ng-content>
   *     </div>
   *  </div>`})
   * export class Zippy {
   *   visible: boolean = true;
   *   @Output() open: EventEmitter = new EventEmitter();
   *   @Output() close: EventEmitter = new EventEmitter();
   * 
   *   toggle() {
   *     this.visible = !this.visible;
   *     if (this.visible) {
   *       this.open.next(null);
   *     } else {
   *       this.close.next(null);
   *     }
   *   }
   * }
   * ```
   * 
   * Use Rx.Observable but provides an adapter to make it work as specified here:
   * https://github.com/jhusain/observable-spec
   * 
   * Once a reference implementation of the spec is available, switch to it.
   */
  class EventEmitter extends Observable {
    
    /**
     * Creates an instance of [EventEmitter], which depending on [isAsync],
     * delivers events synchronously or asynchronously.
     */
    constructor(isAsync?: boolean);
    
    observer(generator: any): any;
    
    toRx(): any;
    
    next(value: any): void;
    
    throw(error: any): void;
    
    return(value?: any): void;
    
  }

    
  interface Predicate<T> {
    
    (value: T, index?: number, array?: T[]): boolean;
    
  }

    
  class WrappedException extends Error {
    
    constructor(_wrapperMessage: string, _originalException: any, _originalStack?: any, _context?: any);
    
    wrapperMessage: string;
    
    wrapperStack: any;
    
    originalException: any;
    
    originalStack: any;
    
    context: any;
    
    message: string;
    
    toString(): string;
    
  }

    
  /**
   * An {@link angular2/di/OpaqueToken} representing the application root type in the {@link
   * Injector}.
   * 
   * ```
   * @Component(...)
   * class MyApp {
   *   ...
   * }
   * 
   * bootstrap(MyApp).then((appRef:ApplicationRef) {
   *   expect(appRef.injector.get(appComponentTypeToken)).toEqual(MyApp);
   * });
   * 
   * ```
   */
  let APP_COMPONENT: OpaqueToken;
  

    
  /**
   * A DI Token representing a unique string id assigned to the application by Angular and used
   * primarily for prefixing application attributes and CSS styles when
   * {@link ViewEncapsulation#Emulated} is being used.
   * 
   * If you need to avoid randomly generated value to be used as an application id, you can provide
   * a custom value via a DI provider <!-- TODO: provider --> configuring the root {@link Injector}
   * using this token.
   */
  let APP_ID: OpaqueToken;
  

    
  /**
   * Initialize the Angular 'platform' on the page.
   * 
   * See {@link PlatformRef} for details on the Angular platform.
   * 
   * ##Without specified providers
   * 
   * If no providers are specified, `platform`'s behavior depends on whether an existing
   * platform exists:
   * 
   * If no platform exists, a new one will be created with the default {@link platformProviders}.
   * 
   * If a platform already exists, it will be returned (regardless of what providers it
   * was created with). This is a convenience feature, allowing for multiple applications
   * to be loaded into the same platform without awareness of each other.
   * 
   * ##With specified providers
   * 
   * It is also possible to specify providers to be made in the new platform. These providers
   * will be shared between all applications on the page. For example, an abstraction for
   * the browser cookie jar should be bound at the platform level, because there is only one
   * cookie jar regardless of how many applications on the age will be accessing it.
   * 
   * If providers are specified directly, `platform` will create the Angular platform with
   * them if a platform did not exist already. If it did exist, however, an error will be
   * thrown.
   * 
   * ##DOM Applications
   * 
   * This version of `platform` initializes Angular to run in the UI thread, with direct
   * DOM access. Web-worker applications should call `platform` from
   * `src/web_workers/worker/application_common` instead.
   */
  function platform(providers?: Array<Type | Provider | any[]>): PlatformRef;
  

    
  /**
   * The Angular platform is the entry point for Angular on a web page. Each page
   * has exactly one platform, and services (such as reflection) which are common
   * to every Angular application running on the page are bound in its scope.
   * 
   * A page's platform is initialized implicitly when {@link bootstrap}() is called, or
   * explicitly by calling {@link platform}().
   */
  abstract class PlatformRef {
    
    /**
     * Register a listener to be called when the platform is disposed.
     */
    registerDisposeListener(dispose: () => void): void;
    
    /**
     * Retrieve the platform {@link Injector}, which is the parent injector for
     * every Angular application on the page and provides singleton providers.
     */
    injector: Injector;
    
    /**
     * Instantiate a new Angular application on the page.
     * 
     * ##What is an application?
     * 
     * Each Angular application has its own zone, change detection, compiler,
     * renderer, and other framework components. An application hosts one or more
     * root components, which can be initialized via `ApplicationRef.bootstrap()`.
     * 
     * ##Application Providers
     * 
     * Angular applications require numerous providers to be properly instantiated.
     * When using `application()` to create a new app on the page, these providers
     * must be provided. Fortunately, there are helper functions to configure
     * typical providers, as shown in the example below.
     * 
     * ### Example
     * ```
     * var myAppProviders = [MyAppService];
     * 
     * platform()
     *   .application([applicationCommonProviders(), applicationDomProviders(), myAppProviders])
     *   .bootstrap(MyTopLevelComponent);
     * ```
     * ##See Also
     * 
     * See the {@link bootstrap} documentation for more details.
     */
    application(providers: Array<Type | Provider | any[]>): ApplicationRef;
    
    /**
     * Instantiate a new Angular application on the page, using providers which
     * are only available asynchronously. One such use case is to initialize an
     * application running in a web worker.
     * 
     * ##Usage
     * 
     * `bindingFn` is a function that will be called in the new application's zone.
     * It should return a `Promise` to a list of providers to be used for the
     * new application. Once this promise resolves, the application will be
     * constructed in the same manner as a normal `application()`.
     */
    asyncApplication(bindingFn: (zone: NgZone) =>
                                    Promise<Array<Type | Provider | any[]>>): Promise<ApplicationRef>;
    
    /**
     * Destroy the Angular platform and all Angular applications on the page.
     */
    dispose(): void;
    
  }

    
  /**
   * A reference to an Angular application running on a page.
   * 
   * For more about Angular applications, see the documentation for {@link bootstrap}.
   */
  abstract class ApplicationRef {
    
    /**
     * Register a listener to be called each time `bootstrap()` is called to bootstrap
     * a new root component.
     */
    registerBootstrapListener(listener: (ref: ComponentRef) => void): void;
    
    /**
     * Register a listener to be called when the application is disposed.
     */
    registerDisposeListener(dispose: () => void): void;
    
    /**
     * Bootstrap a new component at the root level of the application.
     * 
     * ##Bootstrap process
     * 
     * When bootstrapping a new root component into an application, Angular mounts the
     * specified application component onto DOM elements identified by the [componentType]'s
     * selector and kicks off automatic change detection to finish initializing the component.
     * 
     * ##Optional Providers
     * 
     * Providers for the given component can optionally be overridden via the `providers`
     * parameter. These providers will only apply for the root component being added and any
     * child components under it.
     * 
     * ### Example
     * ```
     * var app = platform.application([applicationCommonProviders(), applicationDomProviders()];
     * app.bootstrap(FirstRootComponent);
     * app.bootstrap(SecondRootComponent, [provide(OverrideBinding, {useClass: OverriddenBinding})]);
     * ```
     */
    bootstrap(componentType: Type, providers?: Array<Type | Provider | any[]>): Promise<ComponentRef>;
    
    /**
     * Retrieve the application {@link Injector}.
     */
    injector: Injector;
    
    /**
     * Retrieve the application {@link NgZone}.
     */
    zone: NgZone;
    
    /**
     * Dispose of this application and all of its components.
     */
    dispose(): void;
    
    /**
     * Get a list of component types registered to this application.
     */
    componentTypes: Type[];
    
  }

    
  /**
   * Construct a default set of providers which should be included in any Angular
   * application, regardless of whether it runs on the UI thread or in a web worker.
   */
  function applicationCommonProviders(): Array<Type | Provider | any[]>;
  

    
  /**
   * Create an Angular zone.
   */
  function createNgZone(): NgZone;
  

    
  function platformCommon(providers?: Array<Type | Provider | any[]>, initializer?: () => void): PlatformRef;
  

    
  /**
   * Constructs the set of providers meant for use at the platform level.
   * 
   * These are providers that should be singletons shared among all Angular applications
   * running on the page.
   */
  function platformProviders(): Array<Type | Provider | any[]>;
  

    
  function bootstrap(appComponentType: /*Type*/ any, appProviders?: Array<Type | Provider | any[]>): Promise<ComponentRef>;
  

    
  /**
   * Specifies app root url for the application.
   * 
   * Used by the {@link Compiler} when resolving HTML and CSS template URLs.
   * 
   * This interface can be overridden by the application developer to create custom behavior.
   * 
   * See {@link Compiler}
   */
  class AppRootUrl {
    
    constructor(value: string);
    
    value: string;
    
  }

    
  /**
   * Used by the {@link Compiler} when resolving HTML and CSS template URLs.
   * 
   * This interface can be overridden by the application developer to create custom behavior.
   * 
   * See {@link Compiler}
   */
  class UrlResolver {
    
    /**
     * Resolves the `url` given the `baseUrl`:
     * - when the `url` is null, the `baseUrl` is returned,
     * - if `url` is relative ('path/to/here', './path/to/here'), the resolved url is a combination of
     * `baseUrl` and `url`,
     * - if `url` is absolute (it has a scheme: 'http://', 'https://' or start with '/'), the `url` is
     * returned as is (ignoring the `baseUrl`)
     * 
     * @param {string} baseUrl
     * @param {string} url
     * @returns {string} the resolved URL
     */
    resolve(baseUrl: string, url: string): string;
    
  }

    
  /**
   * A service that can be used to get and set the title of a current HTML document.
   * 
   * Since an Angular 2 application can't be bootstrapped on the entire HTML document (`<html>` tag)
   * it is not possible to bind to the `text` property of the `HTMLTitleElement` elements
   * (representing the `<title>` tag). Instead, this service can be used to set and get the current
   * title value.
   */
  class Title {
    
    /**
     * Get the title of the current HTML document.
     * @returns {string}
     */
    getTitle(): string;
    
    /**
     * Set the title of the current HTML document.
     * @param newTitle
     */
    setTitle(newTitle: string): void;
    
  }

    
  /**
   * Implement this interface to get notified when your directive's content has been fully
   * initialized.
   * 
   * ### Example ([live demo](http://plnkr.co/edit/plamXUpsLQbIXpViZhUO?p=preview))
   * 
   * ```typescript
   * @Component({
   *   selector: 'child-cmp',
   *   template: `{{where}} child`
   * })
   * class ChildComponent {
   *   @Input() where: string;
   * }
   * 
   * @Component({
   *   selector: 'parent-cmp',
   *   template: `<ng-content></ng-content>`
   * })
   * class ParentComponent implements AfterContentInit {
   *   @ContentChild(ChildComponent) contentChild: ChildComponent;
   * 
   *   constructor() {
   *     // contentChild is not initialized yet
   *     console.log(this.getMessage(this.contentChild));
   *   }
   * 
   *   afterContentInit() {
   *     // contentChild is updated after the content has been checked
   *     console.log('AfterContentInit: ' + this.getMessage(this.contentChild));
   *   }
   * 
   *   private getMessage(cmp: ChildComponent): string {
   *     return cmp ? cmp.where + ' child' : 'no child';
   *   }
   * }
   * 
   * @Component({
   *   selector: 'app',
   *   template: `
   *     <parent-cmp>
   *       <child-cmp where="content"></child-cmp>
   *     </parent-cmp>`,
   *   directives: [ParentComponent, ChildComponent]
   * })
   * export class App {
   * }
   * 
   * bootstrap(App).catch(err => console.error(err));
   * ```
   */
  interface AfterContentInit {
    
    afterContentInit(): void;
    
  }

    
  /**
   * Implement this interface to get notified after every check of your directive's content.
   * 
   * ### Example ([live demo](http://plnkr.co/edit/tGdrytNEKQnecIPkD7NU?p=preview))
   * 
   * ```typescript
   * @Component({selector: 'child-cmp', template: `{{where}} child`})
   * class ChildComponent {
   *   @Input() where: string;
   * }
   * 
   * @Component({selector: 'parent-cmp', template: `<ng-content></ng-content>`})
   * class ParentComponent implements AfterContentChecked {
   *   @ContentChild(ChildComponent) contentChild: ChildComponent;
   * 
   *   constructor() {
   *     // contentChild is not initialized yet
   *     console.log(this.getMessage(this.contentChild));
   *   }
   * 
   *   afterContentChecked() {
   *     // contentChild is updated after the content has been checked
   *     console.log('AfterContentChecked: ' + this.getMessage(this.contentChild));
   *   }
   * 
   *   private getMessage(cmp: ChildComponent): string {
   *     return cmp ? cmp.where + ' child' : 'no child';
   *   }
   * }
   * 
   * @Component({
   *   selector: 'app',
   *   template: `
   *     <parent-cmp>
   *       <button (click)="hasContent = !hasContent">Toggle content child</button>
   *       <child-cmp *ng-if="hasContent" where="content"></child-cmp>
   *     </parent-cmp>`,
   *   directives: [NgIf, ParentComponent, ChildComponent]
   * })
   * export class App {
   *   hasContent = true;
   * }
   * 
   * bootstrap(App).catch(err => console.error(err));
   * ```
   */
  interface AfterContentChecked {
    
    afterContentChecked(): void;
    
  }

    
  /**
   * Implement this interface to get notified when your component's view has been fully initialized.
   * 
   * ### Example ([live demo](http://plnkr.co/edit/LhTKVMEM0fkJgyp4CI1W?p=preview))
   * 
   * ```typescript
   * @Component({selector: 'child-cmp', template: `{{where}} child`})
   * class ChildComponent {
   *   @Input() where: string;
   * }
   * 
   * @Component({
   *   selector: 'parent-cmp',
   *   template: `<child-cmp where="view"></child-cmp>`,
   *   directives: [ChildComponent]
   * })
   * class ParentComponent implements AfterViewInit {
   *   @ViewChild(ChildComponent) viewChild: ChildComponent;
   * 
   *   constructor() {
   *     // viewChild is not initialized yet
   *     console.log(this.getMessage(this.viewChild));
   *   }
   * 
   *   afterViewInit() {
   *     // viewChild is updated after the view has been initialized
   *     console.log('afterViewInit: ' + this.getMessage(this.viewChild));
   *   }
   * 
   *   private getMessage(cmp: ChildComponent): string {
   *     return cmp ? cmp.where + ' child' : 'no child';
   *   }
   * }
   * 
   * @Component({
   *   selector: 'app',
   *   template: `<parent-cmp></parent-cmp>`,
   *   directives: [ParentComponent]
   * })
   * export class App {
   * }
   * 
   * bootstrap(App).catch(err => console.error(err));
   * ```
   */
  interface AfterViewInit {
    
    afterViewInit(): void;
    
  }

    
  /**
   * Implement this interface to get notified after every check of your component's view.
   * 
   * ### Example ([live demo](http://plnkr.co/edit/0qDGHcPQkc25CXhTNzKU?p=preview))
   * 
   * ```typescript
   * @Component({selector: 'child-cmp', template: `{{where}} child`})
   * class ChildComponent {
   *   @Input() where: string;
   * }
   * 
   * @Component({
   *   selector: 'parent-cmp',
   *   template: `
   *     <button (click)="showView = !showView">Toggle view child</button>
   *     <child-cmp *ng-if="showView" where="view"></child-cmp>`,
   *   directives: [NgIf, ChildComponent]
   * })
   * class ParentComponent implements AfterViewChecked {
   *   @ViewChild(ChildComponent) viewChild: ChildComponent;
   *   showView = true;
   * 
   *   constructor() {
   *     // viewChild is not initialized yet
   *     console.log(this.getMessage(this.viewChild));
   *   }
   * 
   *   afterViewChecked() {
   *     // viewChild is updated after the view has been checked
   *     console.log('AfterViewChecked: ' + this.getMessage(this.viewChild));
   *   }
   * 
   *   private getMessage(cmp: ChildComponent): string {
   *     return cmp ? cmp.where + ' child' : 'no child';
   *   }
   * }
   * 
   * @Component({
   *   selector: 'app',
   *   template: `<parent-cmp></parent-cmp>`,
   *   directives: [ParentComponent]
   * })
   * export class App {
   * }
   * 
   * bootstrap(App).catch(err => console.error(err));
   * ```
   */
  interface AfterViewChecked {
    
    afterViewChecked(): void;
    
  }

    
  /**
   * Lifecycle hooks are guaranteed to be called in the following order:
   * - `OnChanges` (if any bindings have changed),
   * - `OnInit` (after the first check only),
   * - `DoCheck`,
   * - `AfterContentInit`,
   * - `AfterContentChecked`,
   * - `AfterViewInit`,
   * - `AfterViewChecked`,
   * - `OnDestroy` (at the very end before destruction)
   * Implement this interface to get notified when any data-bound property of your directive changes.
   * 
   * `onChanges` is called right after the data-bound properties have been checked and before view
   * and content children are checked if at least one of them has changed.
   * 
   * The `changes` parameter contains an entry for each of the changed data-bound property. The key is
   * the property name and the value is an instance of {@link SimpleChange}.
   * 
   * ### Example ([live example](http://plnkr.co/edit/AHrB6opLqHDBPkt4KpdT?p=preview)):
   * 
   * ```typescript
   * @Component({
   *   selector: 'my-cmp',
   *   template: `<p>myProp = {{myProp}}</p>`
   * })
   * class MyComponent implements OnChanges {
   *   @Input() myProp: any;
   * 
   *   onChanges(changes: {[propName: string]: SimpleChange}) {
   *     console.log('onChanges - myProp = ' + changes['myProp'].currentValue);
   *   }
   * }
   * 
   * @Component({
   *   selector: 'app',
   *   template: `
   *     <button (click)="value = value + 1">Change MyComponent</button>
   *     <my-cmp [my-prop]="value"></my-cmp>`,
   *   directives: [MyComponent]
   * })
   * export class App {
   *   value = 0;
   * }
   * 
   * bootstrap(App).catch(err => console.error(err));
   * ```
   */
  interface OnChanges {
    
    onChanges(changes: {[key: string]: SimpleChange}): void;
    
  }

    
  /**
   * Implement this interface to get notified when your directive is destroyed.
   * 
   * `onDestroy` callback is typically used for any custom cleanup that needs to occur when the
   * instance is destroyed
   * 
   * ### Example ([live example](http://plnkr.co/edit/1MBypRryXd64v4pV03Yn?p=preview))
   * 
   * ```typesript
   * @Component({
   *   selector: 'my-cmp',
   *   template: `<p>my-component</p>`
   * })
   * class MyComponent implements OnInit, OnDestroy {
   *   onInit() {
   *     console.log('onInit');
   *   }
   * 
   *   onDestroy() {
   *     console.log('onDestroy');
   *   }
   * }
   * 
   * @Component({
   *   selector: 'app',
   *   template: `
   *     <button (click)="hasChild = !hasChild">
   *       {{hasChild ? 'Destroy' : 'Create'}} MyComponent
   *     </button>
   *     <my-cmp *ng-if="hasChild"></my-cmp>`,
   *   directives: [MyComponent, NgIf]
   * })
   * export class App {
   *   hasChild = true;
   * }
   * 
   * bootstrap(App).catch(err => console.error(err));
   * * ```
   */
  interface OnDestroy {
    
    onDestroy(): void;
    
  }

    
  /**
   * Implement this interface to execute custom initialization logic after your directive's
   * data-bound properties have been initialized.
   * 
   * `onInit` is called right after the directive's data-bound properties have been checked for the
   * first time, and before any of its children have been checked. It is invoked only once when the
   * directive is instantiated.
   * 
   * ### Example ([live example](http://plnkr.co/edit/1MBypRryXd64v4pV03Yn?p=preview))
   * 
   * ```typescript
   * @Component({
   *   selector: 'my-cmp',
   *   template: `<p>my-component</p>`
   * })
   * class MyComponent implements OnInit, OnDestroy {
   *   onInit() {
   *     console.log('onInit');
   *   }
   * 
   *   onDestroy() {
   *     console.log('onDestroy');
   *   }
   * }
   * 
   * @Component({
   *   selector: 'app',
   *   template: `
   *     <button (click)="hasChild = !hasChild">
   *       {{hasChild ? 'Destroy' : 'Create'}} MyComponent
   *     </button>
   *     <my-cmp *ng-if="hasChild"></my-cmp>`,
   *   directives: [MyComponent, NgIf]
   * })
   * export class App {
   *   hasChild = true;
   * }
   * 
   * bootstrap(App).catch(err => console.error(err));
   *  ```
   */
  interface OnInit {
    
    onInit(): void;
    
  }

    
  /**
   * Implement this interface to override the default change detection algorithm for your directive.
   * 
   * `doCheck` gets called to check the changes in the directives instead of the default algorithm.
   * 
   * The default change detection algorithm looks for differences by comparing bound-property values
   * by reference across change detection runs. When `DoCheck` is implemented, the default algorithm
   * is disabled and `doCheck` is responsible for checking for changes.
   * 
   * Implementing this interface allows improving performance by using insights about the component,
   * its implementation and data types of its properties.
   * 
   * Note that a directive should not implement both `DoCheck` and {@link OnChanges} at the same time.
   * `onChanges` would not be called when a directive implements `DoCheck`. Reaction to the changes
   * have to be handled from within the `doCheck` callback.
   * 
   * Use {@link KeyValueDiffers} and {@link IterableDiffers} to add your custom check mechanisms.
   * 
   * ### Example ([live demo](http://plnkr.co/edit/QpnIlF0CR2i5bcYbHEUJ?p=preview))
   * 
   * In the following example `doCheck` uses an {@link IterableDiffers} to detect the updates to the
   * array `list`:
   * 
   * ```typescript
   * @Component({
   *   selector: 'custom-check',
   *   template: `
   *     <p>Changes:</p>
   *     <ul>
   *       <li *ng-for="#line of logs">{{line}}</li>
   *     </ul>`,
   *   directives: [NgFor]
   * })
   * class CustomCheckComponent implements DoCheck {
   *   @Input() list: any[];
   *   differ: any;
   *   logs = [];
   * 
   *   constructor(differs: IterableDiffers) {
   *     this.differ = differs.find([]).create(null);
   *   }
   * 
   *   doCheck() {
   *     var changes = this.differ.diff(this.list);
   * 
   *     if (changes) {
   *       changes.forEachAddedItem(r => this.logs.push('added ' + r.item));
   *       changes.forEachRemovedItem(r => this.logs.push('removed ' + r.item))
   *     }
   *   }
   * }
   * 
   * @Component({
   *   selector: 'app',
   *   template: `
   *     <button (click)="list.push(list.length)">Push</button>
   *     <button (click)="list.pop()">Pop</button>
   *     <custom-check [list]="list"></custom-check>`,
   *   directives: [CustomCheckComponent]
   * })
   * export class App {
   *   list = [];
   * }
   * ```
   */
  interface DoCheck {
    
    doCheck(): void;
    
  }

    
  class DirectiveResolver {
    
    /**
     * Return {@link DirectiveMetadata} for a given `Type`.
     */
    resolve(type: Type): DirectiveMetadata;
    
  }

    
  /**
   * Low-level service for compiling {@link Component}s into {@link ProtoViewRef ProtoViews}s, which
   * can later be used to create and render a Component instance.
   * 
   * Most applications should instead use higher-level {@link DynamicComponentLoader} service, which
   * both compiles and instantiates a Component.
   */
  abstract class Compiler {
    
    compileInHost(componentType: Type): Promise<ProtoViewRef>;
    
    clearCache(): void;
    
  }

    
  /**
   * Service exposing low level API for creating, moving and destroying Views.
   * 
   * Most applications should use higher-level abstractions like {@link DynamicComponentLoader} and
   * {@link ViewContainerRef} instead.
   */
  abstract class AppViewManager {
    
    /**
     * Returns a {@link ViewContainerRef} of the View Container at the specified location.
     */
    getViewContainer(location: ElementRef): ViewContainerRef;
    
    /**
     * Returns the {@link ElementRef} that makes up the specified Host View.
     */
    getHostElement(hostViewRef: HostViewRef): ElementRef;
    
    /**
     * Searches the Component View of the Component specified via `hostLocation` and returns the
     * {@link ElementRef} for the Element identified via a Variable Name `variableName`.
     * 
     * Throws an exception if the specified `hostLocation` is not a Host Element of a Component, or if
     * variable `variableName` couldn't be found in the Component View of this Component.
     */
    getNamedElementInComponentView(hostLocation: ElementRef, variableName: string): ElementRef;
    
    /**
     * Returns the component instance for the provided Host Element.
     */
    getComponent(hostLocation: ElementRef): any;
    
    /**
     * Creates an instance of a Component and attaches it to the first element in the global View
     * (usually DOM Document) that matches the component's selector or `overrideSelector`.
     * 
     * This as a low-level way to bootstrap an application and upgrade an existing Element to a
     * Host Element. Most applications should use {@link DynamicComponentLoader#loadAsRoot} instead.
     * 
     * The Component and its View are created based on the `hostProtoViewRef` which can be obtained
     * by compiling the component with {@link Compiler#compileInHost}.
     * 
     * Use {@link AppViewManager#destroyRootHostView} to destroy the created Component and it's Host
     * View.
     * 
     * ### Example
     * 
     * ```
     * @ng.Component({
     *   selector: 'child-component'
     * })
     * @ng.View({
     *   template: 'Child'
     * })
     * class ChildComponent {
     * 
     * }
     * 
     * @ng.Component({
     *   selector: 'my-app'
     * })
     * @ng.View({
     *   template: `
     *     Parent (<some-component></some-component>)
     *   `
     * })
     * class MyApp {
     *   viewRef: ng.ViewRef;
     * 
     *   constructor(public appViewManager: ng.AppViewManager, compiler: ng.Compiler) {
     *     compiler.compileInHost(ChildComponent).then((protoView: ng.ProtoViewRef) => {
     *       this.viewRef = appViewManager.createRootHostView(protoView, 'some-component', null);
     *     })
     *   }
     * 
     *   onDestroy() {
     *     this.appViewManager.destroyRootHostView(this.viewRef);
     *     this.viewRef = null;
     *   }
     * }
     * 
     * ng.bootstrap(MyApp);
     * ```
     */
    createRootHostView(hostProtoViewRef: ProtoViewRef, overrideSelector: string, injector: Injector): HostViewRef;
    
    /**
     * Destroys the Host View created via {@link AppViewManager#createRootHostView}.
     * 
     * Along with the Host View, the Component Instance as well as all nested View and Components are
     * destroyed as well.
     */
    destroyRootHostView(hostViewRef: HostViewRef): void;
    
    /**
     * Instantiates an Embedded View based on the {@link TemplateRef `templateRef`} and inserts it
     * into the View Container specified via `viewContainerLocation` at the specified `index`.
     * 
     * Returns the {@link ViewRef} for the newly created View.
     * 
     * This as a low-level way to create and attach an Embedded via to a View Container. Most
     * applications should used {@link ViewContainerRef#createEmbeddedView} instead.
     * 
     * Use {@link AppViewManager#destroyViewInContainer} to destroy the created Embedded View.
     */
    createEmbeddedViewInContainer(viewContainerLocation: ElementRef, index: number, templateRef: TemplateRef): ViewRef;
    
    /**
     * Instantiates a single {@link Component} and inserts its Host View into the View Container
     * found at `viewContainerLocation`. Within the container, the view will be inserted at position
     * specified via `index`.
     * 
     * The component is instantiated using its {@link ProtoViewRef `protoViewRef`} which can be
     * obtained via {@link Compiler#compileInHost}.
     * 
     * You can optionally specify `imperativelyCreatedInjector`, which configure the {@link Injector}
     * that will be created for the Host View.
     * 
     * Returns the {@link HostViewRef} of the Host View created for the newly instantiated Component.
     * 
     * Use {@link AppViewManager#destroyViewInContainer} to destroy the created Host View.
     */
    createHostViewInContainer(viewContainerLocation: ElementRef, index: number, protoViewRef: ProtoViewRef, imperativelyCreatedInjector: ResolvedProvider[]): HostViewRef;
    
    /**
     * Destroys an Embedded or Host View attached to a View Container at the specified `index`.
     * 
     * The View Container is located via `viewContainerLocation`.
     */
    destroyViewInContainer(viewContainerLocation: ElementRef, index: number): void;
    
    /**
     * See {@link AppViewManager#detachViewInContainer}.
     */
    attachViewInContainer(viewContainerLocation: ElementRef, index: number, viewRef: ViewRef): ViewRef;
    
    /**
     * See {@link AppViewManager#attachViewInContainer}.
     */
    detachViewInContainer(viewContainerLocation: ElementRef, index: number): ViewRef;
    
  }

    
  /**
   * An unmodifiable list of items that Angular keeps up to date when the state
   * of the application changes.
   * 
   * The type of object that {@link QueryMetadata} and {@link ViewQueryMetadata} provide.
   * 
   * Implements an iterable interface, therefore it can be used in both ES6
   * javascript `for (var i of items)` loops as well as in Angular templates with
   * `*ng-for="#i of myList"`.
   * 
   * Changes can be observed by subscribing to the changes `Observable`.
   * 
   * NOTE: In the future this class will implement an `Observable` interface.
   * 
   * ### Example ([live demo](http://plnkr.co/edit/RX8sJnQYl9FWuSCWme5z?p=preview))
   * ```javascript
   * @Component({...})
   * class Container {
   *   constructor(@Query(Item) items: QueryList<Item>) {
   *     items.changes.subscribe(_ => console.log(items.length));
   *   }
   * }
   * ```
   */
  class QueryList<T> {
    
    changes: Observable;
    
    length: number;
    
    first: T;
    
    last: T;
    
    /**
     * returns a new array with the passed in function applied to each element.
     */
    map<U>(fn: (item: T) => U): U[];
    
    /**
     * returns a filtered array.
     */
    filter(fn: (item: T) => boolean): T[];
    
    /**
     * returns a reduced value.
     */
    reduce<U>(fn: (acc: U, item: T) => U, init: U): U;
    
    /**
     * converts QueryList into an array
     */
    toArray(): T[];
    
    toString(): string;
    
  }

    
  /**
   * Service for instantiating a Component and attaching it to a View at a specified location.
   */
  abstract class DynamicComponentLoader {
    
    /**
     * Creates an instance of a Component `type` and attaches it to the first element in the
     * platform-specific global view that matches the component's selector.
     * 
     * In a browser the platform-specific global view is the main DOM Document.
     * 
     * If needed, the component's selector can be overridden via `overrideSelector`.
     * 
     * You can optionally provide `injector` and this {@link Injector} will be used to instantiate the
     * Component.
     * 
     * To be notified when this Component instance is destroyed, you can also optionally provide
     * `onDispose` callback.
     * 
     * Returns a promise for the {@link ComponentRef} representing the newly created Component.
     * 
     * ### Example
     * 
     * ```
     * @Component({
     *   selector: 'child-component',
     *   template: 'Child'
     * })
     * class ChildComponent {
     * }
     * 
     * @Component({
     *   selector: 'my-app',
     *   template: 'Parent (<child id="child"></child>)'
     * })
     * class MyApp {
     *   constructor(dcl: DynamicComponentLoader, injector: Injector) {
     *     dcl.loadAsRoot(ChildComponent, '#child', injector);
     *   }
     * }
     * 
     * bootstrap(MyApp);
     * ```
     * 
     * Resulting DOM:
     * 
     * ```
     * <my-app>
     *   Parent (
     *     <child id="child">Child</child>
     *   )
     * </my-app>
     * ```
     */
    loadAsRoot(type: Type, overrideSelector: string, injector: Injector, onDispose?: () => void): Promise<ComponentRef>;
    
    /**
     * Creates an instance of a Component and attaches it to a View Container located inside of the
     * Component View of another Component instance.
     * 
     * The targeted Component Instance is specified via its `hostLocation` {@link ElementRef}. The
     * location within the Component View of this Component Instance is specified via `anchorName`
     * Template Variable Name.
     * 
     * You can optionally provide `providers` to configure the {@link Injector} provisioned for this
     * Component Instance.
     * 
     * Returns a promise for the {@link ComponentRef} representing the newly created Component.
     * 
     * ### Example
     * 
     * ```
     * @Component({
     *   selector: 'child-component',
     *   template: 'Child'
     * })
     * class ChildComponent {
     * }
     * 
     * @Component({
     *   selector: 'my-app',
     *   template: 'Parent (<div #child></div>)'
     * })
     * class MyApp {
     *   constructor(dcl: DynamicComponentLoader, elementRef: ElementRef) {
     *     dcl.loadIntoLocation(ChildComponent, elementRef, 'child');
     *   }
     * }
     * 
     * bootstrap(MyApp);
     * ```
     * 
     * Resulting DOM:
     * 
     * ```
     * <my-app>
     *    Parent (
     *      <div #child="" class="ng-binding"></div>
     *      <child-component class="ng-binding">Child</child-component>
     *    )
     * </my-app>
     * ```
     */
    loadIntoLocation(type: Type, hostLocation: ElementRef, anchorName: string, providers?: ResolvedProvider[]): Promise<ComponentRef>;
    
    /**
     * Creates an instance of a Component and attaches it to the View Container found at the
     * `location` specified as {@link ElementRef}.
     * 
     * You can optionally provide `providers` to configure the {@link Injector} provisioned for this
     * Component Instance.
     * 
     * Returns a promise for the {@link ComponentRef} representing the newly created Component.
     * 
     * 
     * ### Example
     * 
     * ```
     * @Component({
     *   selector: 'child-component',
     *   template: 'Child'
     * })
     * class ChildComponent {
     * }
     * 
     * @Component({
     *   selector: 'my-app',
     *   template: 'Parent'
     * })
     * class MyApp {
     *   constructor(dcl: DynamicComponentLoader, elementRef: ElementRef) {
     *     dcl.loadNextToLocation(ChildComponent, elementRef);
     *   }
     * }
     * 
     * bootstrap(MyApp);
     * ```
     * 
     * Resulting DOM:
     * 
     * ```
     * <my-app>Parent</my-app>
     * <child-component>Child</child-component>
     * ```
     */
    loadNextToLocation(type: Type, location: ElementRef, providers?: ResolvedProvider[]): Promise<ComponentRef>;
    
  }

    
  /**
   * Represents a location in a View that has an injection, change-detection and render context
   * associated with it.
   * 
   * An `ElementRef` is created for each element in the Template that contains a Directive, Component
   * or data-binding.
   * 
   * An `ElementRef` is backed by a render-specific element. In the browser, this is usually a DOM
   * element.
   */
  abstract class ElementRef implements RenderElementRef {
    
    /**
     * The underlying native element or `null` if direct access to native elements is not supported
     * (e.g. when the application runs in a web worker).
     * 
     * <div class="callout is-critical">
     *   <header>Use with caution</header>
     *   <p>
     *    Use this API as the last resort when direct access to DOM is needed. Use templating and
     *    data-binding provided by Angular instead. Alternatively you take a look at {@link Renderer}
     *    which provides API that can safely be used even when direct access to native elements is not
     *    supported.
     *   </p>
     *   <p>
     *    Relying on direct DOM access creates tight coupling between your application and rendering
     *    layers which will make it impossible to separate the two and deploy your application into a
     *    web worker.
     *   </p>
     * </div>
     */
    nativeElement: any;
    
    renderView: RenderViewRef;
    
  }

    
  /**
   * Represents an Embedded Template that can be used to instantiate Embedded Views.
   * 
   * You can access a `TemplateRef`, in two ways. Via a directive placed on a `<template>` element (or
   * directive prefixed with `*`) and have the `TemplateRef` for this Embedded View injected into the
   * constructor of the directive using the `TemplateRef` Token. Alternatively you can query for the
   * `TemplateRef` from a Component or a Directive via {@link Query}.
   * 
   * To instantiate Embedded Views based on a Template, use
   * {@link ViewContainerRef#createEmbeddedView}, which will create the View and attach it to the
   * View Container.
   */
  abstract class TemplateRef {
    
    /**
     * The location in the View where the Embedded View logically belongs to.
     * 
     * The data-binding and injection contexts of Embedded Views created from this `TemplateRef`
     * inherit from the contexts of this location.
     * 
     * Typically new Embedded Views are attached to the View Container of this location, but in
     * advanced use-cases, the View can be attached to a different container while keeping the
     * data-binding and injection context from the original location.
     */
    elementRef: ElementRef;
    
    /**
     * Allows you to check if this Embedded Template defines Local Variable with name matching `name`.
     */
    hasLocal(name: string): boolean;
    
  }

    
  /**
   * Represents an Angular View.
   * 
   * <!-- TODO: move the next two paragraphs to the dev guide -->
   * A View is a fundamental building block of the application UI. It is the smallest grouping of
   * Elements which are created and destroyed together.
   * 
   * Properties of elements in a View can change, but the structure (number and order) of elements in
   * a View cannot. Changing the structure of Elements can only be done by inserting, moving or
   * removing nested Views via a {@link ViewContainer}. Each View can contain many View Containers.
   * <!-- /TODO -->
   * 
   * ### Example
   * 
   * Given this template...
   * 
   * ```
   * Count: {{items.length}}
   * <ul>
   *   <li *ng-for="var item of items">{{item}}</li>
   * </ul>
   * ```
   * 
   * ... we have two {@link ProtoViewRef}s:
   * 
   * Outer {@link ProtoViewRef}:
   * ```
   * Count: {{items.length}}
   * <ul>
   *   <template ng-for var-item [ng-for-of]="items"></template>
   * </ul>
   * ```
   * 
   * Inner {@link ProtoViewRef}:
   * ```
   *   <li>{{item}}</li>
   * ```
   * 
   * Notice that the original template is broken down into two separate {@link ProtoViewRef}s.
   * 
   * The outer/inner {@link ProtoViewRef}s are then assembled into views like so:
   * 
   * ```
   * <!-- ViewRef: outer-0 -->
   * Count: 2
   * <ul>
   *   <template view-container-ref></template>
   *   <!-- ViewRef: inner-1 --><li>first</li><!-- /ViewRef: inner-1 -->
   *   <!-- ViewRef: inner-2 --><li>second</li><!-- /ViewRef: inner-2 -->
   * </ul>
   * <!-- /ViewRef: outer-0 -->
   * ```
   */
  abstract class ViewRef implements HostViewRef {
    
    /**
     * Sets `value` of local variable called `variableName` in this View.
     */
    setLocal(variableName: string, value: any): void;
    
    changeDetectorRef: ChangeDetectorRef;
    
  }

    
  /**
   * Represents a View containing a single Element that is the Host Element of a {@link Component}
   * instance.
   * 
   * A Host View is created for every dynamically created Component that was compiled on its own (as
   * opposed to as a part of another Component's Template) via {@link Compiler#compileInHost} or one
   * of the higher-level APIs: {@link AppViewManager#createRootHostView},
   * {@link AppViewManager#createHostViewInContainer}, {@link ViewContainerRef#createHostView}.
   */
  interface HostViewRef {
    
  }

    
  /**
   * Represents an Angular ProtoView.
   * 
   * A ProtoView is a prototypical {@link ViewRef View} that is the result of Template compilation and
   * is used by Angular to efficiently create an instance of this View based on the compiled Template.
   * 
   * Most ProtoViews are created and used internally by Angular and you don't need to know about them,
   * except in advanced use-cases where you compile components yourself via the low-level
   * {@link Compiler#compileInHost} API.
   * 
   * 
   * ### Example
   * 
   * Given this template:
   * 
   * ```
   * Count: {{items.length}}
   * <ul>
   *   <li *ng-for="var item of items">{{item}}</li>
   * </ul>
   * ```
   * 
   * Angular desugars and compiles the template into two ProtoViews:
   * 
   * Outer ProtoView:
   * ```
   * Count: {{items.length}}
   * <ul>
   *   <template ng-for var-item [ng-for-of]="items"></template>
   * </ul>
   * ```
   * 
   * Inner ProtoView:
   * ```
   *   <li>{{item}}</li>
   * ```
   * 
   * Notice that the original template is broken down into two separate ProtoViews.
   */
  abstract class ProtoViewRef {
    
  }

    
  /**
   * Represents a container where one or more Views can be attached.
   * 
   * The container can contain two kinds of Views. Host Views, created by instantiating a
   * {@link Component} via {@link #createHostView}, and Embedded Views, created by instantiating an
   * {@link TemplateRef Embedded Template} via {@link #createEmbeddedView}.
   * 
   * The location of the View Container within the containing View is specified by the Anchor
   * `element`. Each View Container can have only one Anchor Element and each Anchor Element can only
   * have a single View Container.
   * 
   * Root elements of Views attached to this container become siblings of the Anchor Element in
   * the Rendered View.
   * 
   * To access a `ViewContainerRef` of an Element, you can either place a {@link Directive} injected
   * with `ViewContainerRef` on the Element, or you obtain it via
   * {@link AppViewManager#getViewContainer}.
   * 
   * <!-- TODO(i): we are also considering ElementRef#viewContainer api -->
   */
  abstract class ViewContainerRef {
    
    /**
     * Anchor element that specifies the location of this container in the containing View.
     * <!-- TODO: rename to anchorElement -->
     */
    element: ElementRef;
    
    /**
     * Destroys all Views in this container.
     */
    clear(): void;
    
    /**
     * Returns the {@link ViewRef} for the View located in this container at the specified index.
     */
    get(index: number): ViewRef;
    
    /**
     * Returns the number of Views currently attached to this container.
     */
    length: number;
    
    /**
     * Instantiates an Embedded View based on the {@link TemplateRef `templateRef`} and inserts it
     * into this container at the specified `index`.
     * 
     * If `index` is not specified, the new View will be inserted as the last View in the container.
     * 
     * Returns the {@link ViewRef} for the newly created View.
     */
    createEmbeddedView(templateRef: TemplateRef, index?: number): ViewRef;
    
    /**
     * Instantiates a single {@link Component} and inserts its Host View into this container at the
     * specified `index`.
     * 
     * The component is instantiated using its {@link ProtoViewRef `protoView`} which can be
     * obtained via {@link Compiler#compileInHost}.
     * 
     * If `index` is not specified, the new View will be inserted as the last View in the container.
     * 
     * You can optionally specify `dynamicallyCreatedProviders`, which configure the {@link Injector}
     * that will be created for the Host View.
     * 
     * Returns the {@link HostViewRef} of the Host View created for the newly instantiated Component.
     */
    createHostView(protoViewRef?: ProtoViewRef, index?: number, dynamicallyCreatedProviders?: ResolvedProvider[]): HostViewRef;
    
    /**
     * Inserts a View identified by a {@link ViewRef} into the container at the specified `index`.
     * 
     * If `index` is not specified, the new View will be inserted as the last View in the container.
     * 
     * Returns the inserted {@link ViewRef}.
     */
    insert(viewRef: ViewRef, index?: number): ViewRef;
    
    /**
     * Returns the index of the View, specified via {@link ViewRef}, within the current container or
     * `-1` if this container doesn't contain the View.
     */
    indexOf(viewRef: ViewRef): number;
    
    /**
     * Destroys a View attached to this container at the specified `index`.
     * 
     * If `index` is not specified, the last View in the container will be removed.
     */
    remove(index?: number): void;
    
    /**
     * Use along with {@link #insert} to move a View within the current container.
     * 
     * If the `index` param is omitted, the last {@link ViewRef} is detached.
     */
    detach(index?: number): ViewRef;
    
  }

    
  /**
   * Represents an instance of a Component created via {@link DynamicComponentLoader}.
   * 
   * `ComponentRef` provides access to the Component Instance as well other objects related to this
   * Component Instance and allows you to destroy the Component Instance via the {@link #dispose}
   * method.
   */
  abstract class ComponentRef {
    
    /**
     * The injector provided {@link DynamicComponentLoader#loadAsRoot}.
     * 
     * TODO(i): this api is useless and should be replaced by an injector retrieved from
     *     the HostElementRef, which is currently not possible.
     */
    injector: Injector;
    
    /**
     * Location of the Host Element of this Component Instance.
     */
    location: ElementRef;
    
    /**
     * The instance of the Component.
     */
    instance: any;
    
    /**
     * The user defined component type, represented via the constructor function.
     * 
     * <!-- TODO: customize wording for Dart docs -->
     */
    componentType: Type;
    
    /**
     * The {@link ViewRef} of the Host View of this Component instance.
     */
    hostView: HostViewRef;
    
    /**
     * Destroys the component instance and all of the data structures associated with it.
     * 
     * TODO(i): rename to destroy to be consistent with AppViewManager and ViewContainerRef
     */
    dispose(): void;
    
  }

    
  /**
   * Provides access to explicitly trigger change detection in an application.
   * 
   * By default, `Zone` triggers change detection in Angular on each virtual machine (VM) turn. When
   * testing, or in some
   * limited application use cases, a developer can also trigger change detection with the
   * `lifecycle.tick()` method.
   * 
   * Each Angular application has a single `LifeCycle` instance.
   * 
   * ### Example
   * 
   * This is a contrived example, since the bootstrap automatically runs inside of the `Zone`, which
   * invokes
   * `lifecycle.tick()` on your behalf.
   * 
   * ```javascript
   * bootstrap(MyApp).then((ref:ComponentRef) => {
   *   var lifeCycle = ref.injector.get(LifeCycle);
   *   var myApp = ref.instance;
   * 
   *   ref.doSomething();
   *   lifecycle.tick();
   * });
   * ```
   */
  abstract class LifeCycle {
    
    /**
     * Invoke this method to explicitly process change detection and its side-effects.
     * 
     *  In development mode, `tick()` also performs a second change detection cycle to ensure that no
     * further
     *  changes are detected. If additional changes are picked up during this second cycle, bindings
     * in
     * the app have
     *  side-effects that cannot be resolved in a single change detection pass. In this case, Angular
     * throws an error,
     *  since an Angular application can only have one change detection pass during which all change
     * detection must
     *  complete.
     */
    tick(): void;
    
  }

    
  /**
   * An injectable service for executing work inside or outside of the Angular zone.
   * 
   * The most common use of this service is to optimize performance when starting a work consisting of
   * one or more asynchronous tasks that don't require UI updates or error handling to be handled by
   * Angular. Such tasks can be kicked off via {@link #runOutsideAngular} and if needed, these tasks
   * can reenter the Angular zone via {@link #run}.
   * 
   * <!-- TODO: add/fix links to:
   *   - docs explaining zones and the use of zones in Angular and change-detection
   *   - link to runOutsideAngular/run (throughout this file!)
   *   -->
   * 
   * ### Example ([live demo](http://plnkr.co/edit/lY9m8HLy7z06vDoUaSN2?p=preview))
   * ```
   * import {Component, View, NgIf, NgZone} from 'angular2/angular2';
   * 
   * @Component({
   *   selector: 'ng-zone-demo'.
   *   template: `
   *     <h2>Demo: NgZone</h2>
   * 
   *     <p>Progress: {{progress}}%</p>
   *     <p *ng-if="progress >= 100">Done processing {{label}} of Angular zone!</p>
   * 
   *     <button (click)="processWithinAngularZone()">Process within Angular zone</button>
   *     <button (click)="processOutsideOfAngularZone()">Process outside of Angular zone</button>
   *   `,
   *   directives: [NgIf]
   * })
   * export class NgZoneDemo {
   *   progress: number = 0;
   *   label: string;
   * 
   *   constructor(private _ngZone: NgZone) {}
   * 
   *   // Loop inside the Angular zone
   *   // so the UI DOES refresh after each setTimeout cycle
   *   processWithinAngularZone() {
   *     this.label = 'inside';
   *     this.progress = 0;
   *     this._increaseProgress(() => console.log('Inside Done!'));
   *   }
   * 
   *   // Loop outside of the Angular zone
   *   // so the UI DOES NOT refresh after each setTimeout cycle
   *   processOutsideOfAngularZone() {
   *     this.label = 'outside';
   *     this.progress = 0;
   *     this._ngZone.runOutsideAngular(() => {
   *       this._increaseProgress(() => {
   *       // reenter the Angular zone and display done
   *       this._ngZone.run(() => {console.log('Outside Done!') });
   *     }}));
   *   }
   * 
   * 
   *   _increaseProgress(doneCallback: () => void) {
   *     this.progress += 1;
   *     console.log(`Current progress: ${this.progress}%`);
   * 
   *     if (this.progress < 100) {
   *       window.setTimeout(() => this._increaseProgress(doneCallback)), 10)
   *     } else {
   *       doneCallback();
   *     }
   *   }
   * }
   * ```
   */
  class NgZone {
    
    /**
     * @param {bool} enableLongStackTrace whether to enable long stack trace. They should only be
     *               enabled in development mode as they significantly impact perf.
     */
    constructor({enableLongStackTrace}: any);
    
    /**
     * Sets the zone hook that is called just before a browser task that is handled by Angular
     * executes.
     * 
     * The hook is called once per browser task that is handled by Angular.
     * 
     * Setting the hook overrides any previously set hook.
     * 
     * @deprecated this API will be removed in the future. Use `onTurnStart` instead.
     */
    overrideOnTurnStart(onTurnStartHook: ZeroArgFunction): void;
    
    /**
     * Notifies subscribers just before Angular event turn starts.
     * 
     * Emits an event once per browser task that is handled by Angular.
     */
    onTurnStart: /* Subject */ any;
    
    /**
     * Sets the zone hook that is called immediately after Angular zone is done processing the current
     * task and any microtasks scheduled from that task.
     * 
     * This is where we typically do change-detection.
     * 
     * The hook is called once per browser task that is handled by Angular.
     * 
     * Setting the hook overrides any previously set hook.
     * 
     * @deprecated this API will be removed in the future. Use `onTurnDone` instead.
     */
    overrideOnTurnDone(onTurnDoneHook: ZeroArgFunction): void;
    
    /**
     * Notifies subscribers immediately after Angular zone is done processing
     * the current turn and any microtasks scheduled from that turn.
     * 
     * Used by Angular as a signal to kick off change-detection.
     */
    onTurnDone: any;
    
    /**
     * Sets the zone hook that is called immediately after the `onTurnDone` callback is called and any
     * microstasks scheduled from within that callback are drained.
     * 
     * `onEventDoneFn` is executed outside Angular zone, which means that we will no longer attempt to
     * sync the UI with any model changes that occur within this callback.
     * 
     * This hook is useful for validating application state (e.g. in a test).
     * 
     * Setting the hook overrides any previously set hook.
     * 
     * @deprecated this API will be removed in the future. Use `onEventDone` instead.
     */
    overrideOnEventDone(onEventDoneFn: ZeroArgFunction, opt_waitForAsync?: boolean): void;
    
    /**
     * Notifies subscribers immediately after the final `onTurnDone` callback
     * before ending VM event.
     * 
     * This event is useful for validating application state (e.g. in a test).
     */
    onEventDone: any;
    
    /**
     * Whether there are any outstanding microtasks.
     */
    hasPendingMicrotasks: boolean;
    
    /**
     * Whether there are any outstanding timers.
     */
    hasPendingTimers: boolean;
    
    /**
     * Whether there are any outstanding asychnronous tasks of any kind that are
     * scheduled to run within Angular zone.
     * 
     * Useful as a signal of UI stability. For example, when a test reaches a
     * point when [hasPendingAsyncTasks] is `false` it might be a good time to run
     * test expectations.
     */
    hasPendingAsyncTasks: boolean;
    
    /**
     * Sets the zone hook that is called when an error is thrown in the Angular zone.
     * 
     * Setting the hook overrides any previously set hook.
     * 
     * @deprecated this API will be removed in the future. Use `onError` instead.
     */
    overrideOnErrorHandler(errorHandler: ErrorHandlingFn): void;
    
    onError: any;
    
    /**
     * Executes the `fn` function synchronously within the Angular zone and returns value returned by
     * the function.
     * 
     * Running functions via `run` allows you to reenter Angular zone from a task that was executed
     * outside of the Angular zone (typically started via {@link #runOutsideAngular}).
     * 
     * Any future tasks or microtasks scheduled from within this function will continue executing from
     * within the Angular zone.
     */
    run(fn: () => any): any;
    
    /**
     * Executes the `fn` function synchronously in Angular's parent zone and returns value returned by
     * the function.
     * 
     * Running functions via `runOutsideAngular` allows you to escape Angular's zone and do work that
     * doesn't trigger Angular change-detection or is subject to Angular's error handling.
     * 
     * Any future tasks or microtasks scheduled from within this function will continue executing from
     * outside of the Angular zone.
     * 
     * Use {@link #run} to reenter the Angular zone and do work that updates the application model.
     */
    runOutsideAngular(fn: () => any): any;
    
  }

    
  interface ZeroArgFunction {
    
    (): void;
    
  }

    
  interface ErrorHandlingFn {
    
    (error: any, stackTrace: any): void;
    
  }

    
  /**
   * Stores error information; delivered via [NgZone.onError] stream.
   */
  class NgZoneError {
    
    constructor(error: any, stackTrace: any);
    
    error: any;
    
    stackTrace: any;
    
  }

    
  /**
   * A dispatcher that relays all events that occur in a Render View.
   * 
   * Use {@link Renderer#setEventDispatcher} to register a dispatcher for a particular Render View.
   */
  interface RenderEventDispatcher {
    
    /**
     * Called when Event called `eventName` was triggered on an Element with an Event Binding for this
     * Event.
     * 
     * `elementIndex` specifies the depth-first index of the Element in the Render View.
     * 
     * `locals` is a map for local variable to value mapping that should be used when evaluating the
     * Event Binding expression.
     * 
     * Returns `false` if `preventDefault` should be called to stop the default behavior of the Event
     * in the Rendering Context.
     */
    dispatchRenderEvent(elementIndex: number, eventName: string, locals: Map<string, any>): boolean;
    
  }

    
  /**
   * Injectable service that provides a low-level interface for modifying the UI.
   * 
   * Use this service to bypass Angular's templating and make custom UI changes that can't be
   * expressed declaratively. For example if you need to set a property or an attribute whose name is
   * not statically known, use {@link #setElementProperty} or {@link #setElementAttribute}
   * respectively.
   * 
   * If you are implementing a custom renderer, you must implement this interface.
   * 
   * The default Renderer implementation is {@link DomRenderer}. Also see {@link WebWorkerRenderer}.
   */
  abstract class Renderer {
    
    /**
     * Registers a component template represented as arrays of {@link RenderTemplateCmd}s and styles
     * with the Renderer.
     * 
     * Once a template is registered it can be referenced via {@link RenderBeginComponentCmd} when
     * {@link #createProtoView creating Render ProtoView}.
     */
    registerComponentTemplate(templateId: number, commands: RenderTemplateCmd[], styles: string[], nativeShadow: boolean): void;
    
    /**
     * Creates a {@link RenderProtoViewRef} from an array of {@link RenderTemplateCmd}`s.
     */
    createProtoView(cmds: RenderTemplateCmd[]): RenderProtoViewRef;
    
    /**
     * Creates a Root Host View based on the provided `hostProtoViewRef`.
     * 
     * `fragmentCount` is the number of nested {@link RenderFragmentRef}s in this View. This parameter
     * is non-optional so that the renderer can create a result synchronously even when application
     * runs in a different context (e.g. in a Web Worker).
     * 
     * `hostElementSelector` is a (CSS) selector for querying the main document to find the Host
     * Element. The newly created Root Host View should be attached to this element.
     * 
     * Returns an instance of {@link RenderViewWithFragments}, representing the Render View.
     */
    createRootHostView(hostProtoViewRef: RenderProtoViewRef, fragmentCount: number, hostElementSelector: string): RenderViewWithFragments;
    
    /**
     * Creates a Render View based on the provided `protoViewRef`.
     * 
     * `fragmentCount` is the number of nested {@link RenderFragmentRef}s in this View. This parameter
     * is non-optional so that the renderer can create a result synchronously even when application
     * runs in a different context (e.g. in a Web Worker).
     * 
     * Returns an instance of {@link RenderViewWithFragments}, representing the Render View.
     */
    createView(protoViewRef: RenderProtoViewRef, fragmentCount: number): RenderViewWithFragments;
    
    /**
     * Destroys a Render View specified via `viewRef`.
     * 
     * This operation should be performed only on a View that has already been dehydrated and
     * all of its Render Fragments have been detached.
     * 
     * Destroying a View indicates to the Renderer that this View is not going to be referenced in any
     * future operations. If the Renderer created any renderer-specific objects for this View, these
     * objects should now be destroyed to prevent memory leaks.
     */
    destroyView(viewRef: RenderViewRef): void;
    
    /**
     * Attaches the Nodes of a Render Fragment after the last Node of `previousFragmentRef`.
     */
    attachFragmentAfterFragment(previousFragmentRef: RenderFragmentRef, fragmentRef: RenderFragmentRef): void;
    
    /**
     * Attaches the Nodes of the Render Fragment after an Element.
     */
    attachFragmentAfterElement(elementRef: RenderElementRef, fragmentRef: RenderFragmentRef): void;
    
    /**
     * Detaches the Nodes of a Render Fragment from their parent.
     * 
     * This operations should be called only on a View that has been already
     * {@link #dehydrateView dehydrated}.
     */
    detachFragment(fragmentRef: RenderFragmentRef): void;
    
    /**
     * Notifies a custom Renderer to initialize a Render View.
     * 
     * This method is called by Angular after a Render View has been created, or when a previously
     * dehydrated Render View is about to be reused.
     */
    hydrateView(viewRef: RenderViewRef): void;
    
    /**
     * Notifies a custom Renderer that a Render View is no longer active.
     * 
     * This method is called by Angular before a Render View will be destroyed, or when a hydrated
     * Render View is about to be put into a pool for future reuse.
     */
    dehydrateView(viewRef: RenderViewRef): void;
    
    /**
     * Returns the underlying native element at the specified `location`, or `null` if direct access
     * to native elements is not supported (e.g. when the application runs in a web worker).
     * 
     * <div class="callout is-critical">
     *   <header>Use with caution</header>
     *   <p>
     *    Use this api as the last resort when direct access to DOM is needed. Use templating and
     *    data-binding, or other {@link Renderer} methods instead.
     *   </p>
     *   <p>
     *    Relying on direct DOM access creates tight coupling between your application and rendering
     *    layers which will make it impossible to separate the two and deploy your application into a
     *    web worker.
     *   </p>
     * </div>
     */
    getNativeElementSync(location: RenderElementRef): any;
    
    /**
     * Sets a property on the Element specified via `location`.
     */
    setElementProperty(location: RenderElementRef, propertyName: string, propertyValue: any): void;
    
    /**
     * Sets an attribute on the Element specified via `location`.
     * 
     * If `attributeValue` is `null`, the attribute is removed.
     */
    setElementAttribute(location: RenderElementRef, attributeName: string, attributeValue: string): void;
    
    /**
     * Sets a (CSS) class on the Element specified via `location`.
     * 
     * `isAdd` specifies if the class should be added or removed.
     */
    setElementClass(location: RenderElementRef, className: string, isAdd: boolean): void;
    
    /**
     * Sets a (CSS) inline style on the Element specified via `location`.
     * 
     * If `styleValue` is `null`, the style is removed.
     */
    setElementStyle(location: RenderElementRef, styleName: string, styleValue: string): void;
    
    /**
     * Calls a method on the Element specified via `location`.
     */
    invokeElementMethod(location: RenderElementRef, methodName: string, args: any[]): void;
    
    /**
     * Sets the value of an interpolated TextNode at the specified index to the `text` value.
     * 
     * `textNodeIndex` is the depth-first index of the Node among interpolated Nodes in the Render
     * View.
     */
    setText(viewRef: RenderViewRef, textNodeIndex: number, text: string): void;
    
    /**
     * Sets a dispatcher to relay all events triggered in the given Render View.
     * 
     * Each Render View can have only one Event Dispatcher, if this method is called multiple times,
     * the last provided dispatcher will be used.
     */
    setEventDispatcher(viewRef: RenderViewRef, dispatcher: RenderEventDispatcher): void;
    
  }

    
  /**
   * Represents an Element that is part of a {@link RenderViewRef Render View}.
   * 
   * `RenderElementRef` is a counterpart to {@link ElementRef} available in the Application Context.
   * 
   * When using `Renderer` from the Application Context, `ElementRef` can be used instead of
   * `RenderElementRef`.
   */
  interface RenderElementRef {
    
    /**
     * Reference to the Render View that contains this Element.
     */
    renderView: RenderViewRef;
    
  }

    
  /**
   * Represents an Angular View in the Rendering Context.
   * 
   * `RenderViewRef` specifies to the {@link Renderer} what View to update or destroy.
   * 
   * Unlike a {@link ViewRef} available in the Application Context, Render View contains all the
   * static Component Views that have been recursively merged into a single Render View.
   * 
   * Each `RenderViewRef` contains one or more {@link RenderFragmentRef Render Fragments}, these
   * Fragments are created, hydrated, dehydrated and destroyed as a single unit together with the
   * View.
   */
  class RenderViewRef {
    
  }

    
  /**
   * Represents an Angular ProtoView in the Rendering Context.
   * 
   * When you implement a custom {@link Renderer}, `RenderProtoViewRef` specifies what Render View
   * your renderer should create.
   * 
   * `RenderProtoViewRef` is a counterpart to {@link ProtoViewRef} available in the Application
   * Context. But unlike `ProtoViewRef`, `RenderProtoViewRef` contains all static nested Proto Views
   * that are recursively merged into a single Render Proto View.
   * 
   * 
   * <!-- TODO: this is created by Renderer#createProtoView in the new compiler -->
   */
  class RenderProtoViewRef {
    
  }

    
  /**
   * Represents a list of sibling Nodes that can be moved by the {@link Renderer} independently of
   * other Render Fragments.
   * 
   * Any {@link RenderView} has one Render Fragment.
   * 
   * Additionally any View with an Embedded View that contains a {@link NgContent View Projection}
   * results in additional Render Fragment.
   */
  class RenderFragmentRef {
    
  }

    
  /**
   * Container class produced by a {@link Renderer} when creating a Render View.
   * 
   * An instance of `RenderViewWithFragments` contains a {@link RenderViewRef} and an array of
   * {@link RenderFragmentRef}s belonging to this Render View.
   */
  class RenderViewWithFragments {
    
    constructor(viewRef: RenderViewRef, fragmentRefs: RenderFragmentRef[]);
    
    /**
     * Reference to the {@link RenderViewRef}.
     */
    viewRef: RenderViewRef;
    
    /**
     * Array of {@link RenderFragmentRef}s ordered in the depth-first order.
     */
    fragmentRefs: RenderFragmentRef[];
    
  }

    
  /**
   * A DI Token representing the main rendering context. In a browser this is the DOM Document.
   * 
   * Note: Document might not be available in the Application Context when Application and Rendering
   * Contexts are not the same (e.g. when running the application into a Web Worker).
   */
  let DOCUMENT: OpaqueToken;
  

    
  interface RenderTemplateCmd {
    
    visit(visitor: RenderCommandVisitor, context: any): any;
    
  }

    
  interface RenderCommandVisitor {
    
    visitText(cmd: RenderTextCmd, context: any): any;
    
    visitNgContent(cmd: RenderNgContentCmd, context: any): any;
    
    visitBeginElement(cmd: RenderBeginElementCmd, context: any): any;
    
    visitEndElement(context: any): any;
    
    visitBeginComponent(cmd: RenderBeginComponentCmd, context: any): any;
    
    visitEndComponent(context: any): any;
    
    visitEmbeddedTemplate(cmd: RenderEmbeddedTemplateCmd, context: any): any;
    
  }

    
  interface RenderTextCmd extends RenderBeginCmd {
    
    value: string;
    
  }

    
  interface RenderNgContentCmd {
    
    index: number;
    
    ngContentIndex: number;
    
  }

    
  interface RenderBeginElementCmd extends RenderBeginCmd {
    
    name: string;
    
    attrNameAndValues: string[];
    
    eventTargetAndNames: string[];
    
  }

    
  interface RenderBeginComponentCmd extends RenderBeginElementCmd {
    
    nativeShadow: boolean;
    
    templateId: number;
    
  }

    
  interface RenderEmbeddedTemplateCmd extends RenderBeginElementCmd {
    
    isMerged: boolean;
    
    children: RenderTemplateCmd[];
    
  }

    
  interface RenderBeginCmd extends RenderTemplateCmd {
    
    ngContentIndex: number;
    
    isBound: boolean;
    
  }

    
  /**
   * The `NgClass` directive conditionally adds and removes CSS classes on an HTML element based on
   * an expression's evaluation result.
   * 
   * The result of an expression evaluation is interpreted differently depending on type of
   * the expression evaluation result:
   * - `string` - all the CSS classes listed in a string (space delimited) are added
   * - `Array` - all the CSS classes (Array elements) are added
   * - `Object` - each key corresponds to a CSS class name while values are interpreted as expressions
   * evaluating to `Boolean`. If a given expression evaluates to `true` a corresponding CSS class
   * is added - otherwise it is removed.
   * 
   * While the `NgClass` directive can interpret expressions evaluating to `string`, `Array`
   * or `Object`, the `Object`-based version is the most often used and has an advantage of keeping
   * all the CSS class names in a template.
   * 
   * ### Example ([live demo](http://plnkr.co/edit/a4YdtmWywhJ33uqfpPPn?p=preview)):
   * 
   * ```
   * import {Component, NgClass} from 'angular2/angular2';
   * 
   * @Component({
   *   selector: 'toggle-button',
   *   inputs: ['isDisabled'],
   *   template: `
   *      <div class="button" [ng-class]="{active: isOn, disabled: isDisabled}"
   *          (click)="toggle(!isOn)">
   *          Click me!
   *      </div>`,
   *   styles: [`
   *     .button {
   *       width: 120px;
   *       border: medium solid black;
   *     }
   * 
   *     .active {
   *       background-color: red;
   *    }
   * 
   *     .disabled {
   *       color: gray;
   *       border: medium solid gray;
   *     }
   *   `]
   *   directives: [NgClass]
   * })
   * class ToggleButton {
   *   isOn = false;
   *   isDisabled = false;
   * 
   *   toggle(newState) {
   *     if (!this.isDisabled) {
   *       this.isOn = newState;
   *     }
   *   }
   * }
   * ```
   */
  class NgClass implements DoCheck,  OnDestroy {
    
    constructor(_iterableDiffers: IterableDiffers, _keyValueDiffers: KeyValueDiffers, _ngEl: ElementRef, _renderer: Renderer);
    
    initialClasses: any;
    
    rawClass: any;
    
    doCheck(): void;
    
    onDestroy(): void;
    
  }

    
  /**
   * The `NgFor` directive instantiates a template once per item from an iterable. The context for
   * each instantiated template inherits from the outer context with the given loop variable set
   * to the current item from the iterable.
   * 
   * It is possible to alias the `index` to a local variable that will be set to the current loop
   * iteration in the template context, and also to alias the 'last' to a local variable that will
   * be set to a boolean indicating if the item is the last one in the iteration
   * 
   * When the contents of the iterator changes, `NgFor` makes the corresponding changes to the DOM:
   * 
   * * When an item is added, a new instance of the template is added to the DOM.
   * * When an item is removed, its template instance is removed from the DOM.
   * * When items are reordered, their respective templates are reordered in the DOM.
   * 
   * ### Example
   * 
   * ```
   * <ul>
   *   <li *ng-for="#error of errors; #i = index">
   *     Error {{i}} of {{errors.length}}: {{error.message}}
   *   </li>
   * </ul>
   * ```
   * 
   * ##Syntax
   * 
   * - `<li *ng-for="#item of items; #i = index">...</li>`
   * - `<li template="ng-for #item of items; #i = index">...</li>`
   * - `<template ng-for #item [ng-for-of]="items" #i="index"><li>...</li></template>`
   */
  class NgFor implements DoCheck {
    
    constructor(_viewContainer: ViewContainerRef, _templateRef: TemplateRef, _iterableDiffers: IterableDiffers, _cdr: ChangeDetectorRef);
    
    ngForOf: any;
    
    ngForTemplate: any;
    
    doCheck(): void;
    
  }

    
  /**
   * Removes or recreates a portion of the DOM tree based on an {expression}.
   * 
   * If the expression assigned to `ng-if` evaluates to a false value then the element
   * is removed from the DOM, otherwise a clone of the element is reinserted into the DOM.
   * 
   * ### Example ([live demo](http://plnkr.co/edit/fe0kgemFBtmQOY31b4tw?p=preview)):
   * 
   * ```
   * <div *ng-if="errorCount > 0" class="error">
   *   <!-- Error message displayed when the errorCount property on the current context is greater
   * than 0. -->
   *   {{errorCount}} errors detected
   * </div>
   * ```
   * 
   * ##Syntax
   * 
   * - `<div *ng-if="condition">...</div>`
   * - `<div template="ng-if condition">...</div>`
   * - `<template [ng-if]="condition"><div>...</div></template>`
   */
  class NgIf {
    
    constructor(_viewContainer: ViewContainerRef, _templateRef: TemplateRef);
    
    ngIf: any;
    
  }

    
  /**
   * The `NgStyle` directive changes styles based on a result of expression evaluation.
   * 
   * An expression assigned to the `ng-style` property must evaluate to an object and the
   * corresponding element styles are updated based on changes to this object. Style names to update
   * are taken from the object's keys, and values - from the corresponding object's values.
   * 
   * ##Syntax
   * 
   * - `<div [ng-style]="{'font-style': style}"></div>`
   * - `<div [ng-style]="styleExp"></div>` - here the `styleExp` must evaluate to an object
   * 
   * ### Example ([live demo](http://plnkr.co/edit/YamGS6GkUh9GqWNQhCyM?p=preview)):
   * 
   * ```
   * import {Component, NgStyle} from 'angular2/angular2';
   * 
   * @Component({
   *  selector: 'ng-style-example',
   *  template: `
   *    <h1 [ng-style]="{'font-style': style, 'font-size': size, 'font-weight': weight}">
   *      Change style of this text!
   *    </h1>
   * 
   *    <hr>
   * 
   *    <label>Italic: <input type="checkbox" (change)="changeStyle($event)"></label>
   *    <label>Bold: <input type="checkbox" (change)="changeWeight($event)"></label>
   *    <label>Size: <input type="text" [value]="size" (change)="size = $event.target.value"></label>
   *  `,
   *  directives: [NgStyle]
   * })
   * export class NgStyleExample {
   *    style = 'normal';
   *    weight = 'normal';
   *    size = '20px';
   * 
   *    changeStyle($event: any) {
   *      this.style = $event.target.checked ? 'italic' : 'normal';
   *    }
   * 
   *    changeWeight($event: any) {
   *      this.weight = $event.target.checked ? 'bold' : 'normal';
   *    }
   * }
   * ```
   * 
   * In this example the `font-style`, `font-size` and `font-weight` styles will be updated
   * based on the `style` property's value changes.
   */
  class NgStyle implements DoCheck {
    
    constructor(_differs: KeyValueDiffers, _ngEl: ElementRef, _renderer: Renderer);
    
    rawStyle: any;
    
    doCheck(): void;
    
  }

    
  /**
   * The `NgSwitch` directive is used to conditionally swap DOM structure on your template based on a
   * scope expression.
   * Elements within `NgSwitch` but without `NgSwitchWhen` or `NgSwitchDefault` directives will be
   * preserved at the location as specified in the template.
   * 
   * `NgSwitch` simply chooses nested elements and makes them visible based on which element matches
   * the value obtained from the evaluated expression. In other words, you define a container element
   * (where you place the directive), place an expression on the **`[ng-switch]="..."` attribute**),
   * define any inner elements inside of the directive and place a `[ng-switch-when]` attribute per
   * element.
   * The when attribute is used to inform NgSwitch which element to display when the expression is
   * evaluated. If a matching expression is not found via a when attribute then an element with the
   * default attribute is displayed.
   * 
   * ### Example
   * 
   * ```
   * <ANY [ng-switch]="expression">
   *   <template [ng-switch-when]="whenExpression1">...</template>
   *   <template [ng-switch-when]="whenExpression1">...</template>
   *   <template ng-switch-default>...</template>
   * </ANY>
   * ```
   */
  class NgSwitch {
    
    ngSwitch: any;
    
  }

    
  /**
   * Defines a case statement as an expression.
   * 
   * If multiple `NgSwitchWhen` match the `NgSwitch` value, all of them are displayed.
   * 
   * Example:
   * 
   * ```
   * // match against a context variable
   * <template [ng-switch-when]="contextVariable">...</template>
   * 
   * // match against a constant string
   * <template ng-switch-when="stringValue">...</template>
   * ```
   */
  class NgSwitchWhen {
    
    constructor(viewContainer: ViewContainerRef, templateRef: TemplateRef, _switch: NgSwitch);
    
    ngSwitchWhen: any;
    
  }

    
  /**
   * Defines a default case statement.
   * 
   * Default case statements are displayed when no `NgSwitchWhen` match the `ng-switch` value.
   * 
   * Example:
   * 
   * ```
   * <template ng-switch-default>...</template>
   * ```
   */
  class NgSwitchDefault {
    
    constructor(viewContainer: ViewContainerRef, templateRef: TemplateRef, sswitch: NgSwitch);
    
  }

    
  /**
   * A collection of Angular core directives that are likely to be used in each and every Angular
   * application.
   * 
   * This collection can be used to quickly enumerate all the built-in directives in the `directives`
   * property of the `@View` annotation.
   * 
   * ### Example ([live demo](http://plnkr.co/edit/yakGwpCdUkg0qfzX5m8g?p=preview))
   * 
   * Instead of writing:
   * 
   * ```typescript
   * import {NgClass, NgIf, NgFor, NgSwitch, NgSwitchWhen, NgSwitchDefault} from 'angular2/angular2';
   * import {OtherDirective} from './myDirectives';
   * 
   * @Component({
   *   selector: 'my-component',
   *   templateUrl: 'myComponent.html',
   *   directives: [NgClass, NgIf, NgFor, NgSwitch, NgSwitchWhen, NgSwitchDefault, OtherDirective]
   * })
   * export class MyComponent {
   *   ...
   * }
   * ```
   * one could import all the core directives at once:
   * 
   * ```typescript
   * import {CORE_DIRECTIVES} from 'angular2/angular2';
   * import {OtherDirective} from './myDirectives';
   * 
   * @Component({
   *   selector: 'my-component',
   *   templateUrl: 'myComponent.html',
   *   directives: [CORE_DIRECTIVES, OtherDirective]
   * })
   * export class MyComponent {
   *   ...
   * }
   * ```
   */
  let CORE_DIRECTIVES: Type[];
  

    
  var workaround_empty_observable_list_diff: any;
  

    
  abstract class AbstractControl {
    
    constructor(validator: Function);
    
    validator: Function;
    
    value: any;
    
    status: string;
    
    valid: boolean;
    
    /**
     * Returns the errors of this control.
     */
    errors: {[key: string]: any};
    
    /**
     * Returns the errors of the child controls.
     */
    controlsErrors: any;
    
    pristine: boolean;
    
    dirty: boolean;
    
    touched: boolean;
    
    untouched: boolean;
    
    valueChanges: Observable;
    
    pending: boolean;
    
    markAsTouched(): void;
    
    markAsDirty({onlySelf}?: {onlySelf?: boolean}): void;
    
    markAsPending({onlySelf}?: {onlySelf?: boolean}): void;
    
    setParent(parent: ControlGroup | ControlArray): void;
    
    updateValueAndValidity({onlySelf, emitEvent}?: {onlySelf?: boolean, emitEvent?: boolean}): void;
    
    /**
     * Sets errors on a control.
     * 
     * This is used when validations are run not automatically, but manually by the user.
     * 
     * Calling `setErrors` will also update the validity of the parent control.
     * 
     * ## Usage
     * 
     * ```
     * var login = new Control("someLogin");
     * login.setErrors({
     *   "notUnique": true
     * });
     * 
     * expect(login.valid).toEqual(false);
     * expect(login.errors).toEqual({"notUnique": true});
     * 
     * login.updateValue("someOtherLogin");
     * 
     * expect(login.valid).toEqual(true);
     * ```
     */
    setErrors(errors: {[key: string]: any}): void;
    
    find(path: Array<string | number>| string): AbstractControl;
    
    getError(errorCode: string, path?: string[]): any;
    
    hasError(errorCode: string, path?: string[]): boolean;
    
  }

    
  /**
   * Defines a part of a form that cannot be divided into other controls. `Control`s have values and
   * validation state, which is determined by an optional validation function.
   * 
   * `Control` is one of the three fundamental building blocks used to define forms in Angular, along
   * with {@link ControlGroup} and {@link ControlArray}.
   * 
   * ##Usage
   * 
   * By default, a `Control` is created for every `<input>` or other form component.
   * With {@link NgFormControl} or {@link NgFormModel} an existing {@link Control} can be
   * bound to a DOM element instead. This `Control` can be configured with a custom
   * validation function.
   * 
   * ### Example ([live demo](http://plnkr.co/edit/23DESOpbNnBpBHZt1BR4?p=preview))
   */
  class Control extends AbstractControl {
    
    constructor(value?: any, validator?: Function);
    
    /**
     * Set the value of the control to `value`.
     * 
     * If `onlySelf` is `true`, this change will only affect the validation of this `Control`
     * and not its parent component. If `emitEvent` is `true`, this change will cause a
     * `valueChanges` event on the `Control` to be emitted. Both of these options default to
     * `false`.
     * 
     * If `emitModelToViewChange` is `true`, the view will be notified about the new value
     * via an `onChange` event. This is the default behavior if `emitModelToViewChange` is not
     * specified.
     */
    updateValue(value: any, {onlySelf, emitEvent, emitModelToViewChange}?: {
        onlySelf?: boolean,
        emitEvent?: boolean,
        emitModelToViewChange?: boolean
      }): void;
    
    /**
     * Register a listener for change events.
     */
    registerOnChange(fn: Function): void;
    
  }

    
  /**
   * Defines a part of a form, of fixed length, that can contain other controls.
   * 
   * A `ControlGroup` aggregates the values and errors of each {@link Control} in the group. Thus, if
   * one of the controls in a group is invalid, the entire group is invalid. Similarly, if a control
   * changes its value, the entire group changes as well.
   * 
   * `ControlGroup` is one of the three fundamental building blocks used to define forms in Angular,
   * along with {@link Control} and {@link ControlArray}. {@link ControlArray} can also contain other
   * controls, but is of variable length.
   * 
   * ### Example ([live demo](http://plnkr.co/edit/23DESOpbNnBpBHZt1BR4?p=preview))
   */
  class ControlGroup extends AbstractControl {
    
    constructor(controls: {[key: string]: AbstractControl}, optionals?: {[key: string]: boolean}, validator?: Function);
    
    controls: {[key: string]: AbstractControl};
    
    addControl(name: string, control: AbstractControl): void;
    
    removeControl(name: string): void;
    
    include(controlName: string): void;
    
    exclude(controlName: string): void;
    
    contains(controlName: string): boolean;
    
  }

    
  /**
   * Defines a part of a form, of variable length, that can contain other controls.
   * 
   * A `ControlArray` aggregates the values and errors of each {@link Control} in the group. Thus, if
   * one of the controls in a group is invalid, the entire group is invalid. Similarly, if a control
   * changes its value, the entire group changes as well.
   * 
   * `ControlArray` is one of the three fundamental building blocks used to define forms in Angular,
   * along with {@link Control} and {@link ControlGroup}. {@link ControlGroup} can also contain
   * other controls, but is of fixed length.
   * 
   * ##Adding or removing controls
   * 
   * To change the controls in the array, use the `push`, `insert`, or `removeAt` methods
   * in `ControlArray` itself. These methods ensure the controls are properly tracked in the
   * form's hierarchy. Do not modify the array of `AbstractControl`s used to instantiate
   * the `ControlArray` directly, as that will result in strange and unexpected behavior such
   * as broken change detection.
   * 
   * ### Example ([live demo](http://plnkr.co/edit/23DESOpbNnBpBHZt1BR4?p=preview))
   */
  class ControlArray extends AbstractControl {
    
    constructor(controls: AbstractControl[], validator?: Function);
    
    controls: AbstractControl[];
    
    /**
     * Get the {@link AbstractControl} at the given `index` in the array.
     */
    at(index: number): AbstractControl;
    
    /**
     * Insert a new {@link AbstractControl} at the end of the array.
     */
    push(control: AbstractControl): void;
    
    /**
     * Insert a new {@link AbstractControl} at the given `index` in the array.
     */
    insert(index: number, control: AbstractControl): void;
    
    /**
     * Remove the control at the given `index` in the array.
     */
    removeAt(index: number): void;
    
    /**
     * Get the length of the control array.
     */
    length: number;
    
  }

    
  abstract class AbstractControlDirective {
    
    control: AbstractControl;
    
    value: any;
    
    valid: boolean;
    
    errors: {[key: string]: any};
    
    controlsErrors: any;
    
    pristine: boolean;
    
    dirty: boolean;
    
    touched: boolean;
    
    untouched: boolean;
    
    path: string[];
    
  }

    
  /**
   * An interface that {@link NgFormModel} and {@link NgForm} implement.
   * 
   * Only used by the forms module.
   */
  interface Form {
    
    addControl(dir: NgControl): void;
    
    removeControl(dir: NgControl): void;
    
    getControl(dir: NgControl): Control;
    
    addControlGroup(dir: NgControlGroup): void;
    
    removeControlGroup(dir: NgControlGroup): void;
    
    getControlGroup(dir: NgControlGroup): ControlGroup;
    
    updateModel(dir: NgControl, value: any): void;
    
  }

    
  /**
   * A directive that contains multiple {@link NgControl}.
   * 
   * Only used by the forms module.
   */
  class ControlContainer extends AbstractControlDirective {
    
    name: string;
    
    formDirective: Form;
    
    path: string[];
    
  }

    
  /**
   * Creates and binds a control with a specified name to a DOM element.
   * 
   * This directive can only be used as a child of {@link NgForm} or {@link NgFormModel}.
   * 
   * ### Example
   * 
   * In this example, we create the login and password controls.
   * We can work with each control separately: check its validity, get its value, listen to its
   * changes.
   * 
   *  ```
   * @Component({
   *      selector: "login-comp",
   *      directives: [FORM_DIRECTIVES],
   *      template: `
   *        <form #f="form" (submit)='onLogIn(f.value)'>
   *          Login <input type='text' ng-control='login' #l="form">
   *          <div *ng-if="!l.valid">Login is invalid</div>
   * 
   *          Password <input type='password' ng-control='password'>
   *          <button type='submit'>Log in!</button>
   *        </form>
   *      `})
   * class LoginComp {
   *  onLogIn(value): void {
   *    // value === {login: 'some login', password: 'some password'}
   *  }
   * }
   *  ```
   * 
   * We can also use ng-model to bind a domain model to the form.
   * 
   *  ```
   * @Component({
   *      selector: "login-comp",
   *      directives: [FORM_DIRECTIVES],
   *      template: `
   *        <form (submit)='onLogIn()'>
   *          Login <input type='text' ng-control='login' [(ng-model)]="credentials.login">
   *          Password <input type='password' ng-control='password'
   *                          [(ng-model)]="credentials.password">
   *          <button type='submit'>Log in!</button>
   *        </form>
   *      `})
   * class LoginComp {
   *  credentials: {login:string, password:string};
   * 
   *  onLogIn(): void {
   *    // this.credentials.login === "some login"
   *    // this.credentials.password === "some password"
   *  }
   * }
   *  ```
   */
  class NgControlName extends NgControl implements OnChanges, 
      OnDestroy {
    
    constructor(parent: ControlContainer, validators:
                      /* Array<Validator|Function> */ any[], valueAccessors: ControlValueAccessor[]);
    
    update: any;
    
    model: any;
    
    viewModel: any;
    
    onChanges(changes: {[key: string]: SimpleChange}): void;
    
    onDestroy(): void;
    
    viewToModelUpdate(newValue: any): void;
    
    path: string[];
    
    formDirective: any;
    
    validator: Function;
    
    control: Control;
    
  }

    
  /**
   * Binds an existing {@link Control} to a DOM element.
   * 
   * ### Example ([live demo](http://plnkr.co/edit/jcQlZ2tTh22BZZ2ucNAT?p=preview))
   * 
   * In this example, we bind the control to an input element. When the value of the input element
   * changes, the value of the control will reflect that change. Likewise, if the value of the
   * control changes, the input element reflects that change.
   * 
   *  ```typescript
   * @Component({
   *   selector: 'my-app',
   *   template: `
   *     <div>
   *       <h2>NgFormControl Example</h2>
   *       <form>
   *         <p>Element with existing control: <input type="text"
   * [ng-form-control]="loginControl"></p>
   *         <p>Value of existing control: {{loginControl.value}}</p>
   *       </form>
   *     </div>
   *   `,
   *   directives: [CORE_DIRECTIVES, FORM_DIRECTIVES]
   * })
   * export class App {
   *   loginControl: Control = new Control('');
   * }
   *  ```
   * 
   * ##ng-model
   * 
   * We can also use `ng-model` to bind a domain model to the form.
   * 
   * ### Example ([live demo](http://plnkr.co/edit/yHMLuHO7DNgT8XvtjTDH?p=preview))
   * 
   *  ```typescript
   * @Component({
   *      selector: "login-comp",
   *      directives: [FORM_DIRECTIVES],
   *      template: "<input type='text' [ng-form-control]='loginControl' [(ng-model)]='login'>"
   *      })
   * class LoginComp {
   *  loginControl: Control = new Control('');
   *  login:string;
   * }
   *  ```
   */
  class NgFormControl extends NgControl implements OnChanges {
    
    constructor(validators:
                      /* Array<Validator|Function> */ any[], valueAccessors: ControlValueAccessor[]);
    
    form: Control;
    
    update: any;
    
    model: any;
    
    viewModel: any;
    
    onChanges(changes: {[key: string]: SimpleChange}): void;
    
    path: string[];
    
    validator: Function;
    
    control: Control;
    
    viewToModelUpdate(newValue: any): void;
    
  }

    
  /**
   * Binds a domain model to a form control.
   * 
   * ##Usage
   * 
   * `ng-model` binds an existing domain model to a form control. For a
   * two-way binding, use `[(ng-model)]` to ensure the model updates in
   * both directions.
   * 
   * ### Example ([live demo](http://plnkr.co/edit/R3UX5qDaUqFO2VYR0UzH?p=preview))
   *  ```typescript
   * @Component({
   *      selector: "search-comp",
   *      directives: [FORM_DIRECTIVES],
   *      template: `<input type='text' [(ng-model)]="searchQuery">`
   *      })
   * class SearchComp {
   *  searchQuery: string;
   * }
   *  ```
   */
  class NgModel extends NgControl implements OnChanges {
    
    constructor(validators:
                      /* Array<Validator|Function> */ any[], valueAccessors: ControlValueAccessor[]);
    
    update: any;
    
    model: any;
    
    viewModel: any;
    
    onChanges(changes: {[key: string]: SimpleChange}): void;
    
    control: Control;
    
    path: string[];
    
    validator: Function;
    
    viewToModelUpdate(newValue: any): void;
    
  }

    
  /**
   * A base class that all control directive extend.
   * It binds a {@link Control} object to a DOM element.
   */
  abstract class NgControl extends AbstractControlDirective {
    
    name: string;
    
    valueAccessor: ControlValueAccessor;
    
    validator: Function;
    
    viewToModelUpdate(newValue: any): void;
    
  }

    
  /**
   * Creates and binds a control group to a DOM element.
   * 
   * This directive can only be used as a child of {@link NgForm} or {@link NgFormModel}.
   * 
   * ### Example
   * 
   * In this example, we create the credentials and personal control groups.
   * We can work with each group separately: check its validity, get its value, listen to its changes.
   * 
   *  ```
   * @Component({
   *      selector: "signup-comp",
   *      directives: [FORM_DIRECTIVES],
   *      template: `
   *              <form #f="form" (submit)='onSignUp(f.value)'>
   *                <div ng-control-group='credentials' #credentials="form">
   *                  Login <input type='text' ng-control='login'>
   *                  Password <input type='password' ng-control='password'>
   *                </div>
   *                <div *ng-if="!credentials.valid">Credentials are invalid</div>
   * 
   *                <div ng-control-group='personal'>
   *                  Name <input type='text' ng-control='name'>
   *                </div>
   *                <button type='submit'>Sign Up!</button>
   *              </form>
   *      `})
   * class SignupComp {
   *  onSignUp(value) {
   *    // value === {
   *    //  personal: {name: 'some name'},
   *    //  credentials: {login: 'some login', password: 'some password'}}
   *  }
   * }
   * 
   *  ```
   */
  class NgControlGroup extends ControlContainer implements OnInit, 
      OnDestroy {
    
    constructor(parent: ControlContainer, validators: Function[]);
    
    onInit(): void;
    
    onDestroy(): void;
    
    control: ControlGroup;
    
    path: string[];
    
    formDirective: Form;
    
    validator: Function;
    
  }

    
  /**
   * Binds an existing control group to a DOM element.
   * 
   * ### Example ([live demo](http://plnkr.co/edit/jqrVirudY8anJxTMUjTP?p=preview))
   * 
   * In this example, we bind the control group to the form element, and we bind the login and
   * password controls to the login and password elements.
   * 
   *  ```typescript
   * @Component({
   *   selector: 'my-app',
   *   template: `
   *     <div>
   *       <h2>NgFormModel Example</h2>
   *       <form [ng-form-model]="loginForm">
   *         <p>Login: <input type="text" ng-control="login"></p>
   *         <p>Password: <input type="password" ng-control="password"></p>
   *       </form>
   *       <p>Value:</p>
   *       <pre>{{value}}</pre>
   *     </div>
   *   `,
   *   directives: [FORM_DIRECTIVES]
   * })
   * export class App {
   *   loginForm: ControlGroup;
   * 
   *   constructor() {
   *     this.loginForm = new ControlGroup({
   *       login: new Control(""),
   *       password: new Control("")
   *     });
   *   }
   * 
   *   get value(): string {
   *     return JSON.stringify(this.loginForm.value, null, 2);
   *   }
   * }
   *  ```
   * 
   * We can also use ng-model to bind a domain model to the form.
   * 
   *  ```typescript
   * @Component({
   *      selector: "login-comp",
   *      directives: [FORM_DIRECTIVES],
   *      template: `
   *        <form [ng-form-model]='loginForm'>
   *          Login <input type='text' ng-control='login' [(ng-model)]='credentials.login'>
   *          Password <input type='password' ng-control='password'
   *                          [(ng-model)]='credentials.password'>
   *          <button (click)="onLogin()">Login</button>
   *        </form>`
   *      })
   * class LoginComp {
   *  credentials: {login: string, password: string};
   *  loginForm: ControlGroup;
   * 
   *  constructor() {
   *    this.loginForm = new ControlGroup({
   *      login: new Control(""),
   *      password: new Control("")
   *    });
   *  }
   * 
   *  onLogin(): void {
   *    // this.credentials.login === 'some login'
   *    // this.credentials.password === 'some password'
   *  }
   * }
   *  ```
   */
  class NgFormModel extends ControlContainer implements Form, 
      OnChanges {
    
    constructor(validators: Function[]);
    
    form: ControlGroup;
    
    directives: NgControl[];
    
    ngSubmit: any;
    
    onChanges(changes: {[key: string]: SimpleChange}): void;
    
    formDirective: Form;
    
    control: ControlGroup;
    
    path: string[];
    
    addControl(dir: NgControl): void;
    
    getControl(dir: NgControl): Control;
    
    removeControl(dir: NgControl): void;
    
    addControlGroup(dir: NgControlGroup): void;
    
    removeControlGroup(dir: NgControlGroup): void;
    
    getControlGroup(dir: NgControlGroup): ControlGroup;
    
    updateModel(dir: NgControl, value: any): void;
    
    onSubmit(): boolean;
    
  }

    
  /**
   * If `NgForm` is bound in a component, `<form>` elements in that component will be
   * upgraded to use the Angular form system.
   * 
   * ##Typical Use
   * 
   * Include `FORM_DIRECTIVES` in the `directives` section of a {@link View} annotation
   * to use `NgForm` and its associated controls.
   * 
   * ##Structure
   * 
   * An Angular form is a collection of `Control`s in some hierarchy.
   * `Control`s can be at the top level or can be organized in `ControlGroup`s
   * or `ControlArray`s. This hierarchy is reflected in the form's `value`, a
   * JSON object that mirrors the form structure.
   * 
   * ##Submission
   * 
   * The `ng-submit` event signals when the user triggers a form submission.
   * 
   * ### Example ([live demo](http://plnkr.co/edit/ltdgYj4P0iY64AR71EpL?p=preview))
   * 
   *  ```typescript
   * @Component({
   *   selector: 'my-app',
   *   template: `
   *     <div>
   *       <p>Submit the form to see the data object Angular builds</p>
   *       <h2>NgForm demo</h2>
   *       <form #f="form" (ng-submit)="onSubmit(f.value)">
   *         <h3>Control group: credentials</h3>
   *         <div ng-control-group="credentials">
   *           <p>Login: <input type="text" ng-control="login"></p>
   *           <p>Password: <input type="password" ng-control="password"></p>
   *         </div>
   *         <h3>Control group: person</h3>
   *         <div ng-control-group="person">
   *           <p>First name: <input type="text" ng-control="firstName"></p>
   *           <p>Last name: <input type="text" ng-control="lastName"></p>
   *         </div>
   *         <button type="submit">Submit Form</button>
   *       <p>Form data submitted:</p>
   *       </form>
   *       <pre>{{data}}</pre>
   *     </div>
   * `,
   *   directives: [CORE_DIRECTIVES, FORM_DIRECTIVES]
   * })
   * export class App {
   *   constructor() {}
   * 
   *   data: string;
   * 
   *   onSubmit(data) {
   *     this.data = JSON.stringify(data, null, 2);
   *   }
   * }
   *  ```
   */
  class NgForm extends ControlContainer implements Form {
    
    constructor(validators: Function[]);
    
    form: ControlGroup;
    
    ngSubmit: any;
    
    formDirective: Form;
    
    control: ControlGroup;
    
    path: string[];
    
    controls: {[key: string]: AbstractControl};
    
    addControl(dir: NgControl): void;
    
    getControl(dir: NgControl): Control;
    
    removeControl(dir: NgControl): void;
    
    addControlGroup(dir: NgControlGroup): void;
    
    removeControlGroup(dir: NgControlGroup): void;
    
    getControlGroup(dir: NgControlGroup): ControlGroup;
    
    updateModel(dir: NgControl, value: any): void;
    
    onSubmit(): boolean;
    
  }

    
  /**
   * A bridge between a control and a native element.
   * 
   * Please see {@link DefaultValueAccessor} for more information.
   */
  interface ControlValueAccessor {
    
    writeValue(obj: any): void;
    
    registerOnChange(fn: any): void;
    
    registerOnTouched(fn: any): void;
    
  }

    
  /**
   * The default accessor for writing a value and listening to changes that is used by the
   * {@link NgModel}, {@link NgFormControl}, and {@link NgControlName} directives.
   * 
   *  ### Example
   *  ```
   *  <input type="text" [(ng-model)]="searchQuery">
   *  ```
   */
  class DefaultValueAccessor implements ControlValueAccessor {
    
    constructor(_renderer: Renderer, _elementRef: ElementRef);
    
    onChange: any;
    
    onTouched: any;
    
    writeValue(value: any): void;
    
    registerOnChange(fn: (_: any) => void): void;
    
    registerOnTouched(fn: () => void): void;
    
  }

    
  class NgControlStatus {
    
    constructor(cd: NgControl);
    
    ngClassUntouched: boolean;
    
    ngClassTouched: boolean;
    
    ngClassPristine: boolean;
    
    ngClassDirty: boolean;
    
    ngClassValid: boolean;
    
    ngClassInvalid: boolean;
    
  }

    
  /**
   * The accessor for writing a value and listening to changes on a checkbox input element.
   * 
   *  ### Example
   *  ```
   *  <input type="checkbox" [ng-control]="rememberLogin">
   *  ```
   */
  class CheckboxControlValueAccessor implements ControlValueAccessor {
    
    constructor(_renderer: Renderer, _elementRef: ElementRef);
    
    onChange: any;
    
    onTouched: any;
    
    writeValue(value: any): void;
    
    registerOnChange(fn: (_: any) => {}): void;
    
    registerOnTouched(fn: () => {}): void;
    
  }

    
  /**
   * Marks `<option>` as dynamic, so Angular can be notified when options change.
   * 
   * ### Example
   * 
   * ```
   * <select ng-control="city">
   *   <option *ng-for="#c of cities" [value]="c"></option>
   * </select>
   * ```
   */
  class NgSelectOption {
    
  }

    
  /**
   * The accessor for writing a value and listening to changes on a select element.
   */
  class SelectControlValueAccessor implements ControlValueAccessor {
    
    constructor(_renderer: Renderer, _elementRef: ElementRef, query: QueryList<NgSelectOption>);
    
    value: string;
    
    onChange: any;
    
    onTouched: any;
    
    writeValue(value: any): void;
    
    registerOnChange(fn: () => any): void;
    
    registerOnTouched(fn: () => any): void;
    
  }

    
  /**
   * A list of all the form directives used as part of a `@View` annotation.
   * 
   *  This is a shorthand for importing them each individually.
   * 
   * ### Example
   * 
   * ```typescript
   * @Component({
   *   selector: 'my-app',
   *   directives: [FORM_DIRECTIVES]
   * })
   * class MyApp {}
   * ```
   */
  let FORM_DIRECTIVES: Type[];
  

    
  let NG_VALIDATORS: OpaqueToken;
  

    
  /**
   * Provides a set of validators used by form controls.
   * 
   * ### Example
   * 
   * ```
   * var loginControl = new Control("", Validators.required)
   * ```
   */
  class Validators {
    
    static required(control:Control): {[key: string]: boolean};
    
    static minLength(minLength: number): Function;
    
    static maxLength(maxLength: number): Function;
    
    static nullValidator(c: any): {[key: string]: boolean};
    
    static compose(validators: Function[]): Function;
    
  }

    
  class RequiredValidator {
    
  }

    
  class MinLengthValidator implements Validator {
    
    constructor(minLength: string);
    
    validate(c: Control): {[key: string]: any};
    
  }

    
  class MaxLengthValidator implements Validator {
    
    constructor(minLength: string);
    
    validate(c: Control): {[key: string]: any};
    
  }

    
  /**
   * An interface that can be implemented by classes that can act as validators.
   * 
   * ## Usage
   * 
   * ```typescript
   * @Directive({
   *   selector: '[custom-validator]',
   *   providers: [provide(NG_VALIDATORS, {useExisting: CustomValidatorDirective, multi: true})]
   * })
   * class CustomValidatorDirective implements Validator {
   *   validate(c: Control): {[key: string]: any} {
   *     return {"custom": true};
   *   }
   * }
   * ```
   */
  interface Validator {
    
    validate(c:Control): {[key: string]: any};
    
  }

    
  /**
   * Creates a form object from a user-specified configuration.
   * 
   * ### Example
   * 
   * ```
   * import {Component, bootstrap} from 'angular2/angular2';
   * import {FormBuilder, Validators, FORM_DIRECTIVES, ControlGroup} from 'angular2/core';
   * 
   * @Component({
   *   selector: 'login-comp',
   *   viewProviders: [FormBuilder],
   *   template: `
   *     <form [control-group]="loginForm">
   *       Login <input control="login">
   * 
   *       <div control-group="passwordRetry">
   *         Password <input type="password" control="password">
   *         Confirm password <input type="password" control="passwordConfirmation">
   *       </div>
   *     </form>
   *   `,
   *   directives: [FORM_DIRECTIVES]
   * })
   * class LoginComp {
   *   loginForm: ControlGroup;
   * 
   *   constructor(builder: FormBuilder) {
   *     this.loginForm = builder.group({
   *       login: ["", Validators.required],
   * 
   *       passwordRetry: builder.group({
   *         password: ["", Validators.required],
   *         passwordConfirmation: ["", Validators.required]
   *       })
   *     });
   *   }
   * }
   * 
   * bootstrap(LoginComp);
   * ```
   * 
   * This example creates a {@link ControlGroup} that consists of a `login` {@link Control}, and a
   * nested {@link ControlGroup} that defines a `password` and a `passwordConfirmation`
   * {@link Control}:
   * 
   * ```
   *  var loginForm = builder.group({
   *    login: ["", Validators.required],
   * 
   *    passwordRetry: builder.group({
   *      password: ["", Validators.required],
   *      passwordConfirmation: ["", Validators.required]
   *    })
   *  });
   * 
   *  ```
   */
  class FormBuilder {
    
    group(controlsConfig: {[key: string]: any}, extra?: {[key: string]: any}): ControlGroup;
    
    control(value: Object, validator?: Function): Control;
    
    array(controlsConfig: any[], validator?: Function): ControlArray;
    
  }

    
  /**
   * Shorthand set of providers used for building Angular forms.
   * 
   * ### Example
   * 
   * ```typescript
   * bootstrap(MyApp, [FORM_PROVIDERS]);
   * ```
   */
  let FORM_PROVIDERS: Type[];
  

    
  /**
   * @deprecated
   */
  let FORM_BINDINGS: any;
  

    
  /**
   * A DebugElement contains information from the Angular compiler about an
   * element and provides access to the corresponding ElementInjector and
   * underlying DOM Element, as well as a way to query for children.
   */
  abstract class DebugElement {
    
    componentInstance: any;
    
    nativeElement: any;
    
    elementRef: ElementRef;
    
    getDirectiveInstance(directiveIndex: number): any;
    
    /**
     * Get child DebugElements from within the Light DOM.
     * 
     * @return {DebugElement[]}
     */
    children: DebugElement[];
    
    /**
     * Get the root DebugElement children of a component. Returns an empty
     * list if the current DebugElement is not a component root.
     * 
     * @return {DebugElement[]}
     */
    componentViewChildren: DebugElement[];
    
    triggerEventHandler(eventName: string, eventObj: Event): void;
    
    hasDirective(type: Type): boolean;
    
    inject(type: Type): any;
    
    getLocal(name: string): any;
    
    /**
     * Return the first descendant TestElement matching the given predicate
     * and scope.
     * 
     * @param {Function: boolean} predicate
     * @param {Scope} scope
     * 
     * @return {DebugElement}
     */
    query(predicate: Predicate<DebugElement>, scope?: Function): DebugElement;
    
    /**
     * Return descendant TestElememts matching the given predicate
     * and scope.
     * 
     * @param {Function: boolean} predicate
     * @param {Scope} scope
     * 
     * @return {DebugElement[]}
     */
    queryAll(predicate: Predicate<DebugElement>, scope?: Function): DebugElement[];
    
  }

    
  function asNativeElements(arr: DebugElement[]): any[];
  

    
  class By {
    
    static all(): Function;
    
    static css(selector: string): Predicate<DebugElement>;
    
    static directive(type: Type): Predicate<DebugElement>;
    
  }

    
  class Scope {
    
    static all(debugElement: DebugElement): DebugElement[];
    
    static light(debugElement: DebugElement): DebugElement[];
    
    static view(debugElement: DebugElement): DebugElement[];
    
  }

    
  /**
   * Returns a DebugElement for a ElementRef.
   * 
   * @param {ElementRef}: elementRef
   * @return {DebugElement}
   */
  function inspectElement(elementRef: ElementRef): DebugElement;
  

    
  function inspectNativeElement(element: any): DebugElement;
  

    
  let ELEMENT_PROBE_PROVIDERS: any[];
  

    
  let ELEMENT_PROBE_BINDINGS: any;
  

    
  enum ChangeDetectionStrategy {
    
    /**
     * `CheckedOnce` means that after calling detectChanges the mode of the change detector
     * will become `Checked`.
     */
    CheckOnce,
    
    /**
     * `Checked` means that the change detector should be skipped until its mode changes to
     * `CheckOnce`.
     */
    Checked,
    
    /**
     * `CheckAlways` means that after calling detectChanges the mode of the change detector
     * will remain `CheckAlways`.
     */
    CheckAlways,
    
    /**
     * `Detached` means that the change detector sub tree is not a part of the main tree and
     * should be skipped.
     */
    Detached,
    
    /**
     * `OnPush` means that the change detector's mode will be set to `CheckOnce` during hydration.
     */
    OnPush,
    
    /**
     * `Default` means that the change detector's mode will be set to `CheckAlways` during hydration.
     */
    Default,
    
    /**
     * This is an experimental feature. Works only in Dart.
     */
    OnPushObserve
  }
  

    
  /**
   * An error thrown if application changes model breaking the top-down data flow.
   * 
   * This exception is only thrown in dev mode.
   * 
   * <!-- TODO: Add a link once the dev mode option is configurable -->
   * 
   * ### Example
   * 
   * ```typescript
   * @Component({
   *   selector: 'parent',
   *   template: `
   *     <child [prop]="parentProp"></child>
   *   `,
   *   directives: [forwardRef(() => Child)]
   * })
   * class Parent {
   *   parentProp = "init";
   * }
   * 
   * @Directive({selector: 'child', inputs: ['prop']})
   * class Child {
   *   constructor(public parent: Parent) {}
   * 
   *   set prop(v) {
   *     // this updates the parent property, which is disallowed during change detection
   *     // this will result in ExpressionChangedAfterItHasBeenCheckedException
   *     this.parent.parentProp = "updated";
   *   }
   * }
   * ```
   */
  class ExpressionChangedAfterItHasBeenCheckedException extends BaseException {
    
    constructor(exp: string, oldValue: any, currValue: any, context: any);
    
  }

    
  /**
   * Thrown when an expression evaluation raises an exception.
   * 
   * This error wraps the original exception to attach additional contextual information that can
   * be useful for debugging.
   * 
   * ### Example ([live demo](http://plnkr.co/edit/2Kywoz?p=preview))
   * 
   * ```typescript
   * @Directive({selector: 'child', inputs: ['prop']})
   * class Child {
   *   prop;
   * }
   * 
   * @Component({
   *   selector: 'app',
   *   template: `
   *     <child [prop]="field.first"></child>
   *   `,
   *   directives: [Child]
   * })
   * class App {
   *   field = null;
   * }
   * 
   * bootstrap(App);
   * ```
   * 
   * You can access the original exception and stack through the `originalException` and
   * `originalStack` properties.
   */
  class ChangeDetectionError extends WrappedException {
    
    constructor(exp: string, originalException: any, originalStack: any, context: any);
    
    /**
     * Information about the expression that triggered the exception.
     */
    location: string;
    
  }

    
  abstract class ChangeDetectorRef {
    
    /**
     * Marks all {@link ChangeDetectionStrategy#OnPush} ancestors as to be checked.
     * 
     * <!-- TODO: Add a link to a chapter on OnPush components -->
     * 
     * ### Example ([live demo](http://plnkr.co/edit/GC512b?p=preview))
     * 
     * ```typescript
     * @Component({
     *   selector: 'cmp',
     *   changeDetection: ChangeDetectionStrategy.OnPush,
     *   template: `Number of ticks: {{numberOfTicks}}`
     * })
     * class Cmp {
     *   numberOfTicks = 0;
     * 
     *   constructor(ref: ChangeDetectorRef) {
     *     setInterval(() => {
     *       this.numberOfTicks ++
     *       // the following is required, otherwise the view will not be updated
     *       this.ref.markForCheck();
     *     }, 1000);
     *   }
     * }
     * 
     * @Component({
     *   selector: 'app',
     *   changeDetection: ChangeDetectionStrategy.OnPush,
     *   template: `
     *     <cmp><cmp>
     *   `,
     *   directives: [Cmp]
     * })
     * class App {
     * }
     * 
     * bootstrap(App);
     * ```
     */
    markForCheck(): void;
    
    /**
     * Detaches the change detector from the change detector tree.
     * 
     * The detached change detector will not be checked until it is reattached.
     * 
     * This can also be used in combination with {@link ChangeDetectorRef#detectChanges} to implement
     * local change
     * detection checks.
     * 
     * <!-- TODO: Add a link to a chapter on detach/reattach/local digest -->
     * <!-- TODO: Add a live demo once ref.detectChanges is merged into master -->
     * 
     * ### Example
     * 
     * The following example defines a component with a large list of readonly data.
     * Imagine the data changes constantly, many times per second. For performance reasons,
     * we want to check and update the list every five seconds. We can do that by detaching
     * the component's change detector and doing a local check every five seconds.
     * 
     * ```typescript
     * class DataProvider {
     *   // in a real application the returned data will be different every time
     *   get data() {
     *     return [1,2,3,4,5];
     *   }
     * }
     * 
     * @Component({
     *   selector: 'giant-list',
     *   template: `
     *     <li *ng-for="#d of dataProvider.data">Data {{d}}</lig>
     *   `,
     *   directives: [NgFor]
     * })
     * class GiantList {
     *   constructor(private ref: ChangeDetectorRef, private dataProvider:DataProvider) {
     *     ref.detach();
     *     setInterval(() => {
     *       this.ref.detectChanges();
     *     }, 5000);
     *   }
     * }
     * 
     * @Component({
     *   selector: 'app',
     *   providers: [DataProvider],
     *   template: `
     *     <giant-list><giant-list>
     *   `,
     *   directives: [GiantList]
     * })
     * class App {
     * }
     * 
     * bootstrap(App);
     * ```
     */
    detach(): void;
    
    /**
     * Checks the change detector and its children.
     * 
     * This can also be used in combination with {@link ChangeDetectorRef#detach} to implement local
     * change detection
     * checks.
     * 
     * <!-- TODO: Add a link to a chapter on detach/reattach/local digest -->
     * <!-- TODO: Add a live demo once ref.detectChanges is merged into master -->
     * 
     * ### Example
     * 
     * The following example defines a component with a large list of readonly data.
     * Imagine, the data changes constantly, many times per second. For performance reasons,
     * we want to check and update the list every five seconds.
     * 
     * We can do that by detaching the component's change detector and doing a local change detection
     * check
     * every five seconds.
     * 
     * See {@link detach} for more information.
     */
    detectChanges(): void;
    
    /**
     * Reattach the change detector to the change detector tree.
     * 
     * This also marks OnPush ancestors as to be checked. This reattached change detector will be
     * checked during the next change detection run.
     * 
     * <!-- TODO: Add a link to a chapter on detach/reattach/local digest -->
     * 
     * ### Example ([live demo](http://plnkr.co/edit/aUhZha?p=preview))
     * 
     * The following example creates a component displaying `live` data. The component will detach
     * its change detector from the main change detector tree when the component's live property
     * is set to false.
     * 
     * ```typescript
     * class DataProvider {
     *   data = 1;
     * 
     *   constructor() {
     *     setInterval(() => {
     *       this.data = this.data * 2;
     *     }, 500);
     *   }
     * }
     * 
     * @Component({
     *   selector: 'live-data',
     *   inputs: ['live'],
     *   template: `Data: {{dataProvider.data}}`
     * })
     * class LiveData {
     *   constructor(private ref: ChangeDetectorRef, private dataProvider:DataProvider) {}
     * 
     *   set live(value) {
     *     if (value)
     *       this.ref.reattach();
     *     else
     *       this.ref.detach();
     *   }
     * }
     * 
     * @Component({
     *   selector: 'app',
     *   providers: [DataProvider],
     *   template: `
     *     Live Update: <input type="checkbox" [(ng-model)]="live">
     *     <live-data [live]="live"><live-data>
     *   `,
     *   directives: [LiveData, FORM_DIRECTIVES]
     * })
     * class App {
     *   live = true;
     * }
     * 
     * bootstrap(App);
     * ```
     */
    reattach(): void;
    
  }

    
  /**
   * Indicates that the result of a {@link PipeMetadata} transformation has changed even though the
   * reference
   * has not changed.
   * 
   * The wrapped value will be unwrapped by change detection, and the unwrapped value will be stored.
   * 
   * Example:
   * 
   * ```
   * if (this._latestValue === this._latestReturnedValue) {
   *    return this._latestReturnedValue;
   *  } else {
   *    this._latestReturnedValue = this._latestValue;
   *    return WrappedValue.wrap(this._latestValue); // this will force update
   *  }
   * ```
   */
  class WrappedValue {
    
    constructor(wrapped: any);
    
    static wrap(value: any): WrappedValue;
    
    wrapped: any;
    
  }

    
  class SimpleChange {
    
    constructor(previousValue: any, currentValue: any);
    
    previousValue: any;
    
    currentValue: any;
    
    isFirstChange(): boolean;
    
  }

    
  /**
   * To create a Pipe, you must implement this interface.
   * 
   * Angular invokes the `transform` method with the value of a binding
   * as the first argument, and any parameters as the second argument in list form.
   * 
   * ## Syntax
   * 
   * `value | pipeName[:arg0[:arg1...]]`
   * 
   * ### Example ([live demo](http://plnkr.co/edit/f5oyIked9M2cKzvZNKHV?p=preview))
   * 
   * The `RepeatPipe` below repeats the value as many times as indicated by the first argument:
   * 
   * ```
   * import {Pipe, PipeTransform} from 'angular2/angular2';
   * 
   * @Pipe({name: 'repeat'})
   * export class RepeatPipe implements PipeTransform {
   *   transform(value: any, args: any[] = []) {
   *     if (args.length == 0) {
   *       throw new Error('repeat pipe requires one argument');
   *     }
   *     let times: number = args[0];
   *     return value.repeat(times);
   *   }
   * }
   * ```
   * 
   * Invoking `{{ 'ok' | repeat:3 }}` in a template produces `okokok`.
   */
  interface PipeTransform {
    
    transform(value: any, args: any[]): any;
    
  }

    
  /**
   * To create a stateful Pipe, you should implement this interface and set the `pure`
   * parameter to `false` in the {@link PipeMetadata}.
   * 
   * A stateful pipe may produce different output, given the same input. It is
   * likely that a stateful pipe may contain state that should be cleaned up when
   * a binding is destroyed. For example, a subscription to a stream of data may need to
   * be disposed, or an interval may need to be cleared.
   * 
   * ### Example ([live demo](http://plnkr.co/edit/i8pm5brO4sPaLxBx56MR?p=preview))
   * 
   * In this example, a pipe is created to countdown its input value, updating it every
   * 50ms. Because it maintains an internal interval, it automatically clears
   * the interval when the binding is destroyed or the countdown completes.
   * 
   * ```
   * import {Pipe, PipeTransform} from 'angular2/angular2'
   * @Pipe({name: 'countdown', pure: false})
   * class CountDown implements PipeTransform, PipeOnDestroy {
   *   remainingTime:Number;
   *   interval:SetInterval;
   *   onDestroy() {
   *     if (this.interval) {
   *       clearInterval(this.interval);
   *     }
   *   }
   *   transform(value: any, args: any[] = []) {
   *     if (!parseInt(value, 10)) return null;
   *     if (typeof this.remainingTime !== 'number') {
   *       this.remainingTime = parseInt(value, 10);
   *     }
   *     if (!this.interval) {
   *       this.interval = setInterval(() => {
   *         this.remainingTime-=50;
   *         if (this.remainingTime <= 0) {
   *           this.remainingTime = 0;
   *           clearInterval(this.interval);
   *           delete this.interval;
   *         }
   *       }, 50);
   *     }
   *     return this.remainingTime;
   *   }
   * }
   * ```
   * 
   * Invoking `{{ 10000 | countdown }}` would cause the value to be decremented by 50,
   * every 50ms, until it reaches 0.
   */
  interface PipeOnDestroy {
    
    onDestroy(): void;
    
  }

    
  /**
   * A repository of different iterable diffing strategies used by NgFor, NgClass, and others.
   */
  class IterableDiffers {
    
    constructor(factories: IterableDifferFactory[]);
    
    static create(factories: IterableDifferFactory[], parent?: IterableDiffers): IterableDiffers;
    
    /**
     * Takes an array of {@link IterableDifferFactory} and returns a provider used to extend the
     * inherited {@link IterableDiffers} instance with the provided factories and return a new
     * {@link IterableDiffers} instance.
     * 
     * The following example shows how to extend an existing list of factories,
     * which will only be applied to the injector for this component and its children.
     * This step is all that's required to make a new {@link IterableDiffer} available.
     * 
     * ### Example
     * 
     * ```
     * @Component({
     *   viewProviders: [
     *     IterableDiffers.extend([new ImmutableListDiffer()])
     *   ]
     * })
     * ```
     */
    static extend(factories: IterableDifferFactory[]): Provider;
    
    factories: IterableDifferFactory[];
    
    find(iterable: Object): IterableDifferFactory;
    
  }

    
  interface IterableDiffer {
    
    diff(object: Object): any;
    
    onDestroy(): void;
    
  }

    
  /**
   * Provides a factory for {@link IterableDiffer}.
   */
  interface IterableDifferFactory {
    
    supports(objects: Object): boolean;
    
    create(cdRef: ChangeDetectorRef): IterableDiffer;
    
  }

    
  /**
   * A repository of different Map diffing strategies used by NgClass, NgStyle, and others.
   */
  class KeyValueDiffers {
    
    constructor(factories: KeyValueDifferFactory[]);
    
    static create(factories: KeyValueDifferFactory[], parent?: KeyValueDiffers): KeyValueDiffers;
    
    /**
     * Takes an array of {@link KeyValueDifferFactory} and returns a provider used to extend the
     * inherited {@link KeyValueDiffers} instance with the provided factories and return a new
     * {@link KeyValueDiffers} instance.
     * 
     * The following example shows how to extend an existing list of factories,
     * which will only be applied to the injector for this component and its children.
     * This step is all that's required to make a new {@link KeyValueDiffer} available.
     * 
     * ### Example
     * 
     * ```
     * @Component({
     *   viewProviders: [
     *     KeyValueDiffers.extend([new ImmutableMapDiffer()])
     *   ]
     * })
     * ```
     */
    static extend(factories: KeyValueDifferFactory[]): Provider;
    
    factories: KeyValueDifferFactory[];
    
    find(kv: Object): KeyValueDifferFactory;
    
  }

    
  interface KeyValueDiffer {
    
    diff(object: Object): void;
    
    onDestroy(): void;
    
  }

    
  /**
   * Provides a factory for {@link KeyValueDiffer}.
   */
  interface KeyValueDifferFactory {
    
    supports(objects: Object): boolean;
    
    create(cdRef: ChangeDetectorRef): KeyValueDiffer;
    
  }

    
  /**
   * Create trace scope.
   * 
   * Scopes must be strictly nested and are analogous to stack frames, but
   * do not have to follow the stack frames. Instead it is recommended that they follow logical
   * nesting. You may want to use
   * [Event
   * Signatures](http://google.github.io/tracing-framework/instrumenting-code.html#custom-events)
   * as they are defined in WTF.
   * 
   * Used to mark scope entry. The return value is used to leave the scope.
   * 
   *     var myScope = wtfCreateScope('MyClass#myMethod(ascii someVal)');
   * 
   *     someMethod() {
   *        var s = myScope('Foo'); // 'Foo' gets stored in tracing UI
   *        // DO SOME WORK HERE
   *        return wtfLeave(s, 123); // Return value 123
   *     }
   * 
   * Note, adding try-finally block around the work to ensure that `wtfLeave` gets called can
   * negatively impact the performance of your application. For this reason we recommend that
   * you don't add them to ensure that `wtfLeave` gets called. In production `wtfLeave` is a noop and
   * so try-finally block has no value. When debugging perf issues, skipping `wtfLeave`, do to
   * exception, will produce incorrect trace, but presence of exception signifies logic error which
   * needs to be fixed before the app should be profiled. Add try-finally only when you expect that
   * an exception is expected during normal execution while profiling.
   */
  var wtfCreateScope: WtfScopeFn;
  

    
  /**
   * Used to mark end of Scope.
   * 
   * - `scope` to end.
   * - `returnValue` (optional) to be passed to the WTF.
   * 
   * Returns the `returnValue for easy chaining.
   */
  var wtfLeave: <T>(scope: any, returnValue?: T) => T;
  

    
  /**
   * Used to mark Async start. Async are similar to scope but they don't have to be strictly nested.
   * The return value is used in the call to [endAsync]. Async ranges only work if WTF has been
   * enabled.
   * 
   *     someMethod() {
   *        var s = wtfStartTimeRange('HTTP:GET', 'some.url');
   *        var future = new Future.delay(5).then((_) {
   *          wtfEndTimeRange(s);
   *        });
   *     }
   */
  var wtfStartTimeRange: (rangeType: string, action: string) => any;
  

    
  /**
   * Ends a async time range operation.
   * [range] is the return value from [wtfStartTimeRange] Async ranges only work if WTF has been
   * enabled.
   */
  var wtfEndTimeRange: (range: any) => void;
  

    
  interface WtfScopeFn {
    
    (arg0?: any, arg1?: any): any;
    
  }

  
}

declare module "angular2/angular2" {
  export = ng;
}



declare module ngWorker {  
  /**
   * A dispatcher that relays all events that occur in a Render View.
   * 
   * Use {@link Renderer#setEventDispatcher} to register a dispatcher for a particular Render View.
   */
  interface RenderEventDispatcher {
    
    /**
     * Called when Event called `eventName` was triggered on an Element with an Event Binding for this
     * Event.
     * 
     * `elementIndex` specifies the depth-first index of the Element in the Render View.
     * 
     * `locals` is a map for local variable to value mapping that should be used when evaluating the
     * Event Binding expression.
     * 
     * Returns `false` if `preventDefault` should be called to stop the default behavior of the Event
     * in the Rendering Context.
     */
    dispatchRenderEvent(elementIndex: number, eventName: string, locals: Map<string, any>): boolean;
    
  }

    
  /**
   * Injectable service that provides a low-level interface for modifying the UI.
   * 
   * Use this service to bypass Angular's templating and make custom UI changes that can't be
   * expressed declaratively. For example if you need to set a property or an attribute whose name is
   * not statically known, use {@link #setElementProperty} or {@link #setElementAttribute}
   * respectively.
   * 
   * If you are implementing a custom renderer, you must implement this interface.
   * 
   * The default Renderer implementation is {@link DomRenderer}. Also see {@link WebWorkerRenderer}.
   */
  abstract class Renderer {
    
    /**
     * Registers a component template represented as arrays of {@link RenderTemplateCmd}s and styles
     * with the Renderer.
     * 
     * Once a template is registered it can be referenced via {@link RenderBeginComponentCmd} when
     * {@link #createProtoView creating Render ProtoView}.
     */
    registerComponentTemplate(templateId: number, commands: RenderTemplateCmd[], styles: string[], nativeShadow: boolean): void;
    
    /**
     * Creates a {@link RenderProtoViewRef} from an array of {@link RenderTemplateCmd}`s.
     */
    createProtoView(cmds: RenderTemplateCmd[]): RenderProtoViewRef;
    
    /**
     * Creates a Root Host View based on the provided `hostProtoViewRef`.
     * 
     * `fragmentCount` is the number of nested {@link RenderFragmentRef}s in this View. This parameter
     * is non-optional so that the renderer can create a result synchronously even when application
     * runs in a different context (e.g. in a Web Worker).
     * 
     * `hostElementSelector` is a (CSS) selector for querying the main document to find the Host
     * Element. The newly created Root Host View should be attached to this element.
     * 
     * Returns an instance of {@link RenderViewWithFragments}, representing the Render View.
     */
    createRootHostView(hostProtoViewRef: RenderProtoViewRef, fragmentCount: number, hostElementSelector: string): RenderViewWithFragments;
    
    /**
     * Creates a Render View based on the provided `protoViewRef`.
     * 
     * `fragmentCount` is the number of nested {@link RenderFragmentRef}s in this View. This parameter
     * is non-optional so that the renderer can create a result synchronously even when application
     * runs in a different context (e.g. in a Web Worker).
     * 
     * Returns an instance of {@link RenderViewWithFragments}, representing the Render View.
     */
    createView(protoViewRef: RenderProtoViewRef, fragmentCount: number): RenderViewWithFragments;
    
    /**
     * Destroys a Render View specified via `viewRef`.
     * 
     * This operation should be performed only on a View that has already been dehydrated and
     * all of its Render Fragments have been detached.
     * 
     * Destroying a View indicates to the Renderer that this View is not going to be referenced in any
     * future operations. If the Renderer created any renderer-specific objects for this View, these
     * objects should now be destroyed to prevent memory leaks.
     */
    destroyView(viewRef: RenderViewRef): void;
    
    /**
     * Attaches the Nodes of a Render Fragment after the last Node of `previousFragmentRef`.
     */
    attachFragmentAfterFragment(previousFragmentRef: RenderFragmentRef, fragmentRef: RenderFragmentRef): void;
    
    /**
     * Attaches the Nodes of the Render Fragment after an Element.
     */
    attachFragmentAfterElement(elementRef: RenderElementRef, fragmentRef: RenderFragmentRef): void;
    
    /**
     * Detaches the Nodes of a Render Fragment from their parent.
     * 
     * This operations should be called only on a View that has been already
     * {@link #dehydrateView dehydrated}.
     */
    detachFragment(fragmentRef: RenderFragmentRef): void;
    
    /**
     * Notifies a custom Renderer to initialize a Render View.
     * 
     * This method is called by Angular after a Render View has been created, or when a previously
     * dehydrated Render View is about to be reused.
     */
    hydrateView(viewRef: RenderViewRef): void;
    
    /**
     * Notifies a custom Renderer that a Render View is no longer active.
     * 
     * This method is called by Angular before a Render View will be destroyed, or when a hydrated
     * Render View is about to be put into a pool for future reuse.
     */
    dehydrateView(viewRef: RenderViewRef): void;
    
    /**
     * Returns the underlying native element at the specified `location`, or `null` if direct access
     * to native elements is not supported (e.g. when the application runs in a web worker).
     * 
     * <div class="callout is-critical">
     *   <header>Use with caution</header>
     *   <p>
     *    Use this api as the last resort when direct access to DOM is needed. Use templating and
     *    data-binding, or other {@link Renderer} methods instead.
     *   </p>
     *   <p>
     *    Relying on direct DOM access creates tight coupling between your application and rendering
     *    layers which will make it impossible to separate the two and deploy your application into a
     *    web worker.
     *   </p>
     * </div>
     */
    getNativeElementSync(location: RenderElementRef): any;
    
    /**
     * Sets a property on the Element specified via `location`.
     */
    setElementProperty(location: RenderElementRef, propertyName: string, propertyValue: any): void;
    
    /**
     * Sets an attribute on the Element specified via `location`.
     * 
     * If `attributeValue` is `null`, the attribute is removed.
     */
    setElementAttribute(location: RenderElementRef, attributeName: string, attributeValue: string): void;
    
    /**
     * Sets a (CSS) class on the Element specified via `location`.
     * 
     * `isAdd` specifies if the class should be added or removed.
     */
    setElementClass(location: RenderElementRef, className: string, isAdd: boolean): void;
    
    /**
     * Sets a (CSS) inline style on the Element specified via `location`.
     * 
     * If `styleValue` is `null`, the style is removed.
     */
    setElementStyle(location: RenderElementRef, styleName: string, styleValue: string): void;
    
    /**
     * Calls a method on the Element specified via `location`.
     */
    invokeElementMethod(location: RenderElementRef, methodName: string, args: any[]): void;
    
    /**
     * Sets the value of an interpolated TextNode at the specified index to the `text` value.
     * 
     * `textNodeIndex` is the depth-first index of the Node among interpolated Nodes in the Render
     * View.
     */
    setText(viewRef: RenderViewRef, textNodeIndex: number, text: string): void;
    
    /**
     * Sets a dispatcher to relay all events triggered in the given Render View.
     * 
     * Each Render View can have only one Event Dispatcher, if this method is called multiple times,
     * the last provided dispatcher will be used.
     */
    setEventDispatcher(viewRef: RenderViewRef, dispatcher: RenderEventDispatcher): void;
    
  }

    
  /**
   * Represents an Element that is part of a {@link RenderViewRef Render View}.
   * 
   * `RenderElementRef` is a counterpart to {@link ElementRef} available in the Application Context.
   * 
   * When using `Renderer` from the Application Context, `ElementRef` can be used instead of
   * `RenderElementRef`.
   */
  interface RenderElementRef {
    
    /**
     * Reference to the Render View that contains this Element.
     */
    renderView: RenderViewRef;
    
  }

    
  /**
   * Represents an Angular View in the Rendering Context.
   * 
   * `RenderViewRef` specifies to the {@link Renderer} what View to update or destroy.
   * 
   * Unlike a {@link ViewRef} available in the Application Context, Render View contains all the
   * static Component Views that have been recursively merged into a single Render View.
   * 
   * Each `RenderViewRef` contains one or more {@link RenderFragmentRef Render Fragments}, these
   * Fragments are created, hydrated, dehydrated and destroyed as a single unit together with the
   * View.
   */
  class RenderViewRef {
    
  }

    
  /**
   * Represents an Angular ProtoView in the Rendering Context.
   * 
   * When you implement a custom {@link Renderer}, `RenderProtoViewRef` specifies what Render View
   * your renderer should create.
   * 
   * `RenderProtoViewRef` is a counterpart to {@link ProtoViewRef} available in the Application
   * Context. But unlike `ProtoViewRef`, `RenderProtoViewRef` contains all static nested Proto Views
   * that are recursively merged into a single Render Proto View.
   * 
   * 
   * <!-- TODO: this is created by Renderer#createProtoView in the new compiler -->
   */
  class RenderProtoViewRef {
    
  }

    
  /**
   * Represents a list of sibling Nodes that can be moved by the {@link Renderer} independently of
   * other Render Fragments.
   * 
   * Any {@link RenderView} has one Render Fragment.
   * 
   * Additionally any View with an Embedded View that contains a {@link NgContent View Projection}
   * results in additional Render Fragment.
   */
  class RenderFragmentRef {
    
  }

    
  /**
   * Container class produced by a {@link Renderer} when creating a Render View.
   * 
   * An instance of `RenderViewWithFragments` contains a {@link RenderViewRef} and an array of
   * {@link RenderFragmentRef}s belonging to this Render View.
   */
  class RenderViewWithFragments {
    
    constructor(viewRef: RenderViewRef, fragmentRefs: RenderFragmentRef[]);
    
    /**
     * Reference to the {@link RenderViewRef}.
     */
    viewRef: RenderViewRef;
    
    /**
     * Array of {@link RenderFragmentRef}s ordered in the depth-first order.
     */
    fragmentRefs: RenderFragmentRef[];
    
  }

    
  interface RenderTemplateCmd {
    
    visit(visitor: RenderCommandVisitor, context: any): any;
    
  }

    
  interface RenderCommandVisitor {
    
    visitText(cmd: RenderTextCmd, context: any): any;
    
    visitNgContent(cmd: RenderNgContentCmd, context: any): any;
    
    visitBeginElement(cmd: RenderBeginElementCmd, context: any): any;
    
    visitEndElement(context: any): any;
    
    visitBeginComponent(cmd: RenderBeginComponentCmd, context: any): any;
    
    visitEndComponent(context: any): any;
    
    visitEmbeddedTemplate(cmd: RenderEmbeddedTemplateCmd, context: any): any;
    
  }

    
  interface RenderTextCmd extends RenderBeginCmd {
    
    value: string;
    
  }

    
  interface RenderNgContentCmd {
    
    index: number;
    
    ngContentIndex: number;
    
  }

    
  interface RenderBeginElementCmd extends RenderBeginCmd {
    
    name: string;
    
    attrNameAndValues: string[];
    
    eventTargetAndNames: string[];
    
  }

    
  interface RenderBeginComponentCmd extends RenderBeginElementCmd {
    
    nativeShadow: boolean;
    
    templateId: number;
    
  }

    
  interface RenderEmbeddedTemplateCmd extends RenderBeginElementCmd {
    
    isMerged: boolean;
    
    children: RenderTemplateCmd[];
    
  }

    
  interface RenderBeginCmd extends RenderTemplateCmd {
    
    ngContentIndex: number;
    
    isBound: boolean;
    
  }

    
  abstract class ClientMessageBroker {
    
    runOnService(args: UiArguments, returnType: Type): Promise<any>;
    
  }

    
  abstract class ClientMessageBrokerFactory {
    
    /**
     * Initializes the given channel and attaches a new {@link ClientMessageBroker} to it.
     */
    createMessageBroker(channel: string, runInZone?: boolean): ClientMessageBroker;
    
  }

    
  class FnArg {
    
    constructor(value: any, type: Type);
    
    value: any;
    
    type: Type;
    
  }

    
  class UiArguments {
    
    constructor(method: string, args?: FnArg[]);
    
    method: string;
    
    args: FnArg[];
    
  }

    
  class ReceivedMessage {
    
    constructor(data: {[key: string]: any});
    
    method: string;
    
    args: any[];
    
    id: string;
    
    type: string;
    
  }

    
  abstract class ServiceMessageBroker {
    
    registerMethod(methodName: string, signature: Type[], method: Function, returnType?: Type): void;
    
  }

    
  abstract class ServiceMessageBrokerFactory {
    
    /**
     * Initializes the given channel and attaches a new {@link ServiceMessageBroker} to it.
     */
    createMessageBroker(channel: string, runInZone?: boolean): ServiceMessageBroker;
    
  }

    
  let PRIMITIVE: Type;
  

    
  /**
   * Implement this interface to get notified when your directive's content has been fully
   * initialized.
   * 
   * ### Example ([live demo](http://plnkr.co/edit/plamXUpsLQbIXpViZhUO?p=preview))
   * 
   * ```typescript
   * @Component({
   *   selector: 'child-cmp',
   *   template: `{{where}} child`
   * })
   * class ChildComponent {
   *   @Input() where: string;
   * }
   * 
   * @Component({
   *   selector: 'parent-cmp',
   *   template: `<ng-content></ng-content>`
   * })
   * class ParentComponent implements AfterContentInit {
   *   @ContentChild(ChildComponent) contentChild: ChildComponent;
   * 
   *   constructor() {
   *     // contentChild is not initialized yet
   *     console.log(this.getMessage(this.contentChild));
   *   }
   * 
   *   afterContentInit() {
   *     // contentChild is updated after the content has been checked
   *     console.log('AfterContentInit: ' + this.getMessage(this.contentChild));
   *   }
   * 
   *   private getMessage(cmp: ChildComponent): string {
   *     return cmp ? cmp.where + ' child' : 'no child';
   *   }
   * }
   * 
   * @Component({
   *   selector: 'app',
   *   template: `
   *     <parent-cmp>
   *       <child-cmp where="content"></child-cmp>
   *     </parent-cmp>`,
   *   directives: [ParentComponent, ChildComponent]
   * })
   * export class App {
   * }
   * 
   * bootstrap(App).catch(err => console.error(err));
   * ```
   */
  interface AfterContentInit {
    
    afterContentInit(): void;
    
  }

    
  /**
   * Implement this interface to get notified after every check of your directive's content.
   * 
   * ### Example ([live demo](http://plnkr.co/edit/tGdrytNEKQnecIPkD7NU?p=preview))
   * 
   * ```typescript
   * @Component({selector: 'child-cmp', template: `{{where}} child`})
   * class ChildComponent {
   *   @Input() where: string;
   * }
   * 
   * @Component({selector: 'parent-cmp', template: `<ng-content></ng-content>`})
   * class ParentComponent implements AfterContentChecked {
   *   @ContentChild(ChildComponent) contentChild: ChildComponent;
   * 
   *   constructor() {
   *     // contentChild is not initialized yet
   *     console.log(this.getMessage(this.contentChild));
   *   }
   * 
   *   afterContentChecked() {
   *     // contentChild is updated after the content has been checked
   *     console.log('AfterContentChecked: ' + this.getMessage(this.contentChild));
   *   }
   * 
   *   private getMessage(cmp: ChildComponent): string {
   *     return cmp ? cmp.where + ' child' : 'no child';
   *   }
   * }
   * 
   * @Component({
   *   selector: 'app',
   *   template: `
   *     <parent-cmp>
   *       <button (click)="hasContent = !hasContent">Toggle content child</button>
   *       <child-cmp *ng-if="hasContent" where="content"></child-cmp>
   *     </parent-cmp>`,
   *   directives: [NgIf, ParentComponent, ChildComponent]
   * })
   * export class App {
   *   hasContent = true;
   * }
   * 
   * bootstrap(App).catch(err => console.error(err));
   * ```
   */
  interface AfterContentChecked {
    
    afterContentChecked(): void;
    
  }

    
  /**
   * Implement this interface to get notified when your component's view has been fully initialized.
   * 
   * ### Example ([live demo](http://plnkr.co/edit/LhTKVMEM0fkJgyp4CI1W?p=preview))
   * 
   * ```typescript
   * @Component({selector: 'child-cmp', template: `{{where}} child`})
   * class ChildComponent {
   *   @Input() where: string;
   * }
   * 
   * @Component({
   *   selector: 'parent-cmp',
   *   template: `<child-cmp where="view"></child-cmp>`,
   *   directives: [ChildComponent]
   * })
   * class ParentComponent implements AfterViewInit {
   *   @ViewChild(ChildComponent) viewChild: ChildComponent;
   * 
   *   constructor() {
   *     // viewChild is not initialized yet
   *     console.log(this.getMessage(this.viewChild));
   *   }
   * 
   *   afterViewInit() {
   *     // viewChild is updated after the view has been initialized
   *     console.log('afterViewInit: ' + this.getMessage(this.viewChild));
   *   }
   * 
   *   private getMessage(cmp: ChildComponent): string {
   *     return cmp ? cmp.where + ' child' : 'no child';
   *   }
   * }
   * 
   * @Component({
   *   selector: 'app',
   *   template: `<parent-cmp></parent-cmp>`,
   *   directives: [ParentComponent]
   * })
   * export class App {
   * }
   * 
   * bootstrap(App).catch(err => console.error(err));
   * ```
   */
  interface AfterViewInit {
    
    afterViewInit(): void;
    
  }

    
  /**
   * Implement this interface to get notified after every check of your component's view.
   * 
   * ### Example ([live demo](http://plnkr.co/edit/0qDGHcPQkc25CXhTNzKU?p=preview))
   * 
   * ```typescript
   * @Component({selector: 'child-cmp', template: `{{where}} child`})
   * class ChildComponent {
   *   @Input() where: string;
   * }
   * 
   * @Component({
   *   selector: 'parent-cmp',
   *   template: `
   *     <button (click)="showView = !showView">Toggle view child</button>
   *     <child-cmp *ng-if="showView" where="view"></child-cmp>`,
   *   directives: [NgIf, ChildComponent]
   * })
   * class ParentComponent implements AfterViewChecked {
   *   @ViewChild(ChildComponent) viewChild: ChildComponent;
   *   showView = true;
   * 
   *   constructor() {
   *     // viewChild is not initialized yet
   *     console.log(this.getMessage(this.viewChild));
   *   }
   * 
   *   afterViewChecked() {
   *     // viewChild is updated after the view has been checked
   *     console.log('AfterViewChecked: ' + this.getMessage(this.viewChild));
   *   }
   * 
   *   private getMessage(cmp: ChildComponent): string {
   *     return cmp ? cmp.where + ' child' : 'no child';
   *   }
   * }
   * 
   * @Component({
   *   selector: 'app',
   *   template: `<parent-cmp></parent-cmp>`,
   *   directives: [ParentComponent]
   * })
   * export class App {
   * }
   * 
   * bootstrap(App).catch(err => console.error(err));
   * ```
   */
  interface AfterViewChecked {
    
    afterViewChecked(): void;
    
  }

    
  /**
   * Lifecycle hooks are guaranteed to be called in the following order:
   * - `OnChanges` (if any bindings have changed),
   * - `OnInit` (after the first check only),
   * - `DoCheck`,
   * - `AfterContentInit`,
   * - `AfterContentChecked`,
   * - `AfterViewInit`,
   * - `AfterViewChecked`,
   * - `OnDestroy` (at the very end before destruction)
   * Implement this interface to get notified when any data-bound property of your directive changes.
   * 
   * `onChanges` is called right after the data-bound properties have been checked and before view
   * and content children are checked if at least one of them has changed.
   * 
   * The `changes` parameter contains an entry for each of the changed data-bound property. The key is
   * the property name and the value is an instance of {@link SimpleChange}.
   * 
   * ### Example ([live example](http://plnkr.co/edit/AHrB6opLqHDBPkt4KpdT?p=preview)):
   * 
   * ```typescript
   * @Component({
   *   selector: 'my-cmp',
   *   template: `<p>myProp = {{myProp}}</p>`
   * })
   * class MyComponent implements OnChanges {
   *   @Input() myProp: any;
   * 
   *   onChanges(changes: {[propName: string]: SimpleChange}) {
   *     console.log('onChanges - myProp = ' + changes['myProp'].currentValue);
   *   }
   * }
   * 
   * @Component({
   *   selector: 'app',
   *   template: `
   *     <button (click)="value = value + 1">Change MyComponent</button>
   *     <my-cmp [my-prop]="value"></my-cmp>`,
   *   directives: [MyComponent]
   * })
   * export class App {
   *   value = 0;
   * }
   * 
   * bootstrap(App).catch(err => console.error(err));
   * ```
   */
  interface OnChanges {
    
    onChanges(changes: {[key: string]: SimpleChange}): void;
    
  }

    
  /**
   * Implement this interface to get notified when your directive is destroyed.
   * 
   * `onDestroy` callback is typically used for any custom cleanup that needs to occur when the
   * instance is destroyed
   * 
   * ### Example ([live example](http://plnkr.co/edit/1MBypRryXd64v4pV03Yn?p=preview))
   * 
   * ```typesript
   * @Component({
   *   selector: 'my-cmp',
   *   template: `<p>my-component</p>`
   * })
   * class MyComponent implements OnInit, OnDestroy {
   *   onInit() {
   *     console.log('onInit');
   *   }
   * 
   *   onDestroy() {
   *     console.log('onDestroy');
   *   }
   * }
   * 
   * @Component({
   *   selector: 'app',
   *   template: `
   *     <button (click)="hasChild = !hasChild">
   *       {{hasChild ? 'Destroy' : 'Create'}} MyComponent
   *     </button>
   *     <my-cmp *ng-if="hasChild"></my-cmp>`,
   *   directives: [MyComponent, NgIf]
   * })
   * export class App {
   *   hasChild = true;
   * }
   * 
   * bootstrap(App).catch(err => console.error(err));
   * * ```
   */
  interface OnDestroy {
    
    onDestroy(): void;
    
  }

    
  /**
   * Implement this interface to execute custom initialization logic after your directive's
   * data-bound properties have been initialized.
   * 
   * `onInit` is called right after the directive's data-bound properties have been checked for the
   * first time, and before any of its children have been checked. It is invoked only once when the
   * directive is instantiated.
   * 
   * ### Example ([live example](http://plnkr.co/edit/1MBypRryXd64v4pV03Yn?p=preview))
   * 
   * ```typescript
   * @Component({
   *   selector: 'my-cmp',
   *   template: `<p>my-component</p>`
   * })
   * class MyComponent implements OnInit, OnDestroy {
   *   onInit() {
   *     console.log('onInit');
   *   }
   * 
   *   onDestroy() {
   *     console.log('onDestroy');
   *   }
   * }
   * 
   * @Component({
   *   selector: 'app',
   *   template: `
   *     <button (click)="hasChild = !hasChild">
   *       {{hasChild ? 'Destroy' : 'Create'}} MyComponent
   *     </button>
   *     <my-cmp *ng-if="hasChild"></my-cmp>`,
   *   directives: [MyComponent, NgIf]
   * })
   * export class App {
   *   hasChild = true;
   * }
   * 
   * bootstrap(App).catch(err => console.error(err));
   *  ```
   */
  interface OnInit {
    
    onInit(): void;
    
  }

    
  /**
   * Implement this interface to override the default change detection algorithm for your directive.
   * 
   * `doCheck` gets called to check the changes in the directives instead of the default algorithm.
   * 
   * The default change detection algorithm looks for differences by comparing bound-property values
   * by reference across change detection runs. When `DoCheck` is implemented, the default algorithm
   * is disabled and `doCheck` is responsible for checking for changes.
   * 
   * Implementing this interface allows improving performance by using insights about the component,
   * its implementation and data types of its properties.
   * 
   * Note that a directive should not implement both `DoCheck` and {@link OnChanges} at the same time.
   * `onChanges` would not be called when a directive implements `DoCheck`. Reaction to the changes
   * have to be handled from within the `doCheck` callback.
   * 
   * Use {@link KeyValueDiffers} and {@link IterableDiffers} to add your custom check mechanisms.
   * 
   * ### Example ([live demo](http://plnkr.co/edit/QpnIlF0CR2i5bcYbHEUJ?p=preview))
   * 
   * In the following example `doCheck` uses an {@link IterableDiffers} to detect the updates to the
   * array `list`:
   * 
   * ```typescript
   * @Component({
   *   selector: 'custom-check',
   *   template: `
   *     <p>Changes:</p>
   *     <ul>
   *       <li *ng-for="#line of logs">{{line}}</li>
   *     </ul>`,
   *   directives: [NgFor]
   * })
   * class CustomCheckComponent implements DoCheck {
   *   @Input() list: any[];
   *   differ: any;
   *   logs = [];
   * 
   *   constructor(differs: IterableDiffers) {
   *     this.differ = differs.find([]).create(null);
   *   }
   * 
   *   doCheck() {
   *     var changes = this.differ.diff(this.list);
   * 
   *     if (changes) {
   *       changes.forEachAddedItem(r => this.logs.push('added ' + r.item));
   *       changes.forEachRemovedItem(r => this.logs.push('removed ' + r.item))
   *     }
   *   }
   * }
   * 
   * @Component({
   *   selector: 'app',
   *   template: `
   *     <button (click)="list.push(list.length)">Push</button>
   *     <button (click)="list.pop()">Pop</button>
   *     <custom-check [list]="list"></custom-check>`,
   *   directives: [CustomCheckComponent]
   * })
   * export class App {
   *   list = [];
   * }
   * ```
   */
  interface DoCheck {
    
    doCheck(): void;
    
  }

    
  /**
   * Declares an injectable parameter to be a live list of directives or variable
   * bindings from the content children of a directive.
   * 
   * ### Example ([live demo](http://plnkr.co/edit/lY9m8HLy7z06vDoUaSN2?p=preview))
   * 
   * Assume that `<tabs>` component would like to get a list its children `<pane>`
   * components as shown in this example:
   * 
   * ```html
   * <tabs>
   *   <pane title="Overview">...</pane>
   *   <pane *ng-for="#o of objects" [title]="o.title">{{o.text}}</pane>
   * </tabs>
   * ```
   * 
   * The preferred solution is to query for `Pane` directives using this decorator.
   * 
   * ```javascript
   * @Component({
   *   selector: 'pane',
   *   inputs: ['title']
   * })
   * class Pane {
   *   title:string;
   * }
   * 
   * @Component({
   *  selector: 'tabs',
   *  template: `
   *    <ul>
   *      <li *ng-for="#pane of panes">{{pane.title}}</li>
   *    </ul>
   *    <content></content>
   *  `
   * })
   * class Tabs {
   *   panes: QueryList<Pane>;
   *   constructor(@Query(Pane) panes:QueryList<Pane>) {
   *    this.panes = panes;
   *  }
   * }
   * ```
   * 
   * A query can look for variable bindings by passing in a string with desired binding symbol.
   * 
   * ### Example ([live demo](http://plnkr.co/edit/sT2j25cH1dURAyBRCKx1?p=preview))
   * ```html
   * <seeker>
   *   <div #findme>...</div>
   * </seeker>
   * 
   * @Component({ selector: 'seeker' })
   * class Seeker {
   *   constructor(@Query('findme') elList: QueryList<ElementRef>) {...}
   * }
   * ```
   * 
   * In this case the object that is injected depend on the type of the variable
   * binding. It can be an ElementRef, a directive or a component.
   * 
   * Passing in a comma separated list of variable bindings will query for all of them.
   * 
   * ```html
   * <seeker>
   *   <div #find-me>...</div>
   *   <div #find-me-too>...</div>
   * </seeker>
   * 
   *  @Component({
   *   selector: 'seeker'
   * })
   * class Seeker {
   *   constructor(@Query('findMe, findMeToo') elList: QueryList<ElementRef>) {...}
   * }
   * ```
   * 
   * Configure whether query looks for direct children or all descendants
   * of the querying element, by using the `descendants` parameter.
   * It is set to `false` by default.
   * 
   * ### Example ([live demo](http://plnkr.co/edit/wtGeB977bv7qvA5FTYl9?p=preview))
   * ```html
   * <container #first>
   *   <item>a</item>
   *   <item>b</item>
   *   <container #second>
   *     <item>c</item>
   *   </container>
   * </container>
   * ```
   * 
   * When querying for items, the first container will see only `a` and `b` by default,
   * but with `Query(TextDirective, {descendants: true})` it will see `c` too.
   * 
   * The queried directives are kept in a depth-first pre-order with respect to their
   * positions in the DOM.
   * 
   * Query does not look deep into any subcomponent views.
   * 
   * Query is updated as part of the change-detection cycle. Since change detection
   * happens after construction of a directive, QueryList will always be empty when observed in the
   * constructor.
   * 
   * The injected object is an unmodifiable live list.
   * See {@link QueryList} for more details.
   */
  class QueryMetadata extends DependencyMetadata {
    
    constructor(_selector: Type | string, {descendants, first}?: {descendants?: boolean, first?: boolean});
    
    /**
     * whether we want to query only direct children (false) or all
     * children (true).
     */
    descendants: boolean;
    
    first: boolean;
    
    /**
     * always `false` to differentiate it with {@link ViewQueryMetadata}.
     */
    isViewQuery: boolean;
    
    /**
     * what this is querying for.
     */
    selector: any;
    
    /**
     * whether this is querying for a variable binding or a directive.
     */
    isVarBindingQuery: boolean;
    
    /**
     * returns a list of variable bindings this is querying for.
     * Only applicable if this is a variable bindings query.
     */
    varBindings: string[];
    
    toString(): string;
    
  }

    
  /**
   * Configures a content query.
   * 
   * Content queries are set before the `afterContentInit` callback is called.
   * 
   * ### Example
   * 
   * ```
   * @Directive({
   *   selector: 'someDir'
   * })
   * class SomeDir {
   *   @ContentChildren(ChildDirective) contentChildren: QueryList<ChildDirective>;
   * 
   *   afterContentInit() {
   *     // contentChildren is set
   *   }
   * }
   * ```
   */
  class ContentChildrenMetadata extends QueryMetadata {
    
    constructor(_selector: Type | string, {descendants}?: {descendants?: boolean});
    
  }

    
  /**
   * Configures a content query.
   * 
   * Content queries are set before the `afterContentInit` callback is called.
   * 
   * ### Example
   * 
   * ```
   * @Directive({
   *   selector: 'someDir'
   * })
   * class SomeDir {
   *   @ContentChild(ChildDirective) contentChild;
   * 
   *   afterContentInit() {
   *     // contentChild is set
   *   }
   * }
   * ```
   */
  class ContentChildMetadata extends QueryMetadata {
    
    constructor(_selector: Type | string);
    
  }

    
  /**
   * Configures a view query.
   * 
   * View queries are set before the `afterViewInit` callback is called.
   * 
   * ### Example
   * 
   * ```
   * @Component({
   *   selector: 'someDir',
   *   templateUrl: 'someTemplate',
   *   directives: [ItemDirective]
   * })
   * class SomeDir {
   *   @ViewChildren(ItemDirective) viewChildren: QueryList<ItemDirective>;
   * 
   *   afterViewInit() {
   *     // viewChildren is set
   *   }
   * }
   * ```
   */
  class ViewChildrenMetadata extends ViewQueryMetadata {
    
    constructor(_selector: Type | string);
    
  }

    
  /**
   * Similar to {@link QueryMetadata}, but querying the component view, instead of
   * the content children.
   * 
   * ### Example ([live demo](http://plnkr.co/edit/eNsFHDf7YjyM6IzKxM1j?p=preview))
   * 
   * ```javascript
   * @Component({...})
   * @View({
   *   template: `
   *     <item> a </item>
   *     <item> b </item>
   *     <item> c </item>
   *   `
   * })
   * class MyComponent {
   *   shown: boolean;
   * 
   *   constructor(private @Query(Item) items:QueryList<Item>) {
   *     items.onChange(() => console.log(items.length));
   *   }
   * }
   * ```
   * 
   * Supports the same querying parameters as {@link QueryMetadata}, except
   * `descendants`. This always queries the whole view.
   * 
   * As `shown` is flipped between true and false, items will contain zero of one
   * items.
   * 
   * Specifies that a {@link QueryList} should be injected.
   * 
   * The injected object is an iterable and observable live list.
   * See {@link QueryList} for more details.
   */
  class ViewQueryMetadata extends QueryMetadata {
    
    constructor(_selector: Type | string, {descendants, first}?: {descendants?: boolean, first?: boolean});
    
    /**
     * always `true` to differentiate it with {@link QueryMetadata}.
     */
    isViewQuery: any;
    
    toString(): string;
    
  }

    
  /**
   * Configures a view query.
   * 
   * View queries are set before the `afterViewInit` callback is called.
   * 
   * ### Example
   * 
   * ```
   * @Component({
   *   selector: 'someDir',
   *   templateUrl: 'someTemplate',
   *   directives: [ItemDirective]
   * })
   * class SomeDir {
   *   @ViewChild(ItemDirective) viewChild:ItemDirective;
   * 
   *   afterViewInit() {
   *     // viewChild is set
   *   }
   * }
   * ```
   */
  class ViewChildMetadata extends ViewQueryMetadata {
    
    constructor(_selector: Type | string);
    
  }

    
  /**
   * Specifies that a constant attribute value should be injected.
   * 
   * The directive can inject constant string literals of host element attributes.
   * 
   * ### Example
   * 
   * Suppose we have an `<input>` element and want to know its `type`.
   * 
   * ```html
   * <input type="text">
   * ```
   * 
   * A decorator can inject string literal `text` like so:
   * 
   * ```javascript
   * @Directive({
   *   selector: `input'
   * })
   * class InputDirective {
   *   constructor(@Attribute('type') type) {
   *     // type would be `text` in this example
   *   }
   * }
   * ```
   */
  class AttributeMetadata extends DependencyMetadata {
    
    constructor(attributeName: string);
    
    attributeName: string;
    
    token: any;
    
    toString(): string;
    
  }

    
  /**
   * Declare reusable UI building blocks for an application.
   * 
   * Each Angular component requires a single `@Component` and at least one `@View` annotation. The
   * `@Component`
   * annotation specifies when a component is instantiated, and which properties and hostListeners it
   * binds to.
   * 
   * When a component is instantiated, Angular
   * - creates a shadow DOM for the component.
   * - loads the selected template into the shadow DOM.
   * - creates all the injectable objects configured with `providers` and `viewProviders`.
   * 
   * All template expressions and statements are then evaluated against the component instance.
   * 
   * For details on the `@View` annotation, see {@link ViewMetadata}.
   * 
   * ## Lifecycle hooks
   * 
   * When the component class implements some {@link angular2/lifecycle_hooks} the callbacks are
   * called by the change detection at defined points in time during the life of the component.
   * 
   * ### Example
   * 
   * ```
   * @Component({
   *   selector: 'greet',
   *   template: 'Hello {{name}}!'
   * })
   * class Greet {
   *   name: string;
   * 
   *   constructor() {
   *     this.name = 'World';
   *   }
   * }
   * ```
   */
  class ComponentMetadata extends DirectiveMetadata {
    
    constructor({selector, inputs, outputs, properties, events, host, exportAs, moduleId, bindings,
                   providers, viewBindings, viewProviders,
                   changeDetection, queries, templateUrl, template,
                   styleUrls, styles, directives, pipes, encapsulation}?: {
        selector?: string,
        inputs?: string[],
        outputs?: string[],
        properties?: string[],
        events?: string[],
        host?: {[key: string]: string},
        /** @deprecated */ bindings?: any[],
        providers?: any[],
        exportAs?: string,
        moduleId?: string,
        /** @deprecated */ viewBindings?: any[],
        viewProviders?: any[],
        queries?: {[key: string]: any},
        changeDetection?: ChangeDetectionStrategy,
        templateUrl?: string,
        template?: string,
        styleUrls?: string[],
        styles?: string[],
        directives?: Array<Type | any[]>,
        pipes?: Array<Type | any[]>,
        encapsulation?: ViewEncapsulation
      });
    
    /**
     * Defines the used change detection strategy.
     * 
     * When a component is instantiated, Angular creates a change detector, which is responsible for
     * propagating the component's bindings.
     * 
     * The `changeDetection` property defines, whether the change detection will be checked every time
     * or only when the component tells it to do so.
     */
    changeDetection: ChangeDetectionStrategy;
    
    /**
     * Defines the set of injectable objects that are visible to its view DOM children.
     * 
     * ## Simple Example
     * 
     * Here is an example of a class that can be injected:
     * 
     * ```
     * class Greeter {
     *    greet(name:string) {
     *      return 'Hello ' + name + '!';
     *    }
     * }
     * 
     * @Directive({
     *   selector: 'needs-greeter'
     * })
     * class NeedsGreeter {
     *   greeter:Greeter;
     * 
     *   constructor(greeter:Greeter) {
     *     this.greeter = greeter;
     *   }
     * }
     * 
     * @Component({
     *   selector: 'greet',
     *   viewProviders: [
     *     Greeter
     *   ],
     *   template: `<needs-greeter></needs-greeter>`,
     *   directives: [NeedsGreeter]
     * })
     * class HelloWorld {
     * }
     * 
     * ```
     */
    viewProviders: any[];
    
    viewBindings: any[];
    
    templateUrl: string;
    
    template: string;
    
    styleUrls: string[];
    
    styles: string[];
    
    directives: Array<Type | any[]>;
    
    pipes: Array<Type | any[]>;
    
    encapsulation: ViewEncapsulation;
    
  }

    
  /**
   * Directives allow you to attach behavior to elements in the DOM.
   * 
   * {@link DirectiveMetadata}s with an embedded view are called {@link ComponentMetadata}s.
   * 
   * A directive consists of a single directive annotation and a controller class. When the
   * directive's `selector` matches
   * elements in the DOM, the following steps occur:
   * 
   * 1. For each directive, the `ElementInjector` attempts to resolve the directive's constructor
   * arguments.
   * 2. Angular instantiates directives for each matched element using `ElementInjector` in a
   * depth-first order,
   *    as declared in the HTML.
   * 
   * ## Understanding How Injection Works
   * 
   * There are three stages of injection resolution.
   * - *Pre-existing Injectors*:
   *   - The terminal {@link Injector} cannot resolve dependencies. It either throws an error or, if
   * the dependency was
   *     specified as `@Optional`, returns `null`.
   *   - The platform injector resolves browser singleton resources, such as: cookies, title,
   * location, and others.
   * - *Component Injectors*: Each component instance has its own {@link Injector}, and they follow
   * the same parent-child hierarchy
   *     as the component instances in the DOM.
   * - *Element Injectors*: Each component instance has a Shadow DOM. Within the Shadow DOM each
   * element has an `ElementInjector`
   *     which follow the same parent-child hierarchy as the DOM elements themselves.
   * 
   * When a template is instantiated, it also must instantiate the corresponding directives in a
   * depth-first order. The
   * current `ElementInjector` resolves the constructor dependencies for each directive.
   * 
   * Angular then resolves dependencies as follows, according to the order in which they appear in the
   * {@link ViewMetadata}:
   * 
   * 1. Dependencies on the current element
   * 2. Dependencies on element injectors and their parents until it encounters a Shadow DOM boundary
   * 3. Dependencies on component injectors and their parents until it encounters the root component
   * 4. Dependencies on pre-existing injectors
   * 
   * 
   * The `ElementInjector` can inject other directives, element-specific special objects, or it can
   * delegate to the parent
   * injector.
   * 
   * To inject other directives, declare the constructor parameter as:
   * - `directive:DirectiveType`: a directive on the current element only
   * - `@Host() directive:DirectiveType`: any directive that matches the type between the current
   * element and the
   *    Shadow DOM root.
   * - `@Query(DirectiveType) query:QueryList<DirectiveType>`: A live collection of direct child
   * directives.
   * - `@QueryDescendants(DirectiveType) query:QueryList<DirectiveType>`: A live collection of any
   * child directives.
   * 
   * To inject element-specific special objects, declare the constructor parameter as:
   * - `element: ElementRef` to obtain a reference to logical element in the view.
   * - `viewContainer: ViewContainerRef` to control child template instantiation, for
   * {@link DirectiveMetadata} directives only
   * - `bindingPropagation: BindingPropagation` to control change detection in a more granular way.
   * 
   * ### Example
   * 
   * The following example demonstrates how dependency injection resolves constructor arguments in
   * practice.
   * 
   * 
   * Assume this HTML template:
   * 
   * ```
   * <div dependency="1">
   *   <div dependency="2">
   *     <div dependency="3" my-directive>
   *       <div dependency="4">
   *         <div dependency="5"></div>
   *       </div>
   *       <div dependency="6"></div>
   *     </div>
   *   </div>
   * </div>
   * ```
   * 
   * With the following `dependency` decorator and `SomeService` injectable class.
   * 
   * ```
   * @Injectable()
   * class SomeService {
   * }
   * 
   * @Directive({
   *   selector: '[dependency]',
   *   inputs: [
   *     'id: dependency'
   *   ]
   * })
   * class Dependency {
   *   id:string;
   * }
   * ```
   * 
   * Let's step through the different ways in which `MyDirective` could be declared...
   * 
   * 
   * ### No injection
   * 
   * Here the constructor is declared with no arguments, therefore nothing is injected into
   * `MyDirective`.
   * 
   * ```
   * @Directive({ selector: '[my-directive]' })
   * class MyDirective {
   *   constructor() {
   *   }
   * }
   * ```
   * 
   * This directive would be instantiated with no dependencies.
   * 
   * 
   * ### Component-level injection
   * 
   * Directives can inject any injectable instance from the closest component injector or any of its
   * parents.
   * 
   * Here, the constructor declares a parameter, `someService`, and injects the `SomeService` type
   * from the parent
   * component's injector.
   * ```
   * @Directive({ selector: '[my-directive]' })
   * class MyDirective {
   *   constructor(someService: SomeService) {
   *   }
   * }
   * ```
   * 
   * This directive would be instantiated with a dependency on `SomeService`.
   * 
   * 
   * ### Injecting a directive from the current element
   * 
   * Directives can inject other directives declared on the current element.
   * 
   * ```
   * @Directive({ selector: '[my-directive]' })
   * class MyDirective {
   *   constructor(dependency: Dependency) {
   *     expect(dependency.id).toEqual(3);
   *   }
   * }
   * ```
   * This directive would be instantiated with `Dependency` declared at the same element, in this case
   * `dependency="3"`.
   * 
   * ### Injecting a directive from any ancestor elements
   * 
   * Directives can inject other directives declared on any ancestor element (in the current Shadow
   * DOM), i.e. on the current element, the
   * parent element, or its parents.
   * ```
   * @Directive({ selector: '[my-directive]' })
   * class MyDirective {
   *   constructor(@Host() dependency: Dependency) {
   *     expect(dependency.id).toEqual(2);
   *   }
   * }
   * ```
   * 
   * `@Host` checks the current element, the parent, as well as its parents recursively. If
   * `dependency="2"` didn't
   * exist on the direct parent, this injection would
   * have returned
   * `dependency="1"`.
   * 
   * 
   * ### Injecting a live collection of direct child directives
   * 
   * 
   * A directive can also query for other child directives. Since parent directives are instantiated
   * before child directives, a directive can't simply inject the list of child directives. Instead,
   * the directive injects a {@link QueryList}, which updates its contents as children are added,
   * removed, or moved by a directive that uses a {@link ViewContainerRef} such as a `ng-for`, an
   * `ng-if`, or an `ng-switch`.
   * 
   * ```
   * @Directive({ selector: '[my-directive]' })
   * class MyDirective {
   *   constructor(@Query(Dependency) dependencies:QueryList<Dependency>) {
   *   }
   * }
   * ```
   * 
   * This directive would be instantiated with a {@link QueryList} which contains `Dependency` 4 and
   * 6. Here, `Dependency` 5 would not be included, because it is not a direct child.
   * 
   * ### Injecting a live collection of descendant directives
   * 
   * By passing the descendant flag to `@Query` above, we can include the children of the child
   * elements.
   * 
   * ```
   * @Directive({ selector: '[my-directive]' })
   * class MyDirective {
   *   constructor(@Query(Dependency, {descendants: true}) dependencies:QueryList<Dependency>) {
   *   }
   * }
   * ```
   * 
   * This directive would be instantiated with a Query which would contain `Dependency` 4, 5 and 6.
   * 
   * ### Optional injection
   * 
   * The normal behavior of directives is to return an error when a specified dependency cannot be
   * resolved. If you
   * would like to inject `null` on unresolved dependency instead, you can annotate that dependency
   * with `@Optional()`.
   * This explicitly permits the author of a template to treat some of the surrounding directives as
   * optional.
   * 
   * ```
   * @Directive({ selector: '[my-directive]' })
   * class MyDirective {
   *   constructor(@Optional() dependency:Dependency) {
   *   }
   * }
   * ```
   * 
   * This directive would be instantiated with a `Dependency` directive found on the current element.
   * If none can be
   * found, the injector supplies `null` instead of throwing an error.
   * 
   * ### Example
   * 
   * Here we use a decorator directive to simply define basic tool-tip behavior.
   * 
   * ```
   * @Directive({
   *   selector: '[tooltip]',
   *   inputs: [
   *     'text: tooltip'
   *   ],
   *   host: {
   *     '(mouseenter)': 'onMouseEnter()',
   *     '(mouseleave)': 'onMouseLeave()'
   *   }
   * })
   * class Tooltip{
   *   text:string;
   *   overlay:Overlay; // NOT YET IMPLEMENTED
   *   overlayManager:OverlayManager; // NOT YET IMPLEMENTED
   * 
   *   constructor(overlayManager:OverlayManager) {
   *     this.overlay = overlay;
   *   }
   * 
   *   onMouseEnter() {
   *     // exact signature to be determined
   *     this.overlay = this.overlayManager.open(text, ...);
   *   }
   * 
   *   onMouseLeave() {
   *     this.overlay.close();
   *     this.overlay = null;
   *   }
   * }
   * ```
   * In our HTML template, we can then add this behavior to a `<div>` or any other element with the
   * `tooltip` selector,
   * like so:
   * 
   * ```
   * <div tooltip="some text here"></div>
   * ```
   * 
   * Directives can also control the instantiation, destruction, and positioning of inline template
   * elements:
   * 
   * A directive uses a {@link ViewContainerRef} to instantiate, insert, move, and destroy views at
   * runtime.
   * The {@link ViewContainerRef} is created as a result of `<template>` element, and represents a
   * location in the current view
   * where these actions are performed.
   * 
   * Views are always created as children of the current {@link ViewMetadata}, and as siblings of the
   * `<template>` element. Thus a
   * directive in a child view cannot inject the directive that created it.
   * 
   * Since directives that create views via ViewContainers are common in Angular, and using the full
   * `<template>` element syntax is wordy, Angular
   * also supports a shorthand notation: `<li *foo="bar">` and `<li template="foo: bar">` are
   * equivalent.
   * 
   * Thus,
   * 
   * ```
   * <ul>
   *   <li *foo="bar" title="text"></li>
   * </ul>
   * ```
   * 
   * Expands in use to:
   * 
   * ```
   * <ul>
   *   <template [foo]="bar">
   *     <li title="text"></li>
   *   </template>
   * </ul>
   * ```
   * 
   * Notice that although the shorthand places `*foo="bar"` within the `<li>` element, the binding for
   * the directive
   * controller is correctly instantiated on the `<template>` element rather than the `<li>` element.
   * 
   * ## Lifecycle hooks
   * 
   * When the directive class implements some {@link angular2/lifecycle_hooks} the callbacks are
   * called by the change detection at defined points in time during the life of the directive.
   * 
   * ### Example
   * 
   * Let's suppose we want to implement the `unless` behavior, to conditionally include a template.
   * 
   * Here is a simple directive that triggers on an `unless` selector:
   * 
   * ```
   * @Directive({
   *   selector: '[unless]',
   *   inputs: ['unless']
   * })
   * export class Unless {
   *   viewContainer: ViewContainerRef;
   *   templateRef: TemplateRef;
   *   prevCondition: boolean;
   * 
   *   constructor(viewContainer: ViewContainerRef, templateRef: TemplateRef) {
   *     this.viewContainer = viewContainer;
   *     this.templateRef = templateRef;
   *     this.prevCondition = null;
   *   }
   * 
   *   set unless(newCondition) {
   *     if (newCondition && (isBlank(this.prevCondition) || !this.prevCondition)) {
   *       this.prevCondition = true;
   *       this.viewContainer.clear();
   *     } else if (!newCondition && (isBlank(this.prevCondition) || this.prevCondition)) {
   *       this.prevCondition = false;
   *       this.viewContainer.create(this.templateRef);
   *     }
   *   }
   * }
   * ```
   * 
   * We can then use this `unless` selector in a template:
   * ```
   * <ul>
   *   <li *unless="expr"></li>
   * </ul>
   * ```
   * 
   * Once the directive instantiates the child view, the shorthand notation for the template expands
   * and the result is:
   * 
   * ```
   * <ul>
   *   <template [unless]="exp">
   *     <li></li>
   *   </template>
   *   <li></li>
   * </ul>
   * ```
   * 
   * Note also that although the `<li></li>` template still exists inside the `<template></template>`,
   * the instantiated
   * view occurs on the second `<li></li>` which is a sibling to the `<template>` element.
   */
  class DirectiveMetadata extends InjectableMetadata {
    
    constructor({selector, inputs, outputs, properties, events, host, bindings, providers, exportAs,
                   moduleId, queries}?: {
        selector?: string,
        inputs?: string[],
        outputs?: string[],
        properties?: string[],
        events?: string[],
        host?: {[key: string]: string},
        providers?: any[],
        /** @deprecated */ bindings?: any[],
        exportAs?: string,
        moduleId?: string,
        queries?: {[key: string]: any}
      });
    
    /**
     * The CSS selector that triggers the instantiation of a directive.
     * 
     * Angular only allows directives to trigger on CSS selectors that do not cross element
     * boundaries.
     * 
     * `selector` may be declared as one of the following:
     * 
     * - `element-name`: select by element name.
     * - `.class`: select by class name.
     * - `[attribute]`: select by attribute name.
     * - `[attribute=value]`: select by attribute name and value.
     * - `:not(sub_selector)`: select only if the element does not match the `sub_selector`.
     * - `selector1, selector2`: select if either `selector1` or `selector2` matches.
     * 
     * 
     * ### Example
     * 
     * Suppose we have a directive with an `input[type=text]` selector.
     * 
     * And the following HTML:
     * 
     * ```html
     * <form>
     *   <input type="text">
     *   <input type="radio">
     * <form>
     * ```
     * 
     * The directive would only be instantiated on the `<input type="text">` element.
     */
    selector: string;
    
    /**
     * Enumerates the set of data-bound input properties for a directive
     * 
     * Angular automatically updates input properties during change detection.
     * 
     * The `inputs` property defines a set of `directiveProperty` to `bindingProperty`
     * configuration:
     * 
     * - `directiveProperty` specifies the component property where the value is written.
     * - `bindingProperty` specifies the DOM property where the value is read from.
     * 
     * When `bindingProperty` is not provided, it is assumed to be equal to `directiveProperty`.
     * 
     * ### Example ([live demo](http://plnkr.co/edit/ivhfXY?p=preview))
     * 
     * The following example creates a component with two data-bound properties.
     * 
     * ```typescript
     * @Component({
     *   selector: 'bank-account',
     *   inputs: ['bankName', 'id: account-id'],
     *   template: `
     *     Bank Name: {{bankName}}
     *     Account Id: {{id}}
     *   `
     * })
     * class BankAccount {
     *   bankName: string;
     *   id: string;
     * 
     *   // this property is not bound, and won't be automatically updated by Angular
     *   normalizedBankName: string;
     * }
     * 
     * @Component({
     *   selector: 'app',
     *   template: `
     *     <bank-account bank-name="RBC" account-id="4747"></bank-account>
     *   `,
     *   directives: [BankAccount]
     * })
     * class App {}
     * 
     * bootstrap(App);
     * ```
     */
    inputs: string[];
    
    properties: string[];
    
    /**
     * Enumerates the set of event-bound output properties.
     * 
     * When an output property emits an event, an event handler attached to that event
     * the template is invoked.
     * 
     * The `outputs` property defines a set of `directiveProperty` to `bindingProperty`
     * configuration:
     * 
     * - `directiveProperty` specifies the component property that emits events.
     * - `bindingProperty` specifies the DOM property the event handler is attached to.
     * 
     * ### Example ([live demo](http://plnkr.co/edit/d5CNq7?p=preview))
     * 
     * ```typescript
     * @Directive({
     *   selector: 'interval-dir',
     *   outputs: ['everySecond', 'five5Secs: everyFiveSeconds']
     * })
     * class IntervalDir {
     *   everySecond = new EventEmitter();
     *   five5Secs = new EventEmitter();
     * 
     *   constructor() {
     *     setInterval(() => this.everySecond.next("event"), 1000);
     *     setInterval(() => this.five5Secs.next("event"), 5000);
     *   }
     * }
     * 
     * @Component({
     *   selector: 'app',
     *   template: `
     *     <interval-dir (every-second)="everySecond()" (every-five-seconds)="everyFiveSeconds()">
     *     </interval-dir>
     *   `,
     *   directives: [IntervalDir]
     * })
     * class App {
     *   everySecond() { console.log('second'); }
     *   everyFiveSeconds() { console.log('five seconds'); }
     * }
     * bootstrap(App);
     * ```
     */
    outputs: string[];
    
    events: string[];
    
    /**
     * Specify the events, actions, properties and attributes related to the host element.
     * 
     * ## Host Listeners
     * 
     * Specifies which DOM events a directive listens to via a set of `(event)` to `method`
     * key-value pairs:
     * 
     * - `event1`: the DOM event that the directive listens to.
     * - `statement`: the statement to execute when the event occurs.
     * If the evaluation of the statement returns `false`, then `preventDefault`is applied on the DOM
     * event.
     * 
     * To listen to global events, a target must be added to the event name.
     * The target can be `window`, `document` or `body`.
     * 
     * When writing a directive event binding, you can also refer to the $event local variable.
     * 
     * ### Example ([live demo](http://plnkr.co/edit/DlA5KU?p=preview))
     * 
     * The following example declares a directive that attaches a click listener to the button and
     * counts clicks.
     * 
     * ```typescript
     * @Directive({
     *   selector: 'button[counting]',
     *   host: {
     *     '(click)': 'onClick($event.target)'
     *   }
     * })
     * class CountClicks {
     *   numberOfClicks = 0;
     * 
     *   onClick(btn) {
     *     console.log("button", btn, "number of clicks:", this.numberOfClicks++);
     *   }
     * }
     * 
     * @Component({
     *   selector: 'app',
     *   template: `<button counting>Increment</button>`,
     *   directives: [CountClicks]
     * })
     * class App {}
     * 
     * bootstrap(App);
     * ```
     * 
     * ## Host Property Bindings
     * 
     * Specifies which DOM properties a directive updates.
     * 
     * Angular automatically checks host property bindings during change detection.
     * If a binding changes, it will update the host element of the directive.
     * 
     * ### Example ([live demo](http://plnkr.co/edit/gNg0ED?p=preview))
     * 
     * The following example creates a directive that sets the `valid` and `invalid` classes
     * on the DOM element that has ng-model directive on it.
     * 
     * ```typescript
     * @Directive({
     *   selector: '[ng-model]',
     *   host: {
     *     '[class.valid]': 'valid',
     *     '[class.invalid]': 'invalid'
     *   }
     * })
     * class NgModelStatus {
     *   constructor(public control:NgModel) {}
     *   get valid { return this.control.valid; }
     *   get invalid { return this.control.invalid; }
     * }
     * 
     * @Component({
     *   selector: 'app',
     *   template: `<input [(ng-model)]="prop">`,
     *   directives: [FORM_DIRECTIVES, NgModelStatus]
     * })
     * class App {
     *   prop;
     * }
     * 
     * bootstrap(App);
     * ```
     * 
     * ## Attributes
     * 
     * Specifies static attributes that should be propagated to a host element.
     * 
     * ### Example
     * 
     * In this example using `my-button` directive (ex.: `<div my-button></div>`) on a host element
     * (here: `<div>` ) will ensure that this element will get the "button" role.
     * 
     * ```typescript
     * @Directive({
     *   selector: '[my-button]',
     *   host: {
     *     'role': 'button'
     *   }
     * })
     * class MyButton {
     * }
     * ```
     */
    host: {[key: string]: string};
    
    /**
     * Defines the set of injectable objects that are visible to a Directive and its light DOM
     * children.
     * 
     * ## Simple Example
     * 
     * Here is an example of a class that can be injected:
     * 
     * ```
     * class Greeter {
     *    greet(name:string) {
     *      return 'Hello ' + name + '!';
     *    }
     * }
     * 
     * @Directive({
     *   selector: 'greet',
     *   bindings: [
     *     Greeter
     *   ]
     * })
     * class HelloWorld {
     *   greeter:Greeter;
     * 
     *   constructor(greeter:Greeter) {
     *     this.greeter = greeter;
     *   }
     * }
     * ```
     */
    providers: any[];
    
    /**
     * @deprecated
     */
    bindings: any[];
    
    /**
     * Defines the name that can be used in the template to assign this directive to a variable.
     * 
     * ## Simple Example
     * 
     * ```
     * @Directive({
     *   selector: 'child-dir',
     *   exportAs: 'child'
     * })
     * class ChildDir {
     * }
     * 
     * @Component({
     *   selector: 'main',
     *   template: `<child-dir #c="child"></child-dir>`,
     *   directives: [ChildDir]
     * })
     * class MainComponent {
     * }
     * 
     * ```
     */
    exportAs: string;
    
    /**
     * The module id of the module that contains the directive.
     * Needed to be able to resolve relative urls for templates and styles.
     * In Dart, this can be determined automatically and does not need to be set.
     * In CommonJS, this can always be set to `module.id`.
     * 
     * ## Simple Example
     * 
     * ```
     * @Directive({
     *   selector: 'someDir',
     *   moduleId: module.id
     * })
     * class SomeDir {
     * }
     * 
     * ```
     */
    moduleId: string;
    
    /**
     * Configures the queries that will be injected into the directive.
     * 
     * Content queries are set before the `afterContentInit` callback is called.
     * View queries are set before the `afterViewInit` callback is called.
     * 
     * ### Example
     * 
     * ```
     * @Component({
     *   selector: 'someDir',
     *   queries: {
     *     contentChildren: new ContentChildren(ChildDirective),
     *     viewChildren: new ViewChildren(ChildDirective)
     *   },
     *   template: '<child-directive></child-directive>',
     *   directives: [ChildDirective]
     * })
     * class SomeDir {
     *   contentChildren: QueryList<ChildDirective>,
     *   viewChildren: QueryList<ChildDirective>
     * 
     *   afterContentInit() {
     *     // contentChildren is set
     *   }
     * 
     *   afterViewInit() {
     *     // viewChildren is set
     *   }
     * }
     * ```
     */
    queries: {[key: string]: any};
    
  }

    
  /**
   * Declare reusable pipe function.
   * 
   * ### Example
   * 
   * ```
   * @Pipe({
   *   name: 'lowercase'
   * })
   * class Lowercase {
   *   transform(v, args) { return v.toLowerCase(); }
   * }
   * ```
   */
  class PipeMetadata extends InjectableMetadata {
    
    constructor({name, pure}: {name: string, pure: boolean});
    
    name: string;
    
    pure: boolean;
    
  }

    
  /**
   * Declares a data-bound input property.
   * 
   * Angular automatically updates data-bound properties during change detection.
   * 
   * `InputMetadata` takes an optional parameter that specifies the name
   * used when instantiating a component in the template. When not provided,
   * the name of the decorated property is used.
   * 
   * ### Example
   * 
   * The following example creates a component with two input properties.
   * 
   * ```typescript
   * @Component({
   *   selector: 'bank-account',
   *   template: `
   *     Bank Name: {{bankName}}
   *     Account Id: {{id}}
   *   `
   * })
   * class BankAccount {
   *   @Input() bankName: string;
   *   @Input('account-id') id: string;
   * 
   *   // this property is not bound, and won't be automatically updated by Angular
   *   normalizedBankName: string;
   * }
   * 
   * @Component({
   *   selector: 'app',
   *   template: `
   *     <bank-account bank-name="RBC" account-id="4747"></bank-account>
   *   `,
   *   directives: [BankAccount]
   * })
   * class App {}
   * 
   * bootstrap(App);
   * ```
   */
  class InputMetadata {
    
    constructor(bindingPropertyName?: string);
    
    /**
     * Name used when instantiating a component in the temlate.
     */
    bindingPropertyName: string;
    
  }

    
  /**
   * Declares an event-bound output property.
   * 
   * When an output property emits an event, an event handler attached to that event
   * the template is invoked.
   * 
   * `OutputMetadata` takes an optional parameter that specifies the name
   * used when instantiating a component in the template. When not provided,
   * the name of the decorated property is used.
   * 
   * ### Example
   * 
   * ```typescript
   * @Directive({
   *   selector: 'interval-dir',
   * })
   * class IntervalDir {
   *   @Output() everySecond = new EventEmitter();
   *   @Output('everyFiveSeconds') five5Secs = new EventEmitter();
   * 
   *   constructor() {
   *     setInterval(() => this.everySecond.next("event"), 1000);
   *     setInterval(() => this.five5Secs.next("event"), 5000);
   *   }
   * }
   * 
   * @Component({
   *   selector: 'app',
   *   template: `
   *     <interval-dir (every-second)="everySecond()" (every-five-seconds)="everyFiveSeconds()">
   *     </interval-dir>
   *   `,
   *   directives: [IntervalDir]
   * })
   * class App {
   *   everySecond() { console.log('second'); }
   *   everyFiveSeconds() { console.log('five seconds'); }
   * }
   * bootstrap(App);
   * ```
   */
  class OutputMetadata {
    
    constructor(bindingPropertyName?: string);
    
    bindingPropertyName: string;
    
  }

    
  /**
   * Declares a host property binding.
   * 
   * Angular automatically checks host property bindings during change detection.
   * If a binding changes, it will update the host element of the directive.
   * 
   * `HostBindingMetadata` takes an optional parameter that specifies the property
   * name of the host element that will be updated. When not provided,
   * the class property name is used.
   * 
   * ### Example
   * 
   * The following example creates a directive that sets the `valid` and `invalid` classes
   * on the DOM element that has ng-model directive on it.
   * 
   * ```typescript
   * @Directive({selector: '[ng-model]'})
   * class NgModelStatus {
   *   constructor(public control:NgModel) {}
   *   @HostBinding('[class.valid]') get valid { return this.control.valid; }
   *   @HostBinding('[class.invalid]') get invalid { return this.control.invalid; }
   * }
   * 
   * @Component({
   *   selector: 'app',
   *   template: `<input [(ng-model)]="prop">`,
   *   directives: [FORM_DIRECTIVES, NgModelStatus]
   * })
   * class App {
   *   prop;
   * }
   * 
   * bootstrap(App);
   * ```
   */
  class HostBindingMetadata {
    
    constructor(hostPropertyName?: string);
    
    hostPropertyName: string;
    
  }

    
  /**
   * Declares a host listener.
   * 
   * Angular will invoke the decorated method when the host element emits the specified event.
   * 
   * If the decorated method returns `false`, then `preventDefault` is applied on the DOM
   * event.
   * 
   * ### Example
   * 
   * The following example declares a directive that attaches a click listener to the button and
   * counts clicks.
   * 
   * ```typescript
   * @Directive({selector: 'button[counting]'})
   * class CountClicks {
   *   numberOfClicks = 0;
   * 
   *   @HostListener('click', ['$event.target'])
   *   onClick(btn) {
   *     console.log("button", btn, "number of clicks:", this.numberOfClicks++);
   *   }
   * }
   * 
   * @Component({
   *   selector: 'app',
   *   template: `<button counting>Increment</button>`,
   *   directives: [CountClicks]
   * })
   * class App {}
   * 
   * bootstrap(App);
   * ```
   */
  class HostListenerMetadata {
    
    constructor(eventName: string, args?: string[]);
    
    eventName: string;
    
    args: string[];
    
  }

    
  /**
   * Metadata properties available for configuring Views.
   * 
   * Each Angular component requires a single `@Component` and at least one `@View` annotation. The
   * `@View` annotation specifies the HTML template to use, and lists the directives that are active
   * within the template.
   * 
   * When a component is instantiated, the template is loaded into the component's shadow root, and
   * the expressions and statements in the template are evaluated against the component.
   * 
   * For details on the `@Component` annotation, see {@link ComponentMetadata}.
   * 
   * ### Example
   * 
   * ```
   * @Component({
   *   selector: 'greet',
   *   template: 'Hello {{name}}!',
   *   directives: [GreetUser, Bold]
   * })
   * class Greet {
   *   name: string;
   * 
   *   constructor() {
   *     this.name = 'World';
   *   }
   * }
   * ```
   */
  class ViewMetadata {
    
    constructor({templateUrl, template, directives, pipes, encapsulation, styles, styleUrls}?: {
        templateUrl?: string,
        template?: string,
        directives?: Array<Type | any[]>,
        pipes?: Array<Type | any[]>,
        encapsulation?: ViewEncapsulation,
        styles?: string[],
        styleUrls?: string[],
      });
    
    /**
     * Specifies a template URL for an Angular component.
     * 
     * NOTE: Only one of `templateUrl` or `template` can be defined per View.
     * 
     * <!-- TODO: what's the url relative to? -->
     */
    templateUrl: string;
    
    /**
     * Specifies an inline template for an Angular component.
     * 
     * NOTE: Only one of `templateUrl` or `template` can be defined per View.
     */
    template: string;
    
    /**
     * Specifies stylesheet URLs for an Angular component.
     * 
     * <!-- TODO: what's the url relative to? -->
     */
    styleUrls: string[];
    
    /**
     * Specifies an inline stylesheet for an Angular component.
     */
    styles: string[];
    
    /**
     * Specifies a list of directives that can be used within a template.
     * 
     * Directives must be listed explicitly to provide proper component encapsulation.
     * 
     * ### Example
     * 
     * ```javascript
     * @Component({
     *   selector: 'my-component',
     *   directives: [NgFor]
     *   template: '
     *   <ul>
     *     <li *ng-for="#item of items">{{item}}</li>
     *   </ul>'
     * })
     * class MyComponent {
     * }
     * ```
     */
    directives: Array<Type | any[]>;
    
    pipes: Array<Type | any[]>;
    
    /**
     * Specify how the template and the styles should be encapsulated.
     * The default is {@link ViewEncapsulation#Emulated `ViewEncapsulation.Emulated`} if the view
     * has styles,
     * otherwise {@link ViewEncapsulation#None `ViewEncapsulation.None`}.
     */
    encapsulation: ViewEncapsulation;
    
  }

    
  /**
   * Defines template and style encapsulation options available for Component's {@link View}.
   * 
   * See {@link ViewMetadata#encapsulation}.
   */
  enum ViewEncapsulation {
    
    /**
     * Emulate `Native` scoping of styles by adding an attribute containing surrogate id to the Host
     * Element and pre-processing the style rules provided via
     * {@link ViewMetadata#styles} or {@link ViewMetadata#stylesUrls}, and adding the new Host Element
     * attribute to all selectors.
     * 
     * This is the default option.
     */
    Emulated,
    
    /**
     * Use the native encapsulation mechanism of the renderer.
     * 
     * For the DOM this means using [Shadow DOM](https://w3c.github.io/webcomponents/spec/shadow/) and
     * creating a ShadowRoot for Component's Host Element.
     */
    Native,
    
    /**
     * Don't provide any template or style encapsulation.
     */
    None
  }
  

    
  /**
   * Interface for the {@link DirectiveMetadata} decorator function.
   * 
   * See {@link DirectiveFactory}.
   */
  interface DirectiveDecorator extends TypeDecorator {
    
  }

    
  /**
   * Interface for the {@link ComponentMetadata} decorator function.
   * 
   * See {@link ComponentFactory}.
   */
  interface ComponentDecorator extends TypeDecorator {
    
    /**
     * Chain {@link ViewMetadata} annotation.
     */
    View(obj: {
        templateUrl?: string,
        template?: string,
        directives?: Array<Type | any[]>,
        pipes?: Array<Type | any[]>,
        renderer?: string,
        styles?: string[],
        styleUrls?: string[],
      }): ViewDecorator;
    
  }

    
  /**
   * Interface for the {@link ViewMetadata} decorator function.
   * 
   * See {@link ViewFactory}.
   */
  interface ViewDecorator extends TypeDecorator {
    
    /**
     * Chain {@link ViewMetadata} annotation.
     */
    View(obj: {
        templateUrl?: string,
        template?: string,
        directives?: Array<Type | any[]>,
        pipes?: Array<Type | any[]>,
        renderer?: string,
        styles?: string[],
        styleUrls?: string[],
      }): ViewDecorator;
    
  }

    
  /**
   * {@link DirectiveMetadata} factory for creating annotations, decorators or DSL.
   * 
   * ### Example as TypeScript Decorator
   * 
   * ```
   * import {Directive} from "angular2/angular2";
   * 
   * @Directive({...})
   * class MyDirective {
   *   constructor() {
   *     ...
   *   }
   * }
   * ```
   * 
   * ### Example as ES5 DSL
   * 
   * ```
   * var MyDirective = ng
   *   .Directive({...})
   *   .Class({
   *     constructor: function() {
   *       ...
   *     }
   *   })
   * ```
   * 
   * ### Example as ES5 annotation
   * 
   * ```
   * var MyDirective = function() {
   *   ...
   * };
   * 
   * MyDirective.annotations = [
   *   new ng.Directive({...})
   * ]
   * ```
   */
  interface DirectiveFactory {
    
    new(obj: {
        selector?: string,
        inputs?: string[],
        outputs?: string[],
        properties?: string[],
        events?: string[],
        host?: {[key: string]: string},
        bindings?: any[],
        providers?: any[],
        exportAs?: string,
        moduleId?: string,
        queries?: {[key: string]: any}
      }): DirectiveMetadata;
    
    (obj: {
        selector?: string,
        inputs?: string[],
        outputs?: string[],
        properties?: string[],
        events?: string[],
        host?: {[key: string]: string},
        bindings?: any[],
        providers?: any[],
        exportAs?: string,
        moduleId?: string,
        queries?: {[key: string]: any}
      }): DirectiveDecorator;
    
  }

    
  /**
   * {@link ComponentMetadata} factory for creating annotations, decorators or DSL.
   * 
   * ### Example as TypeScript Decorator
   * 
   * ```
   * import {Component} from "angular2/angular2";
   * 
   * @Component({...})
   * class MyComponent {
   *   constructor() {
   *     ...
   *   }
   * }
   * ```
   * 
   * ### Example as ES5 DSL
   * 
   * ```
   * var MyComponent = ng
   *   .Component({...})
   *   .Class({
   *     constructor: function() {
   *       ...
   *     }
   *   })
   * ```
   * 
   * ### Example as ES5 annotation
   * 
   * ```
   * var MyComponent = function() {
   *   ...
   * };
   * 
   * MyComponent.annotations = [
   *   new ng.Component({...})
   * ]
   * ```
   */
  interface ComponentFactory {
    
    new(obj: {
        selector?: string,
        inputs?: string[],
        outputs?: string[],
        properties?: string[],
        events?: string[],
        host?: {[key: string]: string},
        /* @deprecated */
        bindings?: any[],
        providers?: any[],
        exportAs?: string,
        moduleId?: string,
        queries?: {[key: string]: any},
        /* @deprecated */
        viewBindings?: any[],
        viewProviders?: any[],
        changeDetection?: ChangeDetectionStrategy,
        templateUrl?: string,
        template?: string,
        styleUrls?: string[],
        styles?: string[],
        directives?: Array<Type | any[]>,
        pipes?: Array<Type | any[]>,
        encapsulation?: ViewEncapsulation
      }): ComponentMetadata;
    
    (obj: {
        selector?: string,
        inputs?: string[],
        outputs?: string[],
        properties?: string[],
        events?: string[],
        host?: {[key: string]: string},
        /* @deprecated */
        bindings?: any[],
        providers?: any[],
        exportAs?: string,
        moduleId?: string,
        queries?: {[key: string]: any},
        viewBindings?: any[],
        viewProviders?: any[],
        changeDetection?: ChangeDetectionStrategy,
        templateUrl?: string,
        template?: string,
        styleUrls?: string[],
        styles?: string[],
        directives?: Array<Type | any[]>,
        pipes?: Array<Type | any[]>,
        encapsulation?: ViewEncapsulation
      }): ComponentDecorator;
    
  }

    
  /**
   * {@link ViewMetadata} factory for creating annotations, decorators or DSL.
   * 
   * ### Example as TypeScript Decorator
   * 
   * ```
   * import {Component, View} from "angular2/angular2";
   * 
   * @Component({...})
   * @View({...})
   * class MyComponent {
   *   constructor() {
   *     ...
   *   }
   * }
   * ```
   * 
   * ### Example as ES5 DSL
   * 
   * ```
   * var MyComponent = ng
   *   .Component({...})
   *   .View({...})
   *   .Class({
   *     constructor: function() {
   *       ...
   *     }
   *   })
   * ```
   * 
   * ### Example as ES5 annotation
   * 
   * ```
   * var MyComponent = function() {
   *   ...
   * };
   * 
   * MyComponent.annotations = [
   *   new ng.Component({...}),
   *   new ng.View({...})
   * ]
   * ```
   */
  interface ViewFactory {
    
    new(obj: {
        templateUrl?: string,
        template?: string,
        directives?: Array<Type | any[]>,
        pipes?: Array<Type | any[]>,
        encapsulation?: ViewEncapsulation,
        styles?: string[],
        styleUrls?: string[],
      }): ViewMetadata;
    
    (obj: {
        templateUrl?: string,
        template?: string,
        directives?: Array<Type | any[]>,
        pipes?: Array<Type | any[]>,
        encapsulation?: ViewEncapsulation,
        styles?: string[],
        styleUrls?: string[],
      }): ViewDecorator;
    
  }

    
  /**
   * {@link AttributeMetadata} factory for creating annotations, decorators or DSL.
   * 
   * ### Example as TypeScript Decorator
   * 
   * ```
   * import {Attribute, Component} from "angular2/angular2";
   * 
   * @Component({...})
   * class MyComponent {
   *   constructor(@Attribute('title') title: string) {
   *     ...
   *   }
   * }
   * ```
   * 
   * ### Example as ES5 DSL
   * 
   * ```
   * var MyComponent = ng
   *   .Component({...})
   *   .Class({
   *     constructor: [new ng.Attribute('title'), function(title) {
   *       ...
   *     }]
   *   })
   * ```
   * 
   * ### Example as ES5 annotation
   * 
   * ```
   * var MyComponent = function(title) {
   *   ...
   * };
   * 
   * MyComponent.annotations = [
   *   new ng.Component({...})
   * ]
   * MyComponent.parameters = [
   *   [new ng.Attribute('title')]
   * ]
   * ```
   */
  interface AttributeFactory {
    
    new(name: string): AttributeMetadata;
    
    (name: string): TypeDecorator;
    
  }

    
  /**
   * {@link QueryMetadata} factory for creating annotations, decorators or DSL.
   * 
   * ### Example as TypeScript Decorator
   * 
   * ```
   * import {Query, QueryList, Component} from "angular2/angular2";
   * 
   * @Component({...})
   * class MyComponent {
   *   constructor(@Query(SomeType) queryList: QueryList<SomeType>) {
   *     ...
   *   }
   * }
   * ```
   * 
   * ### Example as ES5 DSL
   * 
   * ```
   * var MyComponent = ng
   *   .Component({...})
   *   .Class({
   *     constructor: [new ng.Query(SomeType), function(queryList) {
   *       ...
   *     }]
   *   })
   * ```
   * 
   * ### Example as ES5 annotation
   * 
   * ```
   * var MyComponent = function(queryList) {
   *   ...
   * };
   * 
   * MyComponent.annotations = [
   *   new ng.Component({...})
   * ]
   * MyComponent.parameters = [
   *   [new ng.Query(SomeType)]
   * ]
   * ```
   */
  interface QueryFactory {
    
    new(selector: Type | string, {descendants}?: {descendants?: boolean}): QueryMetadata;
    
    (selector: Type | string, {descendants}?: {descendants?: boolean}): ParameterDecorator;
    
  }

    
  interface ContentChildrenFactory {
    
    new(selector: Type | string, {descendants}?: {descendants?: boolean}): ContentChildrenMetadata;
    
    (selector: Type | string, {descendants}?: {descendants?: boolean}): any;
    
  }

    
  interface ContentChildFactory {
    
    new(selector: Type | string): ContentChildFactory;
    
    (selector: Type | string): any;
    
  }

    
  interface ViewChildrenFactory {
    
    new(selector: Type | string): ViewChildrenMetadata;
    
    (selector: Type | string): any;
    
  }

    
  interface ViewChildFactory {
    
    new(selector: Type | string): ViewChildFactory;
    
    (selector: Type | string): any;
    
  }

    
  /**
   * {@link PipeMetadata} factory for creating decorators.
   * 
   * ### Example as TypeScript Decorator
   * 
   * ```
   * import {Pipe} from "angular2/angular2";
   * 
   * @Pipe({...})
   * class MyPipe {
   *   constructor() {
   *     ...
   *   }
   * 
   *   transform(v, args) {}
   * }
   * ```
   */
  interface PipeFactory {
    
    new(obj: {name: string, pure?: boolean}): any;
    
    (obj: {name: string, pure?: boolean}): any;
    
  }

    
  /**
   * {@link InputMetadata} factory for creating decorators.
   * 
   * See {@link InputMetadata}.
   */
  interface InputFactory {
    
    new(bindingPropertyName?: string): any;
    
    (bindingPropertyName?: string): any;
    
  }

    
  /**
   * {@link OutputMetadata} factory for creating decorators.
   * 
   * See {@link OutputMetadata}.
   */
  interface OutputFactory {
    
    new(bindingPropertyName?: string): any;
    
    (bindingPropertyName?: string): any;
    
  }

    
  /**
   * {@link HostBindingMetadata} factory function.
   */
  interface HostBindingFactory {
    
    new(hostPropertyName?: string): any;
    
    (hostPropertyName?: string): any;
    
  }

    
  /**
   * {@link HostListenerMetadata} factory function.
   */
  interface HostListenerFactory {
    
    new(eventName: string, args?: string[]): any;
    
    (eventName: string, args?: string[]): any;
    
  }

    
  /**
   * Declare reusable UI building blocks for an application.
   * 
   * Each Angular component requires a single `@Component` and at least one `@View` annotation. The
   * `@Component`
   * annotation specifies when a component is instantiated, and which properties and hostListeners it
   * binds to.
   * 
   * When a component is instantiated, Angular
   * - creates a shadow DOM for the component.
   * - loads the selected template into the shadow DOM.
   * - creates all the injectable objects configured with `providers` and `viewProviders`.
   * 
   * All template expressions and statements are then evaluated against the component instance.
   * 
   * For details on the `@View` annotation, see {@link ViewMetadata}.
   * 
   * ## Lifecycle hooks
   * 
   * When the component class implements some {@link angular2/lifecycle_hooks} the callbacks are
   * called by the change detection at defined points in time during the life of the component.
   * 
   * ### Example
   * 
   * ```
   * @Component({
   *   selector: 'greet',
   *   template: 'Hello {{name}}!'
   * })
   * class Greet {
   *   name: string;
   * 
   *   constructor() {
   *     this.name = 'World';
   *   }
   * }
   * ```
   */
  var Component: ComponentFactory;
  

    
  /**
   * Directives allow you to attach behavior to elements in the DOM.
   * 
   * {@link DirectiveMetadata}s with an embedded view are called {@link ComponentMetadata}s.
   * 
   * A directive consists of a single directive annotation and a controller class. When the
   * directive's `selector` matches
   * elements in the DOM, the following steps occur:
   * 
   * 1. For each directive, the `ElementInjector` attempts to resolve the directive's constructor
   * arguments.
   * 2. Angular instantiates directives for each matched element using `ElementInjector` in a
   * depth-first order,
   *    as declared in the HTML.
   * 
   * ## Understanding How Injection Works
   * 
   * There are three stages of injection resolution.
   * - *Pre-existing Injectors*:
   *   - The terminal {@link Injector} cannot resolve dependencies. It either throws an error or, if
   * the dependency was
   *     specified as `@Optional`, returns `null`.
   *   - The platform injector resolves browser singleton resources, such as: cookies, title,
   * location, and others.
   * - *Component Injectors*: Each component instance has its own {@link Injector}, and they follow
   * the same parent-child hierarchy
   *     as the component instances in the DOM.
   * - *Element Injectors*: Each component instance has a Shadow DOM. Within the Shadow DOM each
   * element has an `ElementInjector`
   *     which follow the same parent-child hierarchy as the DOM elements themselves.
   * 
   * When a template is instantiated, it also must instantiate the corresponding directives in a
   * depth-first order. The
   * current `ElementInjector` resolves the constructor dependencies for each directive.
   * 
   * Angular then resolves dependencies as follows, according to the order in which they appear in the
   * {@link ViewMetadata}:
   * 
   * 1. Dependencies on the current element
   * 2. Dependencies on element injectors and their parents until it encounters a Shadow DOM boundary
   * 3. Dependencies on component injectors and their parents until it encounters the root component
   * 4. Dependencies on pre-existing injectors
   * 
   * 
   * The `ElementInjector` can inject other directives, element-specific special objects, or it can
   * delegate to the parent
   * injector.
   * 
   * To inject other directives, declare the constructor parameter as:
   * - `directive:DirectiveType`: a directive on the current element only
   * - `@Host() directive:DirectiveType`: any directive that matches the type between the current
   * element and the
   *    Shadow DOM root.
   * - `@Query(DirectiveType) query:QueryList<DirectiveType>`: A live collection of direct child
   * directives.
   * - `@QueryDescendants(DirectiveType) query:QueryList<DirectiveType>`: A live collection of any
   * child directives.
   * 
   * To inject element-specific special objects, declare the constructor parameter as:
   * - `element: ElementRef` to obtain a reference to logical element in the view.
   * - `viewContainer: ViewContainerRef` to control child template instantiation, for
   * {@link DirectiveMetadata} directives only
   * - `bindingPropagation: BindingPropagation` to control change detection in a more granular way.
   * 
   * ### Example
   * 
   * The following example demonstrates how dependency injection resolves constructor arguments in
   * practice.
   * 
   * 
   * Assume this HTML template:
   * 
   * ```
   * <div dependency="1">
   *   <div dependency="2">
   *     <div dependency="3" my-directive>
   *       <div dependency="4">
   *         <div dependency="5"></div>
   *       </div>
   *       <div dependency="6"></div>
   *     </div>
   *   </div>
   * </div>
   * ```
   * 
   * With the following `dependency` decorator and `SomeService` injectable class.
   * 
   * ```
   * @Injectable()
   * class SomeService {
   * }
   * 
   * @Directive({
   *   selector: '[dependency]',
   *   inputs: [
   *     'id: dependency'
   *   ]
   * })
   * class Dependency {
   *   id:string;
   * }
   * ```
   * 
   * Let's step through the different ways in which `MyDirective` could be declared...
   * 
   * 
   * ### No injection
   * 
   * Here the constructor is declared with no arguments, therefore nothing is injected into
   * `MyDirective`.
   * 
   * ```
   * @Directive({ selector: '[my-directive]' })
   * class MyDirective {
   *   constructor() {
   *   }
   * }
   * ```
   * 
   * This directive would be instantiated with no dependencies.
   * 
   * 
   * ### Component-level injection
   * 
   * Directives can inject any injectable instance from the closest component injector or any of its
   * parents.
   * 
   * Here, the constructor declares a parameter, `someService`, and injects the `SomeService` type
   * from the parent
   * component's injector.
   * ```
   * @Directive({ selector: '[my-directive]' })
   * class MyDirective {
   *   constructor(someService: SomeService) {
   *   }
   * }
   * ```
   * 
   * This directive would be instantiated with a dependency on `SomeService`.
   * 
   * 
   * ### Injecting a directive from the current element
   * 
   * Directives can inject other directives declared on the current element.
   * 
   * ```
   * @Directive({ selector: '[my-directive]' })
   * class MyDirective {
   *   constructor(dependency: Dependency) {
   *     expect(dependency.id).toEqual(3);
   *   }
   * }
   * ```
   * This directive would be instantiated with `Dependency` declared at the same element, in this case
   * `dependency="3"`.
   * 
   * ### Injecting a directive from any ancestor elements
   * 
   * Directives can inject other directives declared on any ancestor element (in the current Shadow
   * DOM), i.e. on the current element, the
   * parent element, or its parents.
   * ```
   * @Directive({ selector: '[my-directive]' })
   * class MyDirective {
   *   constructor(@Host() dependency: Dependency) {
   *     expect(dependency.id).toEqual(2);
   *   }
   * }
   * ```
   * 
   * `@Host` checks the current element, the parent, as well as its parents recursively. If
   * `dependency="2"` didn't
   * exist on the direct parent, this injection would
   * have returned
   * `dependency="1"`.
   * 
   * 
   * ### Injecting a live collection of direct child directives
   * 
   * 
   * A directive can also query for other child directives. Since parent directives are instantiated
   * before child directives, a directive can't simply inject the list of child directives. Instead,
   * the directive injects a {@link QueryList}, which updates its contents as children are added,
   * removed, or moved by a directive that uses a {@link ViewContainerRef} such as a `ng-for`, an
   * `ng-if`, or an `ng-switch`.
   * 
   * ```
   * @Directive({ selector: '[my-directive]' })
   * class MyDirective {
   *   constructor(@Query(Dependency) dependencies:QueryList<Dependency>) {
   *   }
   * }
   * ```
   * 
   * This directive would be instantiated with a {@link QueryList} which contains `Dependency` 4 and
   * 6. Here, `Dependency` 5 would not be included, because it is not a direct child.
   * 
   * ### Injecting a live collection of descendant directives
   * 
   * By passing the descendant flag to `@Query` above, we can include the children of the child
   * elements.
   * 
   * ```
   * @Directive({ selector: '[my-directive]' })
   * class MyDirective {
   *   constructor(@Query(Dependency, {descendants: true}) dependencies:QueryList<Dependency>) {
   *   }
   * }
   * ```
   * 
   * This directive would be instantiated with a Query which would contain `Dependency` 4, 5 and 6.
   * 
   * ### Optional injection
   * 
   * The normal behavior of directives is to return an error when a specified dependency cannot be
   * resolved. If you
   * would like to inject `null` on unresolved dependency instead, you can annotate that dependency
   * with `@Optional()`.
   * This explicitly permits the author of a template to treat some of the surrounding directives as
   * optional.
   * 
   * ```
   * @Directive({ selector: '[my-directive]' })
   * class MyDirective {
   *   constructor(@Optional() dependency:Dependency) {
   *   }
   * }
   * ```
   * 
   * This directive would be instantiated with a `Dependency` directive found on the current element.
   * If none can be
   * found, the injector supplies `null` instead of throwing an error.
   * 
   * ### Example
   * 
   * Here we use a decorator directive to simply define basic tool-tip behavior.
   * 
   * ```
   * @Directive({
   *   selector: '[tooltip]',
   *   inputs: [
   *     'text: tooltip'
   *   ],
   *   host: {
   *     '(mouseenter)': 'onMouseEnter()',
   *     '(mouseleave)': 'onMouseLeave()'
   *   }
   * })
   * class Tooltip{
   *   text:string;
   *   overlay:Overlay; // NOT YET IMPLEMENTED
   *   overlayManager:OverlayManager; // NOT YET IMPLEMENTED
   * 
   *   constructor(overlayManager:OverlayManager) {
   *     this.overlay = overlay;
   *   }
   * 
   *   onMouseEnter() {
   *     // exact signature to be determined
   *     this.overlay = this.overlayManager.open(text, ...);
   *   }
   * 
   *   onMouseLeave() {
   *     this.overlay.close();
   *     this.overlay = null;
   *   }
   * }
   * ```
   * In our HTML template, we can then add this behavior to a `<div>` or any other element with the
   * `tooltip` selector,
   * like so:
   * 
   * ```
   * <div tooltip="some text here"></div>
   * ```
   * 
   * Directives can also control the instantiation, destruction, and positioning of inline template
   * elements:
   * 
   * A directive uses a {@link ViewContainerRef} to instantiate, insert, move, and destroy views at
   * runtime.
   * The {@link ViewContainerRef} is created as a result of `<template>` element, and represents a
   * location in the current view
   * where these actions are performed.
   * 
   * Views are always created as children of the current {@link ViewMetadata}, and as siblings of the
   * `<template>` element. Thus a
   * directive in a child view cannot inject the directive that created it.
   * 
   * Since directives that create views via ViewContainers are common in Angular, and using the full
   * `<template>` element syntax is wordy, Angular
   * also supports a shorthand notation: `<li *foo="bar">` and `<li template="foo: bar">` are
   * equivalent.
   * 
   * Thus,
   * 
   * ```
   * <ul>
   *   <li *foo="bar" title="text"></li>
   * </ul>
   * ```
   * 
   * Expands in use to:
   * 
   * ```
   * <ul>
   *   <template [foo]="bar">
   *     <li title="text"></li>
   *   </template>
   * </ul>
   * ```
   * 
   * Notice that although the shorthand places `*foo="bar"` within the `<li>` element, the binding for
   * the directive
   * controller is correctly instantiated on the `<template>` element rather than the `<li>` element.
   * 
   * ## Lifecycle hooks
   * 
   * When the directive class implements some {@link angular2/lifecycle_hooks} the callbacks are
   * called by the change detection at defined points in time during the life of the directive.
   * 
   * ### Example
   * 
   * Let's suppose we want to implement the `unless` behavior, to conditionally include a template.
   * 
   * Here is a simple directive that triggers on an `unless` selector:
   * 
   * ```
   * @Directive({
   *   selector: '[unless]',
   *   inputs: ['unless']
   * })
   * export class Unless {
   *   viewContainer: ViewContainerRef;
   *   templateRef: TemplateRef;
   *   prevCondition: boolean;
   * 
   *   constructor(viewContainer: ViewContainerRef, templateRef: TemplateRef) {
   *     this.viewContainer = viewContainer;
   *     this.templateRef = templateRef;
   *     this.prevCondition = null;
   *   }
   * 
   *   set unless(newCondition) {
   *     if (newCondition && (isBlank(this.prevCondition) || !this.prevCondition)) {
   *       this.prevCondition = true;
   *       this.viewContainer.clear();
   *     } else if (!newCondition && (isBlank(this.prevCondition) || this.prevCondition)) {
   *       this.prevCondition = false;
   *       this.viewContainer.create(this.templateRef);
   *     }
   *   }
   * }
   * ```
   * 
   * We can then use this `unless` selector in a template:
   * ```
   * <ul>
   *   <li *unless="expr"></li>
   * </ul>
   * ```
   * 
   * Once the directive instantiates the child view, the shorthand notation for the template expands
   * and the result is:
   * 
   * ```
   * <ul>
   *   <template [unless]="exp">
   *     <li></li>
   *   </template>
   *   <li></li>
   * </ul>
   * ```
   * 
   * Note also that although the `<li></li>` template still exists inside the `<template></template>`,
   * the instantiated
   * view occurs on the second `<li></li>` which is a sibling to the `<template>` element.
   */
  var Directive: DirectiveFactory;
  

    
  /**
   * Metadata properties available for configuring Views.
   * 
   * Each Angular component requires a single `@Component` and at least one `@View` annotation. The
   * `@View` annotation specifies the HTML template to use, and lists the directives that are active
   * within the template.
   * 
   * When a component is instantiated, the template is loaded into the component's shadow root, and
   * the expressions and statements in the template are evaluated against the component.
   * 
   * For details on the `@Component` annotation, see {@link ComponentMetadata}.
   * 
   * ### Example
   * 
   * ```
   * @Component({
   *   selector: 'greet',
   *   template: 'Hello {{name}}!',
   *   directives: [GreetUser, Bold]
   * })
   * class Greet {
   *   name: string;
   * 
   *   constructor() {
   *     this.name = 'World';
   *   }
   * }
   * ```
   */
  var View: ViewFactory;
  

    
  /**
   * Metadata properties available for configuring Views.
   * 
   * Each Angular component requires a single `@Component` and at least one `@View` annotation. The
   * `@View` annotation specifies the HTML template to use, and lists the directives that are active
   * within the template.
   * 
   * When a component is instantiated, the template is loaded into the component's shadow root, and
   * the expressions and statements in the template are evaluated against the component.
   * 
   * For details on the `@Component` annotation, see {@link ComponentMetadata}.
   * 
   * ### Example
   * 
   * ```
   * @Component({
   *   selector: 'greet',
   *   template: 'Hello {{name}}!',
   *   directives: [GreetUser, Bold]
   * })
   * class Greet {
   *   name: string;
   * 
   *   constructor() {
   *     this.name = 'World';
   *   }
   * }
   * ```
   */
  var Attribute: AttributeFactory;
  

    
  /**
   * Declares an injectable parameter to be a live list of directives or variable
   * bindings from the content children of a directive.
   * 
   * ### Example ([live demo](http://plnkr.co/edit/lY9m8HLy7z06vDoUaSN2?p=preview))
   * 
   * Assume that `<tabs>` component would like to get a list its children `<pane>`
   * components as shown in this example:
   * 
   * ```html
   * <tabs>
   *   <pane title="Overview">...</pane>
   *   <pane *ng-for="#o of objects" [title]="o.title">{{o.text}}</pane>
   * </tabs>
   * ```
   * 
   * The preferred solution is to query for `Pane` directives using this decorator.
   * 
   * ```javascript
   * @Component({
   *   selector: 'pane',
   *   inputs: ['title']
   * })
   * class Pane {
   *   title:string;
   * }
   * 
   * @Component({
   *  selector: 'tabs',
   *  template: `
   *    <ul>
   *      <li *ng-for="#pane of panes">{{pane.title}}</li>
   *    </ul>
   *    <content></content>
   *  `
   * })
   * class Tabs {
   *   panes: QueryList<Pane>;
   *   constructor(@Query(Pane) panes:QueryList<Pane>) {
   *     this.panes = panes;
   *   }
   * }
   * ```
   * 
   * A query can look for variable bindings by passing in a string with desired binding symbol.
   * 
   * ### Example ([live demo](http://plnkr.co/edit/sT2j25cH1dURAyBRCKx1?p=preview))
   * ```html
   * <seeker>
   *   <div #findme>...</div>
   * </seeker>
   * 
   * @Component({ selector: 'foo' })
   * class seeker {
   *   constructor(@Query('findme') elList: QueryList<ElementRef>) {...}
   * }
   * ```
   * 
   * In this case the object that is injected depend on the type of the variable
   * binding. It can be an ElementRef, a directive or a component.
   * 
   * Passing in a comma separated list of variable bindings will query for all of them.
   * 
   * ```html
   * <seeker>
   *   <div #find-me>...</div>
   *   <div #find-me-too>...</div>
   * </seeker>
   * 
   *  @Component({
   *   selector: 'foo'
   * })
   * class Seeker {
   *   constructor(@Query('findMe, findMeToo') elList: QueryList<ElementRef>) {...}
   * }
   * ```
   * 
   * Configure whether query looks for direct children or all descendants
   * of the querying element, by using the `descendants` parameter.
   * It is set to `false` by default.
   * 
   * ### Example ([live demo](http://plnkr.co/edit/wtGeB977bv7qvA5FTYl9?p=preview))
   * ```html
   * <container #first>
   *   <item>a</item>
   *   <item>b</item>
   *   <container #second>
   *     <item>c</item>
   *   </container>
   * </container>
   * ```
   * 
   * When querying for items, the first container will see only `a` and `b` by default,
   * but with `Query(TextDirective, {descendants: true})` it will see `c` too.
   * 
   * The queried directives are kept in a depth-first pre-order with respect to their
   * positions in the DOM.
   * 
   * Query does not look deep into any subcomponent views.
   * 
   * Query is updated as part of the change-detection cycle. Since change detection
   * happens after construction of a directive, QueryList will always be empty when observed in the
   * constructor.
   * 
   * The injected object is an unmodifiable live list.
   * See {@link QueryList} for more details.
   */
  var Query: QueryFactory;
  

    
  /**
   * Configures a content query.
   * 
   * Content queries are set before the `afterContentInit` callback is called.
   * 
   * ### Example
   * 
   * ```
   * @Directive({
   *   selector: 'someDir'
   * })
   * class SomeDir {
   *   @ContentChildren(ChildDirective) contentChildren: QueryList<ChildDirective>;
   * 
   *   afterContentInit() {
   *     // contentChildren is set
   *   }
   * }
   * ```
   */
  var ContentChildren: ContentChildrenFactory;
  

    
  /**
   * Configures a content query.
   * 
   * Content queries are set before the `afterContentInit` callback is called.
   * 
   * ### Example
   * 
   * ```
   * @Directive({
   *   selector: 'someDir'
   * })
   * class SomeDir {
   *   @ContentChild(ChildDirective) contentChild;
   * 
   *   afterContentInit() {
   *     // contentChild is set
   *   }
   * }
   * ```
   */
  var ContentChild: ContentChildFactory;
  

    
  /**
   * Configures a view query.
   * 
   * View queries are set before the `afterViewInit` callback is called.
   * 
   * ### Example
   * 
   * ```
   * @Component({
   *   selector: 'someDir',
   *   templateUrl: 'someTemplate',
   *   directives: [ItemDirective]
   * })
   * class SomeDir {
   *   @ViewChildren(ItemDirective) viewChildren: QueryList<ItemDirective>;
   * 
   *   afterViewInit() {
   *     // viewChildren is set
   *   }
   * }
   * ```
   */
  var ViewChildren: ViewChildrenFactory;
  

    
  /**
   * Configures a view query.
   * 
   * View queries are set before the `afterViewInit` callback is called.
   * 
   * ### Example
   * 
   * ```
   * @Component({
   *   selector: 'someDir',
   *   templateUrl: 'someTemplate',
   *   directives: [ItemDirective]
   * })
   * class SomeDir {
   *   @ViewChild(ItemDirective) viewChild:ItemDirective;
   * 
   *   afterViewInit() {
   *     // viewChild is set
   *   }
   * }
   * ```
   */
  var ViewChild: ViewChildFactory;
  

    
  /**
   * Similar to {@link QueryMetadata}, but querying the component view, instead of
   * the content children.
   * 
   * ### Example ([live demo](http://plnkr.co/edit/eNsFHDf7YjyM6IzKxM1j?p=preview))
   * 
   * ```javascript
   * @Component({...})
   * @View({
   *   template: `
   *     <item> a </item>
   *     <item> b </item>
   *     <item> c </item>
   *   `
   * })
   * class MyComponent {
   *   shown: boolean;
   * 
   *   constructor(private @Query(Item) items:QueryList<Item>) {
   *     items.onChange(() => console.log(items.length));
   *   }
   * }
   * ```
   * 
   * Supports the same querying parameters as {@link QueryMetadata}, except
   * `descendants`. This always queries the whole view.
   * 
   * As `shown` is flipped between true and false, items will contain zero of one
   * items.
   * 
   * Specifies that a {@link QueryList} should be injected.
   * 
   * The injected object is an iterable and observable live list.
   * See {@link QueryList} for more details.
   */
  var ViewQuery: QueryFactory;
  

    
  /**
   * Declare reusable pipe function.
   * 
   * ### Example
   * 
   * ```
   * @Pipe({
   *   name: 'lowercase'
   * })
   * class Lowercase {
   *   transform(v, args) { return v.toLowerCase(); }
   * }
   * ```
   */
  var Pipe: PipeFactory;
  

    
  /**
   * Declares a data-bound input property.
   * 
   * Angular automatically updates data-bound properties during change detection.
   * 
   * `InputMetadata` takes an optional parameter that specifies the name
   * used when instantiating a component in the template. When not provided,
   * the name of the decorated property is used.
   * 
   * ### Example
   * 
   * The following example creates a component with two input properties.
   * 
   * ```typescript
   * @Component({
   *   selector: 'bank-account',
   *   template: `
   *     Bank Name: {{bankName}}
   *     Account Id: {{id}}
   *   `
   * })
   * class BankAccount {
   *   @Input() bankName: string;
   *   @Input('account-id') id: string;
   * 
   *   // this property is not bound, and won't be automatically updated by Angular
   *   normalizedBankName: string;
   * }
   * 
   * @Component({
   *   selector: 'app',
   *   template: `
   *     <bank-account bank-name="RBC" account-id="4747"></bank-account>
   *   `,
   *   directives: [BankAccount]
   * })
   * class App {}
   * 
   * bootstrap(App);
   * ```
   */
  var Input: InputFactory;
  

    
  /**
   * Declares an event-bound output property.
   * 
   * When an output property emits an event, an event handler attached to that event
   * the template is invoked.
   * 
   * `OutputMetadata` takes an optional parameter that specifies the name
   * used when instantiating a component in the template. When not provided,
   * the name of the decorated property is used.
   * 
   * ### Example
   * 
   * ```typescript
   * @Directive({
   *   selector: 'interval-dir',
   * })
   * class IntervalDir {
   *   @Output() everySecond = new EventEmitter();
   *   @Output('everyFiveSeconds') five5Secs = new EventEmitter();
   * 
   *   constructor() {
   *     setInterval(() => this.everySecond.next("event"), 1000);
   *     setInterval(() => this.five5Secs.next("event"), 5000);
   *   }
   * }
   * 
   * @Component({
   *   selector: 'app',
   *   template: `
   *     <interval-dir (every-second)="everySecond()" (every-five-seconds)="everyFiveSeconds()">
   *     </interval-dir>
   *   `,
   *   directives: [IntervalDir]
   * })
   * class App {
   *   everySecond() { console.log('second'); }
   *   everyFiveSeconds() { console.log('five seconds'); }
   * }
   * bootstrap(App);
   * ```
   */
  var Output: OutputFactory;
  

    
  /**
   * Declares a host property binding.
   * 
   * Angular automatically checks host property bindings during change detection.
   * If a binding changes, it will update the host element of the directive.
   * 
   * `HostBindingMetadata` takes an optional parameter that specifies the property
   * name of the host element that will be updated. When not provided,
   * the class property name is used.
   * 
   * ### Example
   * 
   * The following example creates a directive that sets the `valid` and `invalid` classes
   * on the DOM element that has ng-model directive on it.
   * 
   * ```typescript
   * @Directive({selector: '[ng-model]'})
   * class NgModelStatus {
   *   constructor(public control:NgModel) {}
   *   @HostBinding('[class.valid]') get valid { return this.control.valid; }
   *   @HostBinding('[class.invalid]') get invalid { return this.control.invalid; }
   * }
   * 
   * @Component({
   *   selector: 'app',
   *   template: `<input [(ng-model)]="prop">`,
   *   directives: [FORM_DIRECTIVES, NgModelStatus]
   * })
   * class App {
   *   prop;
   * }
   * 
   * bootstrap(App);
   * ```
   */
  var HostBinding: HostBindingFactory;
  

    
  /**
   * Declares a host listener.
   * 
   * Angular will invoke the decorated method when the host element emits the specified event.
   * 
   * If the decorated method returns `false`, then `preventDefault` is applied on the DOM
   * event.
   * 
   * ### Example
   * 
   * The following example declares a directive that attaches a click listener to the button and
   * counts clicks.
   * 
   * ```typescript
   * @Directive({selector: 'button[counting]'})
   * class CountClicks {
   *   numberOfClicks = 0;
   * 
   *   @HostListener('click', ['$event.target'])
   *   onClick(btn) {
   *     console.log("button", btn, "number of clicks:", this.numberOfClicks++);
   *   }
   * }
   * 
   * @Component({
   *   selector: 'app',
   *   template: `<button counting>Increment</button>`,
   *   directives: [CountClicks]
   * })
   * class App {}
   * 
   * bootstrap(App);
   * ```
   */
  var HostListener: HostListenerFactory;
  

    
  /**
   * Provides a way for expressing ES6 classes with parameter annotations in ES5.
   * 
   * ## Basic Example
   * 
   * ```
   * var Greeter = ng.Class({
   *   constructor: function(name) {
   *     this.name = name;
   *   },
   * 
   *   greet: function() {
   *     alert('Hello ' + this.name + '!');
   *   }
   * });
   * ```
   * 
   * is equivalent to ES6:
   * 
   * ```
   * class Greeter {
   *   constructor(name) {
   *     this.name = name;
   *   }
   * 
   *   greet() {
   *     alert('Hello ' + this.name + '!');
   *   }
   * }
   * ```
   * 
   * or equivalent to ES5:
   * 
   * ```
   * var Greeter = function (name) {
   *   this.name = name;
   * }
   * 
   * Greeter.prototype.greet = function () {
   *   alert('Hello ' + this.name + '!');
   * }
   * ```
   * 
   * ### Example with parameter annotations
   * 
   * ```
   * var MyService = ng.Class({
   *   constructor: [String, [new Query(), QueryList], function(name, queryList) {
   *     ...
   *   }]
   * });
   * ```
   * 
   * is equivalent to ES6:
   * 
   * ```
   * class MyService {
   *   constructor(name: string, @Query() queryList: QueryList) {
   *     ...
   *   }
   * }
   * ```
   * 
   * ### Example with inheritance
   * 
   * ```
   * var Shape = ng.Class({
   *   constructor: (color) {
   *     this.color = color;
   *   }
   * });
   * 
   * var Square = ng.Class({
   *   extends: Shape,
   *   constructor: function(color, size) {
   *     Shape.call(this, color);
   *     this.size = size;
   *   }
   * });
   * ```
   */
  function Class(clsDef: ClassDefinition): ConcreteType;
  

    
  /**
   * Declares the interface to be used with {@link Class}.
   */
  interface ClassDefinition {
    
    /**
     * Optional argument for specifying the superclass.
     */
    extends?: Type;
    
    /**
     * Required constructor function for a class.
     * 
     * The function may be optionally wrapped in an `Array`, in which case additional parameter
     * annotations may be specified.
     * The number of arguments and the number of parameter annotations must match.
     * 
     * See {@link Class} for example of usage.
     */
    constructor: Function | any[];
    
  }

    
  /**
   * An interface implemented by all Angular type decorators, which allows them to be used as ES7
   * decorators as well as
   * Angular DSL syntax.
   * 
   * DSL syntax:
   * 
   * ```
   * var MyClass = ng
   *   .Component({...})
   *   .View({...})
   *   .Class({...});
   * ```
   * 
   * ES7 syntax:
   * 
   * ```
   * @ng.Component({...})
   * @ng.View({...})
   * class MyClass {...}
   * ```
   */
  interface TypeDecorator {
    
    /**
     * Invoke as ES7 decorator.
     */
    <T extends Type>(type: T): T;
    
    /**
     * Storage for the accumulated annotations so far used by the DSL syntax.
     * 
     * Used by {@link Class} to annotate the generated class.
     */
    annotations: any[];
    
    /**
     * Generate a class from the definition and annotate it with {@link TypeDecorator#annotations}.
     */
    Class(obj: ClassDefinition): ConcreteType;
    
  }

    
  /**
   * A parameter metadata that specifies a dependency.
   * 
   * ### Example ([live demo](http://plnkr.co/edit/6uHYJK?p=preview))
   * 
   * ```typescript
   * class Engine {}
   * 
   * @Injectable()
   * class Car {
   *   engine;
   *   constructor(@Inject("MyEngine") engine:Engine) {
   *     this.engine = engine;
   *   }
   * }
   * 
   * var injector = Injector.resolveAndCreate([
   *  provide("MyEngine", {useClass: Engine}),
   *  Car
   * ]);
   * 
   * expect(injector.get(Car).engine instanceof Engine).toBe(true);
   * ```
   * 
   * When `@Inject()` is not present, {@link Injector} will use the type annotation of the parameter.
   * 
   * ### Example
   * 
   * ```typescript
   * class Engine {}
   * 
   * @Injectable()
   * class Car {
   *   constructor(public engine: Engine) {} //same as constructor(@Inject(Engine) engine:Engine)
   * }
   * 
   * var injector = Injector.resolveAndCreate([Engine, Car]);
   * expect(injector.get(Car).engine instanceof Engine).toBe(true);
   * ```
   */
  class InjectMetadata {
    
    constructor(token: any);
    
    token: any;
    
    toString(): string;
    
  }

    
  /**
   * A parameter metadata that marks a dependency as optional. {@link Injector} provides `null` if
   * the dependency is not found.
   * 
   * ### Example ([live demo](http://plnkr.co/edit/AsryOm?p=preview))
   * 
   * ```typescript
   * class Engine {}
   * 
   * @Injectable()
   * class Car {
   *   engine;
   *   constructor(@Optional() engine:Engine) {
   *     this.engine = engine;
   *   }
   * }
   * 
   * var injector = Injector.resolveAndCreate([Car]);
   * expect(injector.get(Car).engine).toBeNull();
   * ```
   */
  class OptionalMetadata {
    
    toString(): string;
    
  }

    
  /**
   * A marker metadata that marks a class as available to {@link Injector} for creation.
   * 
   * ### Example ([live demo](http://plnkr.co/edit/Wk4DMQ?p=preview))
   * 
   * ```typescript
   * @Injectable()
   * class UsefulService {}
   * 
   * @Injectable()
   * class NeedsService {
   *   constructor(public service:UsefulService) {}
   * }
   * 
   * var injector = Injector.resolveAndCreate([NeedsService, UsefulService]);
   * expect(injector.get(NeedsService).service instanceof UsefulService).toBe(true);
   * ```
   * {@link Injector} will throw {@link NoAnnotationError} when trying to instantiate a class that
   * does not have `@Injectable` marker, as shown in the example below.
   * 
   * ```typescript
   * class UsefulService {}
   * 
   * class NeedsService {
   *   constructor(public service:UsefulService) {}
   * }
   * 
   * var injector = Injector.resolveAndCreate([NeedsService, UsefulService]);
   * expect(() => injector.get(NeedsService)).toThrowError();
   * ```
   */
  class InjectableMetadata {
    
    constructor();
    
  }

    
  /**
   * Specifies that an {@link Injector} should retrieve a dependency only from itself.
   * 
   * ### Example ([live demo](http://plnkr.co/edit/NeagAg?p=preview))
   * 
   * ```typescript
   * class Dependency {
   * }
   * 
   * @Injectable()
   * class NeedsDependency {
   *   dependency;
   *   constructor(@Self() dependency:Dependency) {
   *     this.dependency = dependency;
   *   }
   * }
   * 
   * var inj = Injector.resolveAndCreate([Dependency, NeedsDependency]);
   * var nd = inj.get(NeedsDependency);
   * 
   * expect(nd.dependency instanceof Dependency).toBe(true);
   * 
   * var inj = Injector.resolveAndCreate([Dependency]);
   * var child = inj.resolveAndCreateChild([NeedsDependency]);
   * expect(() => child.get(NeedsDependency)).toThrowError();
   * ```
   */
  class SelfMetadata {
    
    toString(): string;
    
  }

    
  /**
   * Specifies that an injector should retrieve a dependency from any injector until reaching the
   * closest host.
   * 
   * In Angular, a component element is automatically declared as a host for all the injectors in
   * its view.
   * 
   * ### Example ([live demo](http://plnkr.co/edit/GX79pV?p=preview))
   * 
   * In the following example `App` contains `ParentCmp`, which contains `ChildDirective`.
   * So `ParentCmp` is the host of `ChildDirective`.
   * 
   * `ChildDirective` depends on two services: `HostService` and `OtherService`.
   * `HostService` is defined at `ParentCmp`, and `OtherService` is defined at `App`.
   * 
   * ```typescript
   * class OtherService {}
   * class HostService {}
   * 
   * @Directive({
   *   selector: 'child-directive'
   * })
   * class ChildDirective {
   *   constructor(@Optional() @Host() os:OtherService, @Optional() @Host() hs:HostService){
   *     console.log("os is null", os);
   *     console.log("hs is NOT null", hs);
   *   }
   * }
   * 
   * @Component({
   *   selector: 'parent-cmp',
   *   providers: [HostService],
   *   template: `
   *     Dir: <child-directive></child-directive>
   *   `,
   *   directives: [ChildDirective]
   * })
   * class ParentCmp {
   * }
   * 
   * @Component({
   *   selector: 'app',
   *   providers: [OtherService],
   *   template: `
   *     Parent: <parent-cmp></parent-cmp>
   *   `,
   *   directives: [ParentCmp]
   * })
   * class App {
   * }
   * 
   * bootstrap(App);
   * ```
   */
  class HostMetadata {
    
    toString(): string;
    
  }

    
  /**
   * Specifies that the dependency resolution should start from the parent injector.
   * 
   * ### Example ([live demo](http://plnkr.co/edit/Wchdzb?p=preview))
   * 
   * ```typescript
   * class Dependency {
   * }
   * 
   * @Injectable()
   * class NeedsDependency {
   *   dependency;
   *   constructor(@SkipSelf() dependency:Dependency) {
   *     this.dependency = dependency;
   *   }
   * }
   * 
   * var parent = Injector.resolveAndCreate([Dependency]);
   * var child = parent.resolveAndCreateChild([NeedsDependency]);
   * expect(child.get(NeedsDependency).dependency instanceof Depedency).toBe(true);
   * 
   * var inj = Injector.resolveAndCreate([Dependency, NeedsDependency]);
   * expect(() => inj.get(NeedsDependency)).toThrowError();
   * ```
   */
  class SkipSelfMetadata {
    
    toString(): string;
    
  }

    
  /**
   * `DependencyMetadata` is used by the framework to extend DI.
   * This is internal to Angular and should not be used directly.
   */
  class DependencyMetadata {
    
    token: any;
    
  }

    
  /**
   * Allows to refer to references which are not yet defined.
   * 
   * For instance, `forwardRef` is used when the `token` which we need to refer to for the purposes of
   * DI is declared,
   * but not yet defined. It is also used when the `token` which we use when creating a query is not
   * yet defined.
   * 
   * ### Example ([live demo](http://plnkr.co/edit/bRs0SX2OTQiJzqvjgl8P?p=preview))
   * 
   * ```typescript
   * class Door {
   *   lock: Lock;
   *   constructor(@Inject(forwardRef(() => Lock)) lock:Lock) {
   *     this.lock = lock;
   *   }
   * }
   * 
   * // Only at this point Lock is defined.
   * class Lock {
   * }
   * 
   * var injector = Injector.resolveAndCreate([Door, Lock]);
   * var door = injector.get(Door);
   * expect(door instanceof Door).toBe(true);
   * expect(door.lock instanceof Lock).toBe(true);
   * ```
   */
  function forwardRef(forwardRefFn: ForwardRefFn): Type;
  

    
  /**
   * Lazily retrieves the reference value from a forwardRef.
   * 
   * Acts as the identity function when given a non-forward-ref value.
   * 
   * ### Example ([live demo](http://plnkr.co/edit/GU72mJrk1fiodChcmiDR?p=preview))
   * 
   * ```typescript
   * var ref = forwardRef(() => "refValue");
   * expect(resolveForwardRef(ref)).toEqual("refValue");
   * expect(resolveForwardRef("regularValue")).toEqual("regularValue");
   * ```
   * 
   * See: {@link forwardRef}
   */
  function resolveForwardRef(type: any): any;
  

    
  /**
   * An interface that a function passed into {@link forwardRef} has to implement.
   * 
   * ### Example
   * 
   * ```typescript
   * var fn:ForwardRefFn = forwardRef(() => Lock);
   * ```
   */
  interface ForwardRefFn {
    
    (): any;
    
  }

    
  /**
   * A dependency injection container used for instantiating objects and resolving dependencies.
   * 
   * An `Injector` is a replacement for a `new` operator, which can automatically resolve the
   * constructor dependencies.
   * 
   * In typical use, application code asks for the dependencies in the constructor and they are
   * resolved by the `Injector`.
   * 
   * ### Example ([live demo](http://plnkr.co/edit/jzjec0?p=preview))
   * 
   * The following example creates an `Injector` configured to create `Engine` and `Car`.
   * 
   * ```typescript
   * @Injectable()
   * class Engine {
   * }
   * 
   * @Injectable()
   * class Car {
   *   constructor(public engine:Engine) {}
   * }
   * 
   * var injector = Injector.resolveAndCreate([Car, Engine]);
   * var car = injector.get(Car);
   * expect(car instanceof Car).toBe(true);
   * expect(car.engine instanceof Engine).toBe(true);
   * ```
   * 
   * Notice, we don't use the `new` operator because we explicitly want to have the `Injector`
   * resolve all of the object's dependencies automatically.
   */
  class Injector {
    
    /**
     * Private
     */
    constructor(_proto: any, _parent?: Injector, _depProvider?: any, _debugContext?: Function);
    
    /**
     * Turns an array of provider definitions into an array of resolved providers.
     * 
     * A resolution is a process of flattening multiple nested arrays and converting individual
     * providers into an array of {@link ResolvedProvider}s.
     * 
     * ### Example ([live demo](http://plnkr.co/edit/AiXTHi?p=preview))
     * 
     * ```typescript
     * @Injectable()
     * class Engine {
     * }
     * 
     * @Injectable()
     * class Car {
     *   constructor(public engine:Engine) {}
     * }
     * 
     * var providers = Injector.resolve([Car, [[Engine]]]);
     * 
     * expect(providers.length).toEqual(2);
     * 
     * expect(providers[0] instanceof ResolvedProvider).toBe(true);
     * expect(providers[0].key.displayName).toBe("Car");
     * expect(providers[0].dependencies.length).toEqual(1);
     * expect(providers[0].factory).toBeDefined();
     * 
     * expect(providers[1].key.displayName).toBe("Engine");
     * });
     * ```
     * 
     * See {@link Injector#fromResolvedProviders} for more info.
     */
    static resolve(providers: Array<Type | Provider | any[]>): ResolvedProvider[];
    
    /**
     * Resolves an array of providers and creates an injector from those providers.
     * 
     * The passed-in providers can be an array of `Type`, {@link Provider},
     * or a recursive array of more providers.
     * 
     * ### Example ([live demo](http://plnkr.co/edit/ePOccA?p=preview))
     * 
     * ```typescript
     * @Injectable()
     * class Engine {
     * }
     * 
     * @Injectable()
     * class Car {
     *   constructor(public engine:Engine) {}
     * }
     * 
     * var injector = Injector.resolveAndCreate([Car, Engine]);
     * expect(injector.get(Car) instanceof Car).toBe(true);
     * ```
     * 
     * This function is slower than the corresponding `fromResolvedProviders`
     * because it needs to resolve the passed-in providers first.
     * See {@link Injector#resolve} and {@link Injector#fromResolvedProviders}.
     */
    static resolveAndCreate(providers: Array<Type | Provider | any[]>): Injector;
    
    /**
     * Creates an injector from previously resolved providers.
     * 
     * This API is the recommended way to construct injectors in performance-sensitive parts.
     * 
     * ### Example ([live demo](http://plnkr.co/edit/KrSMci?p=preview))
     * 
     * ```typescript
     * @Injectable()
     * class Engine {
     * }
     * 
     * @Injectable()
     * class Car {
     *   constructor(public engine:Engine) {}
     * }
     * 
     * var providers = Injector.resolve([Car, Engine]);
     * var injector = Injector.fromResolvedProviders(providers);
     * expect(injector.get(Car) instanceof Car).toBe(true);
     * ```
     */
    static fromResolvedProviders(providers: ResolvedProvider[]): Injector;
    
    /**
     * @deprecated
     */
    static fromResolvedBindings(providers: ResolvedProvider[]): Injector;
    
    /**
     * Retrieves an instance from the injector based on the provided token.
     * Throws {@link NoProviderError} if not found.
     * 
     * ### Example ([live demo](http://plnkr.co/edit/HeXSHg?p=preview))
     * 
     * ```typescript
     * var injector = Injector.resolveAndCreate([
     *   provide("validToken", {useValue: "Value"})
     * ]);
     * expect(injector.get("validToken")).toEqual("Value");
     * expect(() => injector.get("invalidToken")).toThrowError();
     * ```
     * 
     * `Injector` returns itself when given `Injector` as a token.
     * 
     * ```typescript
     * var injector = Injector.resolveAndCreate([]);
     * expect(injector.get(Injector)).toBe(injector);
     * ```
     */
    get(token: any): any;
    
    /**
     * Retrieves an instance from the injector based on the provided token.
     * Returns null if not found.
     * 
     * ### Example ([live demo](http://plnkr.co/edit/tpEbEy?p=preview))
     * 
     * ```typescript
     * var injector = Injector.resolveAndCreate([
     *   provide("validToken", {useValue: "Value"})
     * ]);
     * expect(injector.getOptional("validToken")).toEqual("Value");
     * expect(injector.getOptional("invalidToken")).toBe(null);
     * ```
     * 
     * `Injector` returns itself when given `Injector` as a token.
     * 
     * ```typescript
     * var injector = Injector.resolveAndCreate([]);
     * expect(injector.getOptional(Injector)).toBe(injector);
     * ```
     */
    getOptional(token: any): any;
    
    /**
     * Parent of this injector.
     * 
     * <!-- TODO: Add a link to the section of the user guide talking about hierarchical injection.
     * -->
     * 
     * ### Example ([live demo](http://plnkr.co/edit/eosMGo?p=preview))
     * 
     * ```typescript
     * var parent = Injector.resolveAndCreate([]);
     * var child = parent.resolveAndCreateChild([]);
     * expect(child.parent).toBe(parent);
     * ```
     */
    parent: Injector;
    
    /**
     * Resolves an array of providers and creates a child injector from those providers.
     * 
     * <!-- TODO: Add a link to the section of the user guide talking about hierarchical injection.
     * -->
     * 
     * The passed-in providers can be an array of `Type`, {@link Provider},
     * or a recursive array of more providers.
     * 
     * ### Example ([live demo](http://plnkr.co/edit/opB3T4?p=preview))
     * 
     * ```typescript
     * class ParentProvider {}
     * class ChildProvider {}
     * 
     * var parent = Injector.resolveAndCreate([ParentProvider]);
     * var child = parent.resolveAndCreateChild([ChildProvider]);
     * 
     * expect(child.get(ParentProvider) instanceof ParentProvider).toBe(true);
     * expect(child.get(ChildProvider) instanceof ChildProvider).toBe(true);
     * expect(child.get(ParentProvider)).toBe(parent.get(ParentProvider));
     * ```
     * 
     * This function is slower than the corresponding `createChildFromResolved`
     * because it needs to resolve the passed-in providers first.
     * See {@link Injector#resolve} and {@link Injector#createChildFromResolved}.
     */
    resolveAndCreateChild(providers: Array<Type | Provider | any[]>): Injector;
    
    /**
     * Creates a child injector from previously resolved providers.
     * 
     * <!-- TODO: Add a link to the section of the user guide talking about hierarchical injection.
     * -->
     * 
     * This API is the recommended way to construct injectors in performance-sensitive parts.
     * 
     * ### Example ([live demo](http://plnkr.co/edit/VhyfjN?p=preview))
     * 
     * ```typescript
     * class ParentProvider {}
     * class ChildProvider {}
     * 
     * var parentProviders = Injector.resolve([ParentProvider]);
     * var childProviders = Injector.resolve([ChildProvider]);
     * 
     * var parent = Injector.fromResolvedProviders(parentProviders);
     * var child = parent.createChildFromResolved(childProviders);
     * 
     * expect(child.get(ParentProvider) instanceof ParentProvider).toBe(true);
     * expect(child.get(ChildProvider) instanceof ChildProvider).toBe(true);
     * expect(child.get(ParentProvider)).toBe(parent.get(ParentProvider));
     * ```
     */
    createChildFromResolved(providers: ResolvedProvider[]): Injector;
    
    /**
     * Resolves a provider and instantiates an object in the context of the injector.
     * 
     * The created object does not get cached by the injector.
     * 
     * ### Example ([live demo](http://plnkr.co/edit/yvVXoB?p=preview))
     * 
     * ```typescript
     * @Injectable()
     * class Engine {
     * }
     * 
     * @Injectable()
     * class Car {
     *   constructor(public engine:Engine) {}
     * }
     * 
     * var injector = Injector.resolveAndCreate([Engine]);
     * 
     * var car = injector.resolveAndInstantiate(Car);
     * expect(car.engine).toBe(injector.get(Engine));
     * expect(car).not.toBe(injector.resolveAndInstantiate(Car));
     * ```
     */
    resolveAndInstantiate(provider: Type | Provider): any;
    
    /**
     * Instantiates an object using a resolved provider in the context of the injector.
     * 
     * The created object does not get cached by the injector.
     * 
     * ### Example ([live demo](http://plnkr.co/edit/ptCImQ?p=preview))
     * 
     * ```typescript
     * @Injectable()
     * class Engine {
     * }
     * 
     * @Injectable()
     * class Car {
     *   constructor(public engine:Engine) {}
     * }
     * 
     * var injector = Injector.resolveAndCreate([Engine]);
     * var carProvider = Injector.resolve([Car])[0];
     * var car = injector.instantiateResolved(carProvider);
     * expect(car.engine).toBe(injector.get(Engine));
     * expect(car).not.toBe(injector.instantiateResolved(carProvider));
     * ```
     */
    instantiateResolved(provider: ResolvedProvider): any;
    
    displayName: string;
    
    toString(): string;
    
  }

    
  /**
   * @deprecated
   */
  class Binding extends Provider {
    
    constructor(token: any, {toClass, toValue, toAlias, toFactory, deps, multi}: {
        toClass?: Type,
        toValue?: any,
        toAlias?: any,
        toFactory: Function, deps?: Object[], multi?: boolean
      });
    
    /**
     * @deprecated
     */
    toClass: any;
    
    /**
     * @deprecated
     */
    toAlias: any;
    
    /**
     * @deprecated
     */
    toFactory: any;
    
    /**
     * @deprecated
     */
    toValue: any;
    
  }

    
  /**
   * Helper class for the {@link bind} function.
   */
  class ProviderBuilder {
    
    constructor(token: any);
    
    token: any;
    
    /**
     * Binds a DI token to a class.
     * 
     * ### Example ([live demo](http://plnkr.co/edit/ZpBCSYqv6e2ud5KXLdxQ?p=preview))
     * 
     * Because `toAlias` and `toClass` are often confused, the example contains
     * both use cases for easy comparison.
     * 
     * ```typescript
     * class Vehicle {}
     * 
     * class Car extends Vehicle {}
     * 
     * var injectorClass = Injector.resolveAndCreate([
     *   Car,
     *   provide(Vehicle, {useClass: Car})
     * ]);
     * var injectorAlias = Injector.resolveAndCreate([
     *   Car,
     *   provide(Vehicle, {useExisting: Car})
     * ]);
     * 
     * expect(injectorClass.get(Vehicle)).not.toBe(injectorClass.get(Car));
     * expect(injectorClass.get(Vehicle) instanceof Car).toBe(true);
     * 
     * expect(injectorAlias.get(Vehicle)).toBe(injectorAlias.get(Car));
     * expect(injectorAlias.get(Vehicle) instanceof Car).toBe(true);
     * ```
     */
    toClass(type: Type): Provider;
    
    /**
     * Binds a DI token to a value.
     * 
     * ### Example ([live demo](http://plnkr.co/edit/G024PFHmDL0cJFgfZK8O?p=preview))
     * 
     * ```typescript
     * var injector = Injector.resolveAndCreate([
     *   provide('message', {useValue: 'Hello'})
     * ]);
     * 
     * expect(injector.get('message')).toEqual('Hello');
     * ```
     */
    toValue(value: any): Provider;
    
    /**
     * Binds a DI token to an existing token.
     * 
     * Angular will return the same instance as if the provided token was used. (This is
     * in contrast to `useClass` where a separate instance of `useClass` will be returned.)
     * 
     * ### Example ([live demo](http://plnkr.co/edit/uBaoF2pN5cfc5AfZapNw?p=preview))
     * 
     * Because `toAlias` and `toClass` are often confused, the example contains
     * both use cases for easy comparison.
     * 
     * ```typescript
     * class Vehicle {}
     * 
     * class Car extends Vehicle {}
     * 
     * var injectorAlias = Injector.resolveAndCreate([
     *   Car,
     *   provide(Vehicle, {useExisting: Car})
     * ]);
     * var injectorClass = Injector.resolveAndCreate([
     *   Car,
     *   provide(Vehicle, {useClass: Car})
     * ]);
     * 
     * expect(injectorAlias.get(Vehicle)).toBe(injectorAlias.get(Car));
     * expect(injectorAlias.get(Vehicle) instanceof Car).toBe(true);
     * 
     * expect(injectorClass.get(Vehicle)).not.toBe(injectorClass.get(Car));
     * expect(injectorClass.get(Vehicle) instanceof Car).toBe(true);
     * ```
     */
    toAlias(aliasToken: /*Type*/ any): Provider;
    
    /**
     * Binds a DI token to a function which computes the value.
     * 
     * ### Example ([live demo](http://plnkr.co/edit/OejNIfTT3zb1iBxaIYOb?p=preview))
     * 
     * ```typescript
     * var injector = Injector.resolveAndCreate([
     *   provide(Number, {useFactory: () => { return 1+2; }}),
     *   provide(String, {useFactory: (v) => { return "Value: " + v; }, deps: [Number]})
     * ]);
     * 
     * expect(injector.get(Number)).toEqual(3);
     * expect(injector.get(String)).toEqual('Value: 3');
     * ```
     */
    toFactory(factory: Function, dependencies?: any[]): Provider;
    
  }

    
  /**
   * @deprecated
   */
  interface ResolvedBinding extends ResolvedProvider {
    
  }

    
  /**
   * An internal resolved representation of a factory function created by resolving {@link Provider}.
   */
  class ResolvedFactory {
    
    constructor(factory: Function, dependencies: Dependency[]);
    
    /**
     * Factory function which can return an instance of an object represented by a key.
     */
    factory: Function;
    
    /**
     * Arguments (dependencies) to the `factory` function.
     */
    dependencies: Dependency[];
    
  }

    
  class Dependency {
    
    constructor(key: Key, optional: boolean, lowerBoundVisibility: any, upperBoundVisibility: any, properties: any[]);
    
    static fromKey(key: Key): Dependency;
    
    key: Key;
    
    optional: boolean;
    
    lowerBoundVisibility: any;
    
    upperBoundVisibility: any;
    
    properties: any[];
    
  }

    
  /**
   * @deprecated
   * Creates a {@link Provider}.
   * 
   * To construct a {@link Provider}, bind a `token` to either a class, a value, a factory function,
   * or
   * to an existing `token`.
   * See {@link ProviderBuilder} for more details.
   * 
   * The `token` is most commonly a class or {@link angular2/di/OpaqueToken}.
   */
  function bind(token: any): ProviderBuilder;
  

    
  /**
   * Describes how the {@link Injector} should instantiate a given token.
   * 
   * See {@link provide}.
   * 
   * ### Example ([live demo](http://plnkr.co/edit/GNAyj6K6PfYg2NBzgwZ5?p%3Dpreview&p=preview))
   * 
   * ```javascript
   * var injector = Injector.resolveAndCreate([
   *   new Provider("message", { useValue: 'Hello' })
   * ]);
   * 
   * expect(injector.get("message")).toEqual('Hello');
   * ```
   */
  class Provider {
    
    constructor(token: any, {useClass, useValue, useExisting, useFactory, deps, multi}: {
        useClass?: Type,
        useValue?: any,
        useExisting?: any,
        useFactory?: Function,
        deps?: Object[],
        multi?: boolean
      });
    
    /**
     * Token used when retrieving this provider. Usually, it is a type {@link Type}.
     */
    token: any;
    
    /**
     * Binds a DI token to an implementation class.
     * 
     * ### Example ([live demo](http://plnkr.co/edit/RSTG86qgmoxCyj9SWPwY?p=preview))
     * 
     * Because `useExisting` and `useClass` are often confused, the example contains
     * both use cases for easy comparison.
     * 
     * ```typescript
     * class Vehicle {}
     * 
     * class Car extends Vehicle {}
     * 
     * var injectorClass = Injector.resolveAndCreate([
     *   Car,
     *   new Provider(Vehicle, { useClass: Car })
     * ]);
     * var injectorAlias = Injector.resolveAndCreate([
     *   Car,
     *   new Provider(Vehicle, { useExisting: Car })
     * ]);
     * 
     * expect(injectorClass.get(Vehicle)).not.toBe(injectorClass.get(Car));
     * expect(injectorClass.get(Vehicle) instanceof Car).toBe(true);
     * 
     * expect(injectorAlias.get(Vehicle)).toBe(injectorAlias.get(Car));
     * expect(injectorAlias.get(Vehicle) instanceof Car).toBe(true);
     * ```
     */
    useClass: Type;
    
    /**
     * Binds a DI token to a value.
     * 
     * ### Example ([live demo](http://plnkr.co/edit/UFVsMVQIDe7l4waWziES?p=preview))
     * 
     * ```javascript
     * var injector = Injector.resolveAndCreate([
     *   new Provider("message", { useValue: 'Hello' })
     * ]);
     * 
     * expect(injector.get("message")).toEqual('Hello');
     * ```
     */
    useValue: any;
    
    /**
     * Binds a DI token to an existing token.
     * 
     * {@link Injector} returns the same instance as if the provided token was used.
     * This is in contrast to `useClass` where a separate instance of `useClass` is returned.
     * 
     * ### Example ([live demo](http://plnkr.co/edit/QsatsOJJ6P8T2fMe9gr8?p=preview))
     * 
     * Because `useExisting` and `useClass` are often confused the example contains
     * both use cases for easy comparison.
     * 
     * ```typescript
     * class Vehicle {}
     * 
     * class Car extends Vehicle {}
     * 
     * var injectorAlias = Injector.resolveAndCreate([
     *   Car,
     *   new Provider(Vehicle, { useExisting: Car })
     * ]);
     * var injectorClass = Injector.resolveAndCreate([
     *   Car,
     *   new Provider(Vehicle, { useClass: Car })
     * ]);
     * 
     * expect(injectorAlias.get(Vehicle)).toBe(injectorAlias.get(Car));
     * expect(injectorAlias.get(Vehicle) instanceof Car).toBe(true);
     * 
     * expect(injectorClass.get(Vehicle)).not.toBe(injectorClass.get(Car));
     * expect(injectorClass.get(Vehicle) instanceof Car).toBe(true);
     * ```
     */
    useExisting: any;
    
    /**
     * Binds a DI token to a function which computes the value.
     * 
     * ### Example ([live demo](http://plnkr.co/edit/Scoxy0pJNqKGAPZY1VVC?p=preview))
     * 
     * ```typescript
     * var injector = Injector.resolveAndCreate([
     *   new Provider(Number, { useFactory: () => { return 1+2; }}),
     *   new Provider(String, { useFactory: (value) => { return "Value: " + value; },
     *                       deps: [Number] })
     * ]);
     * 
     * expect(injector.get(Number)).toEqual(3);
     * expect(injector.get(String)).toEqual('Value: 3');
     * ```
     * 
     * Used in conjuction with dependencies.
     */
    useFactory: Function;
    
    /**
     * Specifies a set of dependencies
     * (as `token`s) which should be injected into the factory function.
     * 
     * ### Example ([live demo](http://plnkr.co/edit/Scoxy0pJNqKGAPZY1VVC?p=preview))
     * 
     * ```typescript
     * var injector = Injector.resolveAndCreate([
     *   new Provider(Number, { useFactory: () => { return 1+2; }}),
     *   new Provider(String, { useFactory: (value) => { return "Value: " + value; },
     *                       deps: [Number] })
     * ]);
     * 
     * expect(injector.get(Number)).toEqual(3);
     * expect(injector.get(String)).toEqual('Value: 3');
     * ```
     * 
     * Used in conjunction with `useFactory`.
     */
    dependencies: Object[];
    
    /**
     * Creates multiple providers matching the same token (a multi-provider).
     * 
     * Multi-providers are used for creating pluggable service, where the system comes
     * with some default providers, and the user can register additonal providers.
     * The combination of the default providers and the additional providers will be
     * used to drive the behavior of the system.
     * 
     * ### Example
     * 
     * ```typescript
     * var injector = Injector.resolveAndCreate([
     *   new Provider("Strings", { useValue: "String1", multi: true}),
     *   new Provider("Strings", { useValue: "String2", multi: true})
     * ]);
     * 
     * expect(injector.get("Strings")).toEqual(["String1", "String2"]);
     * ```
     * 
     * Multi-providers and regular providers cannot be mixed. The following
     * will throw an exception:
     * 
     * ```typescript
     * var injector = Injector.resolveAndCreate([
     *   new Provider("Strings", { useValue: "String1", multi: true }),
     *   new Provider("Strings", { useValue: "String2"})
     * ]);
     * ```
     */
    multi: boolean;
    
  }

    
  /**
   * An internal resolved representation of a {@link Provider} used by the {@link Injector}.
   * 
   * It is usually created automatically by `Injector.resolveAndCreate`.
   * 
   * It can be created manually, as follows:
   * 
   * ### Example ([live demo](http://plnkr.co/edit/RfEnhh8kUEI0G3qsnIeT?p%3Dpreview&p=preview))
   * 
   * ```typescript
   * var resolvedProviders = Injector.resolve([new Provider('message', {useValue: 'Hello'})]);
   * var injector = Injector.fromResolvedProviders(resolvedProviders);
   * 
   * expect(injector.get('message')).toEqual('Hello');
   * ```
   */
  interface ResolvedProvider {
    
    /**
     * A key, usually a `Type`.
     */
    key: Key;
    
    /**
     * Factory function which can return an instance of an object represented by a key.
     */
    resolvedFactories: ResolvedFactory[];
    
    /**
     * Indicates if the provider is a multi-provider or a regular provider.
     */
    multiProvider: boolean;
    
  }

    
  /**
   * Creates a {@link Provider}.
   * 
   * See {@link Provider} for more details.
   * 
   * <!-- TODO: improve the docs -->
   */
  function provide(token: any, {useClass, useValue, useExisting, useFactory, deps, multi}: {
    useClass?: Type,
    useValue?: any,
    useExisting?: any,
    useFactory?: Function,
    deps?: Object[],
    multi?: boolean
  }): Provider;
  

    
  /**
   * A unique object used for retrieving items from the {@link Injector}.
   * 
   * Keys have:
   * - a system-wide unique `id`.
   * - a `token`.
   * 
   * `Key` is used internally by {@link Injector} because its system-wide unique `id` allows the
   * injector to store created objects in a more efficient way.
   * 
   * `Key` should not be created directly. {@link Injector} creates keys automatically when resolving
   * providers.
   */
  class Key {
    
    /**
     * Private
     */
    constructor(token: Object, id: number);
    
    /**
     * Retrieves a `Key` for a token.
     */
    static get(token: Object): Key;
    
    /**
     * @returns the number of keys registered in the system.
     */
    static numberOfKeys: number;
    
    token: Object;
    
    id: number;
    
    /**
     * Returns a stringified token.
     */
    displayName: string;
    
  }

    
  /**
   * Type literals is a Dart-only feature. This is here only so we can x-compile
   * to multiple languages.
   */
  class TypeLiteral {
    
    type: any;
    
  }

    
  /**
   * Thrown when trying to retrieve a dependency by `Key` from {@link Injector}, but the
   * {@link Injector} does not have a {@link Provider} for {@link Key}.
   * 
   * ### Example ([live demo](http://plnkr.co/edit/vq8D3FRB9aGbnWJqtEPE?p=preview))
   * 
   * ```typescript
   * class A {
   *   constructor(b:B) {}
   * }
   * 
   * expect(() => Injector.resolveAndCreate([A])).toThrowError();
   * ```
   */
  class NoProviderError extends AbstractProviderError {
    
    constructor(injector: Injector, key: Key);
    
  }

    
  /**
   * Base class for all errors arising from misconfigured providers.
   */
  class AbstractProviderError extends BaseException {
    
    constructor(injector: Injector, key: Key, constructResolvingMessage: Function);
    
    addKey(injector: Injector, key: Key): void;
    
    context: any;
    
  }

    
  /**
   * Thrown when dependencies form a cycle.
   * 
   * ### Example ([live demo](http://plnkr.co/edit/wYQdNos0Tzql3ei1EV9j?p=info))
   * 
   * ```typescript
   * var injector = Injector.resolveAndCreate([
   *   provide("one", {useFactory: (two) => "two", deps: [[new Inject("two")]]}),
   *   provide("two", {useFactory: (one) => "one", deps: [[new Inject("one")]]})
   * ]);
   * 
   * expect(() => injector.get("one")).toThrowError();
   * ```
   * 
   * Retrieving `A` or `B` throws a `CyclicDependencyError` as the graph above cannot be constructed.
   */
  class CyclicDependencyError extends AbstractProviderError {
    
    constructor(injector: Injector, key: Key);
    
  }

    
  /**
   * Thrown when a constructing type returns with an Error.
   * 
   * The `InstantiationError` class contains the original error plus the dependency graph which caused
   * this object to be instantiated.
   * 
   * ### Example ([live demo](http://plnkr.co/edit/7aWYdcqTQsP0eNqEdUAf?p=preview))
   * 
   * ```typescript
   * class A {
   *   constructor() {
   *     throw new Error('message');
   *   }
   * }
   * 
   * var injector = Injector.resolveAndCreate([A]);
   * 
   * try {
   *   injector.get(A);
   * } catch (e) {
   *   expect(e instanceof InstantiationError).toBe(true);
   *   expect(e.originalException.message).toEqual("message");
   *   expect(e.originalStack).toBeDefined();
   * }
   * ```
   */
  class InstantiationError extends WrappedException {
    
    constructor(injector: Injector, originalException: any, originalStack: any, key: Key);
    
    addKey(injector: Injector, key: Key): void;
    
    wrapperMessage: string;
    
    causeKey: Key;
    
    context: any;
    
  }

    
  /**
   * Thrown when an object other then {@link Provider} (or `Type`) is passed to {@link Injector}
   * creation.
   * 
   * ### Example ([live demo](http://plnkr.co/edit/YatCFbPAMCL0JSSQ4mvH?p=preview))
   * 
   * ```typescript
   * expect(() => Injector.resolveAndCreate(["not a type"])).toThrowError();
   * ```
   */
  class InvalidProviderError extends BaseException {
    
    constructor(provider: any);
    
  }

    
  /**
   * Thrown when the class has no annotation information.
   * 
   * Lack of annotation information prevents the {@link Injector} from determining which dependencies
   * need to be injected into the constructor.
   * 
   * ### Example ([live demo](http://plnkr.co/edit/rHnZtlNS7vJOPQ6pcVkm?p=preview))
   * 
   * ```typescript
   * class A {
   *   constructor(b) {}
   * }
   * 
   * expect(() => Injector.resolveAndCreate([A])).toThrowError();
   * ```
   * 
   * This error is also thrown when the class not marked with {@link Injectable} has parameter types.
   * 
   * ```typescript
   * class B {}
   * 
   * class A {
   *   constructor(b:B) {} // no information about the parameter types of A is available at runtime.
   * }
   * 
   * expect(() => Injector.resolveAndCreate([A,B])).toThrowError();
   * ```
   */
  class NoAnnotationError extends BaseException {
    
    constructor(typeOrFunc: any, params: any[][]);
    
  }

    
  /**
   * Thrown when getting an object by index.
   * 
   * ### Example ([live demo](http://plnkr.co/edit/bRs0SX2OTQiJzqvjgl8P?p=preview))
   * 
   * ```typescript
   * class A {}
   * 
   * var injector = Injector.resolveAndCreate([A]);
   * 
   * expect(() => injector.getAt(100)).toThrowError();
   * ```
   */
  class OutOfBoundsError extends BaseException {
    
    constructor(index: any);
    
  }

    
  /**
   * Creates a token that can be used in a DI Provider.
   * 
   * ### Example ([live demo](http://plnkr.co/edit/Ys9ezXpj2Mnoy3Uc8KBp?p=preview))
   * 
   * ```typescript
   * var t = new OpaqueToken("value");
   * 
   * var injector = Injector.resolveAndCreate([
   *   provide(t, {useValue: "providedValue"})
   * ]);
   * 
   * expect(injector.get(t)).toEqual("bindingValue");
   * ```
   * 
   * Using an `OpaqueToken` is preferable to using strings as tokens because of possible collisions
   * caused by multiple providers using the same string as two different tokens.
   * 
   * Using an `OpaqueToken` is preferable to using an `Object` as tokens because it provides better
   * error messages.
   */
  class OpaqueToken {
    
    constructor(_desc: string);
    
    toString(): string;
    
  }

    
  /**
   * Factory for creating {@link InjectMetadata}.
   */
  interface InjectFactory {
    
    new(token: any): InjectMetadata;
    
    (token: any): any;
    
  }

    
  /**
   * Factory for creating {@link OptionalMetadata}.
   */
  interface OptionalFactory {
    
    new(): OptionalMetadata;
    
    (): any;
    
  }

    
  /**
   * Factory for creating {@link InjectableMetadata}.
   */
  interface InjectableFactory {
    
    new(): InjectableMetadata;
    
    (): any;
    
  }

    
  /**
   * Factory for creating {@link SelfMetadata}.
   */
  interface SelfFactory {
    
    new(): SelfMetadata;
    
    (): any;
    
  }

    
  /**
   * Factory for creating {@link HostMetadata}.
   */
  interface HostFactory {
    
    new(): HostMetadata;
    
    (): any;
    
  }

    
  /**
   * Factory for creating {@link SkipSelfMetadata}.
   */
  interface SkipSelfFactory {
    
    new(): SkipSelfMetadata;
    
    (): any;
    
  }

    
  /**
   * Factory for creating {@link InjectMetadata}.
   */
  var Inject: InjectFactory;
  

    
  /**
   * Factory for creating {@link OptionalMetadata}.
   */
  var Optional: OptionalFactory;
  

    
  /**
   * Factory for creating {@link InjectableMetadata}.
   */
  var Injectable: InjectableFactory;
  

    
  /**
   * Factory for creating {@link SelfMetadata}.
   */
  var Self: SelfFactory;
  

    
  /**
   * Factory for creating {@link HostMetadata}.
   */
  var Host: HostFactory;
  

    
  /**
   * Factory for creating {@link SkipSelfMetadata}.
   */
  var SkipSelf: SkipSelfFactory;
  

    
  /**
   * The `async` pipe subscribes to an Observable or Promise and returns the latest value it has
   * emitted.
   * When a new value is emitted, the `async` pipe marks the component to be checked for changes.
   * 
   * ### Example
   * The example below binds the `time` Observable to the view. Every 500ms, the `time` Observable
   * updates the view with the current time.
   * 
   * ```
   * import {Observable} from 'angular2/core';
   * @Component({
   *   selector: "task-cmp",
   *   template: "Time: {{ time | async }}"
   * })
   * class Task {
   *   time = new Observable<number>(observer => {
   *     setInterval(_ =>
   *       observer.next(new Date().getTime()), 500);
   *   });
   * }
   * ```
   */
  class AsyncPipe implements PipeTransform,  PipeOnDestroy {
    
    constructor(_ref: ChangeDetectorRef);
    
    onDestroy(): void;
    
    transform(obj: Observable | Promise<any>, args?: any[]): any;
    
  }

    
  /**
   * WARNING: this pipe uses the Internationalization API.
   * Therefore it is only reliable in Chrome and Opera browsers.
   * 
   * Formats a date value to a string based on the requested format.
   * 
   * ##Usage
   * 
   *     expression | date[:format]
   * 
   * where `expression` is a date object or a number (milliseconds since UTC epoch) and
   * `format` indicates which date/time components to include:
   * 
   *  | Component | Symbol | Short Form   | Long Form         | Numeric   | 2-digit   |
   *  |-----------|:------:|--------------|-------------------|-----------|-----------|
   *  | era       |   G    | G (AD)       | GGGG (Anno Domini)| -         | -         |
   *  | year      |   y    | -            | -                 | y (2015)  | yy (15)   |
   *  | month     |   M    | MMM (Sep)    | MMMM (September)  | M (9)     | MM (09)   |
   *  | day       |   d    | -            | -                 | d (3)     | dd (03)   |
   *  | weekday   |   E    | EEE (Sun)    | EEEE (Sunday)     | -         | -         |
   *  | hour      |   j    | -            | -                 | j (13)    | jj (13)   |
   *  | hour12    |   h    | -            | -                 | h (1 PM)  | hh (01 PM)|
   *  | hour24    |   H    | -            | -                 | H (13)    | HH (13)   |
   *  | minute    |   m    | -            | -                 | m (5)     | mm (05)   |
   *  | second    |   s    | -            | -                 | s (9)     | ss (09)   |
   *  | timezone  |   z    | -            | z (Pacific Standard Time)| -  | -         |
   *  | timezone  |   Z    | Z (GMT-8:00) | -                 | -         | -         |
   * 
   * In javascript, only the components specified will be respected (not the ordering,
   * punctuations, ...) and details of the formatting will be dependent on the locale.
   * On the other hand in Dart version, you can also include quoted text as well as some extra
   * date/time components such as quarter. For more information see:
   * https://api.dartlang.org/apidocs/channels/stable/dartdoc-viewer/intl/intl.DateFormat.
   * 
   * `format` can also be one of the following predefined formats:
   * 
   *  - `'medium'`: equivalent to `'yMMMdjms'` (e.g. Sep 3, 2010, 12:05:08 PM for en-US)
   *  - `'short'`: equivalent to `'yMdjm'` (e.g. 9/3/2010, 12:05 PM for en-US)
   *  - `'fullDate'`: equivalent to `'yMMMMEEEEd'` (e.g. Friday, September 3, 2010 for en-US)
   *  - `'longDate'`: equivalent to `'yMMMMd'` (e.g. September 3, 2010)
   *  - `'mediumDate'`: equivalent to `'yMMMd'` (e.g. Sep 3, 2010 for en-US)
   *  - `'shortDate'`: equivalent to `'yMd'` (e.g. 9/3/2010 for en-US)
   *  - `'mediumTime'`: equivalent to `'jms'` (e.g. 12:05:08 PM for en-US)
   *  - `'shortTime'`: equivalent to `'jm'` (e.g. 12:05 PM for en-US)
   * 
   * Timezone of the formatted text will be the local system timezone of the end-users machine.
   * 
   * ### Examples
   * 
   * Assuming `dateObj` is (year: 2015, month: 6, day: 15, hour: 21, minute: 43, second: 11)
   * in the _local_ time and locale is 'en-US':
   * 
   *     {{ dateObj | date }}               // output is 'Jun 15, 2015'
   *     {{ dateObj | date:'medium' }}      // output is 'Jun 15, 2015, 9:43:11 PM'
   *     {{ dateObj | date:'shortTime' }}   // output is '9:43 PM'
   *     {{ dateObj | date:'mmss' }}        // output is '43:11'
   */
  class DatePipe implements PipeTransform {
    
    transform(value: any, args: any[]): string;
    
    supports(obj: any): boolean;
    
  }

    
  let DEFAULT_PIPES: Provider;
  

    
  let DEFAULT_PIPES_TOKEN: OpaqueToken;
  

    
  /**
   * Implements json transforms to any object.
   * 
   * ### Example
   * 
   * In this example we transform the user object to json.
   * 
   *  ```
   * @Component({
   *   selector: "user-cmp",
   *   template: "User: {{ user | json }}"
   * })
   * class Username {
   *  user:Object
   *  constructor() {
   *    this.user = { name: "PatrickJS" };
   *  }
   * }
   * 
   * ```
   */
  class JsonPipe implements PipeTransform {
    
    transform(value: any, args?: any[]): string;
    
  }

    
  /**
   * Creates a new List or String containing only a subset (slice) of the
   * elements.
   * 
   * The starting index of the subset to return is specified by the `start` parameter.
   * 
   * The ending index of the subset to return is specified by the optional `end` parameter.
   * 
   * ##Usage
   * 
   *     expression | slice:start[:end]
   * 
   * All behavior is based on the expected behavior of the JavaScript API
   * Array.prototype.slice() and String.prototype.slice()
   * 
   * Where the input expression is a [List] or [String], and `start` is:
   * 
   * - **a positive integer**: return the item at _start_ index and all items after
   * in the list or string expression.
   * - **a negative integer**: return the item at _start_ index from the end and all items after
   * in the list or string expression.
   * - **`|start|` greater than the size of the expression**: return an empty list or string.
   * - **`|start|` negative greater than the size of the expression**: return entire list or
   * string expression.
   * 
   * and where `end` is:
   * 
   * - **omitted**: return all items until the end of the input
   * - **a positive integer**: return all items before _end_ index of the list or string
   * expression.
   * - **a negative integer**: return all items before _end_ index from the end of the list
   * or string expression.
   * 
   * When operating on a [List], the returned list is always a copy even when all
   * the elements are being returned.
   * 
   * ### Examples
   * 
   * ## List Example
   * 
   * Assuming `var collection = ['a', 'b', 'c', 'd']`, this `ng-for` directive:
   * 
   *     <li *ng-for="var i of collection | slice:1:3">{{i}}</li>
   * 
   * produces the following:
   * 
   *     <li>b</li>
   *     <li>c</li>
   * 
   * ## String Examples
   * 
   *     {{ 'abcdefghij' | slice:0:4 }}       // output is 'abcd'
   *     {{ 'abcdefghij' | slice:4:0 }}       // output is ''
   *     {{ 'abcdefghij' | slice:-4 }}      // output is 'ghij'
   *     {{ 'abcdefghij' | slice:-4,-2 }}      // output is 'gh'
   *     {{ 'abcdefghij' | slice: -100 }}    // output is 'abcdefghij'
   *     {{ 'abcdefghij' | slice: 100 }}    // output is ''
   */
  class SlicePipe implements PipeTransform {
    
    transform(value: any, args?: any[]): any;
    
    supports(obj: any): boolean;
    
  }

    
  /**
   * Implements lowercase transforms to text.
   * 
   * ### Example
   * 
   * In this example we transform the user text lowercase.
   * 
   *  ```
   * @Component({
   *   selector: "username-cmp",
   *   template: "Username: {{ user | lowercase }}"
   * })
   * class Username {
   *   user:string;
   * }
   * 
   * ```
   */
  class LowerCasePipe implements PipeTransform {
    
    transform(value: string, args?: any[]): string;
    
  }

    
  class NumberPipe {
    
  }

    
  /**
   * WARNING: this pipe uses the Internationalization API.
   * Therefore it is only reliable in Chrome and Opera browsers.
   * 
   * Formats a number as local text. i.e. group sizing and separator and other locale-specific
   * configurations are based on the active locale.
   * 
   * ##Usage
   * 
   *     expression | number[:digitInfo]
   * 
   * where `expression` is a number and `digitInfo` has the following format:
   * 
   *     {minIntegerDigits}.{minFractionDigits}-{maxFractionDigits}
   * 
   * - minIntegerDigits is the minimum number of integer digits to use. Defaults to 1.
   * - minFractionDigits is the minimum number of digits after fraction. Defaults to 0.
   * - maxFractionDigits is the maximum number of digits after fraction. Defaults to 3.
   * 
   * For more information on the acceptable range for each of these numbers and other
   * details see your native internationalization library.
   * 
   * ### Examples
   * 
   *     {{ 123 | number }}              // output is 123
   *     {{ 123.1 | number: '.2-3' }}    // output is 123.10
   *     {{ 1 | number: '2.2' }}         // output is 01.00
   */
  class DecimalPipe extends NumberPipe implements PipeTransform {
    
    transform(value: any, args: any[]): string;
    
  }

    
  /**
   * WARNING: this pipe uses the Internationalization API.
   * Therefore it is only reliable in Chrome and Opera browsers.
   * 
   * Formats a number as local percent.
   * 
   * ##Usage
   * 
   *     expression | percent[:digitInfo]
   * 
   * For more information about `digitInfo` see {@link DecimalPipe}
   */
  class PercentPipe extends NumberPipe implements PipeTransform {
    
    transform(value: any, args: any[]): string;
    
  }

    
  /**
   * WARNING: this pipe uses the Internationalization API.
   * Therefore it is only reliable in Chrome and Opera browsers.
   * 
   * Formats a number as local currency.
   * 
   * ##Usage
   * 
   *     expression | currency[:currencyCode[:symbolDisplay[:digitInfo]]]
   * 
   * where `currencyCode` is the ISO 4217 currency code, such as "USD" for the US dollar and
   * "EUR" for the euro. `symbolDisplay` is a boolean indicating whether to use the currency
   * symbol (e.g. $) or the currency code (e.g. USD) in the output. The default for this value
   * is `false`.
   * For more information about `digitInfo` see {@link DecimalPipe}
   */
  class CurrencyPipe extends NumberPipe implements PipeTransform {
    
    transform(value: any, args: any[]): string;
    
  }

    
  /**
   * Implements uppercase transforms to text.
   * 
   * ### Example
   * 
   * In this example we transform the user text uppercase.
   * 
   *  ```
   * @Component({
   *   selector: "username-cmp",
   *   template: "Username: {{ user | uppercase }}"
   * })
   * class Username {
   *   user:string;
   * }
   * 
   * ```
   */
  class UpperCasePipe implements PipeTransform {
    
    transform(value: string, args?: any[]): string;
    
  }

    
  interface ConcreteType extends Type {
    
    new(...args: any[]): any;
    
  }

    
  /**
   * 
   * Runtime representation a type that a Component or other object is instances of.
   * 
   * An example of a `Type` is `MyCustomComponent` class, which in JavaScript is be represented by
   * the `MyCustomComponent` constructor function.
   */
  interface Type extends Function {
    
  }

    
  class Observable {
    
    observer(generator: any): Object;
    
  }

    
  /**
   * Use by directives and components to emit custom Events.
   * 
   * ### Examples
   * 
   * In the following example, `Zippy` alternatively emits `open` and `close` events when its
   * title gets clicked:
   * 
   * ```
   * @Component({
   *   selector: 'zippy',
   *   template: `
   *   <div class="zippy">
   *     <div (click)="toggle()">Toggle</div>
   *     <div [hidden]="!visible">
   *       <ng-content></ng-content>
   *     </div>
   *  </div>`})
   * export class Zippy {
   *   visible: boolean = true;
   *   @Output() open: EventEmitter = new EventEmitter();
   *   @Output() close: EventEmitter = new EventEmitter();
   * 
   *   toggle() {
   *     this.visible = !this.visible;
   *     if (this.visible) {
   *       this.open.next(null);
   *     } else {
   *       this.close.next(null);
   *     }
   *   }
   * }
   * ```
   * 
   * Use Rx.Observable but provides an adapter to make it work as specified here:
   * https://github.com/jhusain/observable-spec
   * 
   * Once a reference implementation of the spec is available, switch to it.
   */
  class EventEmitter extends Observable {
    
    /**
     * Creates an instance of [EventEmitter], which depending on [isAsync],
     * delivers events synchronously or asynchronously.
     */
    constructor(isAsync?: boolean);
    
    observer(generator: any): any;
    
    toRx(): any;
    
    next(value: any): void;
    
    throw(error: any): void;
    
    return(value?: any): void;
    
  }

    
  interface Predicate<T> {
    
    (value: T, index?: number, array?: T[]): boolean;
    
  }

    
  class WrappedException extends Error {
    
    constructor(_wrapperMessage: string, _originalException: any, _originalStack?: any, _context?: any);
    
    wrapperMessage: string;
    
    wrapperStack: any;
    
    originalException: any;
    
    originalStack: any;
    
    context: any;
    
    message: string;
    
    toString(): string;
    
  }

    
  /**
   * Constructs the set of providers meant for use at the platform level.
   * 
   * These are providers that should be singletons shared among all Angular applications
   * running on the page.
   */
  function platformProviders(): Array<Type | Provider | any[]>;
  

    
  /**
   * Construct a default set of providers which should be included in any Angular
   * application, regardless of whether it runs on the UI thread or in a web worker.
   */
  function applicationCommonProviders(): Array<Type | Provider | any[]>;
  

    
  /**
   * Create an Angular zone.
   */
  function createNgZone(): NgZone;
  

    
  function platformCommon(providers?: Array<Type | Provider | any[]>, initializer?: () => void): PlatformRef;
  

    
  /**
   * The Angular platform is the entry point for Angular on a web page. Each page
   * has exactly one platform, and services (such as reflection) which are common
   * to every Angular application running on the page are bound in its scope.
   * 
   * A page's platform is initialized implicitly when {@link bootstrap}() is called, or
   * explicitly by calling {@link platform}().
   */
  abstract class PlatformRef {
    
    /**
     * Register a listener to be called when the platform is disposed.
     */
    registerDisposeListener(dispose: () => void): void;
    
    /**
     * Retrieve the platform {@link Injector}, which is the parent injector for
     * every Angular application on the page and provides singleton providers.
     */
    injector: Injector;
    
    /**
     * Instantiate a new Angular application on the page.
     * 
     * ##What is an application?
     * 
     * Each Angular application has its own zone, change detection, compiler,
     * renderer, and other framework components. An application hosts one or more
     * root components, which can be initialized via `ApplicationRef.bootstrap()`.
     * 
     * ##Application Providers
     * 
     * Angular applications require numerous providers to be properly instantiated.
     * When using `application()` to create a new app on the page, these providers
     * must be provided. Fortunately, there are helper functions to configure
     * typical providers, as shown in the example below.
     * 
     * ### Example
     * ```
     * var myAppProviders = [MyAppService];
     * 
     * platform()
     *   .application([applicationCommonProviders(), applicationDomProviders(), myAppProviders])
     *   .bootstrap(MyTopLevelComponent);
     * ```
     * ##See Also
     * 
     * See the {@link bootstrap} documentation for more details.
     */
    application(providers: Array<Type | Provider | any[]>): ApplicationRef;
    
    /**
     * Instantiate a new Angular application on the page, using providers which
     * are only available asynchronously. One such use case is to initialize an
     * application running in a web worker.
     * 
     * ##Usage
     * 
     * `bindingFn` is a function that will be called in the new application's zone.
     * It should return a `Promise` to a list of providers to be used for the
     * new application. Once this promise resolves, the application will be
     * constructed in the same manner as a normal `application()`.
     */
    asyncApplication(bindingFn: (zone: NgZone) =>
                                    Promise<Array<Type | Provider | any[]>>): Promise<ApplicationRef>;
    
    /**
     * Destroy the Angular platform and all Angular applications on the page.
     */
    dispose(): void;
    
  }

    
  class PlatformRef_ extends PlatformRef {
    
    constructor(_injector: Injector, _dispose: () => void);
    
    registerDisposeListener(dispose: () => void): void;
    
    injector: Injector;
    
    application(providers: Array<Type | Provider | any[]>): ApplicationRef;
    
    asyncApplication(bindingFn: (zone: NgZone) => Promise<Array<Type | Provider | any[]>>): Promise<ApplicationRef>;
    
    dispose(): void;
    
  }

    
  /**
   * A reference to an Angular application running on a page.
   * 
   * For more about Angular applications, see the documentation for {@link bootstrap}.
   */
  abstract class ApplicationRef {
    
    /**
     * Register a listener to be called each time `bootstrap()` is called to bootstrap
     * a new root component.
     */
    registerBootstrapListener(listener: (ref: ComponentRef) => void): void;
    
    /**
     * Register a listener to be called when the application is disposed.
     */
    registerDisposeListener(dispose: () => void): void;
    
    /**
     * Bootstrap a new component at the root level of the application.
     * 
     * ##Bootstrap process
     * 
     * When bootstrapping a new root component into an application, Angular mounts the
     * specified application component onto DOM elements identified by the [componentType]'s
     * selector and kicks off automatic change detection to finish initializing the component.
     * 
     * ##Optional Providers
     * 
     * Providers for the given component can optionally be overridden via the `providers`
     * parameter. These providers will only apply for the root component being added and any
     * child components under it.
     * 
     * ### Example
     * ```
     * var app = platform.application([applicationCommonProviders(), applicationDomProviders()];
     * app.bootstrap(FirstRootComponent);
     * app.bootstrap(SecondRootComponent, [provide(OverrideBinding, {useClass: OverriddenBinding})]);
     * ```
     */
    bootstrap(componentType: Type, providers?: Array<Type | Provider | any[]>): Promise<ComponentRef>;
    
    /**
     * Retrieve the application {@link Injector}.
     */
    injector: Injector;
    
    /**
     * Retrieve the application {@link NgZone}.
     */
    zone: NgZone;
    
    /**
     * Dispose of this application and all of its components.
     */
    dispose(): void;
    
    /**
     * Get a list of component types registered to this application.
     */
    componentTypes: Type[];
    
  }

    
  class ApplicationRef_ extends ApplicationRef {
    
    constructor(_platform: PlatformRef_, _zone: NgZone, _injector: Injector);
    
    registerBootstrapListener(listener: (ref: ComponentRef) => void): void;
    
    registerDisposeListener(dispose: () => void): void;
    
    bootstrap(componentType: Type, providers?: Array<Type | Provider | any[]>): Promise<ComponentRef>;
    
    injector: Injector;
    
    zone: NgZone;
    
    dispose(): void;
    
    componentTypes: any[];
    
  }

    
  /**
   * Specifies app root url for the application.
   * 
   * Used by the {@link Compiler} when resolving HTML and CSS template URLs.
   * 
   * This interface can be overridden by the application developer to create custom behavior.
   * 
   * See {@link Compiler}
   */
  class AppRootUrl {
    
    constructor(value: string);
    
    value: string;
    
  }

    
  /**
   * Used by the {@link Compiler} when resolving HTML and CSS template URLs.
   * 
   * This interface can be overridden by the application developer to create custom behavior.
   * 
   * See {@link Compiler}
   */
  class UrlResolver {
    
    /**
     * Resolves the `url` given the `baseUrl`:
     * - when the `url` is null, the `baseUrl` is returned,
     * - if `url` is relative ('path/to/here', './path/to/here'), the resolved url is a combination of
     * `baseUrl` and `url`,
     * - if `url` is absolute (it has a scheme: 'http://', 'https://' or start with '/'), the `url` is
     * returned as is (ignoring the `baseUrl`)
     * 
     * @param {string} baseUrl
     * @param {string} url
     * @returns {string} the resolved URL
     */
    resolve(baseUrl: string, url: string): string;
    
  }

    
  /**
   * A service that can be used to get and set the title of a current HTML document.
   * 
   * Since an Angular 2 application can't be bootstrapped on the entire HTML document (`<html>` tag)
   * it is not possible to bind to the `text` property of the `HTMLTitleElement` elements
   * (representing the `<title>` tag). Instead, this service can be used to set and get the current
   * title value.
   */
  class Title {
    
    /**
     * Get the title of the current HTML document.
     * @returns {string}
     */
    getTitle(): string;
    
    /**
     * Set the title of the current HTML document.
     * @param newTitle
     */
    setTitle(newTitle: string): void;
    
  }

    
  class DirectiveResolver {
    
    /**
     * Return {@link DirectiveMetadata} for a given `Type`.
     */
    resolve(type: Type): DirectiveMetadata;
    
  }

    
  /**
   * Low-level service for compiling {@link Component}s into {@link ProtoViewRef ProtoViews}s, which
   * can later be used to create and render a Component instance.
   * 
   * Most applications should instead use higher-level {@link DynamicComponentLoader} service, which
   * both compiles and instantiates a Component.
   */
  abstract class Compiler {
    
    compileInHost(componentType: Type): Promise<ProtoViewRef>;
    
    clearCache(): void;
    
  }

    
  /**
   * Service exposing low level API for creating, moving and destroying Views.
   * 
   * Most applications should use higher-level abstractions like {@link DynamicComponentLoader} and
   * {@link ViewContainerRef} instead.
   */
  abstract class AppViewManager {
    
    /**
     * Returns a {@link ViewContainerRef} of the View Container at the specified location.
     */
    getViewContainer(location: ElementRef): ViewContainerRef;
    
    /**
     * Returns the {@link ElementRef} that makes up the specified Host View.
     */
    getHostElement(hostViewRef: HostViewRef): ElementRef;
    
    /**
     * Searches the Component View of the Component specified via `hostLocation` and returns the
     * {@link ElementRef} for the Element identified via a Variable Name `variableName`.
     * 
     * Throws an exception if the specified `hostLocation` is not a Host Element of a Component, or if
     * variable `variableName` couldn't be found in the Component View of this Component.
     */
    getNamedElementInComponentView(hostLocation: ElementRef, variableName: string): ElementRef;
    
    /**
     * Returns the component instance for the provided Host Element.
     */
    getComponent(hostLocation: ElementRef): any;
    
    /**
     * Creates an instance of a Component and attaches it to the first element in the global View
     * (usually DOM Document) that matches the component's selector or `overrideSelector`.
     * 
     * This as a low-level way to bootstrap an application and upgrade an existing Element to a
     * Host Element. Most applications should use {@link DynamicComponentLoader#loadAsRoot} instead.
     * 
     * The Component and its View are created based on the `hostProtoViewRef` which can be obtained
     * by compiling the component with {@link Compiler#compileInHost}.
     * 
     * Use {@link AppViewManager#destroyRootHostView} to destroy the created Component and it's Host
     * View.
     * 
     * ### Example
     * 
     * ```
     * @ng.Component({
     *   selector: 'child-component'
     * })
     * @ng.View({
     *   template: 'Child'
     * })
     * class ChildComponent {
     * 
     * }
     * 
     * @ng.Component({
     *   selector: 'my-app'
     * })
     * @ng.View({
     *   template: `
     *     Parent (<some-component></some-component>)
     *   `
     * })
     * class MyApp {
     *   viewRef: ng.ViewRef;
     * 
     *   constructor(public appViewManager: ng.AppViewManager, compiler: ng.Compiler) {
     *     compiler.compileInHost(ChildComponent).then((protoView: ng.ProtoViewRef) => {
     *       this.viewRef = appViewManager.createRootHostView(protoView, 'some-component', null);
     *     })
     *   }
     * 
     *   onDestroy() {
     *     this.appViewManager.destroyRootHostView(this.viewRef);
     *     this.viewRef = null;
     *   }
     * }
     * 
     * ng.bootstrap(MyApp);
     * ```
     */
    createRootHostView(hostProtoViewRef: ProtoViewRef, overrideSelector: string, injector: Injector): HostViewRef;
    
    /**
     * Destroys the Host View created via {@link AppViewManager#createRootHostView}.
     * 
     * Along with the Host View, the Component Instance as well as all nested View and Components are
     * destroyed as well.
     */
    destroyRootHostView(hostViewRef: HostViewRef): void;
    
    /**
     * Instantiates an Embedded View based on the {@link TemplateRef `templateRef`} and inserts it
     * into the View Container specified via `viewContainerLocation` at the specified `index`.
     * 
     * Returns the {@link ViewRef} for the newly created View.
     * 
     * This as a low-level way to create and attach an Embedded via to a View Container. Most
     * applications should used {@link ViewContainerRef#createEmbeddedView} instead.
     * 
     * Use {@link AppViewManager#destroyViewInContainer} to destroy the created Embedded View.
     */
    createEmbeddedViewInContainer(viewContainerLocation: ElementRef, index: number, templateRef: TemplateRef): ViewRef;
    
    /**
     * Instantiates a single {@link Component} and inserts its Host View into the View Container
     * found at `viewContainerLocation`. Within the container, the view will be inserted at position
     * specified via `index`.
     * 
     * The component is instantiated using its {@link ProtoViewRef `protoViewRef`} which can be
     * obtained via {@link Compiler#compileInHost}.
     * 
     * You can optionally specify `imperativelyCreatedInjector`, which configure the {@link Injector}
     * that will be created for the Host View.
     * 
     * Returns the {@link HostViewRef} of the Host View created for the newly instantiated Component.
     * 
     * Use {@link AppViewManager#destroyViewInContainer} to destroy the created Host View.
     */
    createHostViewInContainer(viewContainerLocation: ElementRef, index: number, protoViewRef: ProtoViewRef, imperativelyCreatedInjector: ResolvedProvider[]): HostViewRef;
    
    /**
     * Destroys an Embedded or Host View attached to a View Container at the specified `index`.
     * 
     * The View Container is located via `viewContainerLocation`.
     */
    destroyViewInContainer(viewContainerLocation: ElementRef, index: number): void;
    
    /**
     * See {@link AppViewManager#detachViewInContainer}.
     */
    attachViewInContainer(viewContainerLocation: ElementRef, index: number, viewRef: ViewRef): ViewRef;
    
    /**
     * See {@link AppViewManager#attachViewInContainer}.
     */
    detachViewInContainer(viewContainerLocation: ElementRef, index: number): ViewRef;
    
  }

    
  /**
   * An unmodifiable list of items that Angular keeps up to date when the state
   * of the application changes.
   * 
   * The type of object that {@link QueryMetadata} and {@link ViewQueryMetadata} provide.
   * 
   * Implements an iterable interface, therefore it can be used in both ES6
   * javascript `for (var i of items)` loops as well as in Angular templates with
   * `*ng-for="#i of myList"`.
   * 
   * Changes can be observed by subscribing to the changes `Observable`.
   * 
   * NOTE: In the future this class will implement an `Observable` interface.
   * 
   * ### Example ([live demo](http://plnkr.co/edit/RX8sJnQYl9FWuSCWme5z?p=preview))
   * ```javascript
   * @Component({...})
   * class Container {
   *   constructor(@Query(Item) items: QueryList<Item>) {
   *     items.changes.subscribe(_ => console.log(items.length));
   *   }
   * }
   * ```
   */
  class QueryList<T> {
    
    changes: Observable;
    
    length: number;
    
    first: T;
    
    last: T;
    
    /**
     * returns a new array with the passed in function applied to each element.
     */
    map<U>(fn: (item: T) => U): U[];
    
    /**
     * returns a filtered array.
     */
    filter(fn: (item: T) => boolean): T[];
    
    /**
     * returns a reduced value.
     */
    reduce<U>(fn: (acc: U, item: T) => U, init: U): U;
    
    /**
     * converts QueryList into an array
     */
    toArray(): T[];
    
    toString(): string;
    
  }

    
  /**
   * Service for instantiating a Component and attaching it to a View at a specified location.
   */
  abstract class DynamicComponentLoader {
    
    /**
     * Creates an instance of a Component `type` and attaches it to the first element in the
     * platform-specific global view that matches the component's selector.
     * 
     * In a browser the platform-specific global view is the main DOM Document.
     * 
     * If needed, the component's selector can be overridden via `overrideSelector`.
     * 
     * You can optionally provide `injector` and this {@link Injector} will be used to instantiate the
     * Component.
     * 
     * To be notified when this Component instance is destroyed, you can also optionally provide
     * `onDispose` callback.
     * 
     * Returns a promise for the {@link ComponentRef} representing the newly created Component.
     * 
     * ### Example
     * 
     * ```
     * @Component({
     *   selector: 'child-component',
     *   template: 'Child'
     * })
     * class ChildComponent {
     * }
     * 
     * @Component({
     *   selector: 'my-app',
     *   template: 'Parent (<child id="child"></child>)'
     * })
     * class MyApp {
     *   constructor(dcl: DynamicComponentLoader, injector: Injector) {
     *     dcl.loadAsRoot(ChildComponent, '#child', injector);
     *   }
     * }
     * 
     * bootstrap(MyApp);
     * ```
     * 
     * Resulting DOM:
     * 
     * ```
     * <my-app>
     *   Parent (
     *     <child id="child">Child</child>
     *   )
     * </my-app>
     * ```
     */
    loadAsRoot(type: Type, overrideSelector: string, injector: Injector, onDispose?: () => void): Promise<ComponentRef>;
    
    /**
     * Creates an instance of a Component and attaches it to a View Container located inside of the
     * Component View of another Component instance.
     * 
     * The targeted Component Instance is specified via its `hostLocation` {@link ElementRef}. The
     * location within the Component View of this Component Instance is specified via `anchorName`
     * Template Variable Name.
     * 
     * You can optionally provide `providers` to configure the {@link Injector} provisioned for this
     * Component Instance.
     * 
     * Returns a promise for the {@link ComponentRef} representing the newly created Component.
     * 
     * ### Example
     * 
     * ```
     * @Component({
     *   selector: 'child-component',
     *   template: 'Child'
     * })
     * class ChildComponent {
     * }
     * 
     * @Component({
     *   selector: 'my-app',
     *   template: 'Parent (<div #child></div>)'
     * })
     * class MyApp {
     *   constructor(dcl: DynamicComponentLoader, elementRef: ElementRef) {
     *     dcl.loadIntoLocation(ChildComponent, elementRef, 'child');
     *   }
     * }
     * 
     * bootstrap(MyApp);
     * ```
     * 
     * Resulting DOM:
     * 
     * ```
     * <my-app>
     *    Parent (
     *      <div #child="" class="ng-binding"></div>
     *      <child-component class="ng-binding">Child</child-component>
     *    )
     * </my-app>
     * ```
     */
    loadIntoLocation(type: Type, hostLocation: ElementRef, anchorName: string, providers?: ResolvedProvider[]): Promise<ComponentRef>;
    
    /**
     * Creates an instance of a Component and attaches it to the View Container found at the
     * `location` specified as {@link ElementRef}.
     * 
     * You can optionally provide `providers` to configure the {@link Injector} provisioned for this
     * Component Instance.
     * 
     * Returns a promise for the {@link ComponentRef} representing the newly created Component.
     * 
     * 
     * ### Example
     * 
     * ```
     * @Component({
     *   selector: 'child-component',
     *   template: 'Child'
     * })
     * class ChildComponent {
     * }
     * 
     * @Component({
     *   selector: 'my-app',
     *   template: 'Parent'
     * })
     * class MyApp {
     *   constructor(dcl: DynamicComponentLoader, elementRef: ElementRef) {
     *     dcl.loadNextToLocation(ChildComponent, elementRef);
     *   }
     * }
     * 
     * bootstrap(MyApp);
     * ```
     * 
     * Resulting DOM:
     * 
     * ```
     * <my-app>Parent</my-app>
     * <child-component>Child</child-component>
     * ```
     */
    loadNextToLocation(type: Type, location: ElementRef, providers?: ResolvedProvider[]): Promise<ComponentRef>;
    
  }

    
  /**
   * Represents a location in a View that has an injection, change-detection and render context
   * associated with it.
   * 
   * An `ElementRef` is created for each element in the Template that contains a Directive, Component
   * or data-binding.
   * 
   * An `ElementRef` is backed by a render-specific element. In the browser, this is usually a DOM
   * element.
   */
  abstract class ElementRef implements RenderElementRef {
    
    /**
     * The underlying native element or `null` if direct access to native elements is not supported
     * (e.g. when the application runs in a web worker).
     * 
     * <div class="callout is-critical">
     *   <header>Use with caution</header>
     *   <p>
     *    Use this API as the last resort when direct access to DOM is needed. Use templating and
     *    data-binding provided by Angular instead. Alternatively you take a look at {@link Renderer}
     *    which provides API that can safely be used even when direct access to native elements is not
     *    supported.
     *   </p>
     *   <p>
     *    Relying on direct DOM access creates tight coupling between your application and rendering
     *    layers which will make it impossible to separate the two and deploy your application into a
     *    web worker.
     *   </p>
     * </div>
     */
    nativeElement: any;
    
    renderView: RenderViewRef;
    
  }

    
  /**
   * Represents an Embedded Template that can be used to instantiate Embedded Views.
   * 
   * You can access a `TemplateRef`, in two ways. Via a directive placed on a `<template>` element (or
   * directive prefixed with `*`) and have the `TemplateRef` for this Embedded View injected into the
   * constructor of the directive using the `TemplateRef` Token. Alternatively you can query for the
   * `TemplateRef` from a Component or a Directive via {@link Query}.
   * 
   * To instantiate Embedded Views based on a Template, use
   * {@link ViewContainerRef#createEmbeddedView}, which will create the View and attach it to the
   * View Container.
   */
  abstract class TemplateRef {
    
    /**
     * The location in the View where the Embedded View logically belongs to.
     * 
     * The data-binding and injection contexts of Embedded Views created from this `TemplateRef`
     * inherit from the contexts of this location.
     * 
     * Typically new Embedded Views are attached to the View Container of this location, but in
     * advanced use-cases, the View can be attached to a different container while keeping the
     * data-binding and injection context from the original location.
     */
    elementRef: ElementRef;
    
    /**
     * Allows you to check if this Embedded Template defines Local Variable with name matching `name`.
     */
    hasLocal(name: string): boolean;
    
  }

    
  /**
   * Represents an Angular View.
   * 
   * <!-- TODO: move the next two paragraphs to the dev guide -->
   * A View is a fundamental building block of the application UI. It is the smallest grouping of
   * Elements which are created and destroyed together.
   * 
   * Properties of elements in a View can change, but the structure (number and order) of elements in
   * a View cannot. Changing the structure of Elements can only be done by inserting, moving or
   * removing nested Views via a {@link ViewContainer}. Each View can contain many View Containers.
   * <!-- /TODO -->
   * 
   * ### Example
   * 
   * Given this template...
   * 
   * ```
   * Count: {{items.length}}
   * <ul>
   *   <li *ng-for="var item of items">{{item}}</li>
   * </ul>
   * ```
   * 
   * ... we have two {@link ProtoViewRef}s:
   * 
   * Outer {@link ProtoViewRef}:
   * ```
   * Count: {{items.length}}
   * <ul>
   *   <template ng-for var-item [ng-for-of]="items"></template>
   * </ul>
   * ```
   * 
   * Inner {@link ProtoViewRef}:
   * ```
   *   <li>{{item}}</li>
   * ```
   * 
   * Notice that the original template is broken down into two separate {@link ProtoViewRef}s.
   * 
   * The outer/inner {@link ProtoViewRef}s are then assembled into views like so:
   * 
   * ```
   * <!-- ViewRef: outer-0 -->
   * Count: 2
   * <ul>
   *   <template view-container-ref></template>
   *   <!-- ViewRef: inner-1 --><li>first</li><!-- /ViewRef: inner-1 -->
   *   <!-- ViewRef: inner-2 --><li>second</li><!-- /ViewRef: inner-2 -->
   * </ul>
   * <!-- /ViewRef: outer-0 -->
   * ```
   */
  abstract class ViewRef implements HostViewRef {
    
    /**
     * Sets `value` of local variable called `variableName` in this View.
     */
    setLocal(variableName: string, value: any): void;
    
    changeDetectorRef: ChangeDetectorRef;
    
  }

    
  /**
   * Represents a View containing a single Element that is the Host Element of a {@link Component}
   * instance.
   * 
   * A Host View is created for every dynamically created Component that was compiled on its own (as
   * opposed to as a part of another Component's Template) via {@link Compiler#compileInHost} or one
   * of the higher-level APIs: {@link AppViewManager#createRootHostView},
   * {@link AppViewManager#createHostViewInContainer}, {@link ViewContainerRef#createHostView}.
   */
  interface HostViewRef {
    
  }

    
  /**
   * Represents an Angular ProtoView.
   * 
   * A ProtoView is a prototypical {@link ViewRef View} that is the result of Template compilation and
   * is used by Angular to efficiently create an instance of this View based on the compiled Template.
   * 
   * Most ProtoViews are created and used internally by Angular and you don't need to know about them,
   * except in advanced use-cases where you compile components yourself via the low-level
   * {@link Compiler#compileInHost} API.
   * 
   * 
   * ### Example
   * 
   * Given this template:
   * 
   * ```
   * Count: {{items.length}}
   * <ul>
   *   <li *ng-for="var item of items">{{item}}</li>
   * </ul>
   * ```
   * 
   * Angular desugars and compiles the template into two ProtoViews:
   * 
   * Outer ProtoView:
   * ```
   * Count: {{items.length}}
   * <ul>
   *   <template ng-for var-item [ng-for-of]="items"></template>
   * </ul>
   * ```
   * 
   * Inner ProtoView:
   * ```
   *   <li>{{item}}</li>
   * ```
   * 
   * Notice that the original template is broken down into two separate ProtoViews.
   */
  abstract class ProtoViewRef {
    
  }

    
  /**
   * Represents a container where one or more Views can be attached.
   * 
   * The container can contain two kinds of Views. Host Views, created by instantiating a
   * {@link Component} via {@link #createHostView}, and Embedded Views, created by instantiating an
   * {@link TemplateRef Embedded Template} via {@link #createEmbeddedView}.
   * 
   * The location of the View Container within the containing View is specified by the Anchor
   * `element`. Each View Container can have only one Anchor Element and each Anchor Element can only
   * have a single View Container.
   * 
   * Root elements of Views attached to this container become siblings of the Anchor Element in
   * the Rendered View.
   * 
   * To access a `ViewContainerRef` of an Element, you can either place a {@link Directive} injected
   * with `ViewContainerRef` on the Element, or you obtain it via
   * {@link AppViewManager#getViewContainer}.
   * 
   * <!-- TODO(i): we are also considering ElementRef#viewContainer api -->
   */
  abstract class ViewContainerRef {
    
    /**
     * Anchor element that specifies the location of this container in the containing View.
     * <!-- TODO: rename to anchorElement -->
     */
    element: ElementRef;
    
    /**
     * Destroys all Views in this container.
     */
    clear(): void;
    
    /**
     * Returns the {@link ViewRef} for the View located in this container at the specified index.
     */
    get(index: number): ViewRef;
    
    /**
     * Returns the number of Views currently attached to this container.
     */
    length: number;
    
    /**
     * Instantiates an Embedded View based on the {@link TemplateRef `templateRef`} and inserts it
     * into this container at the specified `index`.
     * 
     * If `index` is not specified, the new View will be inserted as the last View in the container.
     * 
     * Returns the {@link ViewRef} for the newly created View.
     */
    createEmbeddedView(templateRef: TemplateRef, index?: number): ViewRef;
    
    /**
     * Instantiates a single {@link Component} and inserts its Host View into this container at the
     * specified `index`.
     * 
     * The component is instantiated using its {@link ProtoViewRef `protoView`} which can be
     * obtained via {@link Compiler#compileInHost}.
     * 
     * If `index` is not specified, the new View will be inserted as the last View in the container.
     * 
     * You can optionally specify `dynamicallyCreatedProviders`, which configure the {@link Injector}
     * that will be created for the Host View.
     * 
     * Returns the {@link HostViewRef} of the Host View created for the newly instantiated Component.
     */
    createHostView(protoViewRef?: ProtoViewRef, index?: number, dynamicallyCreatedProviders?: ResolvedProvider[]): HostViewRef;
    
    /**
     * Inserts a View identified by a {@link ViewRef} into the container at the specified `index`.
     * 
     * If `index` is not specified, the new View will be inserted as the last View in the container.
     * 
     * Returns the inserted {@link ViewRef}.
     */
    insert(viewRef: ViewRef, index?: number): ViewRef;
    
    /**
     * Returns the index of the View, specified via {@link ViewRef}, within the current container or
     * `-1` if this container doesn't contain the View.
     */
    indexOf(viewRef: ViewRef): number;
    
    /**
     * Destroys a View attached to this container at the specified `index`.
     * 
     * If `index` is not specified, the last View in the container will be removed.
     */
    remove(index?: number): void;
    
    /**
     * Use along with {@link #insert} to move a View within the current container.
     * 
     * If the `index` param is omitted, the last {@link ViewRef} is detached.
     */
    detach(index?: number): ViewRef;
    
  }

    
  /**
   * Represents an instance of a Component created via {@link DynamicComponentLoader}.
   * 
   * `ComponentRef` provides access to the Component Instance as well other objects related to this
   * Component Instance and allows you to destroy the Component Instance via the {@link #dispose}
   * method.
   */
  abstract class ComponentRef {
    
    /**
     * The injector provided {@link DynamicComponentLoader#loadAsRoot}.
     * 
     * TODO(i): this api is useless and should be replaced by an injector retrieved from
     *     the HostElementRef, which is currently not possible.
     */
    injector: Injector;
    
    /**
     * Location of the Host Element of this Component Instance.
     */
    location: ElementRef;
    
    /**
     * The instance of the Component.
     */
    instance: any;
    
    /**
     * The user defined component type, represented via the constructor function.
     * 
     * <!-- TODO: customize wording for Dart docs -->
     */
    componentType: Type;
    
    /**
     * The {@link ViewRef} of the Host View of this Component instance.
     */
    hostView: HostViewRef;
    
    /**
     * Destroys the component instance and all of the data structures associated with it.
     * 
     * TODO(i): rename to destroy to be consistent with AppViewManager and ViewContainerRef
     */
    dispose(): void;
    
  }

    
  /**
   * Provides access to explicitly trigger change detection in an application.
   * 
   * By default, `Zone` triggers change detection in Angular on each virtual machine (VM) turn. When
   * testing, or in some
   * limited application use cases, a developer can also trigger change detection with the
   * `lifecycle.tick()` method.
   * 
   * Each Angular application has a single `LifeCycle` instance.
   * 
   * ### Example
   * 
   * This is a contrived example, since the bootstrap automatically runs inside of the `Zone`, which
   * invokes
   * `lifecycle.tick()` on your behalf.
   * 
   * ```javascript
   * bootstrap(MyApp).then((ref:ComponentRef) => {
   *   var lifeCycle = ref.injector.get(LifeCycle);
   *   var myApp = ref.instance;
   * 
   *   ref.doSomething();
   *   lifecycle.tick();
   * });
   * ```
   */
  abstract class LifeCycle {
    
    /**
     * Invoke this method to explicitly process change detection and its side-effects.
     * 
     *  In development mode, `tick()` also performs a second change detection cycle to ensure that no
     * further
     *  changes are detected. If additional changes are picked up during this second cycle, bindings
     * in
     * the app have
     *  side-effects that cannot be resolved in a single change detection pass. In this case, Angular
     * throws an error,
     *  since an Angular application can only have one change detection pass during which all change
     * detection must
     *  complete.
     */
    tick(): void;
    
  }

    
  /**
   * An injectable service for executing work inside or outside of the Angular zone.
   * 
   * The most common use of this service is to optimize performance when starting a work consisting of
   * one or more asynchronous tasks that don't require UI updates or error handling to be handled by
   * Angular. Such tasks can be kicked off via {@link #runOutsideAngular} and if needed, these tasks
   * can reenter the Angular zone via {@link #run}.
   * 
   * <!-- TODO: add/fix links to:
   *   - docs explaining zones and the use of zones in Angular and change-detection
   *   - link to runOutsideAngular/run (throughout this file!)
   *   -->
   * 
   * ### Example ([live demo](http://plnkr.co/edit/lY9m8HLy7z06vDoUaSN2?p=preview))
   * ```
   * import {Component, View, NgIf, NgZone} from 'angular2/angular2';
   * 
   * @Component({
   *   selector: 'ng-zone-demo'.
   *   template: `
   *     <h2>Demo: NgZone</h2>
   * 
   *     <p>Progress: {{progress}}%</p>
   *     <p *ng-if="progress >= 100">Done processing {{label}} of Angular zone!</p>
   * 
   *     <button (click)="processWithinAngularZone()">Process within Angular zone</button>
   *     <button (click)="processOutsideOfAngularZone()">Process outside of Angular zone</button>
   *   `,
   *   directives: [NgIf]
   * })
   * export class NgZoneDemo {
   *   progress: number = 0;
   *   label: string;
   * 
   *   constructor(private _ngZone: NgZone) {}
   * 
   *   // Loop inside the Angular zone
   *   // so the UI DOES refresh after each setTimeout cycle
   *   processWithinAngularZone() {
   *     this.label = 'inside';
   *     this.progress = 0;
   *     this._increaseProgress(() => console.log('Inside Done!'));
   *   }
   * 
   *   // Loop outside of the Angular zone
   *   // so the UI DOES NOT refresh after each setTimeout cycle
   *   processOutsideOfAngularZone() {
   *     this.label = 'outside';
   *     this.progress = 0;
   *     this._ngZone.runOutsideAngular(() => {
   *       this._increaseProgress(() => {
   *       // reenter the Angular zone and display done
   *       this._ngZone.run(() => {console.log('Outside Done!') });
   *     }}));
   *   }
   * 
   * 
   *   _increaseProgress(doneCallback: () => void) {
   *     this.progress += 1;
   *     console.log(`Current progress: ${this.progress}%`);
   * 
   *     if (this.progress < 100) {
   *       window.setTimeout(() => this._increaseProgress(doneCallback)), 10)
   *     } else {
   *       doneCallback();
   *     }
   *   }
   * }
   * ```
   */
  class NgZone {
    
    /**
     * @param {bool} enableLongStackTrace whether to enable long stack trace. They should only be
     *               enabled in development mode as they significantly impact perf.
     */
    constructor({enableLongStackTrace}: any);
    
    /**
     * Sets the zone hook that is called just before a browser task that is handled by Angular
     * executes.
     * 
     * The hook is called once per browser task that is handled by Angular.
     * 
     * Setting the hook overrides any previously set hook.
     * 
     * @deprecated this API will be removed in the future. Use `onTurnStart` instead.
     */
    overrideOnTurnStart(onTurnStartHook: ZeroArgFunction): void;
    
    /**
     * Notifies subscribers just before Angular event turn starts.
     * 
     * Emits an event once per browser task that is handled by Angular.
     */
    onTurnStart: /* Subject */ any;
    
    /**
     * Sets the zone hook that is called immediately after Angular zone is done processing the current
     * task and any microtasks scheduled from that task.
     * 
     * This is where we typically do change-detection.
     * 
     * The hook is called once per browser task that is handled by Angular.
     * 
     * Setting the hook overrides any previously set hook.
     * 
     * @deprecated this API will be removed in the future. Use `onTurnDone` instead.
     */
    overrideOnTurnDone(onTurnDoneHook: ZeroArgFunction): void;
    
    /**
     * Notifies subscribers immediately after Angular zone is done processing
     * the current turn and any microtasks scheduled from that turn.
     * 
     * Used by Angular as a signal to kick off change-detection.
     */
    onTurnDone: any;
    
    /**
     * Sets the zone hook that is called immediately after the `onTurnDone` callback is called and any
     * microstasks scheduled from within that callback are drained.
     * 
     * `onEventDoneFn` is executed outside Angular zone, which means that we will no longer attempt to
     * sync the UI with any model changes that occur within this callback.
     * 
     * This hook is useful for validating application state (e.g. in a test).
     * 
     * Setting the hook overrides any previously set hook.
     * 
     * @deprecated this API will be removed in the future. Use `onEventDone` instead.
     */
    overrideOnEventDone(onEventDoneFn: ZeroArgFunction, opt_waitForAsync?: boolean): void;
    
    /**
     * Notifies subscribers immediately after the final `onTurnDone` callback
     * before ending VM event.
     * 
     * This event is useful for validating application state (e.g. in a test).
     */
    onEventDone: any;
    
    /**
     * Whether there are any outstanding microtasks.
     */
    hasPendingMicrotasks: boolean;
    
    /**
     * Whether there are any outstanding timers.
     */
    hasPendingTimers: boolean;
    
    /**
     * Whether there are any outstanding asychnronous tasks of any kind that are
     * scheduled to run within Angular zone.
     * 
     * Useful as a signal of UI stability. For example, when a test reaches a
     * point when [hasPendingAsyncTasks] is `false` it might be a good time to run
     * test expectations.
     */
    hasPendingAsyncTasks: boolean;
    
    /**
     * Sets the zone hook that is called when an error is thrown in the Angular zone.
     * 
     * Setting the hook overrides any previously set hook.
     * 
     * @deprecated this API will be removed in the future. Use `onError` instead.
     */
    overrideOnErrorHandler(errorHandler: ErrorHandlingFn): void;
    
    onError: any;
    
    /**
     * Executes the `fn` function synchronously within the Angular zone and returns value returned by
     * the function.
     * 
     * Running functions via `run` allows you to reenter Angular zone from a task that was executed
     * outside of the Angular zone (typically started via {@link #runOutsideAngular}).
     * 
     * Any future tasks or microtasks scheduled from within this function will continue executing from
     * within the Angular zone.
     */
    run(fn: () => any): any;
    
    /**
     * Executes the `fn` function synchronously in Angular's parent zone and returns value returned by
     * the function.
     * 
     * Running functions via `runOutsideAngular` allows you to escape Angular's zone and do work that
     * doesn't trigger Angular change-detection or is subject to Angular's error handling.
     * 
     * Any future tasks or microtasks scheduled from within this function will continue executing from
     * outside of the Angular zone.
     * 
     * Use {@link #run} to reenter the Angular zone and do work that updates the application model.
     */
    runOutsideAngular(fn: () => any): any;
    
  }

    
  interface ZeroArgFunction {
    
    (): void;
    
  }

    
  interface ErrorHandlingFn {
    
    (error: any, stackTrace: any): void;
    
  }

    
  /**
   * Stores error information; delivered via [NgZone.onError] stream.
   */
  class NgZoneError {
    
    constructor(error: any, stackTrace: any);
    
    error: any;
    
    stackTrace: any;
    
  }

    
  /**
   * The `NgClass` directive conditionally adds and removes CSS classes on an HTML element based on
   * an expression's evaluation result.
   * 
   * The result of an expression evaluation is interpreted differently depending on type of
   * the expression evaluation result:
   * - `string` - all the CSS classes listed in a string (space delimited) are added
   * - `Array` - all the CSS classes (Array elements) are added
   * - `Object` - each key corresponds to a CSS class name while values are interpreted as expressions
   * evaluating to `Boolean`. If a given expression evaluates to `true` a corresponding CSS class
   * is added - otherwise it is removed.
   * 
   * While the `NgClass` directive can interpret expressions evaluating to `string`, `Array`
   * or `Object`, the `Object`-based version is the most often used and has an advantage of keeping
   * all the CSS class names in a template.
   * 
   * ### Example ([live demo](http://plnkr.co/edit/a4YdtmWywhJ33uqfpPPn?p=preview)):
   * 
   * ```
   * import {Component, NgClass} from 'angular2/angular2';
   * 
   * @Component({
   *   selector: 'toggle-button',
   *   inputs: ['isDisabled'],
   *   template: `
   *      <div class="button" [ng-class]="{active: isOn, disabled: isDisabled}"
   *          (click)="toggle(!isOn)">
   *          Click me!
   *      </div>`,
   *   styles: [`
   *     .button {
   *       width: 120px;
   *       border: medium solid black;
   *     }
   * 
   *     .active {
   *       background-color: red;
   *    }
   * 
   *     .disabled {
   *       color: gray;
   *       border: medium solid gray;
   *     }
   *   `]
   *   directives: [NgClass]
   * })
   * class ToggleButton {
   *   isOn = false;
   *   isDisabled = false;
   * 
   *   toggle(newState) {
   *     if (!this.isDisabled) {
   *       this.isOn = newState;
   *     }
   *   }
   * }
   * ```
   */
  class NgClass implements DoCheck,  OnDestroy {
    
    constructor(_iterableDiffers: IterableDiffers, _keyValueDiffers: KeyValueDiffers, _ngEl: ElementRef, _renderer: Renderer);
    
    initialClasses: any;
    
    rawClass: any;
    
    doCheck(): void;
    
    onDestroy(): void;
    
  }

    
  /**
   * The `NgFor` directive instantiates a template once per item from an iterable. The context for
   * each instantiated template inherits from the outer context with the given loop variable set
   * to the current item from the iterable.
   * 
   * It is possible to alias the `index` to a local variable that will be set to the current loop
   * iteration in the template context, and also to alias the 'last' to a local variable that will
   * be set to a boolean indicating if the item is the last one in the iteration
   * 
   * When the contents of the iterator changes, `NgFor` makes the corresponding changes to the DOM:
   * 
   * * When an item is added, a new instance of the template is added to the DOM.
   * * When an item is removed, its template instance is removed from the DOM.
   * * When items are reordered, their respective templates are reordered in the DOM.
   * 
   * ### Example
   * 
   * ```
   * <ul>
   *   <li *ng-for="#error of errors; #i = index">
   *     Error {{i}} of {{errors.length}}: {{error.message}}
   *   </li>
   * </ul>
   * ```
   * 
   * ##Syntax
   * 
   * - `<li *ng-for="#item of items; #i = index">...</li>`
   * - `<li template="ng-for #item of items; #i = index">...</li>`
   * - `<template ng-for #item [ng-for-of]="items" #i="index"><li>...</li></template>`
   */
  class NgFor implements DoCheck {
    
    constructor(_viewContainer: ViewContainerRef, _templateRef: TemplateRef, _iterableDiffers: IterableDiffers, _cdr: ChangeDetectorRef);
    
    ngForOf: any;
    
    ngForTemplate: any;
    
    doCheck(): void;
    
  }

    
  /**
   * Removes or recreates a portion of the DOM tree based on an {expression}.
   * 
   * If the expression assigned to `ng-if` evaluates to a false value then the element
   * is removed from the DOM, otherwise a clone of the element is reinserted into the DOM.
   * 
   * ### Example ([live demo](http://plnkr.co/edit/fe0kgemFBtmQOY31b4tw?p=preview)):
   * 
   * ```
   * <div *ng-if="errorCount > 0" class="error">
   *   <!-- Error message displayed when the errorCount property on the current context is greater
   * than 0. -->
   *   {{errorCount}} errors detected
   * </div>
   * ```
   * 
   * ##Syntax
   * 
   * - `<div *ng-if="condition">...</div>`
   * - `<div template="ng-if condition">...</div>`
   * - `<template [ng-if]="condition"><div>...</div></template>`
   */
  class NgIf {
    
    constructor(_viewContainer: ViewContainerRef, _templateRef: TemplateRef);
    
    ngIf: any;
    
  }

    
  /**
   * The `NgStyle` directive changes styles based on a result of expression evaluation.
   * 
   * An expression assigned to the `ng-style` property must evaluate to an object and the
   * corresponding element styles are updated based on changes to this object. Style names to update
   * are taken from the object's keys, and values - from the corresponding object's values.
   * 
   * ##Syntax
   * 
   * - `<div [ng-style]="{'font-style': style}"></div>`
   * - `<div [ng-style]="styleExp"></div>` - here the `styleExp` must evaluate to an object
   * 
   * ### Example ([live demo](http://plnkr.co/edit/YamGS6GkUh9GqWNQhCyM?p=preview)):
   * 
   * ```
   * import {Component, NgStyle} from 'angular2/angular2';
   * 
   * @Component({
   *  selector: 'ng-style-example',
   *  template: `
   *    <h1 [ng-style]="{'font-style': style, 'font-size': size, 'font-weight': weight}">
   *      Change style of this text!
   *    </h1>
   * 
   *    <hr>
   * 
   *    <label>Italic: <input type="checkbox" (change)="changeStyle($event)"></label>
   *    <label>Bold: <input type="checkbox" (change)="changeWeight($event)"></label>
   *    <label>Size: <input type="text" [value]="size" (change)="size = $event.target.value"></label>
   *  `,
   *  directives: [NgStyle]
   * })
   * export class NgStyleExample {
   *    style = 'normal';
   *    weight = 'normal';
   *    size = '20px';
   * 
   *    changeStyle($event: any) {
   *      this.style = $event.target.checked ? 'italic' : 'normal';
   *    }
   * 
   *    changeWeight($event: any) {
   *      this.weight = $event.target.checked ? 'bold' : 'normal';
   *    }
   * }
   * ```
   * 
   * In this example the `font-style`, `font-size` and `font-weight` styles will be updated
   * based on the `style` property's value changes.
   */
  class NgStyle implements DoCheck {
    
    constructor(_differs: KeyValueDiffers, _ngEl: ElementRef, _renderer: Renderer);
    
    rawStyle: any;
    
    doCheck(): void;
    
  }

    
  /**
   * The `NgSwitch` directive is used to conditionally swap DOM structure on your template based on a
   * scope expression.
   * Elements within `NgSwitch` but without `NgSwitchWhen` or `NgSwitchDefault` directives will be
   * preserved at the location as specified in the template.
   * 
   * `NgSwitch` simply chooses nested elements and makes them visible based on which element matches
   * the value obtained from the evaluated expression. In other words, you define a container element
   * (where you place the directive), place an expression on the **`[ng-switch]="..."` attribute**),
   * define any inner elements inside of the directive and place a `[ng-switch-when]` attribute per
   * element.
   * The when attribute is used to inform NgSwitch which element to display when the expression is
   * evaluated. If a matching expression is not found via a when attribute then an element with the
   * default attribute is displayed.
   * 
   * ### Example
   * 
   * ```
   * <ANY [ng-switch]="expression">
   *   <template [ng-switch-when]="whenExpression1">...</template>
   *   <template [ng-switch-when]="whenExpression1">...</template>
   *   <template ng-switch-default>...</template>
   * </ANY>
   * ```
   */
  class NgSwitch {
    
    ngSwitch: any;
    
  }

    
  /**
   * Defines a case statement as an expression.
   * 
   * If multiple `NgSwitchWhen` match the `NgSwitch` value, all of them are displayed.
   * 
   * Example:
   * 
   * ```
   * // match against a context variable
   * <template [ng-switch-when]="contextVariable">...</template>
   * 
   * // match against a constant string
   * <template ng-switch-when="stringValue">...</template>
   * ```
   */
  class NgSwitchWhen {
    
    constructor(viewContainer: ViewContainerRef, templateRef: TemplateRef, _switch: NgSwitch);
    
    ngSwitchWhen: any;
    
  }

    
  /**
   * Defines a default case statement.
   * 
   * Default case statements are displayed when no `NgSwitchWhen` match the `ng-switch` value.
   * 
   * Example:
   * 
   * ```
   * <template ng-switch-default>...</template>
   * ```
   */
  class NgSwitchDefault {
    
    constructor(viewContainer: ViewContainerRef, templateRef: TemplateRef, sswitch: NgSwitch);
    
  }

    
  /**
   * A collection of Angular core directives that are likely to be used in each and every Angular
   * application.
   * 
   * This collection can be used to quickly enumerate all the built-in directives in the `directives`
   * property of the `@View` annotation.
   * 
   * ### Example ([live demo](http://plnkr.co/edit/yakGwpCdUkg0qfzX5m8g?p=preview))
   * 
   * Instead of writing:
   * 
   * ```typescript
   * import {NgClass, NgIf, NgFor, NgSwitch, NgSwitchWhen, NgSwitchDefault} from 'angular2/angular2';
   * import {OtherDirective} from './myDirectives';
   * 
   * @Component({
   *   selector: 'my-component',
   *   templateUrl: 'myComponent.html',
   *   directives: [NgClass, NgIf, NgFor, NgSwitch, NgSwitchWhen, NgSwitchDefault, OtherDirective]
   * })
   * export class MyComponent {
   *   ...
   * }
   * ```
   * one could import all the core directives at once:
   * 
   * ```typescript
   * import {CORE_DIRECTIVES} from 'angular2/angular2';
   * import {OtherDirective} from './myDirectives';
   * 
   * @Component({
   *   selector: 'my-component',
   *   templateUrl: 'myComponent.html',
   *   directives: [CORE_DIRECTIVES, OtherDirective]
   * })
   * export class MyComponent {
   *   ...
   * }
   * ```
   */
  let CORE_DIRECTIVES: Type[];
  

    
  var workaround_empty_observable_list_diff: any;
  

    
  abstract class AbstractControl {
    
    constructor(validator: Function);
    
    validator: Function;
    
    value: any;
    
    status: string;
    
    valid: boolean;
    
    /**
     * Returns the errors of this control.
     */
    errors: {[key: string]: any};
    
    /**
     * Returns the errors of the child controls.
     */
    controlsErrors: any;
    
    pristine: boolean;
    
    dirty: boolean;
    
    touched: boolean;
    
    untouched: boolean;
    
    valueChanges: Observable;
    
    pending: boolean;
    
    markAsTouched(): void;
    
    markAsDirty({onlySelf}?: {onlySelf?: boolean}): void;
    
    markAsPending({onlySelf}?: {onlySelf?: boolean}): void;
    
    setParent(parent: ControlGroup | ControlArray): void;
    
    updateValueAndValidity({onlySelf, emitEvent}?: {onlySelf?: boolean, emitEvent?: boolean}): void;
    
    /**
     * Sets errors on a control.
     * 
     * This is used when validations are run not automatically, but manually by the user.
     * 
     * Calling `setErrors` will also update the validity of the parent control.
     * 
     * ## Usage
     * 
     * ```
     * var login = new Control("someLogin");
     * login.setErrors({
     *   "notUnique": true
     * });
     * 
     * expect(login.valid).toEqual(false);
     * expect(login.errors).toEqual({"notUnique": true});
     * 
     * login.updateValue("someOtherLogin");
     * 
     * expect(login.valid).toEqual(true);
     * ```
     */
    setErrors(errors: {[key: string]: any}): void;
    
    find(path: Array<string | number>| string): AbstractControl;
    
    getError(errorCode: string, path?: string[]): any;
    
    hasError(errorCode: string, path?: string[]): boolean;
    
  }

    
  /**
   * Defines a part of a form that cannot be divided into other controls. `Control`s have values and
   * validation state, which is determined by an optional validation function.
   * 
   * `Control` is one of the three fundamental building blocks used to define forms in Angular, along
   * with {@link ControlGroup} and {@link ControlArray}.
   * 
   * ##Usage
   * 
   * By default, a `Control` is created for every `<input>` or other form component.
   * With {@link NgFormControl} or {@link NgFormModel} an existing {@link Control} can be
   * bound to a DOM element instead. This `Control` can be configured with a custom
   * validation function.
   * 
   * ### Example ([live demo](http://plnkr.co/edit/23DESOpbNnBpBHZt1BR4?p=preview))
   */
  class Control extends AbstractControl {
    
    constructor(value?: any, validator?: Function);
    
    /**
     * Set the value of the control to `value`.
     * 
     * If `onlySelf` is `true`, this change will only affect the validation of this `Control`
     * and not its parent component. If `emitEvent` is `true`, this change will cause a
     * `valueChanges` event on the `Control` to be emitted. Both of these options default to
     * `false`.
     * 
     * If `emitModelToViewChange` is `true`, the view will be notified about the new value
     * via an `onChange` event. This is the default behavior if `emitModelToViewChange` is not
     * specified.
     */
    updateValue(value: any, {onlySelf, emitEvent, emitModelToViewChange}?: {
        onlySelf?: boolean,
        emitEvent?: boolean,
        emitModelToViewChange?: boolean
      }): void;
    
    /**
     * Register a listener for change events.
     */
    registerOnChange(fn: Function): void;
    
  }

    
  /**
   * Defines a part of a form, of fixed length, that can contain other controls.
   * 
   * A `ControlGroup` aggregates the values and errors of each {@link Control} in the group. Thus, if
   * one of the controls in a group is invalid, the entire group is invalid. Similarly, if a control
   * changes its value, the entire group changes as well.
   * 
   * `ControlGroup` is one of the three fundamental building blocks used to define forms in Angular,
   * along with {@link Control} and {@link ControlArray}. {@link ControlArray} can also contain other
   * controls, but is of variable length.
   * 
   * ### Example ([live demo](http://plnkr.co/edit/23DESOpbNnBpBHZt1BR4?p=preview))
   */
  class ControlGroup extends AbstractControl {
    
    constructor(controls: {[key: string]: AbstractControl}, optionals?: {[key: string]: boolean}, validator?: Function);
    
    controls: {[key: string]: AbstractControl};
    
    addControl(name: string, control: AbstractControl): void;
    
    removeControl(name: string): void;
    
    include(controlName: string): void;
    
    exclude(controlName: string): void;
    
    contains(controlName: string): boolean;
    
  }

    
  /**
   * Defines a part of a form, of variable length, that can contain other controls.
   * 
   * A `ControlArray` aggregates the values and errors of each {@link Control} in the group. Thus, if
   * one of the controls in a group is invalid, the entire group is invalid. Similarly, if a control
   * changes its value, the entire group changes as well.
   * 
   * `ControlArray` is one of the three fundamental building blocks used to define forms in Angular,
   * along with {@link Control} and {@link ControlGroup}. {@link ControlGroup} can also contain
   * other controls, but is of fixed length.
   * 
   * ##Adding or removing controls
   * 
   * To change the controls in the array, use the `push`, `insert`, or `removeAt` methods
   * in `ControlArray` itself. These methods ensure the controls are properly tracked in the
   * form's hierarchy. Do not modify the array of `AbstractControl`s used to instantiate
   * the `ControlArray` directly, as that will result in strange and unexpected behavior such
   * as broken change detection.
   * 
   * ### Example ([live demo](http://plnkr.co/edit/23DESOpbNnBpBHZt1BR4?p=preview))
   */
  class ControlArray extends AbstractControl {
    
    constructor(controls: AbstractControl[], validator?: Function);
    
    controls: AbstractControl[];
    
    /**
     * Get the {@link AbstractControl} at the given `index` in the array.
     */
    at(index: number): AbstractControl;
    
    /**
     * Insert a new {@link AbstractControl} at the end of the array.
     */
    push(control: AbstractControl): void;
    
    /**
     * Insert a new {@link AbstractControl} at the given `index` in the array.
     */
    insert(index: number, control: AbstractControl): void;
    
    /**
     * Remove the control at the given `index` in the array.
     */
    removeAt(index: number): void;
    
    /**
     * Get the length of the control array.
     */
    length: number;
    
  }

    
  abstract class AbstractControlDirective {
    
    control: AbstractControl;
    
    value: any;
    
    valid: boolean;
    
    errors: {[key: string]: any};
    
    controlsErrors: any;
    
    pristine: boolean;
    
    dirty: boolean;
    
    touched: boolean;
    
    untouched: boolean;
    
    path: string[];
    
  }

    
  /**
   * An interface that {@link NgFormModel} and {@link NgForm} implement.
   * 
   * Only used by the forms module.
   */
  interface Form {
    
    addControl(dir: NgControl): void;
    
    removeControl(dir: NgControl): void;
    
    getControl(dir: NgControl): Control;
    
    addControlGroup(dir: NgControlGroup): void;
    
    removeControlGroup(dir: NgControlGroup): void;
    
    getControlGroup(dir: NgControlGroup): ControlGroup;
    
    updateModel(dir: NgControl, value: any): void;
    
  }

    
  /**
   * A directive that contains multiple {@link NgControl}.
   * 
   * Only used by the forms module.
   */
  class ControlContainer extends AbstractControlDirective {
    
    name: string;
    
    formDirective: Form;
    
    path: string[];
    
  }

    
  /**
   * Creates and binds a control with a specified name to a DOM element.
   * 
   * This directive can only be used as a child of {@link NgForm} or {@link NgFormModel}.
   * 
   * ### Example
   * 
   * In this example, we create the login and password controls.
   * We can work with each control separately: check its validity, get its value, listen to its
   * changes.
   * 
   *  ```
   * @Component({
   *      selector: "login-comp",
   *      directives: [FORM_DIRECTIVES],
   *      template: `
   *        <form #f="form" (submit)='onLogIn(f.value)'>
   *          Login <input type='text' ng-control='login' #l="form">
   *          <div *ng-if="!l.valid">Login is invalid</div>
   * 
   *          Password <input type='password' ng-control='password'>
   *          <button type='submit'>Log in!</button>
   *        </form>
   *      `})
   * class LoginComp {
   *  onLogIn(value): void {
   *    // value === {login: 'some login', password: 'some password'}
   *  }
   * }
   *  ```
   * 
   * We can also use ng-model to bind a domain model to the form.
   * 
   *  ```
   * @Component({
   *      selector: "login-comp",
   *      directives: [FORM_DIRECTIVES],
   *      template: `
   *        <form (submit)='onLogIn()'>
   *          Login <input type='text' ng-control='login' [(ng-model)]="credentials.login">
   *          Password <input type='password' ng-control='password'
   *                          [(ng-model)]="credentials.password">
   *          <button type='submit'>Log in!</button>
   *        </form>
   *      `})
   * class LoginComp {
   *  credentials: {login:string, password:string};
   * 
   *  onLogIn(): void {
   *    // this.credentials.login === "some login"
   *    // this.credentials.password === "some password"
   *  }
   * }
   *  ```
   */
  class NgControlName extends NgControl implements OnChanges, 
      OnDestroy {
    
    constructor(parent: ControlContainer, validators:
                      /* Array<Validator|Function> */ any[], valueAccessors: ControlValueAccessor[]);
    
    update: any;
    
    model: any;
    
    viewModel: any;
    
    onChanges(changes: {[key: string]: SimpleChange}): void;
    
    onDestroy(): void;
    
    viewToModelUpdate(newValue: any): void;
    
    path: string[];
    
    formDirective: any;
    
    validator: Function;
    
    control: Control;
    
  }

    
  /**
   * Binds an existing {@link Control} to a DOM element.
   * 
   * ### Example ([live demo](http://plnkr.co/edit/jcQlZ2tTh22BZZ2ucNAT?p=preview))
   * 
   * In this example, we bind the control to an input element. When the value of the input element
   * changes, the value of the control will reflect that change. Likewise, if the value of the
   * control changes, the input element reflects that change.
   * 
   *  ```typescript
   * @Component({
   *   selector: 'my-app',
   *   template: `
   *     <div>
   *       <h2>NgFormControl Example</h2>
   *       <form>
   *         <p>Element with existing control: <input type="text"
   * [ng-form-control]="loginControl"></p>
   *         <p>Value of existing control: {{loginControl.value}}</p>
   *       </form>
   *     </div>
   *   `,
   *   directives: [CORE_DIRECTIVES, FORM_DIRECTIVES]
   * })
   * export class App {
   *   loginControl: Control = new Control('');
   * }
   *  ```
   * 
   * ##ng-model
   * 
   * We can also use `ng-model` to bind a domain model to the form.
   * 
   * ### Example ([live demo](http://plnkr.co/edit/yHMLuHO7DNgT8XvtjTDH?p=preview))
   * 
   *  ```typescript
   * @Component({
   *      selector: "login-comp",
   *      directives: [FORM_DIRECTIVES],
   *      template: "<input type='text' [ng-form-control]='loginControl' [(ng-model)]='login'>"
   *      })
   * class LoginComp {
   *  loginControl: Control = new Control('');
   *  login:string;
   * }
   *  ```
   */
  class NgFormControl extends NgControl implements OnChanges {
    
    constructor(validators:
                      /* Array<Validator|Function> */ any[], valueAccessors: ControlValueAccessor[]);
    
    form: Control;
    
    update: any;
    
    model: any;
    
    viewModel: any;
    
    onChanges(changes: {[key: string]: SimpleChange}): void;
    
    path: string[];
    
    validator: Function;
    
    control: Control;
    
    viewToModelUpdate(newValue: any): void;
    
  }

    
  /**
   * Binds a domain model to a form control.
   * 
   * ##Usage
   * 
   * `ng-model` binds an existing domain model to a form control. For a
   * two-way binding, use `[(ng-model)]` to ensure the model updates in
   * both directions.
   * 
   * ### Example ([live demo](http://plnkr.co/edit/R3UX5qDaUqFO2VYR0UzH?p=preview))
   *  ```typescript
   * @Component({
   *      selector: "search-comp",
   *      directives: [FORM_DIRECTIVES],
   *      template: `<input type='text' [(ng-model)]="searchQuery">`
   *      })
   * class SearchComp {
   *  searchQuery: string;
   * }
   *  ```
   */
  class NgModel extends NgControl implements OnChanges {
    
    constructor(validators:
                      /* Array<Validator|Function> */ any[], valueAccessors: ControlValueAccessor[]);
    
    update: any;
    
    model: any;
    
    viewModel: any;
    
    onChanges(changes: {[key: string]: SimpleChange}): void;
    
    control: Control;
    
    path: string[];
    
    validator: Function;
    
    viewToModelUpdate(newValue: any): void;
    
  }

    
  /**
   * A base class that all control directive extend.
   * It binds a {@link Control} object to a DOM element.
   */
  abstract class NgControl extends AbstractControlDirective {
    
    name: string;
    
    valueAccessor: ControlValueAccessor;
    
    validator: Function;
    
    viewToModelUpdate(newValue: any): void;
    
  }

    
  /**
   * Creates and binds a control group to a DOM element.
   * 
   * This directive can only be used as a child of {@link NgForm} or {@link NgFormModel}.
   * 
   * ### Example
   * 
   * In this example, we create the credentials and personal control groups.
   * We can work with each group separately: check its validity, get its value, listen to its changes.
   * 
   *  ```
   * @Component({
   *      selector: "signup-comp",
   *      directives: [FORM_DIRECTIVES],
   *      template: `
   *              <form #f="form" (submit)='onSignUp(f.value)'>
   *                <div ng-control-group='credentials' #credentials="form">
   *                  Login <input type='text' ng-control='login'>
   *                  Password <input type='password' ng-control='password'>
   *                </div>
   *                <div *ng-if="!credentials.valid">Credentials are invalid</div>
   * 
   *                <div ng-control-group='personal'>
   *                  Name <input type='text' ng-control='name'>
   *                </div>
   *                <button type='submit'>Sign Up!</button>
   *              </form>
   *      `})
   * class SignupComp {
   *  onSignUp(value) {
   *    // value === {
   *    //  personal: {name: 'some name'},
   *    //  credentials: {login: 'some login', password: 'some password'}}
   *  }
   * }
   * 
   *  ```
   */
  class NgControlGroup extends ControlContainer implements OnInit, 
      OnDestroy {
    
    constructor(parent: ControlContainer, validators: Function[]);
    
    onInit(): void;
    
    onDestroy(): void;
    
    control: ControlGroup;
    
    path: string[];
    
    formDirective: Form;
    
    validator: Function;
    
  }

    
  /**
   * Binds an existing control group to a DOM element.
   * 
   * ### Example ([live demo](http://plnkr.co/edit/jqrVirudY8anJxTMUjTP?p=preview))
   * 
   * In this example, we bind the control group to the form element, and we bind the login and
   * password controls to the login and password elements.
   * 
   *  ```typescript
   * @Component({
   *   selector: 'my-app',
   *   template: `
   *     <div>
   *       <h2>NgFormModel Example</h2>
   *       <form [ng-form-model]="loginForm">
   *         <p>Login: <input type="text" ng-control="login"></p>
   *         <p>Password: <input type="password" ng-control="password"></p>
   *       </form>
   *       <p>Value:</p>
   *       <pre>{{value}}</pre>
   *     </div>
   *   `,
   *   directives: [FORM_DIRECTIVES]
   * })
   * export class App {
   *   loginForm: ControlGroup;
   * 
   *   constructor() {
   *     this.loginForm = new ControlGroup({
   *       login: new Control(""),
   *       password: new Control("")
   *     });
   *   }
   * 
   *   get value(): string {
   *     return JSON.stringify(this.loginForm.value, null, 2);
   *   }
   * }
   *  ```
   * 
   * We can also use ng-model to bind a domain model to the form.
   * 
   *  ```typescript
   * @Component({
   *      selector: "login-comp",
   *      directives: [FORM_DIRECTIVES],
   *      template: `
   *        <form [ng-form-model]='loginForm'>
   *          Login <input type='text' ng-control='login' [(ng-model)]='credentials.login'>
   *          Password <input type='password' ng-control='password'
   *                          [(ng-model)]='credentials.password'>
   *          <button (click)="onLogin()">Login</button>
   *        </form>`
   *      })
   * class LoginComp {
   *  credentials: {login: string, password: string};
   *  loginForm: ControlGroup;
   * 
   *  constructor() {
   *    this.loginForm = new ControlGroup({
   *      login: new Control(""),
   *      password: new Control("")
   *    });
   *  }
   * 
   *  onLogin(): void {
   *    // this.credentials.login === 'some login'
   *    // this.credentials.password === 'some password'
   *  }
   * }
   *  ```
   */
  class NgFormModel extends ControlContainer implements Form, 
      OnChanges {
    
    constructor(validators: Function[]);
    
    form: ControlGroup;
    
    directives: NgControl[];
    
    ngSubmit: any;
    
    onChanges(changes: {[key: string]: SimpleChange}): void;
    
    formDirective: Form;
    
    control: ControlGroup;
    
    path: string[];
    
    addControl(dir: NgControl): void;
    
    getControl(dir: NgControl): Control;
    
    removeControl(dir: NgControl): void;
    
    addControlGroup(dir: NgControlGroup): void;
    
    removeControlGroup(dir: NgControlGroup): void;
    
    getControlGroup(dir: NgControlGroup): ControlGroup;
    
    updateModel(dir: NgControl, value: any): void;
    
    onSubmit(): boolean;
    
  }

    
  /**
   * If `NgForm` is bound in a component, `<form>` elements in that component will be
   * upgraded to use the Angular form system.
   * 
   * ##Typical Use
   * 
   * Include `FORM_DIRECTIVES` in the `directives` section of a {@link View} annotation
   * to use `NgForm` and its associated controls.
   * 
   * ##Structure
   * 
   * An Angular form is a collection of `Control`s in some hierarchy.
   * `Control`s can be at the top level or can be organized in `ControlGroup`s
   * or `ControlArray`s. This hierarchy is reflected in the form's `value`, a
   * JSON object that mirrors the form structure.
   * 
   * ##Submission
   * 
   * The `ng-submit` event signals when the user triggers a form submission.
   * 
   * ### Example ([live demo](http://plnkr.co/edit/ltdgYj4P0iY64AR71EpL?p=preview))
   * 
   *  ```typescript
   * @Component({
   *   selector: 'my-app',
   *   template: `
   *     <div>
   *       <p>Submit the form to see the data object Angular builds</p>
   *       <h2>NgForm demo</h2>
   *       <form #f="form" (ng-submit)="onSubmit(f.value)">
   *         <h3>Control group: credentials</h3>
   *         <div ng-control-group="credentials">
   *           <p>Login: <input type="text" ng-control="login"></p>
   *           <p>Password: <input type="password" ng-control="password"></p>
   *         </div>
   *         <h3>Control group: person</h3>
   *         <div ng-control-group="person">
   *           <p>First name: <input type="text" ng-control="firstName"></p>
   *           <p>Last name: <input type="text" ng-control="lastName"></p>
   *         </div>
   *         <button type="submit">Submit Form</button>
   *       <p>Form data submitted:</p>
   *       </form>
   *       <pre>{{data}}</pre>
   *     </div>
   * `,
   *   directives: [CORE_DIRECTIVES, FORM_DIRECTIVES]
   * })
   * export class App {
   *   constructor() {}
   * 
   *   data: string;
   * 
   *   onSubmit(data) {
   *     this.data = JSON.stringify(data, null, 2);
   *   }
   * }
   *  ```
   */
  class NgForm extends ControlContainer implements Form {
    
    constructor(validators: Function[]);
    
    form: ControlGroup;
    
    ngSubmit: any;
    
    formDirective: Form;
    
    control: ControlGroup;
    
    path: string[];
    
    controls: {[key: string]: AbstractControl};
    
    addControl(dir: NgControl): void;
    
    getControl(dir: NgControl): Control;
    
    removeControl(dir: NgControl): void;
    
    addControlGroup(dir: NgControlGroup): void;
    
    removeControlGroup(dir: NgControlGroup): void;
    
    getControlGroup(dir: NgControlGroup): ControlGroup;
    
    updateModel(dir: NgControl, value: any): void;
    
    onSubmit(): boolean;
    
  }

    
  /**
   * A bridge between a control and a native element.
   * 
   * Please see {@link DefaultValueAccessor} for more information.
   */
  interface ControlValueAccessor {
    
    writeValue(obj: any): void;
    
    registerOnChange(fn: any): void;
    
    registerOnTouched(fn: any): void;
    
  }

    
  /**
   * The default accessor for writing a value and listening to changes that is used by the
   * {@link NgModel}, {@link NgFormControl}, and {@link NgControlName} directives.
   * 
   *  ### Example
   *  ```
   *  <input type="text" [(ng-model)]="searchQuery">
   *  ```
   */
  class DefaultValueAccessor implements ControlValueAccessor {
    
    constructor(_renderer: Renderer, _elementRef: ElementRef);
    
    onChange: any;
    
    onTouched: any;
    
    writeValue(value: any): void;
    
    registerOnChange(fn: (_: any) => void): void;
    
    registerOnTouched(fn: () => void): void;
    
  }

    
  class NgControlStatus {
    
    constructor(cd: NgControl);
    
    ngClassUntouched: boolean;
    
    ngClassTouched: boolean;
    
    ngClassPristine: boolean;
    
    ngClassDirty: boolean;
    
    ngClassValid: boolean;
    
    ngClassInvalid: boolean;
    
  }

    
  /**
   * The accessor for writing a value and listening to changes on a checkbox input element.
   * 
   *  ### Example
   *  ```
   *  <input type="checkbox" [ng-control]="rememberLogin">
   *  ```
   */
  class CheckboxControlValueAccessor implements ControlValueAccessor {
    
    constructor(_renderer: Renderer, _elementRef: ElementRef);
    
    onChange: any;
    
    onTouched: any;
    
    writeValue(value: any): void;
    
    registerOnChange(fn: (_: any) => {}): void;
    
    registerOnTouched(fn: () => {}): void;
    
  }

    
  /**
   * Marks `<option>` as dynamic, so Angular can be notified when options change.
   * 
   * ### Example
   * 
   * ```
   * <select ng-control="city">
   *   <option *ng-for="#c of cities" [value]="c"></option>
   * </select>
   * ```
   */
  class NgSelectOption {
    
  }

    
  /**
   * The accessor for writing a value and listening to changes on a select element.
   */
  class SelectControlValueAccessor implements ControlValueAccessor {
    
    constructor(_renderer: Renderer, _elementRef: ElementRef, query: QueryList<NgSelectOption>);
    
    value: string;
    
    onChange: any;
    
    onTouched: any;
    
    writeValue(value: any): void;
    
    registerOnChange(fn: () => any): void;
    
    registerOnTouched(fn: () => any): void;
    
  }

    
  /**
   * A list of all the form directives used as part of a `@View` annotation.
   * 
   *  This is a shorthand for importing them each individually.
   * 
   * ### Example
   * 
   * ```typescript
   * @Component({
   *   selector: 'my-app',
   *   directives: [FORM_DIRECTIVES]
   * })
   * class MyApp {}
   * ```
   */
  let FORM_DIRECTIVES: Type[];
  

    
  let NG_VALIDATORS: OpaqueToken;
  

    
  /**
   * Provides a set of validators used by form controls.
   * 
   * ### Example
   * 
   * ```
   * var loginControl = new Control("", Validators.required)
   * ```
   */
  class Validators {
    
    static required(control:Control): {[key: string]: boolean};
    
    static minLength(minLength: number): Function;
    
    static maxLength(maxLength: number): Function;
    
    static nullValidator(c: any): {[key: string]: boolean};
    
    static compose(validators: Function[]): Function;
    
  }

    
  class RequiredValidator {
    
  }

    
  class MinLengthValidator implements Validator {
    
    constructor(minLength: string);
    
    validate(c: Control): {[key: string]: any};
    
  }

    
  class MaxLengthValidator implements Validator {
    
    constructor(minLength: string);
    
    validate(c: Control): {[key: string]: any};
    
  }

    
  /**
   * An interface that can be implemented by classes that can act as validators.
   * 
   * ## Usage
   * 
   * ```typescript
   * @Directive({
   *   selector: '[custom-validator]',
   *   providers: [provide(NG_VALIDATORS, {useExisting: CustomValidatorDirective, multi: true})]
   * })
   * class CustomValidatorDirective implements Validator {
   *   validate(c: Control): {[key: string]: any} {
   *     return {"custom": true};
   *   }
   * }
   * ```
   */
  interface Validator {
    
    validate(c:Control): {[key: string]: any};
    
  }

    
  /**
   * Creates a form object from a user-specified configuration.
   * 
   * ### Example
   * 
   * ```
   * import {Component, bootstrap} from 'angular2/angular2';
   * import {FormBuilder, Validators, FORM_DIRECTIVES, ControlGroup} from 'angular2/core';
   * 
   * @Component({
   *   selector: 'login-comp',
   *   viewProviders: [FormBuilder],
   *   template: `
   *     <form [control-group]="loginForm">
   *       Login <input control="login">
   * 
   *       <div control-group="passwordRetry">
   *         Password <input type="password" control="password">
   *         Confirm password <input type="password" control="passwordConfirmation">
   *       </div>
   *     </form>
   *   `,
   *   directives: [FORM_DIRECTIVES]
   * })
   * class LoginComp {
   *   loginForm: ControlGroup;
   * 
   *   constructor(builder: FormBuilder) {
   *     this.loginForm = builder.group({
   *       login: ["", Validators.required],
   * 
   *       passwordRetry: builder.group({
   *         password: ["", Validators.required],
   *         passwordConfirmation: ["", Validators.required]
   *       })
   *     });
   *   }
   * }
   * 
   * bootstrap(LoginComp);
   * ```
   * 
   * This example creates a {@link ControlGroup} that consists of a `login` {@link Control}, and a
   * nested {@link ControlGroup} that defines a `password` and a `passwordConfirmation`
   * {@link Control}:
   * 
   * ```
   *  var loginForm = builder.group({
   *    login: ["", Validators.required],
   * 
   *    passwordRetry: builder.group({
   *      password: ["", Validators.required],
   *      passwordConfirmation: ["", Validators.required]
   *    })
   *  });
   * 
   *  ```
   */
  class FormBuilder {
    
    group(controlsConfig: {[key: string]: any}, extra?: {[key: string]: any}): ControlGroup;
    
    control(value: Object, validator?: Function): Control;
    
    array(controlsConfig: any[], validator?: Function): ControlArray;
    
  }

    
  /**
   * Shorthand set of providers used for building Angular forms.
   * 
   * ### Example
   * 
   * ```typescript
   * bootstrap(MyApp, [FORM_PROVIDERS]);
   * ```
   */
  let FORM_PROVIDERS: Type[];
  

    
  /**
   * @deprecated
   */
  let FORM_BINDINGS: any;
  

    
  /**
   * A DebugElement contains information from the Angular compiler about an
   * element and provides access to the corresponding ElementInjector and
   * underlying DOM Element, as well as a way to query for children.
   */
  abstract class DebugElement {
    
    componentInstance: any;
    
    nativeElement: any;
    
    elementRef: ElementRef;
    
    getDirectiveInstance(directiveIndex: number): any;
    
    /**
     * Get child DebugElements from within the Light DOM.
     * 
     * @return {DebugElement[]}
     */
    children: DebugElement[];
    
    /**
     * Get the root DebugElement children of a component. Returns an empty
     * list if the current DebugElement is not a component root.
     * 
     * @return {DebugElement[]}
     */
    componentViewChildren: DebugElement[];
    
    triggerEventHandler(eventName: string, eventObj: Event): void;
    
    hasDirective(type: Type): boolean;
    
    inject(type: Type): any;
    
    getLocal(name: string): any;
    
    /**
     * Return the first descendant TestElement matching the given predicate
     * and scope.
     * 
     * @param {Function: boolean} predicate
     * @param {Scope} scope
     * 
     * @return {DebugElement}
     */
    query(predicate: Predicate<DebugElement>, scope?: Function): DebugElement;
    
    /**
     * Return descendant TestElememts matching the given predicate
     * and scope.
     * 
     * @param {Function: boolean} predicate
     * @param {Scope} scope
     * 
     * @return {DebugElement[]}
     */
    queryAll(predicate: Predicate<DebugElement>, scope?: Function): DebugElement[];
    
  }

    
  function asNativeElements(arr: DebugElement[]): any[];
  

    
  class By {
    
    static all(): Function;
    
    static css(selector: string): Predicate<DebugElement>;
    
    static directive(type: Type): Predicate<DebugElement>;
    
  }

    
  class Scope {
    
    static all(debugElement: DebugElement): DebugElement[];
    
    static light(debugElement: DebugElement): DebugElement[];
    
    static view(debugElement: DebugElement): DebugElement[];
    
  }

    
  /**
   * Returns a DebugElement for a ElementRef.
   * 
   * @param {ElementRef}: elementRef
   * @return {DebugElement}
   */
  function inspectElement(elementRef: ElementRef): DebugElement;
  

    
  function inspectNativeElement(element: any): DebugElement;
  

    
  let ELEMENT_PROBE_PROVIDERS: any[];
  

    
  let ELEMENT_PROBE_BINDINGS: any;
  

    
  enum ChangeDetectionStrategy {
    
    /**
     * `CheckedOnce` means that after calling detectChanges the mode of the change detector
     * will become `Checked`.
     */
    CheckOnce,
    
    /**
     * `Checked` means that the change detector should be skipped until its mode changes to
     * `CheckOnce`.
     */
    Checked,
    
    /**
     * `CheckAlways` means that after calling detectChanges the mode of the change detector
     * will remain `CheckAlways`.
     */
    CheckAlways,
    
    /**
     * `Detached` means that the change detector sub tree is not a part of the main tree and
     * should be skipped.
     */
    Detached,
    
    /**
     * `OnPush` means that the change detector's mode will be set to `CheckOnce` during hydration.
     */
    OnPush,
    
    /**
     * `Default` means that the change detector's mode will be set to `CheckAlways` during hydration.
     */
    Default,
    
    /**
     * This is an experimental feature. Works only in Dart.
     */
    OnPushObserve
  }
  

    
  /**
   * An error thrown if application changes model breaking the top-down data flow.
   * 
   * This exception is only thrown in dev mode.
   * 
   * <!-- TODO: Add a link once the dev mode option is configurable -->
   * 
   * ### Example
   * 
   * ```typescript
   * @Component({
   *   selector: 'parent',
   *   template: `
   *     <child [prop]="parentProp"></child>
   *   `,
   *   directives: [forwardRef(() => Child)]
   * })
   * class Parent {
   *   parentProp = "init";
   * }
   * 
   * @Directive({selector: 'child', inputs: ['prop']})
   * class Child {
   *   constructor(public parent: Parent) {}
   * 
   *   set prop(v) {
   *     // this updates the parent property, which is disallowed during change detection
   *     // this will result in ExpressionChangedAfterItHasBeenCheckedException
   *     this.parent.parentProp = "updated";
   *   }
   * }
   * ```
   */
  class ExpressionChangedAfterItHasBeenCheckedException extends BaseException {
    
    constructor(exp: string, oldValue: any, currValue: any, context: any);
    
  }

    
  /**
   * Thrown when an expression evaluation raises an exception.
   * 
   * This error wraps the original exception to attach additional contextual information that can
   * be useful for debugging.
   * 
   * ### Example ([live demo](http://plnkr.co/edit/2Kywoz?p=preview))
   * 
   * ```typescript
   * @Directive({selector: 'child', inputs: ['prop']})
   * class Child {
   *   prop;
   * }
   * 
   * @Component({
   *   selector: 'app',
   *   template: `
   *     <child [prop]="field.first"></child>
   *   `,
   *   directives: [Child]
   * })
   * class App {
   *   field = null;
   * }
   * 
   * bootstrap(App);
   * ```
   * 
   * You can access the original exception and stack through the `originalException` and
   * `originalStack` properties.
   */
  class ChangeDetectionError extends WrappedException {
    
    constructor(exp: string, originalException: any, originalStack: any, context: any);
    
    /**
     * Information about the expression that triggered the exception.
     */
    location: string;
    
  }

    
  abstract class ChangeDetectorRef {
    
    /**
     * Marks all {@link ChangeDetectionStrategy#OnPush} ancestors as to be checked.
     * 
     * <!-- TODO: Add a link to a chapter on OnPush components -->
     * 
     * ### Example ([live demo](http://plnkr.co/edit/GC512b?p=preview))
     * 
     * ```typescript
     * @Component({
     *   selector: 'cmp',
     *   changeDetection: ChangeDetectionStrategy.OnPush,
     *   template: `Number of ticks: {{numberOfTicks}}`
     * })
     * class Cmp {
     *   numberOfTicks = 0;
     * 
     *   constructor(ref: ChangeDetectorRef) {
     *     setInterval(() => {
     *       this.numberOfTicks ++
     *       // the following is required, otherwise the view will not be updated
     *       this.ref.markForCheck();
     *     }, 1000);
     *   }
     * }
     * 
     * @Component({
     *   selector: 'app',
     *   changeDetection: ChangeDetectionStrategy.OnPush,
     *   template: `
     *     <cmp><cmp>
     *   `,
     *   directives: [Cmp]
     * })
     * class App {
     * }
     * 
     * bootstrap(App);
     * ```
     */
    markForCheck(): void;
    
    /**
     * Detaches the change detector from the change detector tree.
     * 
     * The detached change detector will not be checked until it is reattached.
     * 
     * This can also be used in combination with {@link ChangeDetectorRef#detectChanges} to implement
     * local change
     * detection checks.
     * 
     * <!-- TODO: Add a link to a chapter on detach/reattach/local digest -->
     * <!-- TODO: Add a live demo once ref.detectChanges is merged into master -->
     * 
     * ### Example
     * 
     * The following example defines a component with a large list of readonly data.
     * Imagine the data changes constantly, many times per second. For performance reasons,
     * we want to check and update the list every five seconds. We can do that by detaching
     * the component's change detector and doing a local check every five seconds.
     * 
     * ```typescript
     * class DataProvider {
     *   // in a real application the returned data will be different every time
     *   get data() {
     *     return [1,2,3,4,5];
     *   }
     * }
     * 
     * @Component({
     *   selector: 'giant-list',
     *   template: `
     *     <li *ng-for="#d of dataProvider.data">Data {{d}}</lig>
     *   `,
     *   directives: [NgFor]
     * })
     * class GiantList {
     *   constructor(private ref: ChangeDetectorRef, private dataProvider:DataProvider) {
     *     ref.detach();
     *     setInterval(() => {
     *       this.ref.detectChanges();
     *     }, 5000);
     *   }
     * }
     * 
     * @Component({
     *   selector: 'app',
     *   providers: [DataProvider],
     *   template: `
     *     <giant-list><giant-list>
     *   `,
     *   directives: [GiantList]
     * })
     * class App {
     * }
     * 
     * bootstrap(App);
     * ```
     */
    detach(): void;
    
    /**
     * Checks the change detector and its children.
     * 
     * This can also be used in combination with {@link ChangeDetectorRef#detach} to implement local
     * change detection
     * checks.
     * 
     * <!-- TODO: Add a link to a chapter on detach/reattach/local digest -->
     * <!-- TODO: Add a live demo once ref.detectChanges is merged into master -->
     * 
     * ### Example
     * 
     * The following example defines a component with a large list of readonly data.
     * Imagine, the data changes constantly, many times per second. For performance reasons,
     * we want to check and update the list every five seconds.
     * 
     * We can do that by detaching the component's change detector and doing a local change detection
     * check
     * every five seconds.
     * 
     * See {@link detach} for more information.
     */
    detectChanges(): void;
    
    /**
     * Reattach the change detector to the change detector tree.
     * 
     * This also marks OnPush ancestors as to be checked. This reattached change detector will be
     * checked during the next change detection run.
     * 
     * <!-- TODO: Add a link to a chapter on detach/reattach/local digest -->
     * 
     * ### Example ([live demo](http://plnkr.co/edit/aUhZha?p=preview))
     * 
     * The following example creates a component displaying `live` data. The component will detach
     * its change detector from the main change detector tree when the component's live property
     * is set to false.
     * 
     * ```typescript
     * class DataProvider {
     *   data = 1;
     * 
     *   constructor() {
     *     setInterval(() => {
     *       this.data = this.data * 2;
     *     }, 500);
     *   }
     * }
     * 
     * @Component({
     *   selector: 'live-data',
     *   inputs: ['live'],
     *   template: `Data: {{dataProvider.data}}`
     * })
     * class LiveData {
     *   constructor(private ref: ChangeDetectorRef, private dataProvider:DataProvider) {}
     * 
     *   set live(value) {
     *     if (value)
     *       this.ref.reattach();
     *     else
     *       this.ref.detach();
     *   }
     * }
     * 
     * @Component({
     *   selector: 'app',
     *   providers: [DataProvider],
     *   template: `
     *     Live Update: <input type="checkbox" [(ng-model)]="live">
     *     <live-data [live]="live"><live-data>
     *   `,
     *   directives: [LiveData, FORM_DIRECTIVES]
     * })
     * class App {
     *   live = true;
     * }
     * 
     * bootstrap(App);
     * ```
     */
    reattach(): void;
    
  }

    
  /**
   * Indicates that the result of a {@link PipeMetadata} transformation has changed even though the
   * reference
   * has not changed.
   * 
   * The wrapped value will be unwrapped by change detection, and the unwrapped value will be stored.
   * 
   * Example:
   * 
   * ```
   * if (this._latestValue === this._latestReturnedValue) {
   *    return this._latestReturnedValue;
   *  } else {
   *    this._latestReturnedValue = this._latestValue;
   *    return WrappedValue.wrap(this._latestValue); // this will force update
   *  }
   * ```
   */
  class WrappedValue {
    
    constructor(wrapped: any);
    
    static wrap(value: any): WrappedValue;
    
    wrapped: any;
    
  }

    
  class SimpleChange {
    
    constructor(previousValue: any, currentValue: any);
    
    previousValue: any;
    
    currentValue: any;
    
    isFirstChange(): boolean;
    
  }

    
  /**
   * To create a Pipe, you must implement this interface.
   * 
   * Angular invokes the `transform` method with the value of a binding
   * as the first argument, and any parameters as the second argument in list form.
   * 
   * ## Syntax
   * 
   * `value | pipeName[:arg0[:arg1...]]`
   * 
   * ### Example ([live demo](http://plnkr.co/edit/f5oyIked9M2cKzvZNKHV?p=preview))
   * 
   * The `RepeatPipe` below repeats the value as many times as indicated by the first argument:
   * 
   * ```
   * import {Pipe, PipeTransform} from 'angular2/angular2';
   * 
   * @Pipe({name: 'repeat'})
   * export class RepeatPipe implements PipeTransform {
   *   transform(value: any, args: any[] = []) {
   *     if (args.length == 0) {
   *       throw new Error('repeat pipe requires one argument');
   *     }
   *     let times: number = args[0];
   *     return value.repeat(times);
   *   }
   * }
   * ```
   * 
   * Invoking `{{ 'ok' | repeat:3 }}` in a template produces `okokok`.
   */
  interface PipeTransform {
    
    transform(value: any, args: any[]): any;
    
  }

    
  /**
   * To create a stateful Pipe, you should implement this interface and set the `pure`
   * parameter to `false` in the {@link PipeMetadata}.
   * 
   * A stateful pipe may produce different output, given the same input. It is
   * likely that a stateful pipe may contain state that should be cleaned up when
   * a binding is destroyed. For example, a subscription to a stream of data may need to
   * be disposed, or an interval may need to be cleared.
   * 
   * ### Example ([live demo](http://plnkr.co/edit/i8pm5brO4sPaLxBx56MR?p=preview))
   * 
   * In this example, a pipe is created to countdown its input value, updating it every
   * 50ms. Because it maintains an internal interval, it automatically clears
   * the interval when the binding is destroyed or the countdown completes.
   * 
   * ```
   * import {Pipe, PipeTransform} from 'angular2/angular2'
   * @Pipe({name: 'countdown', pure: false})
   * class CountDown implements PipeTransform, PipeOnDestroy {
   *   remainingTime:Number;
   *   interval:SetInterval;
   *   onDestroy() {
   *     if (this.interval) {
   *       clearInterval(this.interval);
   *     }
   *   }
   *   transform(value: any, args: any[] = []) {
   *     if (!parseInt(value, 10)) return null;
   *     if (typeof this.remainingTime !== 'number') {
   *       this.remainingTime = parseInt(value, 10);
   *     }
   *     if (!this.interval) {
   *       this.interval = setInterval(() => {
   *         this.remainingTime-=50;
   *         if (this.remainingTime <= 0) {
   *           this.remainingTime = 0;
   *           clearInterval(this.interval);
   *           delete this.interval;
   *         }
   *       }, 50);
   *     }
   *     return this.remainingTime;
   *   }
   * }
   * ```
   * 
   * Invoking `{{ 10000 | countdown }}` would cause the value to be decremented by 50,
   * every 50ms, until it reaches 0.
   */
  interface PipeOnDestroy {
    
    onDestroy(): void;
    
  }

    
  /**
   * A repository of different iterable diffing strategies used by NgFor, NgClass, and others.
   */
  class IterableDiffers {
    
    constructor(factories: IterableDifferFactory[]);
    
    static create(factories: IterableDifferFactory[], parent?: IterableDiffers): IterableDiffers;
    
    /**
     * Takes an array of {@link IterableDifferFactory} and returns a provider used to extend the
     * inherited {@link IterableDiffers} instance with the provided factories and return a new
     * {@link IterableDiffers} instance.
     * 
     * The following example shows how to extend an existing list of factories,
     * which will only be applied to the injector for this component and its children.
     * This step is all that's required to make a new {@link IterableDiffer} available.
     * 
     * ### Example
     * 
     * ```
     * @Component({
     *   viewProviders: [
     *     IterableDiffers.extend([new ImmutableListDiffer()])
     *   ]
     * })
     * ```
     */
    static extend(factories: IterableDifferFactory[]): Provider;
    
    factories: IterableDifferFactory[];
    
    find(iterable: Object): IterableDifferFactory;
    
  }

    
  interface IterableDiffer {
    
    diff(object: Object): any;
    
    onDestroy(): void;
    
  }

    
  /**
   * Provides a factory for {@link IterableDiffer}.
   */
  interface IterableDifferFactory {
    
    supports(objects: Object): boolean;
    
    create(cdRef: ChangeDetectorRef): IterableDiffer;
    
  }

    
  /**
   * A repository of different Map diffing strategies used by NgClass, NgStyle, and others.
   */
  class KeyValueDiffers {
    
    constructor(factories: KeyValueDifferFactory[]);
    
    static create(factories: KeyValueDifferFactory[], parent?: KeyValueDiffers): KeyValueDiffers;
    
    /**
     * Takes an array of {@link KeyValueDifferFactory} and returns a provider used to extend the
     * inherited {@link KeyValueDiffers} instance with the provided factories and return a new
     * {@link KeyValueDiffers} instance.
     * 
     * The following example shows how to extend an existing list of factories,
     * which will only be applied to the injector for this component and its children.
     * This step is all that's required to make a new {@link KeyValueDiffer} available.
     * 
     * ### Example
     * 
     * ```
     * @Component({
     *   viewProviders: [
     *     KeyValueDiffers.extend([new ImmutableMapDiffer()])
     *   ]
     * })
     * ```
     */
    static extend(factories: KeyValueDifferFactory[]): Provider;
    
    factories: KeyValueDifferFactory[];
    
    find(kv: Object): KeyValueDifferFactory;
    
  }

    
  interface KeyValueDiffer {
    
    diff(object: Object): void;
    
    onDestroy(): void;
    
  }

    
  /**
   * Provides a factory for {@link KeyValueDiffer}.
   */
  interface KeyValueDifferFactory {
    
    supports(objects: Object): boolean;
    
    create(cdRef: ChangeDetectorRef): KeyValueDiffer;
    
  }

    
  /**
   * Create trace scope.
   * 
   * Scopes must be strictly nested and are analogous to stack frames, but
   * do not have to follow the stack frames. Instead it is recommended that they follow logical
   * nesting. You may want to use
   * [Event
   * Signatures](http://google.github.io/tracing-framework/instrumenting-code.html#custom-events)
   * as they are defined in WTF.
   * 
   * Used to mark scope entry. The return value is used to leave the scope.
   * 
   *     var myScope = wtfCreateScope('MyClass#myMethod(ascii someVal)');
   * 
   *     someMethod() {
   *        var s = myScope('Foo'); // 'Foo' gets stored in tracing UI
   *        // DO SOME WORK HERE
   *        return wtfLeave(s, 123); // Return value 123
   *     }
   * 
   * Note, adding try-finally block around the work to ensure that `wtfLeave` gets called can
   * negatively impact the performance of your application. For this reason we recommend that
   * you don't add them to ensure that `wtfLeave` gets called. In production `wtfLeave` is a noop and
   * so try-finally block has no value. When debugging perf issues, skipping `wtfLeave`, do to
   * exception, will produce incorrect trace, but presence of exception signifies logic error which
   * needs to be fixed before the app should be profiled. Add try-finally only when you expect that
   * an exception is expected during normal execution while profiling.
   */
  var wtfCreateScope: WtfScopeFn;
  

    
  /**
   * Used to mark end of Scope.
   * 
   * - `scope` to end.
   * - `returnValue` (optional) to be passed to the WTF.
   * 
   * Returns the `returnValue for easy chaining.
   */
  var wtfLeave: <T>(scope: any, returnValue?: T) => T;
  

    
  /**
   * Used to mark Async start. Async are similar to scope but they don't have to be strictly nested.
   * The return value is used in the call to [endAsync]. Async ranges only work if WTF has been
   * enabled.
   * 
   *     someMethod() {
   *        var s = wtfStartTimeRange('HTTP:GET', 'some.url');
   *        var future = new Future.delay(5).then((_) {
   *          wtfEndTimeRange(s);
   *        });
   *     }
   */
  var wtfStartTimeRange: (rangeType: string, action: string) => any;
  

    
  /**
   * Ends a async time range operation.
   * [range] is the return value from [wtfStartTimeRange] Async ranges only work if WTF has been
   * enabled.
   */
  var wtfEndTimeRange: (range: any) => void;
  

    
  interface WtfScopeFn {
    
    (arg0?: any, arg1?: any): any;
    
  }

    
  /**
   * Bootstrapping a Webworker Application
   * 
   * You instantiate the application side by calling bootstrapWebworker from your webworker index
   * script.
   * You can call bootstrapWebworker() exactly as you would call bootstrap() in a regular Angular
   * application
   * See the bootstrap() docs for more details.
   */
  function bootstrapWebWorker(appComponentType: Type, componentInjectableProviders?: Array<Type | Provider | any[]>): Promise<ComponentRef>;
  

    
  /**
   * Message Bus is a low level API used to communicate between the UI and the background.
   * Communication is based on a channel abstraction. Messages published in a
   * given channel to one MessageBusSink are received on the same channel
   * by the corresponding MessageBusSource.
   */
  abstract class MessageBus implements MessageBusSource,  MessageBusSink {
    
    /**
     * Sets up a new channel on the MessageBus.
     * MUST be called before calling from or to on the channel.
     * If runInZone is true then the source will emit events inside the angular zone
     * and the sink will buffer messages and send only once the zone exits.
     * if runInZone is false then the source will emit events inside the global zone
     * and the sink will send messages immediately.
     */
    initChannel(channel: string, runInZone?: boolean): void;
    
    /**
     * Assigns this bus to the given zone.
     * Any callbacks attached to channels where runInZone was set to true on initialization
     * will be executed in the given zone.
     */
    attachToZone(zone: NgZone): void;
    
    /**
     * Returns an {@link EventEmitter} that emits every time a message
     * is received on the given channel.
     */
    from(channel: string): EventEmitter;
    
    /**
     * Returns an {@link EventEmitter} for the given channel
     * To publish methods to that channel just call next (or add in dart) on the returned emitter
     */
    to(channel: string): EventEmitter;
    
  }

    
  interface MessageBusSource {
    
    /**
     * Sets up a new channel on the MessageBusSource.
     * MUST be called before calling from on the channel.
     * If runInZone is true then the source will emit events inside the angular zone.
     * if runInZone is false then the source will emit events inside the global zone.
     */
    initChannel(channel: string, runInZone: boolean): void;
    
    /**
     * Assigns this source to the given zone.
     * Any channels which are initialized with runInZone set to true will emit events that will be
     * executed within the given zone.
     */
    attachToZone(zone: NgZone): void;
    
    /**
     * Returns an {@link EventEmitter} that emits every time a message
     * is received on the given channel.
     */
    from(channel: string): EventEmitter;
    
  }

    
  interface MessageBusSink {
    
    /**
     * Sets up a new channel on the MessageBusSink.
     * MUST be called before calling to on the channel.
     * If runInZone is true the sink will buffer messages and send only once the zone exits.
     * if runInZone is false the sink will send messages immediatly.
     */
    initChannel(channel: string, runInZone: boolean): void;
    
    /**
     * Assigns this sink to the given zone.
     * Any channels which are initialized with runInZone set to true will wait for the given zone
     * to exit before sending messages.
     */
    attachToZone(zone: NgZone): void;
    
    /**
     * Returns an {@link EventEmitter} for the given channel
     * To publish methods to that channel just call next (or add in dart) on the returned emitter
     */
    to(channel: string): EventEmitter;
    
  }

  
}

declare module "angular2/web_worker/worker" {
  export = ngWorker;
}



declare module ngUi {  
  abstract class ClientMessageBroker {
    
    runOnService(args: UiArguments, returnType: Type): Promise<any>;
    
  }

    
  abstract class ClientMessageBrokerFactory {
    
    /**
     * Initializes the given channel and attaches a new {@link ClientMessageBroker} to it.
     */
    createMessageBroker(channel: string, runInZone?: boolean): ClientMessageBroker;
    
  }

    
  class FnArg {
    
    constructor(value: any, type: Type);
    
    value: any;
    
    type: Type;
    
  }

    
  class UiArguments {
    
    constructor(method: string, args?: FnArg[]);
    
    method: string;
    
    args: FnArg[];
    
  }

    
  class ReceivedMessage {
    
    constructor(data: {[key: string]: any});
    
    method: string;
    
    args: any[];
    
    id: string;
    
    type: string;
    
  }

    
  abstract class ServiceMessageBroker {
    
    registerMethod(methodName: string, signature: Type[], method: Function, returnType?: Type): void;
    
  }

    
  abstract class ServiceMessageBrokerFactory {
    
    /**
     * Initializes the given channel and attaches a new {@link ServiceMessageBroker} to it.
     */
    createMessageBroker(channel: string, runInZone?: boolean): ServiceMessageBroker;
    
  }

    
  let PRIMITIVE: Type;
  

    
  interface ConcreteType extends Type {
    
    new(...args: any[]): any;
    
  }

    
  /**
   * 
   * Runtime representation a type that a Component or other object is instances of.
   * 
   * An example of a `Type` is `MyCustomComponent` class, which in JavaScript is be represented by
   * the `MyCustomComponent` constructor function.
   */
  interface Type extends Function {
    
  }

    
  class Observable {
    
    observer(generator: any): Object;
    
  }

    
  /**
   * Use by directives and components to emit custom Events.
   * 
   * ### Examples
   * 
   * In the following example, `Zippy` alternatively emits `open` and `close` events when its
   * title gets clicked:
   * 
   * ```
   * @Component({
   *   selector: 'zippy',
   *   template: `
   *   <div class="zippy">
   *     <div (click)="toggle()">Toggle</div>
   *     <div [hidden]="!visible">
   *       <ng-content></ng-content>
   *     </div>
   *  </div>`})
   * export class Zippy {
   *   visible: boolean = true;
   *   @Output() open: EventEmitter = new EventEmitter();
   *   @Output() close: EventEmitter = new EventEmitter();
   * 
   *   toggle() {
   *     this.visible = !this.visible;
   *     if (this.visible) {
   *       this.open.next(null);
   *     } else {
   *       this.close.next(null);
   *     }
   *   }
   * }
   * ```
   * 
   * Use Rx.Observable but provides an adapter to make it work as specified here:
   * https://github.com/jhusain/observable-spec
   * 
   * Once a reference implementation of the spec is available, switch to it.
   */
  class EventEmitter extends Observable {
    
    /**
     * Creates an instance of [EventEmitter], which depending on [isAsync],
     * delivers events synchronously or asynchronously.
     */
    constructor(isAsync?: boolean);
    
    observer(generator: any): any;
    
    toRx(): any;
    
    next(value: any): void;
    
    throw(error: any): void;
    
    return(value?: any): void;
    
  }

    
  interface Predicate<T> {
    
    (value: T, index?: number, array?: T[]): boolean;
    
  }

    
  class WrappedException extends Error {
    
    constructor(_wrapperMessage: string, _originalException: any, _originalStack?: any, _context?: any);
    
    wrapperMessage: string;
    
    wrapperStack: any;
    
    originalException: any;
    
    originalStack: any;
    
    context: any;
    
    message: string;
    
    toString(): string;
    
  }

    
  /**
   * An injectable service for executing work inside or outside of the Angular zone.
   * 
   * The most common use of this service is to optimize performance when starting a work consisting of
   * one or more asynchronous tasks that don't require UI updates or error handling to be handled by
   * Angular. Such tasks can be kicked off via {@link #runOutsideAngular} and if needed, these tasks
   * can reenter the Angular zone via {@link #run}.
   * 
   * <!-- TODO: add/fix links to:
   *   - docs explaining zones and the use of zones in Angular and change-detection
   *   - link to runOutsideAngular/run (throughout this file!)
   *   -->
   * 
   * ### Example ([live demo](http://plnkr.co/edit/lY9m8HLy7z06vDoUaSN2?p=preview))
   * ```
   * import {Component, View, NgIf, NgZone} from 'angular2/angular2';
   * 
   * @Component({
   *   selector: 'ng-zone-demo'.
   *   template: `
   *     <h2>Demo: NgZone</h2>
   * 
   *     <p>Progress: {{progress}}%</p>
   *     <p *ng-if="progress >= 100">Done processing {{label}} of Angular zone!</p>
   * 
   *     <button (click)="processWithinAngularZone()">Process within Angular zone</button>
   *     <button (click)="processOutsideOfAngularZone()">Process outside of Angular zone</button>
   *   `,
   *   directives: [NgIf]
   * })
   * export class NgZoneDemo {
   *   progress: number = 0;
   *   label: string;
   * 
   *   constructor(private _ngZone: NgZone) {}
   * 
   *   // Loop inside the Angular zone
   *   // so the UI DOES refresh after each setTimeout cycle
   *   processWithinAngularZone() {
   *     this.label = 'inside';
   *     this.progress = 0;
   *     this._increaseProgress(() => console.log('Inside Done!'));
   *   }
   * 
   *   // Loop outside of the Angular zone
   *   // so the UI DOES NOT refresh after each setTimeout cycle
   *   processOutsideOfAngularZone() {
   *     this.label = 'outside';
   *     this.progress = 0;
   *     this._ngZone.runOutsideAngular(() => {
   *       this._increaseProgress(() => {
   *       // reenter the Angular zone and display done
   *       this._ngZone.run(() => {console.log('Outside Done!') });
   *     }}));
   *   }
   * 
   * 
   *   _increaseProgress(doneCallback: () => void) {
   *     this.progress += 1;
   *     console.log(`Current progress: ${this.progress}%`);
   * 
   *     if (this.progress < 100) {
   *       window.setTimeout(() => this._increaseProgress(doneCallback)), 10)
   *     } else {
   *       doneCallback();
   *     }
   *   }
   * }
   * ```
   */
  class NgZone {
    
    /**
     * @param {bool} enableLongStackTrace whether to enable long stack trace. They should only be
     *               enabled in development mode as they significantly impact perf.
     */
    constructor({enableLongStackTrace}: any);
    
    /**
     * Sets the zone hook that is called just before a browser task that is handled by Angular
     * executes.
     * 
     * The hook is called once per browser task that is handled by Angular.
     * 
     * Setting the hook overrides any previously set hook.
     * 
     * @deprecated this API will be removed in the future. Use `onTurnStart` instead.
     */
    overrideOnTurnStart(onTurnStartHook: ZeroArgFunction): void;
    
    /**
     * Notifies subscribers just before Angular event turn starts.
     * 
     * Emits an event once per browser task that is handled by Angular.
     */
    onTurnStart: /* Subject */ any;
    
    /**
     * Sets the zone hook that is called immediately after Angular zone is done processing the current
     * task and any microtasks scheduled from that task.
     * 
     * This is where we typically do change-detection.
     * 
     * The hook is called once per browser task that is handled by Angular.
     * 
     * Setting the hook overrides any previously set hook.
     * 
     * @deprecated this API will be removed in the future. Use `onTurnDone` instead.
     */
    overrideOnTurnDone(onTurnDoneHook: ZeroArgFunction): void;
    
    /**
     * Notifies subscribers immediately after Angular zone is done processing
     * the current turn and any microtasks scheduled from that turn.
     * 
     * Used by Angular as a signal to kick off change-detection.
     */
    onTurnDone: any;
    
    /**
     * Sets the zone hook that is called immediately after the `onTurnDone` callback is called and any
     * microstasks scheduled from within that callback are drained.
     * 
     * `onEventDoneFn` is executed outside Angular zone, which means that we will no longer attempt to
     * sync the UI with any model changes that occur within this callback.
     * 
     * This hook is useful for validating application state (e.g. in a test).
     * 
     * Setting the hook overrides any previously set hook.
     * 
     * @deprecated this API will be removed in the future. Use `onEventDone` instead.
     */
    overrideOnEventDone(onEventDoneFn: ZeroArgFunction, opt_waitForAsync?: boolean): void;
    
    /**
     * Notifies subscribers immediately after the final `onTurnDone` callback
     * before ending VM event.
     * 
     * This event is useful for validating application state (e.g. in a test).
     */
    onEventDone: any;
    
    /**
     * Whether there are any outstanding microtasks.
     */
    hasPendingMicrotasks: boolean;
    
    /**
     * Whether there are any outstanding timers.
     */
    hasPendingTimers: boolean;
    
    /**
     * Whether there are any outstanding asychnronous tasks of any kind that are
     * scheduled to run within Angular zone.
     * 
     * Useful as a signal of UI stability. For example, when a test reaches a
     * point when [hasPendingAsyncTasks] is `false` it might be a good time to run
     * test expectations.
     */
    hasPendingAsyncTasks: boolean;
    
    /**
     * Sets the zone hook that is called when an error is thrown in the Angular zone.
     * 
     * Setting the hook overrides any previously set hook.
     * 
     * @deprecated this API will be removed in the future. Use `onError` instead.
     */
    overrideOnErrorHandler(errorHandler: ErrorHandlingFn): void;
    
    onError: any;
    
    /**
     * Executes the `fn` function synchronously within the Angular zone and returns value returned by
     * the function.
     * 
     * Running functions via `run` allows you to reenter Angular zone from a task that was executed
     * outside of the Angular zone (typically started via {@link #runOutsideAngular}).
     * 
     * Any future tasks or microtasks scheduled from within this function will continue executing from
     * within the Angular zone.
     */
    run(fn: () => any): any;
    
    /**
     * Executes the `fn` function synchronously in Angular's parent zone and returns value returned by
     * the function.
     * 
     * Running functions via `runOutsideAngular` allows you to escape Angular's zone and do work that
     * doesn't trigger Angular change-detection or is subject to Angular's error handling.
     * 
     * Any future tasks or microtasks scheduled from within this function will continue executing from
     * outside of the Angular zone.
     * 
     * Use {@link #run} to reenter the Angular zone and do work that updates the application model.
     */
    runOutsideAngular(fn: () => any): any;
    
  }

    
  interface ZeroArgFunction {
    
    (): void;
    
  }

    
  interface ErrorHandlingFn {
    
    (error: any, stackTrace: any): void;
    
  }

    
  /**
   * Stores error information; delivered via [NgZone.onError] stream.
   */
  class NgZoneError {
    
    constructor(error: any, stackTrace: any);
    
    error: any;
    
    stackTrace: any;
    
  }

    
  class WebWorkerApplication {
    
    constructor(_clientMessageBrokerFactory: ClientMessageBrokerFactory, _serviceMessageBrokerFactory: ServiceMessageBrokerFactory);
    
    createClientMessageBroker(channel: string, runInZone?: boolean): ClientMessageBroker;
    
    createServiceMessageBroker(channel: string, runInZone?: boolean): ServiceMessageBroker;
    
  }

    
  /**
   * Bootstrapping a WebWorker
   * 
   * You instantiate a WebWorker application by calling bootstrap with the URI of your worker's index
   * script
   * Note: The WebWorker script must call bootstrapWebworker once it is set up to complete the
   * bootstrapping process
   */
  function bootstrap(uri: string): WebWorkerInstance;
  

    
  function spawnWebWorker(uri: string): WebWorkerInstance;
  

    
  /**
   * Wrapper class that exposes the {@link WebWorkerApplication}
   * Isolate instance and underlying {@link MessageBus} for lower level message passing.
   */
  class WebWorkerInstance {
    
    constructor(app: WebWorkerApplication, worker: Worker, bus: MessageBus);
    
    app: WebWorkerApplication;
    
    worker: Worker;
    
    bus: MessageBus;
    
  }

    
  /**
   * Message Bus is a low level API used to communicate between the UI and the background.
   * Communication is based on a channel abstraction. Messages published in a
   * given channel to one MessageBusSink are received on the same channel
   * by the corresponding MessageBusSource.
   */
  abstract class MessageBus implements MessageBusSource,  MessageBusSink {
    
    /**
     * Sets up a new channel on the MessageBus.
     * MUST be called before calling from or to on the channel.
     * If runInZone is true then the source will emit events inside the angular zone
     * and the sink will buffer messages and send only once the zone exits.
     * if runInZone is false then the source will emit events inside the global zone
     * and the sink will send messages immediately.
     */
    initChannel(channel: string, runInZone?: boolean): void;
    
    /**
     * Assigns this bus to the given zone.
     * Any callbacks attached to channels where runInZone was set to true on initialization
     * will be executed in the given zone.
     */
    attachToZone(zone: NgZone): void;
    
    /**
     * Returns an {@link EventEmitter} that emits every time a message
     * is received on the given channel.
     */
    from(channel: string): EventEmitter;
    
    /**
     * Returns an {@link EventEmitter} for the given channel
     * To publish methods to that channel just call next (or add in dart) on the returned emitter
     */
    to(channel: string): EventEmitter;
    
  }

    
  interface MessageBusSource {
    
    /**
     * Sets up a new channel on the MessageBusSource.
     * MUST be called before calling from on the channel.
     * If runInZone is true then the source will emit events inside the angular zone.
     * if runInZone is false then the source will emit events inside the global zone.
     */
    initChannel(channel: string, runInZone: boolean): void;
    
    /**
     * Assigns this source to the given zone.
     * Any channels which are initialized with runInZone set to true will emit events that will be
     * executed within the given zone.
     */
    attachToZone(zone: NgZone): void;
    
    /**
     * Returns an {@link EventEmitter} that emits every time a message
     * is received on the given channel.
     */
    from(channel: string): EventEmitter;
    
  }

    
  interface MessageBusSink {
    
    /**
     * Sets up a new channel on the MessageBusSink.
     * MUST be called before calling to on the channel.
     * If runInZone is true the sink will buffer messages and send only once the zone exits.
     * if runInZone is false the sink will send messages immediatly.
     */
    initChannel(channel: string, runInZone: boolean): void;
    
    /**
     * Assigns this sink to the given zone.
     * Any channels which are initialized with runInZone set to true will wait for the given zone
     * to exit before sending messages.
     */
    attachToZone(zone: NgZone): void;
    
    /**
     * Returns an {@link EventEmitter} for the given channel
     * To publish methods to that channel just call next (or add in dart) on the returned emitter
     */
    to(channel: string): EventEmitter;
    
  }

  
}

declare module "angular2/web_worker/ui" {
  export = ngUi;
}


