ml.read() loads node/edge data, loads booleans, negative ints, enquoted ints (for big vals), and escapes xml entities

the read() and write() functions for gml files now do what we discussed.  There is a *slight* deviation however, because I think this is what you actually want, but if not it's easy to revert:

Recall that read() looks for node attributes named 'id',  and 'name', and handles these specially (puts them in node_idx and node_obj).  For edges, it looks for 'id', 'weight', 'source', and 'target', and of course these have their special places in the Graph object too.

Now any other attributes that appear aside from those mentioned are packaged into a dictionary which gets aside to the node/edge_data.  This is different from what we discussed, wherein *all* attributes would get packed except for 'weight' in the case of edges... but this would mean that a read / write operation would not leave the gml unchanged.  The way I've done it, it would.  This only applies when zenData is not being used, and the other conditional behaviours we discussed are as discussed.

I can show you what I mean on a whiteboard some time if you want.