/**
 * @license MIT License
 *
 * Copyright (c) 2015 Tetsuharu OHZEKI <saneyuki.snyk@gmail.com>
 * Copyright (c) 2015 Yusuke Suzuki <utatane.tea@gmail.com>
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

import arrayFrom from 'core-js/library/fn/array/from';
import Network from './Network';
import {Some, None} from 'option-t';

/**
 *  This object is based on the assumption that
 *  `Network.id` will be unique while the runtime.
 */
export default class NetworkSet {

    /**
     *  @constructor
     *  @param  {Array}    raw
     */
    constructor(raw) {
        /** @type   {Map<string, Network>}  */
        this._idMap = new Map();

        raw.forEach((item) => {
            const n = new Network(item);
            this._idMap.set(n.id, n);
        });
    }

    /**
     *  @param  {Network}   item
     *  @return {void}
     */
    add(item) {
        if (this.has(item)) {
            return;
        }

        this._idMap.set(item.id, item);
    }

    /**
     *  @param  {string}    item
     *  @return {boolean}
     */
    has(item) {
        const id = item.id;
        return this._idMap.has(id);
    }

    /**
     *  @param  {string}    id
     *  @return {OptionT<Network>}
     */
    getById(id) {
        const result = this._idMap.get(id);
        if (result === undefined) {
            return new None();
        }
        else {
            return new Some(result);
        }
    }

    /**
     *  @param  {Network}   item
     *  @return {boolean}
     */
    delete(item) {
        const id = item.id;
        return this._idMap.delete(id);
    }

    /**
     *  @return {void}
     */
    clear() {
        this._idMap.clear();
    }

    /**
     *  @return {Array<Network>}
     */
    asArray() {
        const set = new Set(this._idMap.values());
        const array = arrayFrom(set);
        return array;
    }
}

@@ -1317,16 +1317,38 @@
 twork';%0A
+import Rx from 'rx';%0A%0A
 import %7B
@@ -1813,16 +1813,281 @@
      %7D);
+%0A%0A        /** @type   %7BRx.Subject%3CNetwork%3E%7D    */%0A        this._added = new Rx.Subject();%0A%0A        /** @type   %7BRx.Subject%3CNetwork%3E%7D   */%0A        this._deleted = new Rx.Subject();%0A%0A        /** @type   %7BRx.Subject%3Cvoid%3E%7D  */%0A        this._cleared = new Rx.Subject();
 %0A    %7D%0A%0A
@@ -2271,24 +2271,185 @@
 .id, item);%0A
+        this._added.onNext(item);%0A    %7D%0A%0A    /**%0A     *  @return %7BRx.Observable%3CNetwork%3E%7D%0A     */%0A    addedStream() %7B%0A        return this._added.asObservable();%0A
     %7D%0A%0A    /
@@ -3017,38 +3017,49 @@
 tem.id;%0A        
-return
+const isDeleted =
  this._idMap.del
@@ -3075,89 +3075,484 @@
     
-%7D%0A%0A    /**%0A     *  @return %7Bvoid%7D%0A     */%0A    clear() %7B%0A        this._idMap.clear
+    if (isDeleted) %7B%0A            this._deleted.onNext(item);%0A        %7D%0A        return isDeleted;%0A    %7D%0A%0A    /**%0A     *  @return %7BRx.Observable%3CNetwork%3E%7D%0A     */%0A    deletedStream() %7B%0A        return this._deleted.asObservable();%0A    %7D%0A%0A    /**%0A     *  @return %7Bvoid%7D%0A     */%0A    clear() %7B%0A        this._idMap.clear();%0A        this._cleared.onNext();%0A    %7D%0A%0A    /**%0A     *  @return %7BRx.Observable%3CNetwork%3E%7D%0A     */%0A    clearedStream() %7B%0A        return this._cleared.asObservable
 ();%0A

Make NetworkSet Observable.