<commit_before>###
Copyright (c) 2013, <NAME> <<EMAIL>>
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice, this
   list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
   this list of conditions and the following disclaimer in the documentation
   and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
###

_ = require "lodash"
async = require "async"
asciify = require "asciify"
connect = require "connect"
logger = require "winston"
events = require "eventemitter2"
colors = require "colors"
assert = require "assert"
nconf = require "nconf"
https = require "https"
http = require "http"
util = require "util"

{remote} = require "../membrane/remote"

# This class contains the definition of the dynamic recomposition
# system. The reason this class exists is to encapsulate this system
# and make it possible to use it on the remote call site. The system
# is a derivative approach from the mixin. It allows to dynamically
# recombinate the inheritance tree to include any number of compounds.
module.exports.Composition = remote -> class Composition extends Object

    # This method exists as a complementary part of the composition
    # system. The cloner is an implementation of the shader that is
    # mapped over each node of the linear hierarchy of the class that
    # invokes the composition functionality to obtain a shadow of the
    # original class that can be later modified to modify hierarchy.
    cloner = module?.exports?.cloner = (subject) ->
        noClass = "the #{subject} is not a class"
        assert _.isObject(subject?.__super__), noClass
        subject = subject.watermark if subject.watermark
        snapshot = _.cloneDeep subject, d = (value) ->
            return unless _.isFunction value
            func = -> value.apply this, arguments
            func.name = value.name or "<anonymous>"
            _.extend func.prototype, value.prototype
            func.constructor = value.constructor; func
        w = get: -> assert not subject.watermark; subject
        Object.defineProperty snapshot, "watermark", w
        assert snapshot.watermark; return snapshot

    # A unique functionality built around the composition system. It
    # allows for an asynchronous way of calling a stream of methods,
    # each defined in the peer of the inheritance tree. Basically this
    # is a way to asynchronously and dynamically call super methods.
    # Each method must call its last parameter `next` for proceeding.
    Object.defineProperty Object::, "upstreamAsync",
        enumerable: no, value: (method, callback) -> (args...) =>
            applicator = (f) => (a...) => f.apply @, args.concat a
            hierarchy = @constructor.hierarchy()
            hierarchy.unshift @constructor
            resolve = (c) -> c.prototype?[method]
            threads = _.map hierarchy, resolve
            methods = _.filter threads, _.isFunction
            prepped = _.unique methods.reverse()
            applied = _.map prepped, applicator
            async.series applied, callback

    # A method for comparing different classes for equality. Be careful
    # as this method is very loose in terms of comparison and its main
    # purpose is aiding in implementation of the composition mechanism
    # rather than any else. Comparison algorithms is likely to change.
    Object.defineProperty Object::, "similarWith",
        enumerable: no, value: (archetype, loose) ->
            isClass = _.isObject this.prototype
            noClass = "The subject is not a class"
            throw new Error noClass unless isClass
            return yes if this is archetype
            return yes if @watermark is archetype
            return undefined unless loose is yes
            return yes if @name is archetype.name
            return yes if @nick is archetype.nick

    # A method for the dynamic lookup of the super methods. This method
    # exists because CoffeeScript resolves super methods by using static
    # hardcoded class names and __super__ attributes. But in order for
    # composition to work - system needs dynamic super method resolution.
    # Call this method with current class and the method name arguments
    Object.defineProperty Object::, "upstack",
        enumerable: no, value: (exclude, name) ->
            current = this[name] or undefined
            hierarchy = @constructor.hierarchy()
            predicate = (c) -> c.similarWith exclude
            pivotal = _.findIndex hierarchy, predicate
            hierarchy = _.drop hierarchy, pivotal + 1
            exists = (x) -> x.prototype?[name]?
            heading = _.find hierarchy, exists
            value = heading?.prototype?[name]
            return value unless value is current
            @upstack _.head(hierarchy), name

    # A complicated piece of functionality for merging arbitrary classes
    # into the linear hierarchical inheritance chain of existing class.
    # This method integrated the supplied compound class in the tear in
    # between the foreign and common peers in the inheritance chain. Do
    # refer to the implementation for the understanding of what happens.
    Object.defineProperty Object::, "compose",
        enumerable: no, value: (compound, shader=cloner) ->
            assert foreign = compound.hierarchy()
            assert identify = compound.identify()
            cmp = (e) -> (c) -> c.similarWith e
            common = (x) -> _.any foreign, cmp x
            culrpit = (s) -> not _.any commons, cmp s
            notAbstract = "the #{identify} is not abstract"
            orphans = "no common base classes in hierarchy"
            assert compound.abstract?(), notAbstract
            commons = _.filter @hierarchy(), common
            assert not _.isEmpty(commons), orphans
            differentiated = _.take @hierarchy(), culrpit
            alternative = _.map differentiated, shader
            compound.composition? this, @hierarchy(), foreign
            return @rebased compound if _.isEmpty alternative
            tails = alternative.pop().rebased compound
            rebased = (acc, cls) -> cls.rebased acc; cls
            @rebased _.foldr alternative, rebased, tails
            return @refactoring compound

    # An important complementary part of the dynamic recomposition
    # system. The refactoring procedure is a recursive algorithm that
    # is executed after each composition invocation to refactor the
    # inheritance tree. The refactoring in this case is getting rid
    # of the indirectly or directly duplicated peers from the tree.
    Object.defineProperty Object::, "refactoring",
        enumerable: no, value: (trigger) ->
            cmp = (peer) -> peer.watermark or peer
            unique = _.unique h = @hierarchy(), cmp
            return null if unique.length is h.length
            assert outstanding = _.difference h, unique
            target = _.head outstanding; h.unshift this
            assert left = h[_.indexOf(h, target) - 1]
            assert right = h[_.indexOf(h, target) + 1]
            shadow = (not left.watermark) or (left is @)
            assert shadow, "original: #{left.identify()}"
            left.rebased right; @refactoring trigger

    # Scan the supplied class and return an entire inheritance hierarchy
    # of classes. The hierarchy is represented as an array of prototypes
    # that follow in the order they appear in the chain: starting from
    # the supplied class and up to the top. The class has to be a valid
    # CoffeeScript class that posses all the necessary internal members.
    Object.defineProperty Object::, "hierarchy",
        enumerable: no, value: ->
            [chaining, subject] = [new Array, @]
            isClass = _.isObject subject.__super__<commit_msg>Fix logical mistale<commit_after>###
Copyright (c) 2013, <NAME> <<EMAIL>>
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice, this
   list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
   this list of conditions and the following disclaimer in the documentation
   and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
###

_ = require "lodash"
async = require "async"
asciify = require "asciify"
connect = require "connect"
logger = require "winston"
events = require "eventemitter2"
colors = require "colors"
assert = require "assert"
nconf = require "nconf"
https = require "https"
http = require "http"
util = require "util"

{remote} = require "../membrane/remote"

# This class contains the definition of the dynamic recomposition
# system. The reason this class exists is to encapsulate this system
# and make it possible to use it on the remote call site. The system
# is a derivative approach from the mixin. It allows to dynamically
# recombinate the inheritance tree to include any number of compounds.
module.exports.Composition = remote -> class Composition extends Object

    # This method exists as a complementary part of the composition
    # system. The cloner is an implementation of the shader that is
    # mapped over each node of the linear hierarchy of the class that
    # invokes the composition functionality to obtain a shadow of the
    # original class that can be later modified to modify hierarchy.
    cloner = module?.exports?.cloner = (subject) ->
        noClass = "the #{subject} is not a class"
        assert _.isObject(subject?.__super__), noClass
        subject = subject.watermark if subject.watermark
        snapshot = _.cloneDeep subject, d = (value) ->
            return unless _.isFunction value
            func = -> value.apply this, arguments
            func.name = value.name or "<anonymous>"
            _.extend func.prototype, value.prototype
            func.constructor = value.constructor; func
        w = get: -> assert not subject.watermark; subject
        Object.defineProperty snapshot, "watermark", w
        assert snapshot.watermark; return snapshot

    # A unique functionality built around the composition system. It
    # allows for an asynchronous way of calling a stream of methods,
    # each defined in the peer of the inheritance tree. Basically this
    # is a way to asynchronously and dynamically call super methods.
    # Each method must call its last parameter `next` for proceeding.
    Object.defineProperty Object::, "upstreamAsync",
        enumerable: no, value: (method, callback) -> (args...) =>
            applicator = (f) => (a...) => f.apply @, args.concat a
            hierarchy = @constructor.hierarchy()
            hierarchy.unshift @constructor
            resolve = (c) -> c.prototype?[method]
            threads = _.map hierarchy, resolve
            methods = _.filter threads, _.isFunction
            prepped = _.unique methods.reverse()
            applied = _.map prepped, applicator
            async.series applied, callback

    # A method for comparing different classes for equality. Be careful
    # as this method is very loose in terms of comparison and its main
    # purpose is aiding in implementation of the composition mechanism
    # rather than any else. Comparison algorithms is likely to change.
    Object.defineProperty Object::, "similarWith",
        enumerable: no, value: (archetype, loose) ->
            isClass = _.isObject this.prototype
            noClass = "The subject is not a class"
            throw new Error noClass unless isClass
            return yes if this is archetype
            return yes if @watermark is archetype
            return undefined unless loose is yes
            return yes if @name is archetype.name
            return yes if @nick is archetype.nick

    # A method for the dynamic lookup of the super methods. This method
    # exists because CoffeeScript resolves super methods by using static
    # hardcoded class names and __super__ attributes. But in order for
    # composition to work - system needs dynamic super method resolution.
    # Call this method with current class and the method name arguments
    Object.defineProperty Object::, "upstack",
        enumerable: no, value: (exclude, name) ->
            current = this[name] or undefined
            hierarchy = @constructor.hierarchy()
            predicate = (c) -> c.similarWith exclude
            pivotal = _.findIndex hierarchy, predicate
            hierarchy = _.drop hierarchy, pivotal + 1
            exists = (x) -> x.prototype?[name]?
            heading = _.find hierarchy, exists
            value = heading?.prototype?[name]
            return value unless value is current
            @upstack _.head(hierarchy), name

    # A complicated piece of functionality for merging arbitrary classes
    # into the linear hierarchical inheritance chain of existing class.
    # This method integrated the supplied compound class in the tear in
    # between the foreign and common peers in the inheritance chain. Do
    # refer to the implementation for the understanding of what happens.
    Object.defineProperty Object::, "compose",
        enumerable: no, value: (compound, shader=cloner) ->
            assert foreign = compound.hierarchy()
            assert identify = compound.identify()
            cmp = (e) -> (c) -> c.similarWith e
            common = (x) -> _.any foreign, cmp x
            culrpit = (s) -> not _.any commons, cmp s
            notAbstract = "the #{identify} is not abstract"
            orphans = "no common base classes in hierarchy"
            assert compound.abstract?(), notAbstract
            commons = _.filter @hierarchy(), common
            assert not _.isEmpty(commons), orphans
            differentiated = _.take @hierarchy(), culrpit
            alternative = _.map differentiated, shader
            compound.composition? this, @hierarchy(), foreign
            return @rebased compound if _.isEmpty alternative
            tails = alternative.pop().rebased compound
            rebased = (acc, cls) -> cls.rebased acc; cls
            @rebased _.foldr alternative, rebased, tails
            return @refactoring compound

    # An important complementary part of the dynamic recomposition
    # system. The refactoring procedure is a recursive algorithm that
    # is executed after each composition invocation to refactor the
    # inheritance tree. The refactoring in this case is getting rid
    # of the indirectly or directly duplicated peers from the tree.
    Object.defineProperty Object::, "refactoring",
        enumerable: no, value: (trigger) ->
            cmp = (peer) -> peer.watermark or peer
            unique = _.unique h = @hierarchy(), cmp
            return null if unique.length is h.length
            assert outstanding = _.difference h, unique
            target = _.head outstanding; h.unshift this
            assert left = h[_.indexOf(h, target) - 1]
            assert right = h[_.indexOf(h, target) + 1]
            shadow = left.watermark or (left is this)
            assert shadow, "original: #{left.identify()}"
            left.rebased right; @refactoring trigger

    # Scan the supplied class and return an entire inheritance hierarchy
    # of classes. The hierarchy is represented as an array of prototypes
    # that follow in the order they appear in the chain: starting from
    # the supplied class and up to the top. The class has to be a valid
    # CoffeeScript class that posses all the necessary internal members.
    Object.defineProperty Object::, "hierarchy",
        enumerable: no, value: ->
            [chaining, subject] = [new Array, @]
            isClass = _.isObject subject.__super__
{'fraction_non_alphanumeric': 0.06844779357195867, 'fraction_numerical': 0.0011417480162128218, 'mean_word_length': 2.7901341410644744, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 57, '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': '1184901', 'n_tokens_mistral': 4325, 'n_tokens_neox': 4122, 'n_words': 1995}