Catching and reraising exceptions properly

This new method of reraising exceptions should retain the original traceback. So if you have pdb or ipdb on, you will receive the reraised exception with a more informative message, but your traceback will actually be where the original error occurred. It will also append the original exceptions and their messages to the new message by default.

See also https://groups.google.com/forum/#!topic/pylearn-dev/UbWz5tQDH5M
I updated the code. It makes the code a bit messier, but I think this is fairly decent default behaviour.

You can reraise with multiple arguments, and if the original exception had multiple arguments they will all be added to the error message:
```python
try:
    try:
        data = []
        data[3]
    except IndexError:
        reraise_as(ValueError("This is bad", "Very bad"))
except ValueError as e:
    assert e.args[1] == "Very bad"
    reraise_as(ValueError("This is even worse"))
```
```
ValueError: This is even worse

Original exception:
	ValueError: This is bad, Very bad

Original exception:
	IndexError: list index out of range
```
If you want to maintain the arguments you can just pass them on:
```python
try:
    try:
        raise ValueError("A", "B")
    except ValueError as e:
        reraise_as(TypeError("C", *e.args))
except TypeError:
    reraise_as(ValueError("D"))
```
```
ValueError: D

Original exception:
	TypeError: C, A, B

Original exception:
	ValueError: A, B
```