public function validate_target_location() {

        if (!isset($this->assertions['plugintype'])) {
            throw new coding_exception('Required plugin type must be set before calling this');
        }

        $plugintypepath = $this->get_plugintype_location($this->assertions['plugintype']);

        if (is_null($plugintypepath)) {
            $this->add_message(self::ERROR, 'unknowntype', $this->assertions['plugintype']);
            return false;
        }

        if (!is_dir($plugintypepath)) {
            throw new coding_exception('Plugin type location does not exist!');
        }

        // Always check that the plugintype root is writable.
        if (!is_writable($plugintypepath)) {
            $this->add_message(self::ERROR, 'pathwritable', $plugintypepath);
            return false;
        } else {
            $this->add_message(self::INFO, 'pathwritable', $plugintypepath);
        }

        // The target location itself may or may not exist. Even if installing an
        // available update, the code could have been removed by accident (and
        // be reported as missing) etc. So we just make sure that the code
        // can be replaced if it already exists.
        $target = $plugintypepath.'/'.$this->rootdir;
        if (file_exists($target)) {
            if (!is_dir($target)) {
                $this->add_message(self::ERROR, 'targetnotdir', $target);
                return false;
            }
            $this->add_message(self::WARNING, 'targetexists', $target);
            if ($this->get_plugin_manager()->is_directory_removable($target)) {
                $this->add_message(self::INFO, 'pathwritable', $target);
            } else {
                $this->add_message(self::ERROR, 'pathwritable', $target);
                return false;
            }
        }

        return true;
    }