I collapsed several wallet mutexes into two: one for the keystore, and one for the wallet. That fixes many potential deadlocks due to wallet code acquiring the various locks in different orders.
And I fixed several other potential deadlocks by requiring that code that needs both the cs_main and cs_wallet mutexes acquire them in that order.
One somewhat scary semantic change: Transaction times reported by in the rpc interface and in the GUI are now always the time the transaction was received by this node (and not the average-time-of-the-last-n-blocks-that-the-transaction-ended-up-in).
Having transaction times change as they were confirmed was a mistake, in my humble opinion, but the main reason I changed this behavior was so that CWallet::GetTxTime() doesn't require the cs_main lock.
I'd like to further compartmentalize locking, but that's a task for another day...