Support for adding to an associative array's domain via the array itself

This code allows for one to implicitly add to an associative array's domain via that array. This makes associative arrays a little more pleasant to work with.

Before:

myDom += newKey;
myArr[newKey] = foo;

After:

myArr[newKey] = foo; // newKey added to backing domain if not present.

An important restriction is that the array and domain must share a 1:1 relationship. More simply, the domain must be backing only one array. The motivation for this restriction is that it may be surprising that other arrays' index sets are modified when it appears that we are only modifying one array. If this restriction is violated, the program will halt.

An 'out of bounds' halt will still occur if attempting to read from a bad index:

Before and after:

writeln(myArr[badKey]); // if 'badKey' is not in myArr's index set, the usual error will be encountered.
dsiAccess() is racy.  In the previous version I set haveLock=true even though we didn't actually have it, because we weren't going to modify the table (simultaneous access and assignment were not guaranteed to be thread-safe).  But, even if you pass in haveLock=false, it is still racy, because the same slotNum can be returned to two or more simultaneous calls to dsiAccess().  You need to grab the lock in dsiAccess() and not let it go until after you add to the domain below (line: 474 if setter and slotNum != -1) or immediately for the 2 other cases.