<commit_before>﻿module xp {
    /**
     * Event.
     * @param TEventArgs Type of event arguments object.
     */
    export class Event<TEventArgs>
    {
        private handlers: Subscription<TEventArgs>[] = [];

        /**
         * Adds event handler.
         * @param handler Function which will be called when event happens.
         * @param thisArg Context of handler.
         * @returns Subscription.
         */
        addHandler(handler: EventHandler<TEventArgs>, thisArg?: any): Subscription<TEventArgs> {
            var subscription = {
                event: this,
                handler: handler,
                scope: thisArg
            };
            if (this.handlers.filter((h) => h.handler === handler/* && h.scope === thisArg*/)[0]) {
                throw new Error('Duplicate subscription.');
            }
            this.handlers.push(subscription);
            return subscription;
        }

        /**
         * Removes event handler.
         * @param handler Function to remove.
         * @returns Removed handler.
         */
        removeHandler(handler: EventHandler<TEventArgs>): EventHandler<TEventArgs> {
            var found = this.handlers.filter((h) => h.handler === handler)[0];
            if (!found) {
                throw new Error('Unable to remove event handler :\n' + handler.toString());
            }
            this.handlers.splice(this.handlers.indexOf(found), 1);
            return found.handler;
        }

        /**
         * Removes all event handlers.
         */
        removeAllHandlers() {
            this.handlers = [];
        }

        /**
         * Determines if the specified handler is already subscribed for an event.
         * @param handler Event handler.
         */
        hasHandler(handler: EventHandler<TEventArgs>): boolean {
            return this.handlers.filter((h) => h.handler === handler).length > 0;
        }

        /**
         * Fires the event.
         * @param args Event arguments.
         */
        invoke(args: TEventArgs) {
            this.handlers.forEach((item) => {
                item.handler.call(item.scope, args);
            });
        }
    }

    /**
     * Function which handles an event.
     * @param TEventArgs Type of event arguments object.
     */
    export interface EventHandler<TEventArgs> {
        /**
         * @param args Event arguments object.
         */
        (args: TEventArgs): void;
    }

    /**<commit_msg>Fixed calling event handlers after remove.<commit_after>﻿module xp {
    /**
     * Event.
     * @param TEventArgs Type of event arguments object.
     */
    export class Event<TEventArgs>
    {
        private handlers: Subscription<TEventArgs>[] = [];

        /**
         * Adds event handler.
         * @param handler Function which will be called when event happens.
         * @param thisArg Context of handler.
         * @returns Subscription.
         */
        addHandler(handler: EventHandler<TEventArgs>, thisArg?: any): Subscription<TEventArgs> {
            var subscription = {
                event: this,
                handler: handler,
                scope: thisArg
            };
            if (this.handlers.filter((h) => h.handler === handler/* && h.scope === thisArg*/)[0]) {
                throw new Error('Duplicate subscription.');
            }
            this.handlers.push(subscription);
            return subscription;
        }

        /**
         * Removes event handler.
         * @param handler Function to remove.
         * @returns Removed handler.
         */
        removeHandler(handler: EventHandler<TEventArgs>): EventHandler<TEventArgs> {
            var found = this.handlers.filter((h) => h.handler === handler)[0];
            if (!found) {
                throw new Error('Unable to remove event handler :\n' + handler.toString());
            }
            this.handlers.splice(this.handlers.indexOf(found), 1);
            return found.handler;
        }

        /**
         * Removes all event handlers.
         */
        removeAllHandlers() {
            this.handlers = [];
        }

        /**
         * Determines if the specified handler is already subscribed for an event.
         * @param handler Event handler.
         */
        hasHandler(handler: EventHandler<TEventArgs>): boolean {
            return this.handlers.filter((h) => h.handler === handler).length > 0;
        }

        /**
         * Fires the event.
         * @param args Event arguments.
         */
        invoke(args: TEventArgs) {
            this.handlers.slice(0).forEach((item) => {
                item.handler.call(item.scope, args);
            });
        }
    }

    /**
     * Function which handles an event.
     * @param TEventArgs Type of event arguments object.
     */
    export interface EventHandler<TEventArgs> {
        /**
         * @param args Event arguments object.
         */
        (args: TEventArgs): void;
    }

    /**
{'fraction_non_alphanumeric': 0.11521477318346046, 'fraction_numerical': 0.0018065034122842231, 'mean_word_length': 1.5953125, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 29, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6841430', 'n_tokens_mistral': 1273, 'n_tokens_neox': 1255, 'n_words': 325}