    protected function copyFile($file, $destination = null, $extra = array()) {
        $sample = file_get_contents(dirname(__FILE__).DIRECTORY_SEPARATOR.'templates'.DIRECTORY_SEPARATOR.$file.'.sample');
        $destination = $this->getDestinationDirectory().(is_null($destination) ? $file : $destination);
        if (!file_exists(dirname($destination))) {
            mkdir(dirname($destination), 0770, true);
        }
        $map = array(
        	'{id}' => $this->id,
            '{name}' => self::escape($this->label),
            '{version}' => self::escape($this->version),
            '{author}' => self::escape($this->author),
            '{license}' => self::escape($this->license),
            '{description}' => self::escape($this->description),
            '{authorNs}' => $this->authorNamespace,
            '{dependencies}' => 'array(\''.implode('\',\'', array_keys($this->requires)).'\')',
            '{requires}' => \common_Utils::toHumanReadablePhpString($this->requires, 1),
            '{managementRole}' => GenerisRdf::GENERIS_NS.'#'.$this->id.'Manager',
            '{licenseBlock}' => $this->getLicense(),
            '{installScripts}' => $this->substituteConstantTemplates(\common_Utils::toHumanReadablePhpString($this->installScripts, 1)),
            '{devtools}' => \common_ext_ExtensionsManager::singleton()->getInstalledVersion('taoDevTools')
        );
        $map = array_merge($map, $extra);
        $content = str_replace(array_keys($map), array_values($map), $sample);
        return file_put_contents($destination, $content);
    }