/**
 * Use this object for finding elements and then invoking an object on them
 */
function Finder(el){
    if(!el) return;

    //setup the base attributes
    var isNode = el.nodeName != null;

    this.owner = isNode ? el : el.owner;

    if(this.replaceOwner)
        this.replaceOwner(this.owner);

    var _this = this;
    for(var x in this.attributes){
        _this[x] = isNode ? el.getAttribute(x) : el[x];

        if(_this[x] == null && _this.attributes[x]["default"] !== undefined)
            _this[x] = _this.attributes[x]["default"];
    }

}

Finder.prototype.xpath = null;
Finder.prototype.baseattr = null;
Finder.prototype.instances = {};


Finder.prototype.detect = function (invoker){

    if(this.baseattr){ 
        var items = getNodesWithAttr(document.body, this.baseattr);//xpathQuery(document, this.xpath);
        for(var x = 0; x < items.length; x++){
            //check that the element hasn't been added to the instances
            var doPush = true;

            if(doPush) {
                if(!items[x][invoker]) {
                    var inv;
                    eval ("inv = " + invoker + ";");
                    eval("items[x]['" + invoker + "'] = true");
                    eval("items[x]['" + invoker + "'] = new " + invoker + "(items[x]);");

                    inv.prototype.instances[items[x].id] = items[x][invoker];
                }
            }
        }
    }
}

Finder.prototype.invoke = function(invoker, delay, condition, doc){
    var doInvoke = true;
    var invokeProp;
    try {
        eval("invokeProp = " + invoker + "Invoke;");
        doInvoke = invokeProp === undefined || invokeProp === null ? true : false;
    } catch (e){}
    if(doInvoke !== false) {
        var _this = this;
        var callback = function(){var invk = invoker; 
                                  addEventListener(document.body, "htmlchange", function(e){
                                      if(evtSrc(e) != invk )
                                          _this.detect(invk);
                                  });
                                  createEvent(document.body, "htmlchange");
                                 }
        waitUntil(callback, delay ? delay : 100, condition ?  condition : function(){return document.body;});
    }
};

