jQuery.fn.objectiveCMethodHighlight = function(){    
    //setup "private" functions
    function textEntered(e,oDisplay){    
        var src = e.srcElement;
        if(!src){src=e.originalTarget;}    
        var aInfo       = splitOffReturnType(src.value+' ');
        var sReturnType = aInfo[0];
        var sSelectors  = aInfo[1];        
        var aSelectorParts = splitOffMethodParts(sSelectors);        
        $(oDisplay).html((buildSignatureHTML(sReturnType,aSelectorParts)));
        //$('#'+sMethodDisplayID).html( buildSignatureHTML(sReturnType,aSelectorParts) );
    };

    function buildForm(){
        var sHTML = '';
        sHTML += '<form class="formAction">';
        sHTML += '<input type="button" value="Highlight Method Name Parts" class="selectorName" />';        
        sHTML += '<input type="button" value="Highlight Parameter Type Declarations"  class="selectorType" />';        
        sHTML += '<input type="button" value="Highlight Parameter Names" class="selectorVariableName" />';        
        sHTML += '<input type="button" value="Revert"  class="revert"/>';
        sHTML += '</form>';        
        return sHTML;
    };
    
    function buildSignatureHTML(sReturnType,aSelectorParts){
        var sHTML = '<span class"returnType">'+sReturnType+'</span> ';
        $.each(aSelectorParts,function(){
            sHTML += '<span class="selectorName">'+this.selector+'</span> ';
            sHTML += ':';
            sHTML += '<span class="selectorType">('+this.paramType+')</span> ';            
            sHTML += '<span class="selectorVariableName">'+this.param+'</span> ';
        });
        sHTML = '<div class="objectiveCMethod">'+sHTML+'</div>';        
        return sHTML;
    };
    
    function splitOffMethodParts(s){
        var re = /\s*?(?:([a-z0-9_]+?)\s*?:\s*?\((.+?)\)\s*(.+?))\W/ig;
        var aInfo = re.exec(s);
        var aReturn = [];
        var oParts  = {};
        while(aInfo){
            oParts = {};
            oParts['selector']  = aInfo[1];
            oParts['paramType'] = aInfo[2];
            oParts['param']     = aInfo[3];
            aReturn.push(oParts);
            aInfo = re.exec(s);
        }
        return aReturn;
    };    
    
    function splitOffReturnType(s){
        var re = /^\s*-\s*?\(.+?\)/;
        var m = re.exec(s);
        if(m){
            var sRemaining = s.replace(m[0],'');
            return [m[0],sRemaining];
        }
        else{
            return '';
        }
        
    };
    
    function revertColors(oDisplay){
        var aColors = ['#ddd'];
        var i = -1;    
        var colorCycle = function(){
            i++;
            if(i == aColors.length){
                i=0;
            }    
            return aColors[i];
        };            
        var i = -1;
        $('.objectiveCMethod .selectorName',oDisplay).css('backgroundColor',colorCycle);
        var i = -1;
        $('.objectiveCMethod .selectorType',oDisplay).css('backgroundColor',colorCycle);
        var i = -1;
        $('.objectiveCMethod .selectorVariableName',oDisplay).css('backgroundColor',colorCycle);    
    };    

    //create strings for clearer code
    //only act on a single text area elemeent
    var sMethodDisplayID; //give private functin access
    return this.each(function(){
        var sNamespace      = this.id;        
        //var sTextareaID   = sNamespace+'entrySelector';
        sMethodDisplayID    = sNamespace+'ObjectiveCMethodDisplay';
    
        var oForm    = $(buildForm()).insertAfter(this);
        var oDisplay = $('<div></div>').insertAfter(this);
        
        //hookup event handlers
        $(this).bind('keyup',function(e){
            textEntered(e,oDisplay);
        });    
        $(oForm).bind('click', function(e){        
            revertColors(oDisplay);
            //e.originalTarget
            var src = e.srcElement;
            if(!src){src=e.originalTarget;}
            if(src.className != 'revert' && src.type == 'button'){
                var sSelector = '.'+src.className;
                $(sSelector,oDisplay).css('background-color','#ff0');                
            }
        });
    });            
}
