interface URLS {
  resetPassword: (token: string) => string;
  verifyEmail: (token: string) => string;
  enrollAccount: (token: string) => string;
}

declare module Accounts {
  var urls: URLS;

  function user(): Meteor.User;

  function userId(): string;

  function createUser(options: {
    username?: string;
    email?: string;
    password?: string;
    profile?: Object;
  }, callback?: Function): string;

  function config(options: {
    sendVerificationEmail?: boolean;
    forbidClientAccountCreation?: boolean;
    restrictCreationByEmailDomain?: string | Function;
    loginExpirationInDays?: number;
    oauthSecretKey?: string;
  }): void;

  function onLogin(func: Function): {
    stop: () => void
  };

  function onLoginFailure(func: Function): {
    stop: () => void
  };

  function loginServicesConfigured(): boolean;

  function onPageLoadLogin(func: Function): void;
}

declare module "meteor/accounts-base" {
  interface URLS {
    resetPassword: (token: string) => string;
    verifyEmail: (token: string) => string;
    enrollAccount: (token: string) => string;
  }

  module Accounts {
    var urls: URLS;

    function user(): Meteor.User;

    function userId(): string;

    function createUser(options: {
      username?: string;
      email?: string;
      password?: string;
      profile?: Object;
    }, callback?: Function): string;

    function config(options: {
      sendVerificationEmail?: boolean;
      forbidClientAccountCreation?: boolean;
      restrictCreationByEmailDomain?: string | Function;
      loginExpirationInDays?: number;
      oauthSecretKey?: string;
    }): void;

    function onLogin(func: Function): {
      stop: () => void
    };

    function onLoginFailure(func: Function): {
      stop: () => void
    };

    function loginServicesConfigured(): boolean;

    function onPageLoadLogin(func: Function): void;
  }
}

declare module Accounts {
  function changePassword(oldPassword: string, newPassword: string, callback?: Function): void;

  function forgotPassword(options: {
    email?: string;
  }, callback?: Function): void;

  function resetPassword(token: string, newPassword: string, callback?: Function): void;

  function verifyEmail(token: string, callback?: Function): void;

  function onEmailVerificationLink(callback: Function): void;

  function onEnrollmentLink(callback: Function): void;

  function onResetPasswordLink(callback: Function): void;

  function loggingIn(): boolean;

  function logout(callback?: Function): void;

  function logoutOtherClients(callback?: Function): void;

  var ui: {
    config(options: {
      requestPermissions?: Object;
      requestOfflineToken?: Object;
      forceApprovalPrompt?: Object;
      passwordSignupFields?: string;
    }): void;
  };
}

declare module "meteor/accounts-base" {
  module Accounts {
    function changePassword(oldPassword: string, newPassword: string, callback?: Function): void;

    function forgotPassword(options: {
      email?: string;
    }, callback?: Function): void;

    function resetPassword(token: string, newPassword: string, callback?: Function): void;

    function verifyEmail(token: string, callback?: Function): void;

    function onEmailVerificationLink(callback: Function): void;

    function onEnrollmentLink(callback: Function): void;

    function onResetPasswordLink(callback: Function): void;

    function loggingIn(): boolean;

    function logout(callback?: Function): void;

    function logoutOtherClients(callback?: Function): void;

    var ui: {
      config(options: {
        requestPermissions?: Object;
        requestOfflineToken?: Object;
        forceApprovalPrompt?: Object;
        passwordSignupFields?: string;
      }): void;
    };
  }
}

declare module Blaze {
  var View: ViewStatic;

  interface ViewStatic {
    new(name?: string, renderFunction?: Function): View;
  }

  interface View {
    name: string;
    parentView: View;
    isCreated: boolean;
    isRendered: boolean;
    isDestroyed: boolean;
    renderCount: number;
    autorun(runFunc: (computation: Tracker.Computation) => void): Tracker.Computation;
    onViewCreated(func: Function): void;
    onViewReady(func: Function): void;
    onViewDestroyed(func: Function): void;
    firstNode(): Node;
    lastNode(): Node;
    template: Template;
    templateInstance(): TemplateInstance;
  }
  var currentView: View;

  function isTemplate(value: any): boolean;

  interface HelpersMap {
    [key: string]: Function;
  }

  interface EventsMap {
    [key: string]: Function;
  }

  var Template: TemplateStatic;

  interface TemplateStatic {
    new(viewName?: string, renderFunction?: Function): Template;

    registerHelper(name: string, func: Function): void;
    instance(): TemplateInstance;
    currentData(): any;
    parentData(numLevels: number): any;
  }

  interface Template {
    viewName: string;
    renderFunction: Function;
    constructView(): View;
    head: Template;
    find(selector: string): HTMLElement;
    findAll(selector: string): HTMLElement[];
    $: any;
    onCreated(cb: Function): void;
    onRendered(cb: Function): void;
    onDestroyed(cb: Function): void;
    created: Function;
    rendered: Function;
    destroyed: Function;
    helpers(helpersMap: HelpersMap): void;
    events(eventsMap: EventsMap): void;
  }

  var TemplateInstance: TemplateInstanceStatic;

  interface TemplateInstanceStatic {
    new(view: View): TemplateInstance;
  }

  interface TemplateInstance {
    $(selector: string): any;
    autorun(runFunc: (computation: Tracker.Computation) => void): Tracker.Computation;
    data: Object;
    find(selector: string): HTMLElement;
    findAll(selector: string): HTMLElement[];
    firstNode: Object;
    lastNode: Object;
    subscribe(name: string, ...args: any[]): Meteor.SubscriptionHandle;
    subscriptionsReady(): boolean;
    view: Object;
  }

  function Each(argFunc: Function, contentFunc: Function, elseFunc?: Function): View;

  function Unless(conditionFunc: Function, contentFunc: Function, elseFunc?: Function): View;

  function If(conditionFunc: Function, contentFunc: Function, elseFunc?: Function): View;

  function Let(bindings: Function, contentFunc: Function): View;

  function With(data: Object | Function, contentFunc: Function): View;

  function getData(elementOrView?: HTMLElement | View): Object;

  function getView(element?: HTMLElement): View;

  function remove(renderedView: View): void;

  function render(templateOrView: Template | View, parentNode: Node, nextNode?: Node, parentView?: View): View;

  function renderWithData(templateOrView: Template | View, data: Object | Function, parentNode: Node, nextNode?: Node, parentView?: View): View;

  function toHTML(templateOrView: Template | View): string;

  function toHTMLWithData(templateOrView: Template | View, data: Object | Function): string;
}

declare module "meteor/blaze" {
  module Blaze {
    var View: ViewStatic;

    interface ViewStatic {
      new(name?: string, renderFunction?: Function): View;
    }

    interface View {
      name: string;
      parentView: View;
      isCreated: boolean;
      isRendered: boolean;
      isDestroyed: boolean;
      renderCount: number;
      autorun(runFunc: (computation: Tracker.Computation) => void): Tracker.Computation;
      onViewCreated(func: Function): void;
      onViewReady(func: Function): void;
      onViewDestroyed(func: Function): void;
      firstNode(): Node;
      lastNode(): Node;
      template: Template;
      templateInstance(): TemplateInstance;
    }
    var currentView: View;

    function isTemplate(value: any): boolean;

    interface HelpersMap {
      [key: string]: Function;
    }

    interface EventsMap {
      [key: string]: Function;
    }

    var Template: TemplateStatic;

    interface TemplateStatic {
      new(viewName?: string, renderFunction?: Function): Template;

      registerHelper(name: string, func: Function): void;
      instance(): TemplateInstance;
      currentData(): any;
      parentData(numLevels: number): any;
    }

    interface Template {
      viewName: string;
      renderFunction: Function;
      constructView(): View;
      head: Template;
      find(selector: string): HTMLElement;
      findAll(selector: string): HTMLElement[];
      $: any;
      onCreated(cb: Function): void;
      onRendered(cb: Function): void;
      onDestroyed(cb: Function): void;
      created: Function;
      rendered: Function;
      destroyed: Function;
      helpers(helpersMap: HelpersMap): void;
      events(eventsMap: EventsMap): void;
    }

    var TemplateInstance: TemplateInstanceStatic;

    interface TemplateInstanceStatic {
      new(view: View): TemplateInstance;
    }

    interface TemplateInstance {
      $(selector: string): any;
      autorun(runFunc: (computation: Tracker.Computation) => void): Tracker.Computation;
      data: Object;
      find(selector: string): HTMLElement;
      findAll(selector: string): HTMLElement[];
      firstNode: Object;
      lastNode: Object;
      subscribe(name: string, ...args: any[]): Meteor.SubscriptionHandle;
      subscriptionsReady(): boolean;
      view: Object;
    }

    function Each(argFunc: Function, contentFunc: Function, elseFunc?: Function): View;

    function Unless(conditionFunc: Function, contentFunc: Function, elseFunc?: Function): View;

    function If(conditionFunc: Function, contentFunc: Function, elseFunc?: Function): View;

    function Let(bindings: Function, contentFunc: Function): View;

    function With(data: Object | Function, contentFunc: Function): View;

    function getData(elementOrView?: HTMLElement | View): Object;

    function getView(element?: HTMLElement): View;

    function remove(renderedView: View): void;

    function render(templateOrView: Template | View, parentNode: Node, nextNode?: Node, parentView?: View): View;

    function renderWithData(templateOrView: Template | View, data: Object | Function, parentNode: Node, nextNode?: Node, parentView?: View): View;

    function toHTML(templateOrView: Template | View): string;

    function toHTMLWithData(templateOrView: Template | View, data: Object | Function): string;
  }
}

declare module BrowserPolicy {
  var framing: {
    disallow(): void;
    restrictToOrigin(origin: string): void;
    allowAll(): void;
  };

  var content: {
    allowEval(): void;
    allowInlineStyles(): void;
    allowInlineScripts(): void;
    allowSameOriginForAll(): void;
    allowDataUrlForAll(): void;
    allowOriginForAll(origin: string): void;
    allowImageOrigin(origin: string): void;
    allowMediaOrigin(origin: string): void;
    allowFontOrigin(origin: string): void;
    allowStyleOrigin(origin: string): void;
    allowScriptOrigin(origin: string): void;
    allowFrameOrigin(origin: string): void;
    allowContentTypeSniffing(): void;
    allowAllContentOrigin(): void;
    allowAllContentDataUrl(): void;
    allowAllContentSameOrigin(): void;

    disallowAll(): void;
    disallowInlineStyles(): void;
    disallowEval(): void;
    disallowInlineScripts(): void;
    disallowFont(): void;
    disallowObject(): void;
    disallowAllContent(): void;
  };
}

declare module "meteor/browser-policy-common" {
  module BrowserPolicy {
    var framing: {
      disallow(): void;
      restrictToOrigin(origin: string): void;
      allowAll(): void;
    };

    var content: {
      allowEval(): void;
      allowInlineStyles(): void;
      allowInlineScripts(): void;
      allowSameOriginForAll(): void;
      allowDataUrlForAll(): void;
      allowOriginForAll(origin: string): void;
      allowImageOrigin(origin: string): void;
      allowMediaOrigin(origin: string): void;
      allowFontOrigin(origin: string): void;
      allowStyleOrigin(origin: string): void;
      allowScriptOrigin(origin: string): void;
      allowFrameOrigin(origin: string): void;
      allowContentTypeSniffing(): void;
      allowAllContentOrigin(): void;
      allowAllContentDataUrl(): void;
      allowAllContentSameOrigin(): void;

      disallowAll(): void;
      disallowInlineStyles(): void;
      disallowEval(): void;
      disallowInlineScripts(): void;
      disallowFont(): void;
      disallowObject(): void;
      disallowAllContent(): void;
    };
  }
}

declare module Match {
  var Any: any;
  var String: any;
  var Integer: any;
  var Boolean: any;
  var undefined: any;
  var Object: any;

  function Optional(pattern: any): boolean;

  function ObjectIncluding(dico: any): boolean;

  function OneOf(...patterns: any[]): any;

  function Where(condition: any): any;

  function test(value: any, pattern: any): boolean;
}

declare function check(value: any, pattern: any): void;

declare module "meteor/check" {
  module Match {
    var Any: any;
    var String: any;
    var Integer: any;
    var Boolean: any;
    var undefined: any;
    var Object: any;

    function Optional(pattern: any): boolean;

    function ObjectIncluding(dico: any): boolean;

    function OneOf(...patterns: any[]): any;

    function Where(condition: any): any;

    function test(value: any, pattern: any): boolean;
  }

  function check(value: any, pattern: any): void;
}

declare module DDP {
  interface DDPStatic {
    subscribe(name: string, ...rest: any[]): Meteor.SubscriptionHandle;
    call(method: string, ...parameters: any[]): void;
    apply(method: string, ...parameters: any[]): void;
    methods(IMeteorMethodsDictionary: any): any;
    status(): DDPStatus;
    reconnect(): void;
    disconnect(): void;
    onReconnect(): void;
  }

  function _allSubscriptionsReady(): boolean;

  type Status = 'connected' | 'connecting' | 'failed' | 'waiting' | 'offline';

  interface DDPStatus {
    connected: boolean;
    status: Status;
    retryCount: number;
    retryTime?: number;
    reason?: string;
  }

  function connect(url: string): DDPStatic;
}

declare module DDPCommon {
  interface MethodInvocation {
    new(options: {}): MethodInvocation;

    unblock(): void;

    setUserId(userId: number): void;
  }
}

declare module "meteor/ddp" {
  module DDP {
    interface DDPStatic {
      subscribe(name: string, ...rest: any[]): Meteor.SubscriptionHandle;
      call(method: string, ...parameters: any[]): void;
      apply(method: string, ...parameters: any[]): void;
      methods(IMeteorMethodsDictionary: any): any;
      status(): DDPStatus;
      reconnect(): void;
      disconnect(): void;
      onReconnect(): void;
    }

    function _allSubscriptionsReady(): boolean;

    type Status = 'connected' | 'connecting' | 'failed' | 'waiting' | 'offline';

    interface DDPStatus {
      connected: boolean;
      status: Status;
      retryCount: number;
      retryTime?: number;
      reason?: string;
    }

    function connect(url: string): DDPStatic;
  }

  module DDPCommon {
    interface MethodInvocation {
      new(options: {}): MethodInvocation;

      unblock(): void;

      setUserId(userId: number): void;
    }
  }
}

interface EJSONableCustomType {
  clone(): EJSONableCustomType;
  equals(other: Object): boolean;
  toJSONValue(): JSONable;
  typeName(): string;
}
interface EJSONable {
  [key: string]: number | string | boolean | Object | number[] | string[] | Object[] | Date | Uint8Array | EJSONableCustomType;
}
interface JSONable {
  [key: string]: number | string | boolean | Object | number[] | string[] | Object[];
}
interface EJSON extends EJSONable {}

declare module EJSON {
  function addType(name: string, factory: (val: JSONable) => EJSONableCustomType): void;

  function clone < T > (val: T): T;

  function equals(a: EJSON, b: EJSON, options?: {
    keyOrderSensitive?: boolean;
  }): boolean;

  function fromJSONValue(val: JSONable): any;

  function isBinary(x: Object): boolean;
  var newBinary: any;

  function parse(str: string): EJSON;

  function stringify(val: EJSON, options?: {
    indent?: boolean | number | string;
    canonical?: boolean;
  }): string;

  function toJSONValue(val: EJSON): JSONable;
}

declare module "meteor/ejson" {
  interface EJSONableCustomType {
    clone(): EJSONableCustomType;
    equals(other: Object): boolean;
    toJSONValue(): JSONable;
    typeName(): string;
  }
  interface EJSONable {
    [key: string]: number | string | boolean | Object | number[] | string[] | Object[] | Date | Uint8Array | EJSONableCustomType;
  }
  interface JSONable {
    [key: string]: number | string | boolean | Object | number[] | string[] | Object[];
  }
  interface EJSON extends EJSONable {}

  module EJSON {
    function addType(name: string, factory: (val: JSONable) => EJSONableCustomType): void;

    function clone < T > (val: T): T;

    function equals(a: EJSON, b: EJSON, options?: {
      keyOrderSensitive?: boolean;
    }): boolean;

    function fromJSONValue(val: JSONable): any;

    function isBinary(x: Object): boolean;
    var newBinary: any;

    function parse(str: string): EJSON;

    function stringify(val: EJSON, options?: {
      indent?: boolean | number | string;
      canonical?: boolean;
    }): string;

    function toJSONValue(val: EJSON): JSONable;
  }
}

declare module HTTP {
  interface HTTPRequest {
    content?: string;
    data?: any;
    query?: string;
    params?: {
      [id: string]: string
    };
    auth?: string;
    headers?: {
      [id: string]: string
    };
    timeout?: number;
    followRedirects?: boolean;
    npmRequestOptions?: Object;
  }

  interface HTTPResponse {
    statusCode?: number;
    headers?: {
      [id: string]: string
    };
    content?: string;
    data?: any;
  }

  function call(method: string, url: string, options?: HTTP.HTTPRequest, asyncCallback?: Function): HTTP.HTTPResponse;

  function del(url: string, callOptions?: HTTP.HTTPRequest, asyncCallback?: Function): HTTP.HTTPResponse;

  function get(url: string, callOptions?: HTTP.HTTPRequest, asyncCallback?: Function): HTTP.HTTPResponse;

  function post(url: string, callOptions?: HTTP.HTTPRequest, asyncCallback?: Function): HTTP.HTTPResponse;

  function put(url: string, callOptions?: HTTP.HTTPRequest, asyncCallback?: Function): HTTP.HTTPResponse;

  function call(method: string, url: string, options?: {
    content?: string;
    data?: Object;
    query?: string;
    params?: Object;
    auth?: string;
    headers?: Object;
    timeout?: number;
    followRedirects?: boolean;
    npmRequestOptions?: Object;
    beforeSend?: Function;
  }, asyncCallback?: Function): HTTP.HTTPResponse;
}

declare module "meteor/http" {
  module HTTP {
    interface HTTPRequest {
      content?: string;
      data?: any;
      query?: string;
      params?: {
        [id: string]: string
      };
      auth?: string;
      headers?: {
        [id: string]: string
      };
      timeout?: number;
      followRedirects?: boolean;
      npmRequestOptions?: Object;
    }

    interface HTTPResponse {
      statusCode?: number;
      headers?: {
        [id: string]: string
      };
      content?: string;
      data?: any;
    }

    function call(method: string, url: string, options?: HTTP.HTTPRequest, asyncCallback?: Function): HTTP.HTTPResponse;

    function del(url: string, callOptions?: HTTP.HTTPRequest, asyncCallback?: Function): HTTP.HTTPResponse;

    function get(url: string, callOptions?: HTTP.HTTPRequest, asyncCallback?: Function): HTTP.HTTPResponse;

    function post(url: string, callOptions?: HTTP.HTTPRequest, asyncCallback?: Function): HTTP.HTTPResponse;

    function put(url: string, callOptions?: HTTP.HTTPRequest, asyncCallback?: Function): HTTP.HTTPResponse;

    function call(method: string, url: string, options?: {
      content?: string;
      data?: Object;
      query?: string;
      params?: Object;
      auth?: string;
      headers?: Object;
      timeout?: number;
      followRedirects?: boolean;
      npmRequestOptions?: Object;
      beforeSend?: Function;
    }, asyncCallback?: Function): HTTP.HTTPResponse;
  }
}

declare module Meteor {
  /** Global props **/
  var isClient: boolean;
  var isCordova: boolean;
  var isServer: boolean;
  var isProduction: boolean;
  var release: string;
  /** Global props **/

  /** Settings **/
  interface Settings {
    public: {
      [id: string]: any
    }, [id: string]: any
  }
  var settings: Settings;
  /** Settings **/

  /** User **/
  interface UserEmail {
    address: string;
    verified: boolean;
  }
  interface User {
    _id?: string;
    username?: string;
    emails?: UserEmail[];
    createdAt?: number;
    profile?: any;
    services?: any;
  }

  function user(): User;

  function userId(): string;
  var users: Mongo.Collection < User > ;
  /** User **/

  /** Error **/
  var Error: ErrorStatic;
  interface ErrorStatic {
    new(error: string | number, reason?: string, details?: string): Error;
  }
  interface Error {
    error: string | number;
    reason?: string;
    details?: string;
  }
  /** Error **/

  /** Method **/
  function methods(methods: Object): void;

  function call(name: string, ...args: any[]): any;

  function apply(name: string, args: EJSONable[], options?: {
    wait?: boolean;
    onResultReceived?: Function;
  }, asyncCallback?: Function): any;
  /** Method **/

  /** Url **/
  function absoluteUrl(path?: string, options?: {
    secure?: boolean;
    replaceLocalhost?: boolean;
    rootUrl?: string;
  }): string;
  /** Url **/

  /** Timeout **/
  function setInterval(func: Function, delay: number): number;

  function setTimeout(func: Function, delay: number): number;

  function clearInterval(id: number): void;

  function clearTimeout(id: number): void;

  function defer(func: Function): void;
  /** Timeout **/

  /** utils **/
  function startup(func: Function): void;

  function wrapAsync(func: Function, context?: Object): any;

  function bindEnvironment(func: Function): any;
  /** utils **/

  /** Pub/Sub **/
  interface SubscriptionHandle {
    stop(): void;
    ready(): boolean;
  }
  interface LiveQueryHandle {
    stop(): void;
  }
  /** Pub/Sub **/
}

declare module "meteor/meteor" {
  module Meteor {
    /** Global props **/
    var isClient: boolean;
    var isCordova: boolean;
    var isServer: boolean;
    var isProduction: boolean;
    var release: string;
    /** Global props **/

    /** Settings **/
    interface Settings {
      public: {
        [id: string]: any
      }, [id: string]: any
    }
    var settings: Settings;
    /** Settings **/

    /** User **/
    interface UserEmail {
      address: string;
      verified: boolean;
    }
    interface User {
      _id?: string;
      username?: string;
      emails?: UserEmail[];
      createdAt?: number;
      profile?: any;
      services?: any;
    }

    function user(): User;

    function userId(): string;
    var users: Mongo.Collection < User > ;
    /** User **/

    /** Error **/
    var Error: ErrorStatic;
    interface ErrorStatic {
      new(error: string | number, reason?: string, details?: string): Error;
    }
    interface Error {
      error: string | number;
      reason?: string;
      details?: string;
    }
    /** Error **/

    /** Method **/
    function methods(methods: Object): void;

    function call(name: string, ...args: any[]): any;

    function apply(name: string, args: EJSONable[], options?: {
      wait?: boolean;
      onResultReceived?: Function;
    }, asyncCallback?: Function): any;
    /** Method **/

    /** Url **/
    function absoluteUrl(path?: string, options?: {
      secure?: boolean;
      replaceLocalhost?: boolean;
      rootUrl?: string;
    }): string;
    /** Url **/

    /** Timeout **/
    function setInterval(func: Function, delay: number): number;

    function setTimeout(func: Function, delay: number): number;

    function clearInterval(id: number): void;

    function clearTimeout(id: number): void;

    function defer(func: Function): void;
    /** Timeout **/

    /** utils **/
    function startup(func: Function): void;

    function wrapAsync(func: Function, context?: Object): any;

    function bindEnvironment(func: Function): any;
    /** utils **/

    /** Pub/Sub **/
    interface SubscriptionHandle {
      stop(): void;
      ready(): boolean;
    }
    interface LiveQueryHandle {
      stop(): void;
    }
    /** Pub/Sub **/
  }
}

declare module Meteor {
  /** Login **/
  interface LoginWithExternalServiceOptions {
    requestPermissions?: string[];
    requestOfflineToken?: Boolean;
    forceApprovalPrompt?: Boolean;
    loginUrlParameters?: Object;
    redirectUrl?: string;
    loginHint?: string;
    loginStyle?: string;
  }

  function loginWithMeteorDeveloperAccount(options?: Meteor.LoginWithExternalServiceOptions, callback?: Function): void;

  function loginWithFacebook(options?: Meteor.LoginWithExternalServiceOptions, callback?: Function): void;

  function loginWithGithub(options?: Meteor.LoginWithExternalServiceOptions, callback?: Function): void;

  function loginWithGoogle(options?: Meteor.LoginWithExternalServiceOptions, callback?: Function): void;

  function loginWithMeetup(options?: Meteor.LoginWithExternalServiceOptions, callback?: Function): void;

  function loginWithTwitter(options?: Meteor.LoginWithExternalServiceOptions, callback?: Function): void;

  function loginWithWeibo(options?: Meteor.LoginWithExternalServiceOptions, callback?: Function): void;

  function loggingIn(): boolean;

  function loginWith < ExternalService > (options?: {
    requestPermissions?: string[];
    requestOfflineToken?: boolean;
    loginUrlParameters?: Object;
    userEmail?: string;
    loginStyle?: string;
    redirectUrl?: string;
  }, callback?: Function): void;

  function loginWithPassword(user: Object | string, password: string, callback?: Function): void;

  function loginWithToken(token: string, callback?: Function): void;

  function logout(callback?: Function): void;

  function logoutOtherClients(callback?: Function): void;
  /** Login **/

  /** Event **/
  interface Event {
    type: string;
    target: HTMLElement;
    currentTarget: HTMLElement;
    which: number;
    stopPropagation(): void;
    stopImmediatePropagation(): void;
    preventDefault(): void;
    isPropagationStopped(): boolean;
    isImmediatePropagationStopped(): boolean;
    isDefaultPrevented(): boolean;
  }
  interface EventHandlerFunction extends Function {
    (event?: Meteor.Event, templateInstance?: Blaze.TemplateInstance): void;
  }
  interface EventMap {
    [id: string]: Meteor.EventHandlerFunction;
  }
  /** Event **/

  /** Connection **/
  function reconnect(): void;

  function disconnect(): void;
  /** Connection **/

  /** Status **/
  function status(): DDP.DDPStatus;
  /** Status **/

  /** Pub/Sub **/
  function subscribe(name: string, ...args: any[]): Meteor.SubscriptionHandle;
  /** Pub/Sub **/
}

declare module "meteor/meteor" {
  module Meteor {
    /** Login **/
    interface LoginWithExternalServiceOptions {
      requestPermissions?: string[];
      requestOfflineToken?: Boolean;
      forceApprovalPrompt?: Boolean;
      loginUrlParameters?: Object;
      redirectUrl?: string;
      loginHint?: string;
      loginStyle?: string;
    }

    function loginWithMeteorDeveloperAccount(options?: Meteor.LoginWithExternalServiceOptions, callback?: Function): void;

    function loginWithFacebook(options?: Meteor.LoginWithExternalServiceOptions, callback?: Function): void;

    function loginWithGithub(options?: Meteor.LoginWithExternalServiceOptions, callback?: Function): void;

    function loginWithGoogle(options?: Meteor.LoginWithExternalServiceOptions, callback?: Function): void;

    function loginWithMeetup(options?: Meteor.LoginWithExternalServiceOptions, callback?: Function): void;

    function loginWithTwitter(options?: Meteor.LoginWithExternalServiceOptions, callback?: Function): void;

    function loginWithWeibo(options?: Meteor.LoginWithExternalServiceOptions, callback?: Function): void;

    function loggingIn(): boolean;

    function loginWith < ExternalService > (options?: {
      requestPermissions?: string[];
      requestOfflineToken?: boolean;
      loginUrlParameters?: Object;
      userEmail?: string;
      loginStyle?: string;
      redirectUrl?: string;
    }, callback?: Function): void;

    function loginWithPassword(user: Object | string, password: string, callback?: Function): void;

    function loginWithToken(token: string, callback?: Function): void;

    function logout(callback?: Function): void;

    function logoutOtherClients(callback?: Function): void;
    /** Login **/

    /** Event **/
    interface Event {
      type: string;
      target: HTMLElement;
      currentTarget: HTMLElement;
      which: number;
      stopPropagation(): void;
      stopImmediatePropagation(): void;
      preventDefault(): void;
      isPropagationStopped(): boolean;
      isImmediatePropagationStopped(): boolean;
      isDefaultPrevented(): boolean;
    }
    interface EventHandlerFunction extends Function {
      (event?: Meteor.Event, templateInstance?: Blaze.TemplateInstance): void;
    }
    interface EventMap {
      [id: string]: Meteor.EventHandlerFunction;
    }
    /** Event **/

    /** Connection **/
    function reconnect(): void;

    function disconnect(): void;
    /** Connection **/

    /** Status **/
    function status(): DDP.DDPStatus;
    /** Status **/

    /** Pub/Sub **/
    function subscribe(name: string, ...args: any[]): Meteor.SubscriptionHandle;
    /** Pub/Sub **/
  }
}

declare module Mongo {
  interface Selector {
    [key: string]: any;
  }
  interface Selector extends Object {}
  interface Modifier {}
  interface SortSpecifier {}
  interface FieldSpecifier {
    [id: string]: Number;
  }

  var Collection: CollectionStatic;
  interface CollectionStatic {
    new < T > (name: string | null, options?: {
      connection?: Object;
      idGeneration?: string;
      transform?: Function;
    }): Collection < T > ;
  }
  interface Collection < T > {
    allow(options: {
      insert?: (userId: string, doc: T) => boolean;
      update?: (userId: string, doc: T, fieldNames: string[], modifier: any) => boolean;
      remove?: (userId: string, doc: T) => boolean;
      fetch?: string[];
      transform?: Function;
    }): boolean;
    deny(options: {
      insert?: (userId: string, doc: T) => boolean;
      update?: (userId: string, doc: T, fieldNames: string[], modifier: any) => boolean;
      remove?: (userId: string, doc: T) => boolean;
      fetch?: string[];
      transform?: Function;
    }): boolean;
    find(selector?: Selector | ObjectID | string, options?: {
      sort?: SortSpecifier;
      skip?: number;
      limit?: number;
      fields?: FieldSpecifier;
      reactive?: boolean;
      transform?: Function;
    }): Cursor < T > ;
    findOne(selector?: Selector | ObjectID | string, options?: {
      sort?: SortSpecifier;
      skip?: number;
      fields?: FieldSpecifier;
      reactive?: boolean;
      transform?: Function;
    }): T;
    insert(doc: T, callback?: Function): string;
    rawCollection(): any;
    rawDatabase(): any;
    remove(selector: Selector | ObjectID | string, callback?: Function): number;
    update(selector: Selector | ObjectID | string, modifier: Modifier, options?: {
      multi?: boolean;
      upsert?: boolean;
    }, callback?: Function): number;
    upsert(selector: Selector | ObjectID | string, modifier: Modifier, options?: {
      multi?: boolean;
    }, callback?: Function): {
      numberAffected?: number;insertedId?: string;
    };
    _ensureIndex(keys: {
      [key: string]: number | string
    } | string, options?: {
      [key: string]: any
    }): void;
    _dropIndex(keys: {
      [key: string]: number | string
    } | string): void;
  }

  var Cursor: CursorStatic;
  interface CursorStatic {
    new < T > (): Cursor < T > ;
  }
  interface ObserveCallbacks {
    added?(document: Object) : void;
    addedAt?(document: Object, atIndex: number, before: Object) : void;
    changed?(newDocument: Object, oldDocument: Object) : void;
    changedAt?(newDocument: Object, oldDocument: Object, indexAt: number) : void;
    removed?(oldDocument: Object) : void;
    removedAt?(oldDocument: Object, atIndex: number) : void;
    movedTo?(document: Object, fromIndex: number, toIndex: number, before: Object) : void;
  }
  interface ObserveChangesCallbacks {
    added?(id: string, fields: Object) : void;
    addedBefore?(id: string, fields: Object, before: Object) : void;
    changed?(id: string, fields: Object) : void;
    movedBefore?(id: string, before: Object) : void;
    removed?(id: string) : void;
  }
  interface Cursor < T > {
    count(applySkipLimit?: boolean): number;
    fetch(): Array < T > ;
    forEach(callback: (doc: T, index: number, cursor: Cursor < T > ) => void, thisArg?: any): void;
    map < U > (callback: (doc: T, index: number, cursor: Cursor < T > ) => U, thisArg?: any): Array < U > ;
    observe(callbacks: ObserveCallbacks): Meteor.LiveQueryHandle;
    observeChanges(callbacks: ObserveChangesCallbacks): Meteor.LiveQueryHandle;
  }

  var ObjectID: ObjectIDStatic;
  interface ObjectIDStatic {
    new(hexString?: string): ObjectID;
  }
  interface ObjectID {}
}

declare module "meteor/mongo" {
  module Mongo {
    interface Selector {
      [key: string]: any;
    }
    interface Selector extends Object {}
    interface Modifier {}
    interface SortSpecifier {}
    interface FieldSpecifier {
      [id: string]: Number;
    }

    var Collection: CollectionStatic;
    interface CollectionStatic {
      new < T > (name: string | null, options?: {
        connection?: Object;
        idGeneration?: string;
        transform?: Function;
      }): Collection < T > ;
    }
    interface Collection < T > {
      allow(options: {
        insert?: (userId: string, doc: T) => boolean;
        update?: (userId: string, doc: T, fieldNames: string[], modifier: any) => boolean;
        remove?: (userId: string, doc: T) => boolean;
        fetch?: string[];
        transform?: Function;
      }): boolean;
      deny(options: {
        insert?: (userId: string, doc: T) => boolean;
        update?: (userId: string, doc: T, fieldNames: string[], modifier: any) => boolean;
        remove?: (userId: string, doc: T) => boolean;
        fetch?: string[];
        transform?: Function;
      }): boolean;
      find(selector?: Selector | ObjectID | string, options?: {
        sort?: SortSpecifier;
        skip?: number;
        limit?: number;
        fields?: FieldSpecifier;
        reactive?: boolean;
        transform?: Function;
      }): Cursor < T > ;
      findOne(selector?: Selector | ObjectID | string, options?: {
        sort?: SortSpecifier;
        skip?: number;
        fields?: FieldSpecifier;
        reactive?: boolean;
        transform?: Function;
      }): T;
      insert(doc: T, callback?: Function): string;
      rawCollection(): any;
      rawDatabase(): any;
      remove(selector: Selector | ObjectID | string, callback?: Function): number;
      update(selector: Selector | ObjectID | string, modifier: Modifier, options?: {
        multi?: boolean;
        upsert?: boolean;
      }, callback?: Function): number;
      upsert(selector: Selector | ObjectID | string, modifier: Modifier, options?: {
        multi?: boolean;
      }, callback?: Function): {
        numberAffected?: number;insertedId?: string;
      };
      _ensureIndex(keys: {
        [key: string]: number | string
      } | string, options?: {
        [key: string]: any
      }): void;
      _dropIndex(keys: {
        [key: string]: number | string
      } | string): void;
    }

    var Cursor: CursorStatic;
    interface CursorStatic {
      new < T > (): Cursor < T > ;
    }
    interface ObserveCallbacks {
      added?(document: Object) : void;
      addedAt?(document: Object, atIndex: number, before: Object) : void;
      changed?(newDocument: Object, oldDocument: Object) : void;
      changedAt?(newDocument: Object, oldDocument: Object, indexAt: number) : void;
      removed?(oldDocument: Object) : void;
      removedAt?(oldDocument: Object, atIndex: number) : void;
      movedTo?(document: Object, fromIndex: number, toIndex: number, before: Object) : void;
    }
    interface ObserveChangesCallbacks {
      added?(id: string, fields: Object) : void;
      addedBefore?(id: string, fields: Object, before: Object) : void;
      changed?(id: string, fields: Object) : void;
      movedBefore?(id: string, before: Object) : void;
      removed?(id: string) : void;
    }
    interface Cursor < T > {
      count(applySkipLimit?: boolean): number;
      fetch(): Array < T > ;
      forEach(callback: (doc: T, index: number, cursor: Cursor < T > ) => void, thisArg?: any): void;
      map < U > (callback: (doc: T, index: number, cursor: Cursor < T > ) => U, thisArg?: any): Array < U > ;
      observe(callbacks: ObserveCallbacks): Meteor.LiveQueryHandle;
      observeChanges(callbacks: ObserveChangesCallbacks): Meteor.LiveQueryHandle;
    }

    var ObjectID: ObjectIDStatic;
    interface ObjectIDStatic {
      new(hexString?: string): ObjectID;
    }
    interface ObjectID {}
  }
}

declare module Random {
  function id(numberOfChars?: number): string;

  function secret(numberOfChars?: number): string;

  function fraction(): number;
  // @param numberOfDigits, @returns a random hex string of the given length
  function hexString(numberOfDigits: number): string;
  // @param array, @return a random element in array
  function choice(array: any[]): string;
  // @param str, @return a random char in str
  function choice(str: string): string;
}

declare module "meteor/random" {
  module Random {
    function id(numberOfChars?: number): string;

    function secret(numberOfChars?: number): string;

    function fraction(): number;
    // @param numberOfDigits, @returns a random hex string of the given length
    function hexString(numberOfDigits: number): string;
    // @param array, @return a random element in array
    function choice(array: any[]): string;
    // @param str, @return a random char in str
    function choice(str: string): string;
  }
}

declare var ReactiveVar: ReactiveVarStatic;
interface ReactiveVarStatic {
  new < T > (initialValue: T, equalsFunc?: Function): ReactiveVar < T > ;
}
interface ReactiveVar < T > {
  get(): T;
  set(newValue: T): void;
}

declare module "meteor/reactive-var" {
  var ReactiveVar: ReactiveVarStatic;
  interface ReactiveVarStatic {
    new < T > (initialValue: T, equalsFunc?: Function): ReactiveVar < T > ;
  }
  interface ReactiveVar < T > {
    get(): T;
    set(newValue: T): void;
  }
}

declare module Session {
  function equals(key: string, value: string | number | boolean | any): boolean;

  function get(key: string): any;

  function set(key: string, value: EJSONable | any): void;

  function setDefault(key: string, value: EJSONable | any): void;
}

declare module "meteor/session" {
  module Session {
    function equals(key: string, value: string | number | boolean | any): boolean;

    function get(key: string): any;

    function set(key: string, value: EJSONable | any): void;

    function setDefault(key: string, value: EJSONable | any): void;
  }
}

declare var Template: TemplateStatic;
interface TemplateStatic extends Blaze.TemplateStatic {
  new(viewName?: string, renderFunction?: Function): Blaze.Template;
  body: Blaze.Template;
  [index: string]: any | Blaze.Template;
}

declare module "meteor/templating" {
  var Template: TemplateStatic;
  interface TemplateStatic extends Blaze.TemplateStatic {
    new(viewName?: string, renderFunction?: Function): Blaze.Template;
    body: Blaze.Template;
    [index: string]: any | Blaze.Template;
  }
}

interface ILengthAble {
  length: number;
}

interface ITinytestAssertions {
  ok(doc: Object): void;
  expect_fail(): void;
  fail(doc: Object): void;
  runId(): string;
  equal < T > (actual: T, expected: T, message?: string, not?: boolean): void;
  notEqual < T > (actual: T, expected: T, message?: string): void;
  instanceOf(obj: Object, klass: Function, message?: string): void;
  notInstanceOf(obj: Object, klass: Function, message?: string): void;
  matches(actual: any, regexp: RegExp, message?: string): void;
  notMatches(actual: any, regexp: RegExp, message?: string): void;
  throws(f: Function, expected?: string | RegExp): void;
  isTrue(v: boolean, msg?: string): void;
  isFalse(v: boolean, msg?: string): void;
  isNull(v: any, msg?: string): void;
  isNotNull(v: any, msg?: string): void;
  isUndefined(v: any, msg?: string): void;
  isNotUndefined(v: any, msg?: string): void;
  isNan(v: any, msg?: string): void;
  isNotNan(v: any, msg?: string): void;
  include < T > (s: Array < T > | Object | string, value: any, msg?: string, not?: boolean): void;

  notInclude < T > (s: Array < T > | Object | string, value: any, msg?: string, not?: boolean): void;
  length(obj: ILengthAble, expected_length: number, msg?: string): void;
  _stringEqual(actual: string, expected: string, msg?: string): void;
}

declare module Tinytest {
  function add(description: string, func: (test: ITinytestAssertions) => void): void;

  function addAsync(description: string, func: (test: ITinytestAssertions) => void): void;
}

declare module "meteor/tiny-test" {
  interface ILengthAble {
    length: number;
  }

  interface ITinytestAssertions {
    ok(doc: Object): void;
    expect_fail(): void;
    fail(doc: Object): void;
    runId(): string;
    equal < T > (actual: T, expected: T, message?: string, not?: boolean): void;
    notEqual < T > (actual: T, expected: T, message?: string): void;
    instanceOf(obj: Object, klass: Function, message?: string): void;
    notInstanceOf(obj: Object, klass: Function, message?: string): void;
    matches(actual: any, regexp: RegExp, message?: string): void;
    notMatches(actual: any, regexp: RegExp, message?: string): void;
    throws(f: Function, expected?: string | RegExp): void;
    isTrue(v: boolean, msg?: string): void;
    isFalse(v: boolean, msg?: string): void;
    isNull(v: any, msg?: string): void;
    isNotNull(v: any, msg?: string): void;
    isUndefined(v: any, msg?: string): void;
    isNotUndefined(v: any, msg?: string): void;
    isNan(v: any, msg?: string): void;
    isNotNan(v: any, msg?: string): void;
    include < T > (s: Array < T > | Object | string, value: any, msg?: string, not?: boolean): void;

    notInclude < T > (s: Array < T > | Object | string, value: any, msg?: string, not?: boolean): void;
    length(obj: ILengthAble, expected_length: number, msg?: string): void;
    _stringEqual(actual: string, expected: string, msg?: string): void;
  }

  module Tinytest {
    function add(description: string, func: (test: ITinytestAssertions) => void): void;

    function addAsync(description: string, func: (test: ITinytestAssertions) => void): void;
  }
}

declare module Tracker {
  function Computation(): void;
  interface Computation {
    firstRun: boolean;
    invalidate(): void;
    invalidated: boolean;
    onInvalidate(callback: Function): void;
    onStop(callback: Function): void;
    stop(): void;
    stopped: boolean;
  }
  var currentComputation: Computation;

  var Dependency: DependencyStatic;
  interface DependencyStatic {
    new(): Dependency;
  }
  interface Dependency {
    changed(): void;
    depend(fromComputation?: Computation): boolean;
    hasDependents(): boolean;
  }

  var active: boolean;

  function afterFlush(callback: Function): void;

  function autorun(runFunc: (computation: Computation) => void, options?: {
    onError?: Function;
  }): Computation;

  function flush(): void;

  function nonreactive(func: Function): void;

  function onInvalidate(callback: Function): void;
}

declare module "meteor/tracker" {
  module Tracker {
    function Computation(): void;
    interface Computation {
      firstRun: boolean;
      invalidate(): void;
      invalidated: boolean;
      onInvalidate(callback: Function): void;
      onStop(callback: Function): void;
      stop(): void;
      stopped: boolean;
    }
    var currentComputation: Computation;

    var Dependency: DependencyStatic;
    interface DependencyStatic {
      new(): Dependency;
    }
    interface Dependency {
      changed(): void;
      depend(fromComputation?: Computation): boolean;
      hasDependents(): boolean;
    }

    var active: boolean;

    function afterFlush(callback: Function): void;

    function autorun(runFunc: (computation: Computation) => void, options?: {
      onError?: Function;
    }): Computation;

    function flush(): void;

    function nonreactive(func: Function): void;

    function onInvalidate(callback: Function): void;
  }
}

declare module Match {
  function Maybe(pattern: any): boolean;
}

declare module "meteor/check" {
  module Match {
    function Maybe(pattern: any): boolean;
  }
}

declare module Meteor {
  /** Global props **/
  var isDevelopment: boolean;
  var isTest: boolean;
  /** Global props **/
}

declare module "meteor/meteor" {
  module Meteor {
    /** Global props **/
    var isDevelopment: boolean;
    var isTest: boolean;
    /** Global props **/
  }
}

declare module Accounts {
  function onLogout(func: Function): void;

  function makeClientLoggedOut(): boolean | void;
}

declare module "meteor/accounts-base" {
  module Accounts {
    function onLogout(func: Function): void;

    function makeClientLoggedOut(): boolean | void;
  }
}
declare module "meteor/accounts-base" {
  module Accounts {
    function onLogout(func: Function): void;

    function makeClientLoggedOut(): boolean | void;
  }

  module "meteor/accounts-base" {
    module Accounts {
      function onLogout(func: Function): void;

      function makeClientLoggedOut(): boolean | void;
    }
  }
}

declare module Meteor {
  /** Local storage **/
  var _localStorage: LocalStorage;
  interface LocalStorage {
    _data: any;
    getItem(key: any): any;
    removeItem(key: any): void;
    setItem(key: any, value: any): any;
  }
  /** Local storage **/
}
declare module "meteor/meteor" {
  module Meteor {
    /** Local storage **/
    var _localStorage: LocalStorage;
    interface LocalStorage {
      _data: any;
      getItem(key: any): any;
      removeItem(key: any): void;
      setItem(key: any, value: any): any;
    }
    /** Local storage **/
  }
}
