public function merge($to)
    {
        if (is_array($to)) {
            $to = Url::createFromArray($to);
        }
        else if (is_string($to)) {
            $to = self::createFromString($to);
        }
        else if (($to instanceof Url) === false) {
            throw new \InvalidArgumentException(
                "invalid value provided for 'to'; expecting a url as string, ".
                "an instance of sndsgd\\Url, or an array of url properties"
            );
        }

        $toValues = $to->__toArray();

        # the query property will be an empty array if it has no value
        if (count($this->query) === 0 && $toValues['query']) {
            $this->setQuery($toValues['query']);
        }

        $keys = ['scheme','user','pass','host','port','path','fragment'];
        foreach ($keys as $key) {
            if ($this->$key === null && $toValues[$key] !== null) {
                call_user_func([$this, 'set'.ucfirst($key)], $toValues[$key]);
            }
        }

        return $this;
    }