PreCommit trigger support + a fix.

* Shield.PreCommit can be used to define a pre-commit trigger. It is very
similar to Shield.Conditional, except it runs within a transaction that changes
one of the fields it depends on, and it runs just before it commits. This
allows for implementing invariant checks, and for easily implementing
a priority scheme (define a PreCommit which kills all lower-priority
thread's transactions...).
* A very subtle bug was revealed by the above introduction. Since IShielded
implementors do not call Enlist() if they have local data, then they might not
enlist themselves while in WithTransactionContext() calls. This is now corrected,
they will pass their local data status to Shield.Enlist, and it will use it if not
within WithTransactionContext. Otherwise, it will always access the tracking
HashSet, to make sure they enlist.
* Shield.Conditional's second param, the body to run when test passes, is now
an ordinary Action. It can still achieve one time running by "manually" calling
Dispose on it's own subscription. It could do this before as well, and it would
have caused an error, it was not expected by the system that you might do that.