function FindIn (Obj, SearchTerms, OnFound, DepthMax, ClientCallPoint)
{
function ThrowException (Str)
{
throw new Error ("Error in call to FindIn - "
+ Str
+ " Client-code call point: "
+ ClientCallPoint);
}
if (!Obj) { ThrowException ("Obj argument is null or undefined."); }
if (!SearchTerms) { SearchTerms = "."; }
else if ( typeof SearchTerms !== "string") { ThrowException ("SearchTerms argument is not a string."); }
if (!OnFound) { OnFound = function () { return true; }; }
else if ( typeof OnFound !== "function") { ThrowException ("OnFound argument is not a reference to a function."); }
if ( DepthMax === null
|| DepthMax === undefined) { DepthMax = Infinity; }
else
{
if ( typeof DepthMax !== "number") { ThrowException ("DepthMax argument is non-numeric."); }
if ( DepthMax < 0) { ThrowException ("DepthMax argument is less than zero."); }
}
function FindIn_ (Obj, Depth, InvDepth)
{
for (var Mem in Obj)
{
if (SearchExpr.test (Mem))
{
if (OnFound (Obj, Mem, SearchTerms, InvDepth, ClientCallPoint)) { TotalFound++; }
else { return false; }
}
if (Depth > 0)
{
try // Try block is necessary because IE throws an exception
{ // on propertyIsEnumerable calls to some built-in objects.
if (typeof Obj[Mem] === "string" // Test for 'string' is necessary because of an oddity in
|| (!Obj.propertyIsEnumerable (Mem))) { continue; } // string implementation.
}
catch (E) { continue; }
if (FindIn_ (Obj[Mem], Depth - 1, InvDepth + 1)) { continue; }
else { return false; }
}
}
return true;
}
var TotalFound = 0;
var SearchExpr = new RegExp (SearchTerms);
FindIn_ (Obj, DepthMax, 0);
return TotalFound;
}