'use strict';

/**
 * @ignore
 * @suppress {duplicate}
 */
var fs = require('fs');

/**
 * @ignore
 * @suppress {duplicate}
 */
var path = require('path');

/**
 * @ignore
 * @suppress {duplicate}
 */
var Q = require('q');

/**
 * @ignore
 * @suppress {duplicate}
 */
var utils = require('./utils.js');

/**
 * @type {WarningsFilterProcessor}
 */
var instance;

/**
 * Instantiates a {@link WarningsFilterProcessor} object.
 *
 * @classdesc This class contains all filters from the registered warnings filter files. Further it filters out all
 * messages that are catched by any registered filter.
 *
 * @constructor
 */
function WarningsFilterProcessor () {
    this._registry = {};
}

/**
 * Register a warnings filter file to this object.
 *
 * @returns {Promise} A promise that will be resolved in case of success and rejected in case of an error.
 * @param {string} pathToFile The file path of the warnings filter file that willm be registered to this instance.
 */
WarningsFilterProcessor.prototype.registerWarningsFilterFile = function (pathToFile) {
    var resolvedPathToFile = path.resolve(pathToFile);
    var self = this;
    var defered = Q.defer();
    if (Object.keys(this._registry).indexOf(resolvedPathToFile) !== -1) {
        defered.resolve(self);
        return defered.promise;
    }
    fs.readFile(resolvedPathToFile, 'utf8', function (err, data) {
        if (err) {
            defered.reject(err);
        } else {
            self._registry[resolvedPathToFile] = data.split('\n').filter(function (line) {
                return line.trim().length !== 0;
            });
            defered.resolve(self);
        }
    });
    return defered.promise;
};

/**
 * Get all defined warning filters from the passed warnings filter file paths.
 *
 * @returns {Array<string>} An array of filters defined by the warnings filter files represented by the given file
 *          paths.
 * @param {Array<string>} pathsToFiles A collection of file paths to the warning filter files.
 */
WarningsFilterProcessor.prototype.getFilters = function (pathsToFiles) {
    var self = this;
    return utils
        .arrayToSet((pathsToFiles || [])
                    .map(function (pathToFile) {
                        return path.resolve(pathToFile);
                    })
                    .reduce(function (accumulator, currentPath) {
                        if (!Object.prototype.hasOwnProperty.call(self._registry, currentPath)) {
                            throw new Error('The warnings filter file "' + currentPath + '" is not known!');
                        }
                        Array.prototype.push.apply(accumulator, this._registry[currentPath]);
                        return accumulator;
                    }, []));
};

/**
 * Processes all passed messages and filters out all warnings that are catched by any filter defined in a corresponding
 * warnigns filter file.
 *
 * @returns {Array<GCCMessage>} The resulting collection of messages.
 * @param {Array<GCCMessage>} messages The original collection of messages generated by the GCC on stderr.
 * @param {Array<string>} pathsToFiles A collection of file paths to warnigns filter files.
 */
WarningsFilterProcessor.prototype.processMessages = function (messages, pathsToFiles) {
    var filters = this.getFilters(pathsToFiles);
    var results = (messages || [])
        .filter(function (message) {
            return !message.isWarning() || filters.indexOf(message.getHeading()) === -1;
        });

    if (results.length !== 0 && results[results.length - 1].isStatus()) {
        results[results.length - 1].setWarningsCount(results.length - 1);
        results[results.length - 1].setFilteredWarningsCount(messages.length - results.length);
    }
    return results;
};

/**
 * A factory function for the type {@link WarningsFilterProcessor}. The factory method ensures that there is only one
 * instance of {@link WarningsFilterProcessor}, so it is realized as a singleton.
 *
 * @returns {WarningsFilterProcessor} The created {@link WarningsFilterProcessor} instance.
 */
function getWarningsFilterProcessor () {
    if (instance) {
        return instance;
    } else {
        instance = new /** @type {function(new:WarningsFilterProcessor)} */ (WarningsFilterProcessor)();
        return instance;
    }
}

module.exports = getWarningsFilterProcessor;

@@ -2639,20 +2639,20 @@
 ulator, 
-this
+self
 ._regist

Fix a bug with the this context in WarningsFilterProcessor