Fix bugs in fields handling, and make it consistent.

The existing handling of fields is inconsistent in the three places it 
appears: `EdgeIterator`, `AbstractCrudObject.get_by_ids` and
`AbstractCrudObject.remote_read`. The result varies between a string, a list,
None, or omitted from params.

This commit ensures that:

  1. In all cases, `params['fields']` will contain either a non-empty
    string, or will be omitted entirely.

  2. If fields is passed to a function, even an empty list, it will be
    respected rather than falling back to `get_default_read_fields`. This
    is accomplished by testing for `is None` rather than just a falsy
    value.

Additionally this uses a more common Python idiom for duplicating a dict, 
using `dict(orig)` rather than `orig.copy()`.
Nice. I was going to say we have a couple weird quirks where passing `fields=[]` can break the API, but this would appropriately account for that.