declare type RTCPeerConnectionConfig = any;

declare class Easyrtc_ReceivedMediaConstraints {
    offerToReceiveAudio:boolean;
    offerToReceiveVideo:boolean;
}

declare type Easyrtc_PerPeerRoomData = any;

declare type Easyrtc_PerRoomData = {
    [peerEasyrtcId:string]:Easyrtc_PerPeerRoomData;
}

declare interface Easyrtc_MessageTargeting {
    targetEasyrtcid:string;
    targetGroup:string;
    targetRoom:string;
}

declare  interface Easyrtc_BasicMessage {
    msgType:string;
    msgData:any;
}

declare  interface Easyrtc_PeerMessage extends Easyrtc_BasicMessage {
    senderEasyrtcid?:string;
    serverTime?:number;
    targetEasyrtcid?:string;  // may be present
    targetRoom?:string;
    msgType:string;
    msgData:any;
}

declare type Easyrtc_ErrorHandler = ({errorCode, errorText}:{errorCode:string, errorText:string}) => void;

declare type Easyrtc_ReceivePeerCallback = (easyrtcId:string, msgType:string, msgData:any, targetting:Easyrtc_MessageTargeting) => void;

declare type Easyrtc_ReceiveServerCallback = (msgType:string, msgData:any, targeting:Easyrtc_MessageTargeting) => void;

declare type Easyrtc_StatsCallback = (easyrtcId:string, values:{
    [fieldName:string]:any;
}) => void;

declare type Easyrtc_PeerMessageDestination = string | Easyrtc_MessageTargeting;

declare type Easyrtc_RedundantMap = { [key:string]:{fieldName:string, fieldValue:string}};

declare interface Easyrtc_RatesOptions {
    audioRecvCodec ?: string;
    videoRecvCodec ?: string;
    audioRecvBitrate ?:number;
    videoRecvBitrate ?: number;
    stereo ?:boolean;
    audioSendCodec ?:string;
    videoSendCodec ?:string;
    audioSendBitrate?:number;
    videoSendBitrate?:number;
    videoSendInitialBitRate?: number;
}

declare class Easyrtc {
    _presetMediaConstraints:MediaStreamConstraints;
    setDebugPrinter(printMethod:(message:any[]) => void):void;

    /**
     * Sets functions which filter sdp records before calling setLocalDescription or setRemoteDescription.
     * This is advanced functionality which can break things, easily. See the easyrtc_rates.js file for a
     * filter builder.
     * @param {Function} localFilter a function that takes an sdp string and returns an sdp string.
     * @param {Function} remoteFilter a function that takes an sdp string and returns an sdp string.
     */
    setSdpFilters(localFilter:(sdp:string) => string, remoteFilter:(sdp:string) => string):void;

    /**
     * Sets a function to warn about the peer connection closing.
     *  @param {Function} handler: a function that gets an easyrtcid as an argument.
     */
    setPeerClosedListener(handler:(easyrtcid:string) => void):void;

    /**
     * Sets a function to receive warnings about the peer connection
     * failing. The peer connection may recover by itthis.
     *  @param {Function} failingHandler: a function that gets an easyrtcid as an argument.
     *  @param {Function} recoveredHandler: a function that gets an easyrtcid as an argument.
     */
    setPeerFailingListener(failingHandler:(easyrtcid:string) => void, recoveredHandler:(easyrtcid:string) => void):void;

    /**
     * Sets a function which filters IceCandidate records being sent or received.
     *
     * Candidate records can be received while they are being generated locally (before being
     * sent to a peer), and after they are received by the peer. The filter receives two arguments, the candidate record and a boolean
     * flag that is true for a candidate being received from another peer,
     * and false for a candidate that was generated locally. The candidate record has the form:
     *  {type: 'candidate', label: sdpMLineIndex, id: sdpMid, candidate: candidateString}
     * The function should return one of the following: the input candidate record, a modified candidate record, or null (indicating that the
     * candidate should be discarded).
     * @param {Function} filter
     */
    setIceCandidateFilter(filter:(RTCIceCandidate, boolean) => RTCIceCandidate):void;

    /**
     * Sets a function that listens on IceConnectionStateChange events.
     *
     * During ICE negotiation the peer connection fires the iceconnectionstatechange event.
     * It is sometimes useful for the application to learn about these changes, especially if the ICE connection fails.
     * The function should accept three parameters: the easyrtc id of the peer, the iceconnectionstatechange event target,
     * and the ice connection state itself.
     * @param {Function} listener
     */
    setIceConnectionStateChangeListener:(listener:(easyrtcid:string, eventTarget:Event) => void) => void;

    /**
     * Sets a function that listens on SignalingStateChange events.
     *
     * During ICE negotiation the peer connection fires the signalingstatechange event.
     * The function should accept three parameters: the easyrtc id of the peer, the signalingstatechange event target and the signalingstate.
     * @param {Function} listener
     */
    setSignalingStateChangeListener:(listener:(easyrtcid:string, eventTarget:Event, signalingState:string) => void) => void;

    /**
     * Returns an array of easyrtcid's of peers in a particular room.
     * @param roomName
     * @returns {Array} of easyrtcids or null if the client is not in the room.
     * @example
     *     var occupants = easyrtc.getRoomOccupants("default");
     *     var i;
     *     for( i = 0; i < occupants.length; i++ ) {
     *         console.log( occupants[i] + " is in the room");
     *     }
     */
    getRoomOccupantsAsArray:(roomName:string) => string[];

    /**
     * Returns a map of easyrtcid's of peers in a particular room. You should only test elements in the map to see if they are
     * null; their actual values are not guaranteed to be the same in different releases.
     * @param roomName
     * @returns {Object} of easyrtcids or null if the client is not in the room.
     * @example
     *      if( easyrtc.getRoomOccupantsAsMap("default")[some_easyrtcid]) {
     *          console.log("yep, " + some_easyrtcid + " is in the room");
     *      }
     */
    getRoomOccupantsAsMap:(roomName:string) => {[peerEasyrtcId:string]:any };

    /**
     * Controls whether a default local media stream should be acquired automatically during calls and accepts
     * if a list of streamNames is not supplied. The default is true, which mimics the behaviour of earlier releases
     * that didn't support multiple streams. This function should be called before easyrtc.call or before entering an
     * accept  callback.
     * @param {Boolean} flag true to allocate a default local media stream.
     */
    setAutoInitUserMedia:(flag:boolean) => void;

    /**
     * This function performs a printf like formatting. It actually takes an unlimited
     * number of arguments, the declared arguments arg1, arg2, arg3 are present just for
     * documentation purposes.
     * @param {String} formatStr A string like "abcd{1}efg{2}hij{1}."
     * @param {String} arg1 The value that replaces {1}
     * @param {String} arg2 The value that replaces {2}
     * @param {String} arg3 The value that replaces {3}
     * @returns {String} the formatted string.
     */
    format:(formatStr:string, ...args:any[]) => string;

    /**
     * Adds an event listener for a particular type of event.
     * Currently the only eventName supported is "roomOccupant".
     * @param {String} eventName the type of the event
     * @param {Function} eventListener the function that expects the event.
     * The eventListener gets called with the eventName as it's first argument, and the event
     * data as it's second argument.
     * @returns {void}
     */
    addEventListener(eventName:string, eventListener:(eventName:string, eventData:any) => void):void;

    /**
     * Removes an event listener.
     * @param {String} eventName
     * @param {Function} eventListener
     */
    removeEventListener:(eventName:string, eventListener:(eventName:string, eventData:any) => void) => void;

    /**
     * Emits an event, or in other words, calls all the eventListeners for a
     * particular event.
     * @param {String} eventName
     * @param {Object} eventData
     */
    emitEvent:(eventName:string, eventData:any) => void;

    /**
     * Error codes that the EasyRTC will use in the errorCode field of error object passed
     * to error handler set by easyrtc.setOnError. The error codes are short printable strings.
     * @type Object
     */
    errCodes:{
        BAD_NAME:string;
        CALL_ERR:string;
        DEVELOPER_ERR:string;
        SYSTEM_ERR:string;
        CONNECT_ERR:string;
        MEDIA_ERR:string;
        MEDIA_WARNING:string;
        INTERNAL_ERR:string;
        PEER_GONE:string;
        ALREADY_CONNECTED:string;
        BAD_CREDENTIAL:string;
        ICECANDIDATE_ERR:string;
        NOVIABLEICE:string;
        SIGNAL_ERR:string;
    };
    apiVersion:string;

    /** Most basic message acknowledgment object */
    ackMessage:{
        msgType:string;
    };

    /** Regular expression pattern for user ids. This will need modification to support non US character sets */
    usernameRegExp:RegExp;

    /** Default cookieId name */
    cookieId:string;

    /** Flag to indicate that user is currently logging out */
    loggingOut:boolean;

    /**
     * Control whether the client requests audio from a peer during a call.
     * Must be called before the call to have an effect.
     * @param value - true to receive audio, false otherwise. The default is true.
     */
    enableAudioReceive(value:boolean):void;

    /**
     * Control whether the client requests video from a peer during a call.
     * Must be called before the call to have an effect.
     * @param value - true to receive video, false otherwise. The default is true.
     */
    enableVideoReceive(value:boolean):void;

    /**
     * Sets the audio output device of a Video object.
     * That is to say, this controls what speakers get the sound.
     * In theory, this works on Chrome but probably doesn't work anywhere else yet.
     * This code was cribbed from https://webrtc.github.io/samples/src/content/devices/multi/.
     *  @param {Object} element an HTML5 video element
     *  @param {String} sinkId a deviceid from getAudioSinkList
     */
    setAudioOutput(element:HTMLVideoElement, sinkId:string):void;

    /**
     * Gets a list of the available audio sinks (ie, speakers)
     * @param {Function} callback receives list of {deviceId:String, groupId:String, label:String, kind:"audio"}
     * @example  easyrtc.getAudioSinkList( function(list) {
     *               var i;
     *               for( i = 0; i < list.length; i++ ) {
     *                   console.log("label=" + list[i].label + ", id= " + list[i].deviceId);
     *               }
     *          });
     */
    getAudioSinkList(callback:(items:MediaDeviceInfo[]) => void):void;

    /**
     * Gets a list of the available audio sources (ie, microphones)
     * @param {Function} callback receives list of {deviceId:String, groupId:String, label:String, kind:"audio"}
     * @example  easyrtc.getAudioSourceList( function(list) {
     *               var i;
     *               for( i = 0; i < list.length; i++ ) {
     *                   console.log("label=" + list[i].label + ", id= " + list[i].deviceId);
     *               }
     *          });
     */
    getAudioSourceList(callback:(items:MediaDeviceInfo[]) => void):void;

    /**
     * Gets a list of the available video sources (ie, cameras)
     * @param {Function} callback receives list of {deviceId:String, groupId:String, label:String, kind:"video"}
     * @example  easyrtc.getVideoSourceList( function(list) {
     *               var i;
     *               for( i = 0; i < list.length; i++ ) {
     *                   console.log("label=" + list[i].label + ", id= " + list[i].deviceId);
     *               }
     *          });
     */
    getVideoSourceList(callback:(items:MediaDeviceInfo[]) => void):void;

    /** The height of the local media stream video in pixels. This field is set an indeterminate period
     * of time after easyrtc.initMediaSource succeeds. Note: in actuality, the dimensions of a video stream
     * change dynamically in response to external factors, you should check the videoWidth and videoHeight attributes
     * of your video objects before you use them for pixel specific operations.
     */
    nativeVideoHeight:number;
    /** This constant determines how long (in bytes) a message can be before being split in chunks of that size.
     * This is because there is a limitation of the length of the message you can send on the
     * data channel between browsers.
     */
    maxP2PMessageLength:number;
    /** The width of the local media stream video in pixels. This field is set an indeterminate period
     * of time after easyrtc.initMediaSource succeeds.  Note: in actuality, the dimensions of a video stream
     * change dynamically in response to external factors, you should check the videoWidth and videoHeight attributes
     * of your video objects before you use them for pixel specific operations.
     */
    nativeVideoWidth:number;

    /** Checks if the supplied string is a valid user name (standard identifier rules)
     * @param {String} name
     * @return {Boolean} true for a valid user name
     * @example
     *    var name = document.getElementById('nameField').value;
     *    if( !easyrtc.isNameValid(name)){
     *        console.error("Bad user name");
     *    }
     */
    isNameValid(name:string):boolean;

    /**
     * This function sets the name of the cookie that client side library will look for
     * and transmit back to the server as it's easyrtcsid in the first message.
     * @param {String} cookieId
     */
    setCookieId(cookieId:string):void;

    /**
     * Specify particular video source. Call this before you call easyrtc.initMediaSource().
     * @param {String} videoSrcId is a id value from one of the entries fetched by getVideoSourceList. null for default.
     * @example easyrtc.setVideoSource( videoSrcId);
     */
    setVideoSource(videoSrcId:string):void;

    /**
     * Specify particular video source. Call this before you call easyrtc.initMediaSource().
     * @param {String} audioSrcId is a id value from one of the entries fetched by getAudioSourceList. null for default.
     * @example easyrtc.setAudioSource( audioSrcId);
     */
    setAudioSource(audioSrcId:string):void;

    /** This function is used to set the dimensions of the local camera, usually to get HD.
     *  If called, it must be called before calling easyrtc.initMediaSource (explicitly or implicitly).
     *  assuming it is supported. If you don't pass any parameters, it will use default camera dimensions.
     * @param {Number} width in pixels
     * @param {Number} height in pixels
     * @param {number} frameRate is optional
     * @example
     *    easyrtc.setVideoDims(1280,720);
     * @example
     *    easyrtc.setVideoDims();
     */
    setVideoDims:(width:any, height:any, frameRate:any) => void;

    /** Set the application name. Applications can only communicate with other applications
     * that share the same API Key and application name. There is no predefined set of application
     * names. Maximum length is
     * @param {String} name
     * @example
     *    easyrtc.setApplicationName('simpleAudioVideo');
     */
    setApplicationName(name:string):void;

    /** Enable or disable logging to the console.
     * Note: if you want to control the printing of debug messages, override the
     *    easyrtc.debugPrinter variable with a function that takes a message string as it's argument.
     *    This is exactly what easyrtc.enableDebug does when it's enable argument is true.
     * @param {Boolean} enable - true to turn on debugging, false to turn off debugging. Default is false.
     * @example
     *    easyrtc.enableDebug(true);
     */
    enableDebug(enable:boolean):void;

    /**
     * Determines if the local browser supports WebRTC GetUserMedia (access to camera and microphone).
     * @returns {Boolean} True getUserMedia is supported.
     */
    supportsGetUserMedia():boolean;

    /**
     * Determines if the local browser supports WebRTC Peer connections to the extent of being able to do video chats.
     * @returns {Boolean} True if Peer connections are supported.
     */
    supportsPeerConnections():boolean;

    /** Determines whether the current browser supports the new data channels.
     * EasyRTC will not open up connections with the old data channels.
     * @returns {Boolean}
     */
    supportsDataChannels():boolean;

    /** Determines whether the current browser supports peer connection statistics.
     * @returns {Boolean}
     */
    supportsStatistics():boolean;

    /**
     * This function gets the raw RTCPeerConnection for a given easyrtcid. If there are more than one, returns the first.
     * @param {String} easyrtcid
     * @param {RTCPeerConnection} for that easyrtcid, or null if no connection exists
     * Submitted by Fabian Bernhard.
     */
    getPeerConnectionByUserId(easyrtcid:string): RTCPeerConnection;

    /**
     * This is a filter that can be used with getPeerStatistics. It tries filter out the entries that are irrelevant to
     * most people and provide items like bandwidth and frame rates.
     */
    standardStatsFilter: any;
    /**
     * This function gets the statistics for a particular peer connection.
     * @param {String} easyrtcid
     * @param {Function} callback gets the easyrtcid for the peer and a map of {userDefinedKey: value}. If there is no peer connection to easyrtcid, then the map will
     *  have a value of {connected:false}.
     * @param {Object} if filter is undefined/null then the statistics are filtered to provide results that most people will find
     *  useful. If filter is not defined, the callback will get the raw statistics from WebRTC.
     */
    getPeerStatistics:(easyrtcid:string, callback:Easyrtc_StatsCallback, filter:any) => void;

    /** Provide a set of application defined fields that will be part of this instances
     * configuration information. This data will get sent to other peers via the websocket
     * path.
     * @param {String} roomName - the room the field is attached to.
     * @param {String} fieldName - the name of the field.
     * @param {Object} fieldValue - the value of the field.
     * @example
     *   easyrtc.setRoomApiField("trekkieRoom",  "favorite_alien", "Mr Spock");
     *   easyrtc.setRoomOccupantListener( function(roomName, list){
     *      for( var i in list ){
     *         console.log("easyrtcid=" + i + " favorite alien is " + list[i].apiFields.favorite_alien);
     *      }
     *   });
     */
    setRoomApiField(roomName:string, fieldName:string, fieldValue:any):void;

    /**
     * Default error reporting function. The default implementation displays error messages
     * in a programmatically created div with the id easyrtcErrorDialog. The div has title
     * component with a class name of easyrtcErrorDialog_title. The error messages get added to a
     * container with the id easyrtcErrorDialog_body. Each error message is a text node inside a div
     * with a class of easyrtcErrorDialog_element. There is an "okay" button with the className of easyrtcErrorDialog_okayButton.
     * @param {String} messageCode An error message code
     * @param {String} message the error message text without any markup.
     * @example
     *     easyrtc.showError("BAD_NAME", "Invalid username");
     */
    showError(messageCode:string, message:string):void;

    /**
     * Override the default open-easyrtc error handler. The default handler shows a popup error dialog.
     * @param {Easyrtc_ErrorHandler} handler Error handler function with one param, an object with keys 'errorCode' and 'errorText'
     * @example 
     *  easyrtc.setErrorListener(({errorCode, errorText}) => {
     *    alert(`${errorCode} error:\n${errorText}`);
     * });
     * @example // Removing previously set handler: 
     * easyrtc.setErrorListener(undefined);
     */
    setErrorListener(handler:Easyrtc_ErrorHandler):void;

    /**
     * A convenience function to ensure that a string doesn't have symbols that will be interpreted by HTML.
     * @param {String} idString
     * @return {String} The cleaned string.
     * @example
     *   console.log( easyrtc.cleanId('&hello'));
     */
    cleanId(idString:string):string;

    /**
     * Set a callback that will be invoked when the application enters or leaves a room.
     * @param {Function} handler - the first parameter is true for entering a room, false for leaving a room. The second parameter is the room name.
     * @example
     *   easyrtc.setRoomEntryListener(function(entry, roomName){
     *       if( entry ){
     *           console.log("entering room " + roomName);
     *       }
     *       else{
     *           console.log("leaving room " + roomName);
     *       }
     *   });
     */
    setRoomEntryListener(handler:(entering:boolean, roomName:string) => void):void;

    /**
     * Set the callback that will be invoked when the list of people logged in changes.
     * The callback expects to receive a room name argument, and
     * a map whose ideas are easyrtcids and whose values are in turn maps
     * supplying user specific information. The inner maps have the following keys:
     * username, applicationName, browserFamily, browserMajor, osFamily, osMajor, deviceFamily.
     * The third argument to the listener is the innerMap for the connections own data (not needed by most applications).
     * @param {Function} listener
     * @example
     *   easyrtc.setRoomOccupantListener( function(roomName, list, selfInfo){
     *      for( var i in list ){
     *         ("easyrtcid=" + i + " belongs to user " + list[i].username);
     *      }
     *   });
     */
    setRoomOccupantListener(listener:(roomName:string, occupants:Easyrtc_PerRoomData, isOwner:boolean) => void):void;

    /**
     * Sets a callback that is called when a data channel is open and ready to send data.
     * The callback will be called with an easyrtcid as it's sole argument.
     * @param {Function} listener
     * @example
     *    easyrtc.setDataChannelOpenListener( function(easyrtcid){
     *         easyrtc.sendDataP2P(easyrtcid, "greeting", "hello");
     *    });
     */
    setDataChannelOpenListener(listener:(easyrtcid:string) => void):void;

    /** Sets a callback that is called when a previously open data channel closes.
     * The callback will be called with an easyrtcid as it's sole argument.
     * @param {Function} listener
     * @example
     *    easyrtc.setDataChannelCloseListener( function(easyrtcid){
     *            ("No longer connected to " + easyrtc.idToName(easyrtcid));
     *    });
     */
    setDataChannelCloseListener(listener:(easyrtcid:string) => void):void;

    /** Returns the number of live peer connections the client has.
     * @return {Number}
     * @example
     *    ("You have " + easyrtc.getConnectionCount() + " peer connections");
     */
    getConnectionCount():number;

    /** Sets the maximum length in bytes of P2P messages that can be sent.
     * @param {Number} maxLength maximum length to set
     * @example
     *     easyrtc.setMaxP2PMessageLength(10000);
     */
    setMaxP2PMessageLength(maxLength:number):void;

    /** Sets whether audio is transmitted by the local user in any subsequent calls.
     * @param {Boolean} enabled true to include audio, false to exclude audio. The default is true.
     * @example
     *      easyrtc.enableAudio(false);
     */
    enableAudio(enabled:boolean):void;

    /**
     *Sets whether video is transmitted by the local user in any subsequent calls.
     * @param {Boolean} enabled - true to include video, false to exclude video. The default is true.
     * @example
     *      easyrtc.enableVideo(false);
     */
    enableVideo(enabled:boolean):void;

    /**
     * Sets whether WebRTC data channels are used to send inter-client messages.
     * This is only the messages that applications explicitly send to other applications, not the WebRTC signaling messages.
     * @param {Boolean} enabled  true to use data channels, false otherwise. The default is false.
     * @example
     *     easyrtc.enableDataChannels(true);
     */
    enableDataChannels(enabled:boolean):void;

    /**
     * Returns the user assigned id's of currently active local media streams.
     * Note: user assigned suggests we want the name of the stream, not the id.
     * @return {Array}
     */
    getLocalMediaIds:() => string[];

    /**
     * Allow an externally created mediastream (ie, created by another
     * library) to be used within easyrtc. Tracking when it closes
     * must be done by the supplying party.
     */
    register3rdPartyLocalMediaStream(stream:MediaStream, streamName:string):void;

    getNameOfRemoteStream(easyrtcId:string, webrtcStream:string | MediaStream):string;

    /**
     * Close the local media stream. You usually need to close the existing media stream
     * of a camera before reacquiring it at a different resolution.
     * @param {String} streamName - an option stream name.
     */
    closeLocalStream(streamName:string):void;

    /**
     * This function is used to enable and disable the local camera. If you disable the
     * camera, video objects which display it will "freeze" until the camera is re-enabled. *
     * By default, a camera is enabled.
     * @param {Boolean} enable - true to enable the camera, false to disable it.
     * @param {String} streamName - the name of the stream, optional.
     */
    enableCamera(enable:boolean, streamName:string):void;

    /**
     * This function is used to enable and disable the local microphone. If you disable
     * the microphone, sounds stops being transmitted to your peers. By default, the microphone
     * is enabled.
     * @param {Boolean} enable - true to enable the microphone, false to disable it.
     * @param {String} streamName - an optional streamName
     */
    enableMicrophone:(enable:boolean, streamName:string) => void;

    /**
     * Mute a video object.
     * @param {String} videoObjectName - A DOMObject or the id of the DOMObject.
     * @param {Boolean} mute - true to mute the video object, false to unmute it.
     */
    muteVideoObject(videoObjectName:string|HTMLVideoElement, mute:boolean):void;

    /**
     * Returns a URL for your local camera and microphone.
     *  It can be called only after easyrtc.initMediaSource has succeeded.
     *  It returns a url that can be used as a source by the Chrome video element or the &lt;canvas&gt; element.
     *  @param {String} streamName - an option stream name.
     *  @return {URL}
     *  @example
     *      document.getElementById("myVideo").src = easyrtc.getLocalStreamAsUrl();
     */
    getLocalStreamAsUrl(streamName:string):string;

    /**
     * Returns a media stream for your local camera and microphone.
     *  It can be called only after easyrtc.initMediaSource has succeeded.
     *  It returns a stream that can be used as an argument to easyrtc.setVideoObjectSrc.
     *  Returns null if there is no local media stream acquired yet.
     * @return {?MediaStream}
     * @example
     *    easyrtc.setVideoObjectSrc( document.getElementById("myVideo"), easyrtc.getLocalStream());
     */
    getLocalStream(streamName?:string):MediaStream;

    /** Clears the media stream on a video object.
     *
     * @param {Object} element the video object.
     * @example
     *    easyrtc.clearMediaStream( document.getElementById('selfVideo'));
     *
     */
    clearMediaStream(element:HTMLVideoElement):void;

    /**
     *  Sets a video or audio object from a media stream.
     *  Chrome uses the src attribute and expects a URL, while firefox
     *  uses the mozSrcObject and expects a stream. This procedure hides
     *  that from you.
     *  If the media stream is from a local webcam, you may want to add the
     *  easyrtcMirror class to the video object so it looks like a proper mirror.
     *  The easyrtcMirror class is defined in this.css.
     *  Which is could be added using the same path of easyrtc.js file to an HTML file
     *  @param {Object} element an HTML5 video element
     *  @param {MediaStream|String} stream a media stream as returned by easyrtc.getLocalStream or your stream acceptor.
     * @example
     *    easyrtc.setVideoObjectSrc( document.getElementById("myVideo"), easyrtc.getLocalStream());
     *
     */
    setVideoObjectSrc(element:HTMLVideoElement, stream:MediaStream):void;

    /**
     * This function builds a new named local media stream from a set of existing audio and video tracks from other media streams.
     * @param {String} streamName is the name of the new media stream.
     * @param {Array} audioTracks is an array of MediaStreamTracks
     * @param {Array} videoTracks is an array of MediaStreamTracks
     * @returns {?MediaStream} the track created.
     * @example
     *    easyrtc.buildLocalMediaStream("myComposedStream",
     *             easyrtc.getLocalStream("camera1").getVideoTracks(),
     *             easyrtc.getLocalStream("camera2").getAudioTracks());
     */
    buildLocalMediaStream(streamName:string, audioTracks:MediaStreamTrack[], videoTracks:MediaStreamTrack[]):MediaStream;

    /** Load Easyrtc Stylesheet.
     *   Easyrtc Stylesheet define easyrtcMirror class and some basic css class for using easyrtc.js.
     *   That way, developers can override it or use it's own css file minified css or package.
     * @example
     *       easyrtc.loadStylesheet();
     *
     */
    loadStylesheet():void;

    /**
     * Initializes your access to a local camera and microphone.
     * Failure could be caused a browser that didn't support WebRTC, or by the user not granting permission.
     * If you are going to call easyrtc.enableAudio or easyrtc.enableVideo, you need to do it before
     * calling easyrtc.initMediaSource.
     * @param {function(Object)} successCallback - will be called with localmedia stream on success.
     * @param {function(String,String)} errorCallback - is called with an error code and error description.
     * @param {String} streamName - an optional name for the media source so you can use multiple cameras and
     * screen share simultaneously.
     * @example
     *       easyrtc.initMediaSource(
     *          function(mediastream){
     *              easyrtc.setVideoObjectSrc( document.getElementById("mirrorVideo"), mediastream);
     *          },
     *          function(errorCode, errorText){
     *               easyrtc.showError(errorCode, errorText);
     *          });
     */
    initMediaSource(successCallback:(mediaStream:MediaStream) => void, errorCallback:(errorCode:string, errorText:string) => void, streamName:string):void;

    /**
     * Sets the callback used to decide whether to accept or reject an incoming call.
     * @param {Function} acceptCheck takes the arguments (callerEasyrtcid, acceptor).
     * The acceptCheck callback is passed an easyrtcid and an acceptor function. The acceptor function should be called with either
     * a true value (accept the call) or false value( reject the call) as it's first argument, and optionally,
     * an array of local media streamNames as a second argument.
     * @example
     *      easyrtc.setAcceptChecker( function(easyrtcid, acceptor){
     *           if( easyrtc.idToName(easyrtcid) === 'Fred' ){
     *              acceptor(true);
     *           }
     *           else if( easyrtc.idToName(easyrtcid) === 'Barney' ){
     *              setTimeout( function(){
     acceptor(true, ['myOtherCam']); // myOtherCam presumed to a streamName
     }, 10000);
     *           }
     *           else{
     *              acceptor(false);
     *           }
     *      });
     */
    setAcceptChecker(acceptCheck:(callerEasyrtcId:string, acceptor:(acceptTheCall:boolean, mediaStreamNames:string[]) => void) => void):void;

    /**
     * easyrtc.setStreamAcceptor sets a callback to receive media streams from other peers, independent
     * of where the call was initiated (caller or callee).
     * @param {Function} acceptor takes arguments (caller, mediaStream, mediaStreamName)
     * @example
     *  easyrtc.setStreamAcceptor(function(easyrtcid, stream, streamName){
     *     document.getElementById('callerName').innerHTML = easyrtc.idToName(easyrtcid);
     *     easyrtc.setVideoObjectSrc( document.getElementById("callerVideo"), stream);
     *  });
     */
    setStreamAcceptor(acceptor:(easyrtcid:string, stream:MediaStream, streamName:string) => void):void;

    /** Sets the easyrtc.onError field to a user specified function.
     * @param {Function} errListener takes an object of the form {errorCode: String, errorText: String}
     * @example
     *    easyrtc.setOnError( function(errorObject){
     *        document.getElementById("errMessageDiv").innerHTML += errorObject.errorText;
     *    });
     */
    setOnError(errListener:(errorObject:{
        errorCode:string;
        errorText:string;
    }) => void):void;

    /**
     * Sets the callCancelled callback. This will be called when a remote user
     * initiates a call to you, but does a "hangup" before you have a chance to get his video stream.
     * @param {Function} callCancelled takes an easyrtcid as an argument and a boolean that indicates whether
     *  the call was explicitly cancelled remotely (true), or actually accepted by the user attempting a call to
     *  the same party.
     * @example
     *     easyrtc.setCallCancelled( function(easyrtcid, explicitlyCancelled){
     *        if( explicitlyCancelled ){
     *            console.log(easyrtc.idToName(easyrtcid) + " stopped trying to reach you");
     *         }
     *         else{
     *            console.log("Implicitly called "  + easyrtc.idToName(easyrtcid));
     *         }
     *     });
     */
    setCallCancelled:(callCancelled:(easyrtcid:string, explicitlyCancelled:boolean) => void) => void;
    /**  Sets a callback to receive notification of a media stream closing. The usual
     *  use of this is to clear the source of your video object so you aren't left with
     *  the last frame of the video displayed on it.
     *  @param {Function} onStreamClosed takes an easyrtcid as it's first parameter, the stream as it's second argument, and name of the video stream as it's third.
     *  @example
     *     easyrtc.setOnStreamClosed( function(easyrtcid, stream, streamName){
     *         easyrtc.setVideoObjectSrc( document.getElementById("callerVideo"), "");
     *         ( easyrtc.idToName(easyrtcid) + " closed stream " + stream.id + " " + streamName);
     *     });
     */
    setOnStreamClosed:(onStreamClosed:(easyrtc:string, mediaStream:MediaStream, streamName:string) => void) => void;

    /**
     * Sets a listener for data sent from another client (either peer to peer or via websockets).
     * If no msgType or source is provided, the listener applies to all events that aren't otherwise handled.
     * If a msgType but no source is provided, the listener applies to all messages of that msgType that aren't otherwise handled.
     * If a msgType and a source is provided, the listener applies to only message of the specified type coming from the specified peer.
     * The most specific case takes priority over the more general.
     * @param {Function} listener has the signature (easyrtcid, msgType, msgData, targeting).
     *   msgType is a string. targeting is null if the message was received using WebRTC data channels, otherwise it
     *   is an object that contains one or more of the following string valued elements {targetEasyrtcid, targetGroup, targetRoom}.
     * @param {String} msgType - a string, optional.
     * @param {String} source - the sender's easyrtcid, optional.
     * @example
     *     easyrtc.setPeerListener( function(easyrtcid, msgType, msgData, targeting){
     *         console.log("From " + easyrtc.idToName(easyrtcid) +
     *             " sent the following data " + JSON.stringify(msgData));
     *     });
     *     easyrtc.setPeerListener( function(easyrtcid, msgType, msgData, targeting){
     *         console.log("From " + easyrtc.idToName(easyrtcid) +
     *             " sent the following data " + JSON.stringify(msgData));
     *     }, 'food', 'dkdjdekj44--');
     *     easyrtc.setPeerListener( function(easyrtcid, msgType, msgData, targeting){
     *         console.log("From " + easyrtcid +
     *             " sent the following data " + JSON.stringify(msgData));
     *     }, 'drink');
     *
     *
     */
    setPeerListener(listener:Easyrtc_ReceivePeerCallback, msgType?:string, source?:string):void;

    /**
     * Sets a listener for messages from the server.
     * @param {Function} listener has the signature (msgType, msgData, targeting)
     * @example
     *     easyrtc.setServerListener( function(msgType, msgData, targeting){
     *         ("The Server sent the following message " + JSON.stringify(msgData));
     *     });
     */
    /**
     * Sets the url of the Socket server.
     * The node.js server is great as a socket server, but it doesn't have
     * all the hooks you'd like in a general web server, like PHP or Python
     * plug-ins. By setting the serverPath your application can get it's regular
     * pages from a regular web server, but the EasyRTC library can still reach the
     * socket server.
     * @param {String} socketUrl
     * @param {Object} options an optional dictionary of options for socket.io's connect method.
     * The default is {'connect timeout': 10000,'force new connection': true }
     * @example
     *     easyrtc.setSocketUrl(":8080", options);
     */
    setSocketUrl(socketUrl:string, options:{
        [key:string]:any;
    }):void;

    /**
     * Sets the user name associated with the connection.
     * @param {String} username must obey standard identifier conventions.
     * @returns {Boolean} true if the call succeeded, false if the username was invalid.
     * @example
     *    if( !easyrtc.setUsername("JohnSmith") ){
     *        console.error("bad user name);
     *    }
     *
     */
    setUsername(username:string):void;

    /**
     * Get an array of easyrtcids that are using a particular username
     * @param {String} username - the username of interest.
     * @param {String} room - an optional room name argument limiting results to a particular room.
     * @returns {Array} an array of {easyrtcid:id, roomName: roomName}.
     */
    usernameToIds(username:string, room:string):string[];

    /**
     * Returns another peers API field, if it exists.
     * @param {type} roomName
     * @param {type} easyrtcid
     * @param {type} fieldName
     * @returns {Object}  Undefined if the attribute does not exist, its value otherwise.
     */
    getRoomApiField(roomName:string, easyrtcid:string, fieldName:string):any;

    /**
     * Set the authentication credential if needed.
     * @param {Object} credentialParm - a JSONable object.
     */
    setCredential(credentialParm:string):void;

    /**
     * Sets the listener for socket disconnection by external (to the API) reasons.
     * @param {Function} disconnectListener takes no arguments and is not called as a result of calling easyrtc.disconnect.
     * @example
     *    easyrtc.setDisconnectListener(function(){
     *        easyrtc.showError("SYSTEM-ERROR", "Lost our connection to the socket server");
     *    });
     */
    setDisconnectListener(disconnectListener:() => void):void;

    /**
     * Convert an easyrtcid to a user name. This is useful for labeling buttons and messages
     * regarding peers.
     * @param {String} easyrtcid
     * @return {String} the username associated with the easyrtcid, or the easyrtcid if there is
     * no associated username.
     * @example
     *    console.log(easyrtcid + " is actually " + easyrtc.idToName(easyrtcid));
     */
    idToName(easyrtcid:string):string;

    /**
     * Determines whether fresh ice server configuration should be requested from the server for each peer connection.
     * @param {Boolean} value the default is false.
     */
    setUseFreshIceEachPeerConnection(value:boolean):void;

    /**
     * Returns the last ice config supplied by the EasyRTC server. This function is not normally used, it is provided
     * for people who want to try filtering ice server configuration on the client.
     * @return {Object} which has the form {iceServers:[ice_server_entry, ice_server_entry, ...]}
     */
    getServerIce():RTCPeerConnectionConfig;

    /**
     * Sets the ice server configuration that will be used in subsequent calls. You only need this function if you are filtering
     * the ice server configuration on the client or if you are using TURN certificates that have a very short lifespan.
     * @param {Object} ice An object with iceServers element containing an array of ice server entries.
     * @example
     *     easyrtc.setIceUsedInCalls( {"iceServers": [
     *      {
     *         "url": "stun:stun.sipgate.net"
     *      },
     *      {
     *         "url": "stun:217.10.68.152"
     *      },
     *      {
     *         "url": "stun:stun.sipgate.net:10000"
     *      }
     *      ]});
     *      easyrtc.call(...);
     */
    setIceUsedInCalls(ice:RTCPeerConnectionConfig):void;

    /** Determines if a particular peer2peer connection has an audio track.
     * @param {String} easyrtcid - the id of the other caller in the connection. If easyrtcid is not supplied, checks the local media.
     * @param {String} streamName - an optional stream id.
     * @return {Boolean} true if there is an audio track or the browser can't tell us.
     */
    haveAudioTrack(easyrtcid:string, streamName:string):boolean;

    /** Determines if a particular peer2peer connection has a video track.
     * @param {String} easyrtcid - the id of the other caller in the connection. If easyrtcid is not supplied, checks the local media.
     * @param {String} streamName - an optional stream id.     *
     * @return {Boolean} true if there is an video track or the browser can't tell us.
     */
    haveVideoTrack(easyrtcid:string, streamName:string):boolean;

    /**
     * Gets a data field associated with a room.
     * @param {String} roomName - the name of the room.
     * @param {String} fieldName - the name of the field.
     * @return {Object} dataValue - the value of the field if present, undefined if not present.
     */
    getRoomField(roomName:string, fieldName:string):any;

    /**
     * Disconnect from the EasyRTC server.
     * @example
     *    easyrtc.disconnect();
     */
    disconnect():void;

    /**
     *Sends data to another user using previously established data channel. This method will
     * fail if no data channel has been established yet. Unlike the easyrtc.sendWS method,
     * you can't send a dictionary, convert dictionaries to strings using JSON.stringify first.
     * What data types you can send, and how large a data type depends on your browser.
     * @param {String} destUser (an easyrtcid)
     * @param {String} msgType - the type of message being sent (application specific).
     * @param {Object} msgData - a JSONable object.
     * @example
     *     easyrtc.sendDataP2P(someEasyrtcid, "roomData", {room:499, bldgNum:'asd'});
     */
    sendDataP2P(destUser:string, msgType:string, msgData:any):void;

    /** Sends data to another user using websockets. The easyrtc.sendServerMessage or easyrtc.sendPeerMessage methods
     * are wrappers for this method; application code should use them instead.
     * @param {String} destination - either a string containing the easyrtcId of the other user, or an object containing some subset of the following fields: targetEasyrtcid, targetGroup, targetRoom.
     * Specifying multiple fields restricts the scope of the destination (operates as a logical AND, not a logical OR).
     * @param {String} msgType -the type of message being sent (application specific).
     * @param {Object} msgData - a JSONable object.
     * @param {Function} ackhandler - by default, the ackhandler handles acknowledgments from the server that your message was delivered to it's destination.
     * However, application logic in the server can over-ride this. If you leave this null, a stub ackHandler will be used. The ackHandler
     * gets passed a message with the same msgType as your outgoing message, or a message type of "error" in which case
     * msgData will contain a errorCode and errorText fields.
     * @example
     *    easyrtc.sendDataWS(someEasyrtcid, "setPostalAddress", {room:499, bldgNum:'asd'},
     *      function(ackMsg){
     *          console.log("saw the following acknowledgment " + JSON.stringify(ackMsg));
     *      }
     *    );
     */
    sendDataWS(destination:Easyrtc_PeerMessageDestination, msgType:string, msgData:any, ackhandler:(ackmsg:Easyrtc_BasicMessage) => void):void;

    /** Sends data to another user. This method uses data channels if one has been set up, or websockets otherwise.
     * @param {String} destUser - a string containing the easyrtcId of the other user.
     * Specifying multiple fields restricts the scope of the destination (operates as a logical AND, not a logical OR).
     * @param {String} msgType -the type of message being sent (application specific).
     * @param {Object} msgData - a JSONable object.
     * @param {Function} ackHandler - a function which receives acknowledgments. May only be invoked in
     *  the websocket case.
     * @example
     *    easyrtc.sendData(someEasyrtcid, "roomData",  {room:499, bldgNum:'asd'},
     *       function ackHandler(msgType, msgData);
     *    );
     */
    sendData(destUser:any, msgType:string, msgData:any, ackHandler:(ack:any) => void):void;

    /**
     * Sends a message to another peer on the easyrtcMsg channel.
     * @param {String} destination - either a string containing the easyrtcId of the other user, or an object containing some subset of the following fields: targetEasyrtcid, targetGroup, targetRoom.
     * Specifying multiple fields restricts the scope of the destination (operates as a logical AND, not a logical OR).
     * @param {String} msgType - the type of message being sent (application specific).
     * @param {Object} msgData - a JSONable object with the message contents.
     * @param {function(String, Object)} successCB - a callback function with results from the server.
     * @param {function(String, String)} failureCB - a callback function to handle errors.
     * @example
     *     easyrtc.sendPeerMessage(otherUser, 'offer_candy', {candy_name:'mars'},
     *             function(msgType, msgBody ){
     *                console.log("message was sent");
     *             },
     *             function(errorCode, errorText){
     *                console.log("error was " + errorText);
     *             });
     */
    sendPeerMessage(destination:Easyrtc_PeerMessageDestination, msgType:string, msgData:any, successCB:(a:string, b:any) => void, failureCB:(a:string, b:string) => void):void;

    /**
     * Sends a message to the application code in the server (ie, on the easyrtcMsg channel).
     * @param {String} msgType - the type of message being sent (application specific).
     * @param {Object} msgData - a JSONable object with the message contents.
     * @param {function(String, Object)} successCB - a callback function with results from the server.
     * @param {function(String, String)} failureCB - a callback function to handle errors.
     * @example
     *     easyrtc.sendServerMessage('get_candy', {candy_name:'mars'},
     *             function(msgType, msgData ){
     *                console.log("got candy count of " + msgData.barCount);
     *             },
     *             function(errorCode, errorText){
     *                console.log("error was " + errorText);
     *             });
     */
    sendServerMessage(msgType:string, msgData:any,
                      successCB:(successMessageType:string, successData:any) => void,
                      failureCB:(errorCode:string, errText:string) => void):void;

    /** Sends the server a request for the list of rooms the user can see.
     * You must have already be connected to use this function.
     * @param {function(Object)} callback - on success, this function is called with a map of the form  { roomName:{"roomName":String, "numberClients": Number}}.
     * The roomName appears as both the key to the map, and as the value of the "roomName" field.
     * @param {function(String, String)} errorCallback   is called on failure. It gets an errorCode and errorText as it's too arguments.
     * @example
     *    easyrtc.getRoomList(
     *        function(roomList){
     *           for(roomName in roomList){
     *              console.log("saw room " + roomName);
     *           }
     *         },
     *         function(errorCode, errorText){
     *            easyrtc.showError(errorCode, errorText);
     *         }
     *    );
     */
    getRoomList(callback:(roomNames:string[]) => void, errorCallback:(errCode:string, errorText:string) => void):void;

    /** Value returned by easyrtc.getConnectStatus if the other user isn't connected to us. */
    NOT_CONNECTED:string;
    /** Value returned by easyrtc.getConnectStatus if the other user is in the process of getting connected */
    BECOMING_CONNECTED:string;
    /** Value returned by easyrtc.getConnectStatus if the other user is connected to us. */
    IS_CONNECTED:string;

    /**
     * Check if the client has a peer-2-peer connection to another user.
     * The return values are text strings so you can use them in debugging output.
     *  @param {String} otherUser - the easyrtcid of the other user.
     *  @return {String} one of the following values: easyrtc.NOT_CONNECTED, easyrtc.BECOMING_CONNECTED, easyrtc.IS_CONNECTED
     *  @example
     *     if( easyrtc.getConnectStatus(otherEasyrtcid) == easyrtc.NOT_CONNECTED ){
     *         easyrtc.call(otherEasyrtcid,
     *                  function(){ console.log("success"); },
     *                  function(){ console.log("failure"); });
     *     }
     */
    getConnectStatus(otherUser:string):string;



    /**
     * Initiates a call to another user. If it succeeds, the streamAcceptor callback will be called.
     * @param {String} otherUser - the easyrtcid of the peer being called.
     * @param {Function} callSuccessCB (otherCaller, mediaType) - is called when the datachannel is established or the MediaStream is established. mediaType will have a value of "audiovideo" or "datachannel"
     * @param {Function} callFailureCB (errorCode, errMessage) - is called if there was a system error interfering with the call.
     * @param {Function} wasAcceptedCB (wasAccepted:boolean,otherUser:string) - is called when a call is accepted or rejected by another party. It can be left null.
     * @param {Array} streamNames - optional array of streamNames.
     * @example
     *    easyrtc.call( otherEasyrtcid,
     *        function(easyrtcid, mediaType){
     *           console.log("Got mediaType " + mediaType + " from " + easyrtc.idToName(easyrtcid));
     *        },
     *        function(errorCode, errMessage){
     *           console.log("call to  " + easyrtc.idToName(otherEasyrtcid) + " failed:" + errMessage);
     *        },
     *        function(wasAccepted, easyrtcid){
     *            if( wasAccepted ){
     *               console.log("call accepted by " + easyrtc.idToName(easyrtcid));
     *            }
     *            else{
     *                console.log("call rejected" + easyrtc.idToName(easyrtcid));
     *            }
     *        });
     */
    call(otherUser:string, callSuccessCB:(easyrtcid:string, mediaType:string) => void,
         callFailureCB:(errcode:string, errString:string) => void,
         wasAcceptedCB:(wasAccepted:boolean, easyrtcid:string) => void,
         streamNames:string[]):void;

    /**
     * Hang up on a particular user or all users.
     *  @param {String} otherUser - the easyrtcid of the person to hang up on.
     *  @example
     *     easyrtc.hangup(someEasyrtcid);
     */
    hangup(otherUser:string):void;

    /**
     * Hangs up on all current connections.
     * @example
     *    easyrtc.hangupAll();
     */
    hangupAll:() => void;

    /**
     * Checks to see if data channels work between two peers.
     * @param {String} otherUser - the other peer.
     * @returns {Boolean} true if data channels work and are ready to be used
     *   between the two peers.
     */
    doesDataChannelWork(otherUser:any):boolean;

    /**
     * Return the media stream shared by a particular peer. This is needed when you
     * add a stream in the middle of a call.
     * @param {String} easyrtcid the peer.
     * @param {String} remoteStreamName an optional argument supplying the streamName.
     * @returns {Object} A mediaStream.
     */
    getRemoteStream(easyrtcid:string, remoteStreamName:string):MediaStream;

    registerLocalMediaStreamByName(remoteStream:MediaStream, localStreamName:string):void;

    /**
     * Assign a local streamName to a remote stream so that it can be forwarded to other callers.
     * @param {String} easyrtcid the peer supplying the remote stream
     * @param {String} remoteStreamName the streamName supplied by the peer.
     * @param {String} localStreamName streamName used when passing the stream to other peers.
     * @example
     *    easyrtc.makeLocalStreamFromRemoteStream(sourcePeer, "default", "forwardedStream");
     *    easyrtc.call(nextPeer, callSuccessCB, callFailureCB, wasAcceptedCB, ["forwardedStream"]);
     */
    makeLocalStreamFromRemoteStream(easyrtcid:string, remoteStreamName:string, localStreamName:string):void;

    /**
     * Add a named local stream to a call.
     * @param {String} easyrtcId The id of client receiving the stream.
     * @param {String} streamName The name of the stream.
     * @param {Function} receiptHandler is a function that gets called when the other side sends a message
     *   that the stream has been received. The receiptHandler gets called with an easyrtcid and a stream name. This
     *   argument is optional.
     */
    addStreamToCall(easyrtcId:string, streamName:string, receiptHandler:(easyrtcid:string, streamName:string) => void):void;

    isPeerInAnyRoom(easyrtcid:string):boolean;

    /**
     * Sets the presence state on the server.
     * @param {String} state - one of 'away','chat','dnd','xa'
     * @param {String} statusText - User configurable status string. May be length limited.
     * @example   easyrtc.updatePresence('dnd', 'sleeping');
     */
    updatePresence(state:string, statusText:string):void;

    /**
     * Fetch the collection of session fields as a map. The map has the structure:
     *  {key1: {"fieldName": key1, "fieldValue": value1}, ...,
     *   key2: {"fieldName": key2, "fieldValue": value2}
     *  }
     * @returns {Object}
     */

    getSessionFields(): Easyrtc_RedundantMap;
    /**
     * Fetch the value of a session field by name.
     * @param {String} name - name of the session field to be fetched.
     * @returns the field value (which can be anything). Returns undefined if the field does not exist.
     */
    getSessionField(name:string):any;

    
    /**
     * Returns true if the ipAddress parameter was the address of a turn server. This is done by checking against information
     * collected during peer to peer calls. Don't expect it to work before the first call, or to identify turn servers that aren't
     * in the ice config.
     * @param ipAddress
     * @returns {boolean} true if ip address is known to be that of a turn server, false otherwise.
     */
    isTurnServer(ipAddress:string):boolean;

    /**
     * Returns true if the ipAddress parameter was the address of a stun server. This is done by checking against information
     * collected during peer to peer calls. Don't expect it to work before the first call, or to identify turn servers that aren't
     * in the ice config.
     * @param ipAddress
     * @returns {boolean} true if ip address is known to be that of a stun server, false otherwise.
     */
    isStunServer(ipAddress:string):boolean;

    /**
     * Request fresh ice config information from the server.
     * This should be done periodically by long running applications.
     * @param {Function} callback is called with a value of true on success, false on failure.
     */
    getFreshIceConfig(callback:(sawSuccess:boolean)=>void);

    /**
     * This method allows you to join a single room. It may be called multiple times to be in
     * multiple rooms simultaneously. It may be called before or after connecting to the server.
     * Note: the successCB and failureDB will only be called if you are already connected to the server.
     * @param {String} roomName the room to be joined.
     * @param {Object} roomParameters application specific parameters, can be null.
     * @param {Function} successCB called once, with a roomName as it's argument, once the room is joined.
     * @param {Function} failureCB called if the room can not be joined. The arguments of failureCB are errorCode, errorText, roomName.
     */
    joinRoom(roomName:string, roomParameters:{
        [key:string]:any;
    }, successCB:(roomName:string) => void, failureCB:(errorCode:string, errorText:string, roomName:string) => void):void;

    /**
     * This function allows you to leave a single room. Note: the successCB and failureDB
     *  arguments are optional and will only be called if you are already connected to the server.
     * @param {String} roomName
     * @param {Function} successCallback - A function which expects a roomName.
     * @param {Function} failureCallback - A function which expects the following arguments: errorCode, errorText, roomName.
     * @example
     *    easyrtc.leaveRoom("freds_room");
     *    easyrtc.leaveRoom("freds_room", function(roomName){ console.log("left the room")},
     *                       function(errorCode, errorText, roomName){ console.log("left the room")});
     */
    leaveRoom(roomName:string, successCallback:(roomName:string) => void, failureCallback:(errorCode:string, errorText:string, roomName:string) => void):void;

    /** Get a list of the rooms you are in. You must be connected to call this function.
     * @returns {Object} A map whose keys are the room names
     */
    getRoomsJoined():{
        [key:string]:boolean;
    };

    /** Get server defined fields associated with a particular room. Only valid
     * after a connection has been made.
     * @param {String} roomName - the name of the room you want the fields for.
     * @returns {Object} A dictionary containing entries of the form {key:{'fieldName':key, 'fieldValue':value1}} or undefined
     * if you are not connected to the room.
     */
    getRoomFields(roomName:string):Easyrtc_RedundantMap;

    /** Get server defined fields associated with the current application. Only valid
     * after a connection has been made.
     * @returns {Object} A dictionary containing entries of the form {key:{'fieldName':key, 'fieldValue':value1}}
     */
    getApplicationFields():Easyrtc_RedundantMap;

    /** Get server defined fields associated with the connection. Only valid
     * after a connection has been made.
     * @returns {Object} A dictionary containing entries of the form {key:{'fieldName':key, 'fieldValue':value1}}
     */
    getConnectionFields():Easyrtc_RedundantMap;

    /**
     * Supply a socket.io connection that will be used instead of allocating a new socket.
     * The expected usage is that you allocate a websocket, assign options to it, call
     * easyrtc.useThisSocketConnection, followed by easyrtc.connect or easyrtc.easyApp. Easyrtc will not attempt to
     * close sockets that were supplied with easyrtc.useThisSocketConnection.
     * @param {Object} alreadyAllocatedSocketIo A value allocated with the connect method of socket.io.
     */
    useThisSocketConnection(alreadyAllocatedSocketIo:any):void;

    /**
     * Connects to the EasyRTC signaling server. You must connect before trying to
     * call other users.
     * @param {String} applicationName is a string that identifies the application so that different applications can have different
     *        lists of users. Note that the server configuration specifies a regular expression that is used to check application names
     *        for validity. The default pattern is that of an identifier, spaces are not allowed.
     * @param {Function} successCallback (easyrtcId, roomOwner) - is called on successful connect. easyrtcId is the
     *   unique name that the client is known to the server by. A client usually only needs it's own easyrtcId for debugging purposes.
     *       roomOwner is true if the user is the owner of a room. It's value is random if the user is in multiple rooms.
     * @param {Function} errorCallback (errorCode, errorText) - is called on unsuccessful connect. if null, an alert is called instead.
     *  The errorCode takes it's value from easyrtc.errCodes.
     * @example
     *   easyrtc.connect("my_chat_app",
     *                   function(easyrtcid, roomOwner){
     *                       if( roomOwner){ console.log("I'm the room owner"); }
     *                       console.log("my id is " + easyrtcid);
     *                   },
     *                   function(errorText){
     *                       console.log("failed to connect ", erFrText);
     *                   });
     */
    connect(applicationName:string, successCallback:(easyrtcid:string, roomOwner:boolean) => void, errorCallback:(errorCode:string, errorText:string) => void):void;

    //
    // methods provided by easyrtc_app.
    //
    /** By default, the easyApp routine sticks a "close" button on top of each caller
     * video object that it manages. Call this function(before calling easyApp) to disable that particular feature.
     * @function
     * @memberOf Easyrtc_App
     * @example
     *    easyrtc.dontAddCloseButtons();
     */
    dontAddCloseButtons():void;

    /**
     * Get the easyrtcid of the ith caller, starting at 0.
     * @function
     * @memberOf Easyrtc_App
     * @param {number} i
     * @returns {String}
     */
    getIthCaller(i:number):string;

    /**
     * This is the complement of getIthCaller. Given an easyrtcid,
     * it determines which slot the easyrtc is in.
     * @function
     * @memberOf Easyrtc_App
     * @param {string} easyrtcid
     * @returns {number} or -1 if the easyrtcid is not a caller.
     */
    getSlotOfCaller(easyrtcid:string):number;

    /**
     * Provides a layer on top of the easyrtc.initMediaSource and easyrtc.connect, assign the local media stream to
     * the video object identified by monitorVideoId, assign remote video streams to
     * the video objects identified by videoIds, and then call onReady. One of it's
     * side effects is to add hangup buttons to the remote video objects, buttons
     * that only appear when you hover over them with the mouse cursor. This method will also add the
     * easyrtcMirror class to the monitor video object so that it behaves like a mirror.
     * @function
     * @memberOf Easyrtc_App
     *  @param {String} applicationName - name of the application.
     *  @param {String} monitorVideoId - the id of the video object used for monitoring the local stream.
     *  @param {Array} videoIds - an array of video object ids (strings)
     *  @param {Function} onReady - a callback function used on success. It is called with the easyrtcId this peer is known to the server as.
     *  @param {Function} onFailure - a callback function used on failure (failed to get local media or a connection of the signaling server).
     *  @example
     *     easyrtc.easyApp('multiChat', 'selfVideo', ['remote1', 'remote2', 'remote3'],
     *              function(easyrtcId){
     *                  console.log("successfully connected, I am " + easyrtcId);
     *              },
     *              function(errorCode, errorText){
     *                  console.log(errorText);
     *              });
     */
    easyApp(applicationName:string,
            monitorVideoId:string,
            videoIds:string[],
            onReady:(easyrtcId:string)=>void,
            onFailure:(errorCode:string, errorText:string)=>void):void;

    /**
     * Sets a callback that will be called when easyApp allocates a media stream.
     * @memberOf Easyrtc_App
     * @param gotMediaCB : a callback whose first argument is a boolean
     *    flag (true for success, false for failure), and second argument
     *    is a humanly readable reason for why the function failed (if it
     *    did).
     */
    setGotMedia(gotMediaCB:(gotMedia:boolean, errorText:string)=>void);

    /** Sets an event handler that gets called when a connection to the signaling
     * server has or has not been made. Can only be called after calling easyrtc.easyApp.
     * @function
     * @memberOf Easyrtc_App
     * @param {Function} gotConnectionCB has the signature (gotConnection, errorText)
     * @example
     *    easyrtc.setGotConnection( function(gotConnection, errorText){
         *        if( gotConnection ){
         *            console.log("Successfully connected to signaling server");
         *        }
         *        else{
         *            console.log("Failed to connect to signaling server because: " + errorText);
         *        }
         *    });
     */

    setGotConnection(gotConnectionCB:(gotConnection:boolean, errorText:string)=>void);


    /**
     *  This function returns an sdp filter function.
     * @function
     * @memberOf Easyrtc_Rates
     * @param options
     * @returns {Function} which takes an SDP string and returns a modified SDP string.
     */
    buildLocalSdpFilter(options:Easyrtc_RatesOptions): (sdp:string)=>string;

    /**
     *  This function returns an sdp filter function.
     * @function
     * @memberOf Easyrtc_Rates
     * @param options
     * @returns {Function} which takes an SDP string and returns a modified SDP string.
     */
    buildRemoteSdpFilter(options:Easyrtc_RatesOptions): (sdp:string)=>string;



}

declare var easyrtc:Easyrtc;

