static function run_update_package_xml( $task=null, $args=array(), $cliopts=array() )
    {
        /// @todo replace hostname, build time

        $opts = self::getOpts( @$args[0], @$args[1], $cliopts );
        if ( !SharedLock::acquire( $opts['extension']['name'], LOCK_EX, $opts ) )
            throw new PakeException( "Source code locked by another process" );

        $destdir = $opts['build']['dir'];
        $files = pakeFinder::type( 'file' )->name( 'package.xml' )->maxdepth( 0 );
        if ( count( $files ) == 1 )
        {
            // original format
            pake_replace_regexp( $files, $destdir, array(
                // <name>xxx</name>
                '#^( *\074name\076)(.*)(\074/name\076\r?\n?)$#m' => '${1}' . $opts['extension']['name'] . '_extension' . '$3',
                // <version>xxx</version>
                '#^( *\074version\076)(.*)(\074/version\076\r?\n?)$#m' => '${1}' . $opts['ezp']['version']['major'] . '.' . $opts['ezp']['version']['minor'] . '.' . $opts['ezp']['version']['release'] . '$3',
                // <named-version>xxx</named-version>
                '#^( *\074named-version\076)(.*)(\074/named-version\076\r?\n?)$#m' => '${1}' . $opts['ezp']['version']['major'] . '.' . $opts['ezp']['version']['minor'] . '$3',
                // <package version="zzzz"
                //'#^( *\074package +version=")(.*)("\r?\n?)$#m' => '${1}' . $opts['version']['major'] . '.' . $opts['version']['minor'] . $opts['releasenr']['separator'] . $opts['version']['release'] . '$3',
                // <number>xxxx</number>
                '#^( *\074number\076)(.*)(\074/number\076\r?\n?)$#m' => '${1}' . $opts['version']['alias'] . '$3',
                // <release>yyy</release>
                '#^( *\074release\076)(.*)(\074/release\076\r?\n?)$#m' => '${1}' . $opts['version']['release'] . '$3',

                '#^( *\074timestamp\076)(.*)(\074/timestamp\076\r?\n?)$#m' => '${1}' . time() . '$3',
                '#^( *\074host\076)(.*)(\074/host\076\r?\n?)$#m' => '${1}' . gethostname() . '$3',
                '#^( *\074licence\076)(.*)(\074/licence\076\r?\n?)$#m' => '${1}' . $opts['version']['license'] . '$3',
            ) );
            // replacing a token based on its value instead of its location (text immediately before and after,
            // as done above) has a disadvantage: we cannot execute the substitution many
            // times on the same text, as the 1st substitution will remove the token's
            // value. This means we have to reinit the build to get a 100% updated
            // package file. Unfortunately hunting for xml attributes not based on
            // token values needs a real xml parser, simplistic regexps are not enough...
            pake_replace_tokens( $files, $destdir, '{', '}', array(
                '$name' => $opts['extension']['name'],
                '$version' => $opts['version']['alias'],
                '$ezp_version' => $opts['ezp']['version']['major'] . '.' . $opts['ezp']['version']['minor'] . '.' . $opts['ezp']['version']['release']
            ) );
        }

        SharedLock::release( $opts['extension']['name'], LOCK_EX, $opts );
    }