Parse a GPX file into a GpxModel.

    Args:
        xml: A file-like-object opened in binary mode - that is containing
             bytes rather than characters. The root element of the XML should
             be a <gpx> element containing a version attribute. GPX versions
             1.0 is supported.

    Returns:
        A GpxModel representing the data from the supplies xml.

    Raises:
        ValueError: The supplied XML could not be parsed as GPX.

def parse_gpx(gpx_element, gpxns=None):
    """Parse a GPX file into a GpxModel.

    Args:
        xml: A file-like-object opened in binary mode - that is containing
             bytes rather than characters. The root element of the XML should
             be a <gpx> element containing a version attribute. GPX versions
             1.0 is supported.

    Returns:
        A GpxModel representing the data from the supplies xml.

    Raises:
        ValueError: The supplied XML could not be parsed as GPX.
    """
    gpxns = gpxns if gpxns is not None else determine_gpx_namespace(gpx_element)

    if gpx_element.tag != gpxns+'gpx':
        raise ValueError("No gpx root element")

    get_text = lambda tag: optional_text(gpx_element, gpxns+tag)

    version = gpx_element.attrib['version']

    if not version.startswith('1.0'):
        raise ValueError("Not a GPX 1.0 file")

    creator = gpx_element.attrib['creator']

    name = get_text('name')
    description = get_text('desc')

    author_name = get_text('author')
    email = get_text('email')
    author = Person(author_name, email)

    url = get_text('url')
    urlname = get_text('urlname')
    links = make_links(url, urlname)

    time = get_text('time')
    keywords = get_text('keywords')

    bounds_element = gpx_element.find(gpxns+'bounds')
    bounds = nullable(parse_bounds)(bounds_element)

    metadata = Metadata(name=name, description=description, author=author,
               links=links, time=time, keywords=keywords, bounds=bounds)

    waypoint_elements = gpx_element.findall(gpxns+'wpt')
    waypoints = [parse_waypoint(waypoint_element, gpxns) for waypoint_element in waypoint_elements]

    route_elements = gpx_element.findall(gpxns+'rte')
    routes = [parse_route(route_element, gpxns) for route_element in route_elements]

    track_elements = gpx_element.findall(gpxns+'trk')
    tracks = [parse_track(track_element, gpxns) for track_element in track_elements]

    # TODO : Private elements

    gpx_model  = GpxModel(creator, metadata, waypoints, routes, tracks)

    return gpx_model