Task Queue Compacting and Task Ordering

Background
-----
This pull request enables `DynamoScheduler` to perform two important steps in task management -- to *compact the task queue*, and to *reorder tasks in queue*. These two steps are done right before `ISchedulerThread` picks up the next task for processing. Which means many `AsyncTask` can be scheduled before `ISchedulerThread` returns for more task, making queue compacting more effective (i.e. there might be more tasks for compacting when `ISchedulerThread` revitis the queue).

##### Compacting task queue
Compacting task queue means removing redundant tasks on the queue. `AsyncTask.CanMergeWith` method is introduced to allow comparison between two `AsyncTask` objects. The return value from this call helps `DynamoScheduler` determines if either of the tasks should be discarded, or both should be kept. Derived classes override this method to provide type specific decision.

##### Reordering tasks
Take reordering is done right after task queue has been compacted. In this step, the remaining tasks in queue are sorted based on their *priority*. `DynamoScheduler` relies on the return value of `AsyncTask.Compare` method in determining the relative priority of any two given tasks. Derived `AsyncTask` classes override this method to provide type specific prioritization.

Unit test
-----
Two mock `AsyncTask` classes are introduced to ensure these two task management steps do not regress: `PrioritizedAsyncTask` and `InconsequentialAsyncTask`. Please see source code documentation for more details on their roles. Various test cases are written in conjunction with these two new classes to test the new task management functionality. Please see the tests and their documentation for test scenarios.

Notes to reviewer
-----
Hi @lukechurch, thanks for looking. The actual `AsyncTask` derived classes are not overriding `CompareCore` and `CanMergeWithCore` methods yet. So even queue compacting and task ordering are already enabled, they do not have any effect on the way tasks are processed today. Your review comments are addressed.
```start``` will be ```-1``` if the first task is to be discarded, subsequently ```++start``` will restore it to ```0``` again in the next iteration. The statement ```start = start - 1``` is meant to offset the effect of ```++start```, regardless of where the index is on the list, so I can't quite add that here :)