private OnlineMapsGoogleDirections(Params p)
    {
        _status = OnlineMapsQueryStatus.downloading;

        StringBuilder url = new StringBuilder();

        url.Append("https://maps.googleapis.com/maps/api/directions/xml?sensor=false");
        url.Append("&origin=");

        if (p.origin is string)
        {
            url.Append(OnlineMapsWWW.EscapeURL(p.origin as string));
        }
        else if (p.origin is Vector2)
        {
            Vector2 o = (Vector2)p.origin;
            url.Append(o.y).Append(",").Append(o.x);
        }
        else
        {
            throw new Exception("Origin must be string or Vector2.");
        }

        url.Append("&destination=");

        if (p.destination is string)
        {
            url.Append(OnlineMapsWWW.EscapeURL(p.destination as string));
        }
        else if (p.destination is Vector2)
        {
            Vector2 d = (Vector2)p.destination;
            url.Append(d.y).Append(",").Append(d.x);
        }
        else
        {
            throw new Exception("Destination must be string or Vector2.");
        }

        if (p.mode.HasValue && p.mode.Value != Mode.driving)
        {
            url.Append("&mode=").Append(Enum.GetName(typeof(Mode), p.mode.Value));
        }
        if (p.waypoints != null)
        {
            StringBuilder waypointStr    = new StringBuilder();
            bool          isFirst        = true;
            int           countWaypoints = 0;
            foreach (object w in p.waypoints)
            {
                if (countWaypoints >= 8)
                {
                    Debug.LogWarning("The maximum number of waypoints is 8.");
                    break;
                }

                if (!isFirst)
                {
                    waypointStr = waypointStr.Append("|");
                }

                if (w is string)
                {
                    waypointStr.Append(OnlineMapsWWW.EscapeURL(w as string));
                }
                else if (w is Vector2)
                {
                    Vector2 v = (Vector2)w;
                    waypointStr.Append(v.y).Append(",").Append(v.x);
                }
                else
                {
                    throw new Exception("Waypoints must be string or Vector2.");
                }

                countWaypoints++;

                isFirst = false;
            }

            if (countWaypoints > 0)
            {
                url.Append("&waypoints=optimize:true|").Append(waypointStr);
            }
        }
        if (p.alternatives)
        {
            url.Append("&alternatives=true");
        }
        if (p.avoid.HasValue && p.avoid.Value != Avoid.none)
        {
            url.Append("&avoid=").Append(Enum.GetName(typeof(Avoid), p.avoid.Value));
        }
        if (p.units.HasValue && p.units.Value != Units.metric)
        {
            url.Append("&units=").Append(Enum.GetName(typeof(Units), p.units.Value));
        }
        if (!string.IsNullOrEmpty(p.region))
        {
            url.Append("&region=").Append(p.region);
        }
        if (p.departure_time != null)
        {
            url.Append("&departure_time=").Append(p.departure_time);
        }
        if (p.arrival_time.HasValue && p.arrival_time.Value > 0)
        {
            url.Append("&arrival_time=").Append(p.arrival_time.Value);
        }
        if (!string.IsNullOrEmpty(p.language))
        {
            url.Append("&language=").Append(p.language);
        }
        if (!string.IsNullOrEmpty(p.key))
        {
            url.Append("&key=").Append(p.key);
        }
        if (p.traffic_model.HasValue && p.traffic_model.Value != TrafficModel.bestGuess)
        {
            url.Append("&traffic_model=").Append(Enum.GetName(typeof(TrafficModel), p.traffic_model.Value));
        }
        if (p.transit_mode.HasValue)
        {
            OnlineMapsUtils.GetValuesFromEnum(url, "transit_mode", typeof(TransitMode), (int)p.transit_mode.Value);
        }
        if (p.transit_routing_preference.HasValue)
        {
            url.Append("&transit_routing_preference=").Append(Enum.GetName(typeof(TransitRoutingPreference), p.transit_routing_preference.Value));
        }

        www             = OnlineMapsUtils.GetWWW(url);
        www.OnComplete += OnRequestComplete;
    }