lib/JQL.js
function find(prefix, suffix)
    {
        if(valStack.length > 0)
        {
            var currentVal = valStack[valStack.length - 1];

            if(prefix.length > 0)
            {
                // Manipulate prefix and suffix
                var currentField = prefix.shift();
                suffix.push(currentField);

                if(currentVal.hasOwnProperty(currentField))
                {
                    if(prefix.length > 0)
                    {
                        valStack.push(currentVal[currentField]);
                        find(prefix, suffix);
                        valStack.pop();
                    }
                    else
                    {
                        //finalResults.push(currentVal[currentField]);
                        store(suffix, currentVal[currentField]);
                    }
                }
                else if(currentField == "$")
                {
                    find(prefix, suffix);
                }
                else if(currentField == "*")
                {
                    findInEachChild(prefix, suffix);
                }
                else if(currentField == "^")
                {
                    findInParent(prefix, suffix);
                }
                else if(currentField == "~")
                {
                    findInAllDescendants(prefix, suffix);
                }
                else if(currentField.indexOf(",") >= 0)
                {
                    findMultiple(prefix, suffix);
                }
                else if(currentField.substr(0, 1) == "?")
                {
                    findByCondition(currentField.replace(/^\?\((.*?)\)$/,"$1"), prefix, suffix);
                }
                else
                {
                    // alert("Property not found");
                    // NOOP
                }

                // Restore prefix and suffix
                prefix.unshift(suffix.pop());
            }
            else
            {
                // alert("prefix is empty!");
                //finalResults.push(currentVal);
                store(suffix, currentVal);
            }
        }
        else
        {
            // alert("valStack is empty!");
            // NOOP
        }
    }
function find(prefix, suffix)
    {
        if(valStack.length > 0)
        {
            var currentVal = valStack[valStack.length - 1];

            if(prefix.length > 0)
            {
                // Manipulate prefix and suffix
                var currentField = prefix.shift();
                suffix.push(currentField);

                if(currentVal.hasOwnProperty(currentField))
                {
                    if(prefix.length > 0)
                    {
                        valStack.push(currentVal[currentField]);
                        find(prefix, suffix);
                        valStack.pop();
                    }
                    else
                    {
                        //finalResults.push(currentVal[currentField]);
                        store(suffix, currentVal[currentField]);
                    }
                }
                else if(currentField == "$")
                {
                    find(prefix, suffix);
                }
                else if(currentField == "*")
                {
                    findInEachChild(prefix, suffix);
                }
                else if(currentField == "^")
                {
                    findInParent(prefix, suffix);
                }
                else if(currentField == "~")
                {
                    findInAllDescendants(prefix, suffix);
                }
                else if(currentField.indexOf(",") >= 0)
                {
                    findMultiple(prefix, suffix);
                }
                else if(currentField.substr(0, 1) == "?")
                {
                    findByCondition(currentField.replace(/^\?\((.*?)\)$/,"$1"), prefix, suffix);
                }
                else
                {
                    // alert("Property not found");
                    // NOOP
                }

                // Restore prefix and suffix
                prefix.unshift(suffix.pop());
            }
            else
            {
                // alert("prefix is empty!");
                //finalResults.push(currentVal);
                store(suffix, currentVal);
            }
        }
        else
        {
            // alert("valStack is empty!");
            // NOOP
        }
    }
function find ( prefix , suffix ) { if ( valStack . length > 0 ) { var currentVal = valStack [ valStack . length - 1 ] ; if ( prefix . length > 0 ) { // Manipulate prefix and suffix var currentField = prefix . shift ( ) ; suffix . push ( currentField ) ; if ( currentVal . hasOwnProperty ( currentField ) ) { if ( prefix . length > 0 ) { valStack . push ( currentVal [ currentField ] ) ; find ( prefix , suffix ) ; valStack . pop ( ) ; } else { //finalResults.push(currentVal[currentField]); store ( suffix , currentVal [ currentField ] ) ; } } else if ( currentField == "$" ) { find ( prefix , suffix ) ; } else if ( currentField == "*" ) { findInEachChild ( prefix , suffix ) ; } else if ( currentField == "^" ) { findInParent ( prefix , suffix ) ; } else if ( currentField == "~" ) { findInAllDescendants ( prefix , suffix ) ; } else if ( currentField . indexOf ( "," ) >= 0 ) { findMultiple ( prefix , suffix ) ; } else if ( currentField . substr ( 0 , 1 ) == "?" ) { findByCondition ( currentField . replace ( / ^\?\((.*?)\)$ / , "$1" ) , prefix , suffix ) ; } else { // alert("Property not found"); // NOOP } // Restore prefix and suffix prefix . unshift ( suffix . pop ( ) ) ; } else { // alert("prefix is empty!"); //finalResults.push(currentVal); store ( suffix , currentVal ) ; } } else { // alert("valStack is empty!"); // NOOP } }
This is the foundation of all searching in JQL; it chooses specific search types based upon the current part of the JQL string

@private
@param {Array} prefix - Initial part of path
@param {Array} suffix - Final part of path
This is the foundation of all searching in JQL ; it chooses specific search types based upon the current part of the JQL string