auto import from //depot/cupcake/@135843
diff --git a/WebKitTools/Scripts/SpacingHeuristics.pm b/WebKitTools/Scripts/SpacingHeuristics.pm
new file mode 100644
index 0000000..7de0172
--- /dev/null
+++ b/WebKitTools/Scripts/SpacingHeuristics.pm
@@ -0,0 +1,101 @@
+#!/usr/bin/perl -w
+
+# Copyright (C) 2006 Apple Computer, Inc.  All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1.  Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer. 
+# 2.  Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution. 
+# 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+#     its contributors may be used to endorse or promote products derived
+#     from this software without specific prior written permission. 
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+# Used for helping remove extra blank lines from files when processing.
+# see split-class for an example usage (or other scripts in bugzilla)
+
+BEGIN {
+   use Exporter   ();
+   our ($VERSION, @ISA, @EXPORT, @EXPORT_OK, %EXPORT_TAGS);
+   $VERSION     = 1.00;
+   @ISA         = qw(Exporter);
+   @EXPORT      = qw(&resetSpacingHeuristics &isOnlyWhiteSpace &applySpacingHeuristicsAndPrint &setPreviousAllowedLine &setPreviousAllowedLine &printPendingEmptyLines &ignoringLine);
+   %EXPORT_TAGS = ();
+   @EXPORT_OK   = ();
+}
+
+our @EXPORT_OK;
+
+my $justFoundEmptyLine = 0;
+my $previousLineWasDisallowed = 0;
+my $previousAllowedLine = "";
+my $pendingEmptyLines = "";
+
+sub resetSpacingHeuristics
+{
+    $justFoundEmptyLine = 0;
+    $previousLineWasDisallowed = 0;
+    $previousAllowedLine = "";
+    $pendingEmptyLines = "";
+}
+
+sub isOnlyWhiteSpace
+{
+    my $line = shift;
+    my $isOnlyWhiteSpace = ($line =~ m/^\s+$/);
+    $pendingEmptyLines .= $line if ($isOnlyWhiteSpace);
+    return $isOnlyWhiteSpace;
+}
+
+sub applySpacingHeuristicsAndPrint
+{
+    my ($out, $line) = @_;
+    
+    printPendingEmptyLines($out, $line);
+    $previousLineWasDisallowed = 0;
+    print $out $line;
+}
+
+sub setPreviousAllowedLine
+{
+    my $line = shift;
+    $previousAllowedLine = $line;
+}
+
+sub printPendingEmptyLines
+{
+    my $out = shift;
+    my $line = shift;
+    if ($previousLineWasDisallowed) {
+        if (!($pendingEmptyLines eq "") && !($previousAllowedLine =~ m/{\s*$/) && !($line =~ m/^\s*}/)) {
+            $pendingEmptyLines = "\n";
+        } else {
+            $pendingEmptyLines = "";
+        }
+    }
+    print $out $pendingEmptyLines;
+    $pendingEmptyLines = "";
+}
+
+sub ignoringLine
+{
+    # my $line = shift; # ignoring input argument
+    $previousLineWasDisallowed = 1;
+}
+
+1;
\ No newline at end of file
diff --git a/WebKitTools/Scripts/VCSUtils.pm b/WebKitTools/Scripts/VCSUtils.pm
new file mode 100644
index 0000000..e09d331
--- /dev/null
+++ b/WebKitTools/Scripts/VCSUtils.pm
@@ -0,0 +1,119 @@
+# Copyright (C) 2007 Apple Inc.  All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1.  Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer. 
+# 2.  Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution. 
+# 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+#     its contributors may be used to endorse or promote products derived
+#     from this software without specific prior written permission. 
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+# Module to share code to work with various version control systems.
+
+use strict;
+use warnings;
+use File::Spec;
+use webkitdirs;
+
+BEGIN {
+   use Exporter   ();
+   our ($VERSION, @ISA, @EXPORT, @EXPORT_OK, %EXPORT_TAGS);
+   $VERSION     = 1.00;
+   @ISA         = qw(Exporter);
+   @EXPORT      = qw(&isGitDirectory &isGit &isSVNDirectory &isSVN &makeFilePathRelative);
+   %EXPORT_TAGS = ( );
+   @EXPORT_OK   = ();
+}
+
+our @EXPORT_OK;
+
+my $isGit;
+my $isSVN;
+my $gitBranch;
+my $isGitBranchBuild;
+
+sub isGitDirectory($)
+{
+    my ($dir) = @_;
+    return system("cd $dir && git rev-parse > /dev/null 2>&1") == 0;
+}
+
+sub isGit()
+{
+    return $isGit if defined $isGit;
+
+    $isGit = isGitDirectory(".");
+    return $isGit;
+}
+
+sub gitBranch()
+{
+    unless (defined $gitBranch) {
+        chomp($gitBranch = `git symbolic-ref -q HEAD`);
+        $gitBranch = "" if exitStatus($?);
+        $gitBranch =~ s#^refs/heads/##;
+        $gitBranch = "" if $gitBranch eq "master";
+    }
+
+    return $gitBranch;
+}
+
+sub isGitBranchBuild()
+{
+    my $branch = gitBranch();
+    chomp(my $override = `git config --bool branch.$branch.webKitBranchBuild`);
+    return 1 if $override eq "true";
+    return 0 if $override eq "false";
+
+    unless (defined $isGitBranchBuild) {
+        chomp(my $gitBranchBuild = `git config --bool core.webKitBranchBuild`);
+        $isGitBranchBuild = $gitBranchBuild eq "true";
+    }
+
+    return $isGitBranchBuild;
+}
+
+sub isSVNDirectory($)
+{
+    my ($dir) = @_;
+
+    return -d File::Spec->catdir($dir, ".svn");
+}
+
+sub isSVN()
+{
+    return $isSVN if defined $isSVN;
+
+    $isSVN = isSVNDirectory(".");
+    return $isSVN;
+}
+
+my $gitRoot;
+sub makeFilePathRelative($)
+{
+    my ($path) = @_;
+    return $path unless isGit();
+
+    unless (defined $gitRoot) {
+        chomp($gitRoot = `git rev-parse --show-cdup`);
+    }
+    return $gitRoot . $path;
+}
+
+1;
diff --git a/WebKitTools/Scripts/bisect-builds b/WebKitTools/Scripts/bisect-builds
new file mode 100755
index 0000000..f77f81f
--- /dev/null
+++ b/WebKitTools/Scripts/bisect-builds
@@ -0,0 +1,420 @@
+#!/usr/bin/perl -w
+
+# Copyright (C) 2007 Apple Inc.  All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1.  Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer. 
+# 2.  Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution. 
+# 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+#     its contributors may be used to endorse or promote products derived
+#     from this software without specific prior written permission. 
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+# This script attempts to find the point at which a regression (or progression)
+# of behavior occurred by searching WebKit nightly builds.
+
+# To override the location where the nightly builds are downloaded or the path
+# to the Safari web browser, create a ~/.bisect-buildsrc file with one or more of
+# the following lines (use "~/" to specify a path from your home directory):
+#
+# $branch = "branch-name";
+# $nightlyDownloadDirectory = "~/path/to/nightly/downloads";
+# $safariPath = "/path/to/Safari.app";
+
+use strict;
+
+use File::Basename;
+use File::Path;
+use File::Spec;
+use File::Temp qw(tempfile);
+use Getopt::Long;
+use Time::HiRes qw(usleep);
+
+sub createTempFile($);
+sub downloadNightly($$$);
+sub findMacOSXVersion();
+sub findNearestNightlyIndex(\@$$);
+sub findSafariVersion($);
+sub loadSettings();
+sub makeNightlyList($$$$);
+sub mountAndRunNightly($$$$);
+sub parseRevisions($$;$);
+sub printStatus($$$);
+sub promptForTest($);
+
+loadSettings();
+
+my %validBranches = map { $_ => 1 } qw(feature-branch trunk);
+my $branch = $Settings::branch;
+my $nightlyDownloadDirectory = $Settings::nightlyDownloadDirectory;
+my $safariPath = $Settings::safariPath;
+
+my @nightlies;
+
+my $isProgression;
+my $localOnly;
+my @revisions;
+my $sanityCheck;
+my $showHelp;
+my $testURL;
+
+# Fix up -r switches in @ARGV
+@ARGV = map { /^(-r)(.+)$/ ? ($1, $2) : $_ } @ARGV;
+
+my $result = GetOptions(
+    "b|branch=s"             => \$branch,
+    "d|download-directory=s" => \$nightlyDownloadDirectory,
+    "h|help"                 => \$showHelp,
+    "l|local!"               => \$localOnly,
+    "p|progression!"         => \$isProgression,
+    "r|revisions=s"          => \&parseRevisions,
+    "safari-path=s"          => \$safariPath,
+    "s|sanity-check!"        => \$sanityCheck,
+);
+$testURL = shift @ARGV;
+
+$branch = "feature-branch" if $branch eq "feature";
+if (!exists $validBranches{$branch}) {
+    print STDERR "ERROR: Invalid branch '$branch'\n";
+    $showHelp = 1;
+}
+
+if (!$result || $showHelp || scalar(@ARGV) > 0) {
+    print STDERR "Search WebKit nightly builds for changes in behavior.\n";
+    print STDERR "Usage: " . basename($0) . " [options] [url]\n";
+    print STDERR <<END;
+  [-b|--branch name]             name of the nightly build branch (default: trunk)
+  [-d|--download-directory dir]  nightly build download directory (default: ~/Library/Caches/WebKit-Nightlies)
+  [-h|--help]                    show this help message
+  [-l|--local]                   only use local (already downloaded) nightlies
+  [-p|--progression]             searching for a progression, not a regression
+  [-r|--revision M[:N]]          specify starting (and optional ending) revisions to search
+  [--safari-path path]           path to Safari application bundle (default: /Applications/Safari.app)
+  [-s|--sanity-check]            verify both starting and ending revisions before bisecting
+END
+    exit 1;
+}
+
+my $nightlyWebSite = "http://nightly.webkit.org";
+my $nightlyBuildsURLBase = $nightlyWebSite . File::Spec->catdir("/builds", $branch, "mac");
+my $nightlyFilesURLBase = $nightlyWebSite . File::Spec->catdir("/files", $branch, "mac");
+
+$nightlyDownloadDirectory = glob($nightlyDownloadDirectory) if $nightlyDownloadDirectory =~ /^~/;
+$safariPath = glob($safariPath) if $safariPath =~ /^~/;
+$safariPath = File::Spec->catdir($safariPath, "Contents/MacOS/Safari") if $safariPath =~ m#\.app/*#;
+
+$nightlyDownloadDirectory = File::Spec->catdir($nightlyDownloadDirectory, $branch);
+if (! -d $nightlyDownloadDirectory) {
+    mkpath($nightlyDownloadDirectory, 0, 0755) || die "Could not create $nightlyDownloadDirectory: $!";
+}
+
+@nightlies = makeNightlyList($localOnly, $nightlyDownloadDirectory, findMacOSXVersion(), findSafariVersion($safariPath));
+
+my $startIndex = $revisions[0] ? findNearestNightlyIndex(@nightlies, $revisions[0], 'ceil') : 0;
+my $endIndex = $revisions[1] ? findNearestNightlyIndex(@nightlies, $revisions[1], 'floor') : $#nightlies;
+
+my $tempFile = createTempFile($testURL);
+
+if ($sanityCheck) {
+    my $didReproduceBug;
+
+    do {
+        printf "\nChecking starting revision (r%s)...\n",
+            $nightlies[$startIndex]->{rev};
+        downloadNightly($nightlies[$startIndex]->{file}, $nightlyFilesURLBase, $nightlyDownloadDirectory);
+        mountAndRunNightly($nightlies[$startIndex]->{file}, $nightlyDownloadDirectory, $safariPath, $tempFile);
+        $didReproduceBug = promptForTest($nightlies[$startIndex]->{rev});
+        $startIndex-- if $didReproduceBug < 0;
+    } while ($didReproduceBug < 0);
+    die "ERROR: Bug reproduced in starting revision!  Do you need to test an earlier revision or for a progression?"
+        if $didReproduceBug && !$isProgression;
+    die "ERROR: Bug not reproduced in starting revision!  Do you need to test an earlier revision or for a regression?"
+        if !$didReproduceBug && $isProgression;
+
+    do {
+        printf "\nChecking ending revision (r%s)...\n",
+            $nightlies[$endIndex]->{rev};
+        downloadNightly($nightlies[$endIndex]->{file}, $nightlyFilesURLBase, $nightlyDownloadDirectory);
+        mountAndRunNightly($nightlies[$endIndex]->{file}, $nightlyDownloadDirectory, $safariPath, $tempFile);
+        $didReproduceBug = promptForTest($nightlies[$endIndex]->{rev});
+        $endIndex++ if $didReproduceBug < 0;
+    } while ($didReproduceBug < 0);
+    die "ERROR: Bug NOT reproduced in ending revision!  Do you need to test a later revision or for a progression?"
+        if !$didReproduceBug && !$isProgression;
+    die "ERROR: Bug reproduced in ending revision!  Do you need to test a later revision or for a regression?"
+        if $didReproduceBug && $isProgression;
+}
+
+printStatus($nightlies[$startIndex]->{rev}, $nightlies[$endIndex]->{rev}, $isProgression);
+
+my %brokenRevisions = ();
+while (abs($endIndex - $startIndex) > 1) {
+    my $index = $startIndex + int(($endIndex - $startIndex) / 2);
+
+    my $didReproduceBug;
+    do {
+        if (exists $nightlies[$index]) {
+            printf "\nChecking revision (r%s)...\n", $nightlies[$index]->{rev};
+            downloadNightly($nightlies[$index]->{file}, $nightlyFilesURLBase, $nightlyDownloadDirectory);
+            mountAndRunNightly($nightlies[$index]->{file}, $nightlyDownloadDirectory, $safariPath, $tempFile);
+            $didReproduceBug = promptForTest($nightlies[$index]->{rev});
+        }
+        if ($didReproduceBug < 0) {
+            $brokenRevisions{$nightlies[$index]->{rev}} = $nightlies[$index]->{file};
+            delete $nightlies[$index];
+            $endIndex--;
+            $index = $startIndex + int(($endIndex - $startIndex) / 2);
+        }
+    } while ($didReproduceBug < 0);
+
+    if ($didReproduceBug && !$isProgression || !$didReproduceBug && $isProgression) {
+        $endIndex = $index;
+    } else {
+        $startIndex = $index;
+    }
+
+    print "\nBroken revisions skipped: r" . join(", r", keys %brokenRevisions) . "\n"
+        if scalar keys %brokenRevisions > 0;
+    printStatus($nightlies[$startIndex]->{rev}, $nightlies[$endIndex]->{rev}, $isProgression);
+}
+
+unlink $tempFile if $tempFile;
+
+exit 0;
+
+sub createTempFile($)
+{
+    my ($url) = @_;
+
+    return undef if !$url;
+
+    my ($fh, $tempFile) = tempfile(
+        basename($0) . "-XXXXXXXX",
+        DIR => ($ENV{'TMPDIR'} || "/tmp"),
+        SUFFIX => ".html",
+        UNLINK => 0,
+    );
+    print $fh "<meta http-equiv=\"refresh\" content=\"0; $url\">\n";
+    close($fh);
+
+    return $tempFile;
+}
+
+sub downloadNightly($$$)
+{
+    my ($filename, $urlBase, $directory) = @_;
+    my $path = File::Spec->catfile($directory, $filename);
+    if (! -f $path) {
+        print "Downloading $filename to $directory...\n";
+        `curl -# -o '$path' '$urlBase/$filename'`;
+    }
+}
+
+sub findMacOSXVersion()
+{
+    my $version;
+    open(SW_VERS, "-|", "/usr/bin/sw_vers") || die;
+    while (<SW_VERS>) {
+        $version = $1 if /^ProductVersion:\s+([^\s]+)/;
+    }
+    close(SW_VERS);
+    return $version;
+}
+
+sub findNearestNightlyIndex(\@$$)
+{
+    my ($nightlies, $revision, $round) = @_;
+
+    my $lowIndex = 0;
+    my $highIndex = $#{$nightlies};
+
+    return $highIndex if uc($revision) eq 'HEAD' || $revision >= $nightlies->[$highIndex]->{rev};
+    return $lowIndex if $revision <= $nightlies->[$lowIndex]->{rev};
+
+    while (abs($highIndex - $lowIndex) > 1) {
+        my $index = $lowIndex + int(($highIndex - $lowIndex) / 2);
+        if ($revision < $nightlies->[$index]->{rev}) {
+            $highIndex = $index;
+        } elsif ($revision > $nightlies->[$index]->{rev}) {
+            $lowIndex = $index;
+        } else {
+            return $index;
+        }
+    }
+
+    return ($round eq "floor") ? $lowIndex : $highIndex;
+}
+
+sub findSafariVersion($)
+{
+    my ($path) = @_;
+    my $versionPlist = File::Spec->catdir(dirname(dirname($path)), "version.plist");
+    my $version;
+    open(PLIST, "< $versionPlist") || die;
+    while (<PLIST>) {
+        if (m#^\s*<key>CFBundleShortVersionString</key>#) {
+            $version = <PLIST>;
+            $version =~ s#^\s*<string>(.+)</string>\s*[\r\n]*#$1#;
+        }
+    }
+    close(PLIST);
+    return $version;
+}
+
+sub loadSettings()
+{
+    package Settings;
+
+    our $branch = "trunk";
+    our $nightlyDownloadDirectory = File::Spec->catdir($ENV{HOME}, "Library/Caches/WebKit-Nightlies");
+    our $safariPath = "/Applications/Safari.app";
+
+    my $rcfile = File::Spec->catdir($ENV{HOME}, ".bisect-buildsrc");
+    return if !-f $rcfile;
+
+    my $result = do $rcfile;
+    die "Could not parse $rcfile: $@" if $@;
+}
+
+sub makeNightlyList($$$$)
+{
+    my ($useLocalFiles, $localDirectory, $macOSXVersion, $safariVersion) = @_;
+    my @files;
+
+    if ($useLocalFiles) {
+        opendir(DIR, $localDirectory) || die "$!";
+        foreach my $file (readdir(DIR)) {
+            if ($file =~ /^WebKit-SVN-r([0-9]+)\.dmg$/) {
+                push(@files, +{ rev => $1, file => $file });
+            }
+        }
+        closedir(DIR);
+    } else {
+        open(NIGHTLIES, "curl -s $nightlyBuildsURLBase/all |") || die;
+
+        while (my $line = <NIGHTLIES>) {
+            chomp $line;
+            my ($revision, $timestamp, $url) = split(/,/, $line);
+            my $nightly = basename($url);
+            push(@files, +{ rev => $revision, file => $nightly });
+        }
+        close(NIGHTLIES);
+    }
+
+    if (eval "v$macOSXVersion" ge v10.5) {
+        if (eval "v$safariVersion" ge v3.1) {
+            @files = grep { $_->{rev} >= 29711 } @files;
+        } elsif (eval "v$safariVersion" ge v3.0) {
+            @files = grep { $_->{rev} >= 25124 } @files;
+        } elsif (eval "v$safariVersion" ge v2.0) {
+            @files = grep { $_->{rev} >= 19594 } @files;
+        } else {
+            die "Requires Safari 2.0 or newer";
+        }
+    } elsif (eval "v$macOSXVersion" ge v10.4) {
+        if (eval "v$safariVersion" ge v3.1) {
+            @files = grep { $_->{rev} >= 29711 } @files;
+        } elsif (eval "v$safariVersion" ge v3.0) {
+            @files = grep { $_->{rev} >= 19992 } @files;
+        } elsif (eval "v$safariVersion" ge v2.0) {
+            @files = grep { $_->{rev} >= 11976 } @files;
+        } else {
+            die "Requires Safari 2.0 or newer";
+        }
+    } else {
+        die "Requires Mac OS X 10.4 (Tiger) or 10.5 (Leopard)";
+    }
+
+    my $nightlycmp = sub { return $a->{rev} <=> $b->{rev}; };
+
+    return sort $nightlycmp @files;
+}
+
+sub mountAndRunNightly($$$$)
+{
+    my ($filename, $directory, $safari, $tempFile) = @_;
+    my $mountPath = "/Volumes/WebKit";
+    my $webkitApp = File::Spec->catfile($mountPath, "WebKit.app");
+    my $diskImage = File::Spec->catfile($directory, $filename);
+
+    my $i = 0;
+    while (-e $mountPath) {
+        $i++;
+        usleep 100 if $i > 1;
+        `hdiutil detach '$mountPath' 2> /dev/null`;
+        die "Could not unmount $diskImage at $mountPath" if $i > 100;
+    }
+    die "Can't mount $diskImage: $mountPath already exists!" if -e $mountPath;
+
+    print "Mounting disk image and running WebKit...\n";
+    `hdiutil attach '$diskImage'`;
+    $i = 0;
+    while (! -e $webkitApp) {
+        usleep 100;
+        $i++;
+        die "Could not mount $diskImage at $mountPath" if $i > 100;
+    }
+
+    my $frameworkPath;
+    if (-d "/Volumes/WebKit/WebKit.app/Contents/Frameworks") {
+        my $osXVersion = join('.', (split(/\./, findMacOSXVersion()))[0..1]);
+        $frameworkPath = "/Volumes/WebKit/WebKit.app/Contents/Frameworks/$osXVersion";
+    } else {
+        $frameworkPath = "/Volumes/WebKit/WebKit.app/Contents/Resources";
+    }
+
+    $tempFile ||= "";
+    `DYLD_FRAMEWORK_PATH=$frameworkPath WEBKIT_UNSET_DYLD_FRAMEWORK_PATH=YES $safari $tempFile`;
+
+    `hdiutil detach '$mountPath' 2> /dev/null`;
+}
+
+sub parseRevisions($$;$)
+{
+    my ($optionName, $value, $ignored) = @_;
+
+    if ($value =~ /^r?([0-9]+|HEAD):?$/i) {
+        push(@revisions, $1);
+        die "Too many revision arguments specified" if scalar @revisions > 2;
+    } elsif ($value =~ /^r?([0-9]+):?r?([0-9]+|HEAD)$/i) {
+        $revisions[0] = $1;
+        $revisions[1] = $2;
+    } else {
+        die "Unknown revision '$value':  expected 'M' or 'M:N'";
+    }
+}
+
+sub printStatus($$$)
+{
+    my ($startRevision, $endRevision, $isProgression) = @_;
+    printf "\n%s: r%s  %s: r%s\n",
+        $isProgression ? "Fails" : "Works", $startRevision,
+        $isProgression ? "Works" : "Fails", $endRevision;
+}
+
+sub promptForTest($)
+{
+    my ($revision) = @_;
+    print "Did the bug reproduce in r$revision (yes/no/broken)? ";
+    my $answer = <STDIN>;
+    return 1 if $answer =~ /^(1|y.*)$/i;
+    return -1 if $answer =~ /^(-1|b.*)$/i; # Broken
+    return 0;
+}
+
diff --git a/WebKitTools/Scripts/build-drawtest b/WebKitTools/Scripts/build-drawtest
new file mode 100755
index 0000000..fa9b7c2
--- /dev/null
+++ b/WebKitTools/Scripts/build-drawtest
@@ -0,0 +1,48 @@
+#!/usr/bin/perl -w
+
+# Copyright (C) 2005, 2006 Apple Computer, Inc.  All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1.  Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer. 
+# 2.  Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution. 
+# 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+#     its contributors may be used to endorse or promote products derived
+#     from this software without specific prior written permission. 
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+# Simplified build script for WebKit Open Source Project.
+# Modified copy of build-dumprendertree. Perhaps these could share code.
+
+use strict;
+use FindBin;
+use lib $FindBin::Bin;
+use webkitdirs;
+
+checkRequiredSystemConfig();
+setConfiguration();
+chdirWebKit();
+my @options = XcodeOptions();
+
+# Check to see that all the frameworks are built (w/ SVG support).
+checkFrameworks();
+checkWebCoreSVGSupport(1);
+
+# Build
+chdir "WebKitTools/DrawTest" or die;
+exit system "xcodebuild", "-project", "DrawTest.xcodeproj", @options;
diff --git a/WebKitTools/Scripts/build-dumprendertree b/WebKitTools/Scripts/build-dumprendertree
new file mode 100755
index 0000000..a11481b
--- /dev/null
+++ b/WebKitTools/Scripts/build-dumprendertree
@@ -0,0 +1,54 @@
+#!/usr/bin/perl -w
+
+# Copyright (C) 2005 Apple Computer, Inc.  All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1.  Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer. 
+# 2.  Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution. 
+# 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+#     its contributors may be used to endorse or promote products derived
+#     from this software without specific prior written permission. 
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+use strict;
+use FindBin;
+use lib $FindBin::Bin;
+use webkitdirs;
+use POSIX;
+
+checkRequiredSystemConfig();
+setConfiguration();
+chdirWebKit();
+my @options = XcodeOptions();
+
+# Build
+chdir "WebKitTools/DumpRenderTree" or die;
+my $result;
+if (isOSX()) {
+    $result = system "xcodebuild", "-project", "DumpRenderTree.xcodeproj", @options, @ARGV;
+} elsif (isCygwin()) {
+    $result = buildVisualStudioProject("DumpRenderTree.sln");
+} elsif (isQt() || isGtk()) {
+    # Qt and Gtk build everything in one shot. No need to build anything here.
+    $result = 0;
+} else {
+    die "Building not defined for this platform!\n";
+}
+exit exitStatus($result);
diff --git a/WebKitTools/Scripts/build-jsc b/WebKitTools/Scripts/build-jsc
new file mode 100755
index 0000000..f258ea5
--- /dev/null
+++ b/WebKitTools/Scripts/build-jsc
@@ -0,0 +1,54 @@
+#!/usr/bin/perl -w
+
+# Copyright (C) 2005 Apple Computer, Inc.  All rights reserved.
+# Copyright (C) 2007 Eric Seidel <[email protected]>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1.  Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer. 
+# 2.  Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution. 
+# 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+#     its contributors may be used to endorse or promote products derived
+#     from this software without specific prior written permission. 
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+use strict;
+use FindBin;
+use lib $FindBin::Bin;
+use webkitdirs;
+use POSIX;
+
+checkRequiredSystemConfig();
+setConfiguration();
+chdirWebKit();
+my @options = XcodeOptions();
+
+chdir "JavaScriptCore" or die "Can't find JavaScriptCore directory to build from";
+my $result;
+if (isOSX()) {
+    $result = system "sh", "-c", 'xcodebuild -project JavaScriptCore.xcodeproj -target jsc "$@" | grep -v setenv && exit ${PIPESTATUS[0]}', "xcodebuild",  @options, @ARGV;
+} elsif (isCygwin()) {
+    $result = buildVisualStudioProject("JavaScriptCore.vcproj/JavaScriptCore.sln");
+} elsif (isQt() or isGtk() or isWx()) {
+    # Qt and Gtk build everything in one-shot. No need to build anything here.
+    $result = 0;
+} else {
+    die "Building not defined for this platform!\n";
+}
+exit exitStatus($result);
diff --git a/WebKitTools/Scripts/build-webkit b/WebKitTools/Scripts/build-webkit
new file mode 100755
index 0000000..6ed3ddc
--- /dev/null
+++ b/WebKitTools/Scripts/build-webkit
@@ -0,0 +1,350 @@
+#!/usr/bin/perl -w
+
+# Copyright (C) 2005, 2006 Apple Computer, Inc.  All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1.  Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer. 
+# 2.  Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution. 
+# 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+#     its contributors may be used to endorse or promote products derived
+#     from this software without specific prior written permission. 
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+# Simplified build script for WebKit Open Source Project.
+
+use strict;
+use File::Basename;
+use File::Spec;
+use FindBin;
+use Getopt::Long qw(:config pass_through);
+use lib $FindBin::Bin;
+use webkitdirs;
+use POSIX;
+
+my $originalWorkingDirectory = getcwd();
+
+my $databaseSupport = 1;
+my $domStorageSupport = 1;
+my $iconDatabaseSupport = 1;
+my $offlineWebApplicationSupport = 1;
+my $svgSupport = 1;
+my $svgExperimentalSupport = 0;
+my $svgAnimationSupport = 1;
+my $svgFiltersSupport = $svgExperimentalSupport;
+my $svgForeignObjectSupport = 1;
+my $svgUseSupport = 1;
+my $svgFontsSupport = 1;
+my $svgAsImageSupport = 1;
+my $xpathSupport = 1;
+my $xsltSupport = 1;
+my $coverageSupport = 0;
+my $videoSupport = (isOSX() || isCygwin()); # Enable by default on OSX and Windows
+my $showHelp = 0;
+my $clean = 0;
+my $buildUniversal = 0;
+my $buildSixtyFourBit = 0;
+
+my $programName = basename($0);
+my $usage = <<EOF;
+Usage: $programName [options] [options to pass to build system]
+  --help                        Show this help message
+  --cairo-win32                 Build using Cairo (rather than CoreGraphics) on Windows
+  --clean                       Cleanup the build directory
+  --universal                   Build 2-way universal (PPC and Intel 32-bit)
+  --64-bit                      Build 64-bit, combine with --universal to build 4-way universal
+  --[no-]offline-web-applications   Toggle Offline Web Application Support (default : $offlineWebApplicationSupport)
+  --[no-]database               Toggle Database Support (default: $databaseSupport)
+  --[no-]dom-storage            Toggle DOM Storage Support (default: $domStorageSupport)
+  --[no-]icon-database          Toggle Icon database support (default: $iconDatabaseSupport)
+  --[no-]svg                    Toggle SVG support (default: $svgSupport)
+  --[no-]svg-experimental       Toggle SVG experimental features support (default: $svgExperimentalSupport, 
+                                implies SVG Support)
+  --[no-]svg-animation          Toggle SVG animation support (default: $svgAnimationSupport, implies SVG Support)
+  --[no-]svg-filters            Toggle SVG filters support (default: $svgFiltersSupport, implies SVG Support)
+  --[no-]svg-foreign-object     Toggle SVG foreign object support (default: $svgForeignObjectSupport, implies SVG Support)
+  --[no-]svg-fonts              Toggle SVG fonts support (default: $svgFontsSupport, implies SVG Support)
+  --[no-]svg-as-image           Toggle SVG as Image support (default: $svgAsImageSupport, implies SVG Support)
+  --[no-]svg-use                Toggle SVG use element support (default: $svgUseSupport, implies SVG Support)
+  --[no-]xpath                  Toggle XPath support (default: $xpathSupport)
+  --[no-]xslt                   Toggle XSLT support (default: $xsltSupport)
+  --[no-]video                  Toggle Video support (default: $videoSupport)
+  --[no-]coverage               Toggle code coverage support (default: $coverageSupport)
+EOF
+
+GetOptions('database!' => \$databaseSupport,
+           'dom-storage!' => \$domStorageSupport,
+           'icon-database!' => \$iconDatabaseSupport,
+           'offline-web-applications!' => \$offlineWebApplicationSupport,
+           'svg!' => \$svgSupport,
+           'svg-experimental!' => \$svgExperimentalSupport,
+           'svg-animation!' => \$svgAnimationSupport,
+           'svg-filters!' => \$svgFiltersSupport,
+           'svg-foreign-object!' => \$svgForeignObjectSupport,
+           'svg-fonts!' => \$svgFontsSupport,
+           'svg-as-image!' => \$svgAsImageSupport,
+           'svg-use!' => \$svgUseSupport,
+           'xpath!' => \$xpathSupport,
+           'xslt!' => \$xsltSupport,
+           'video!' => \$videoSupport,
+           'coverage!' => \$coverageSupport,
+           'help' => \$showHelp,
+           'universal' => \$buildUniversal,
+           '64-bit' => \$buildSixtyFourBit,
+           'clean' => \$clean);
+
+if ($showHelp) {
+   print STDERR $usage;
+   exit 1;
+}
+
+$svgExperimentalSupport = 0 unless $svgSupport;
+$svgAnimationSupport = 0 unless $svgSupport;
+$svgFiltersSupport = 0 unless $svgSupport;
+$svgForeignObjectSupport = 0 unless $svgSupport;
+$svgFontsSupport = 0 unless $svgSupport;
+$svgAsImageSupport = 0 unless $svgSupport;
+$svgUseSupport = 0 unless $svgSupport;
+
+if ($svgExperimentalSupport) {
+    $svgAnimationSupport = 1;
+    $svgFiltersSupport = 1;
+    $svgForeignObjectSupport = 1;
+    $svgFontsSupport = 1;
+    $svgAsImageSupport = 1;
+    $svgUseSupport = 1;
+}
+
+checkRequiredSystemConfig();
+setConfiguration();
+chdirWebKit();
+
+# FIXME: Migrate build-wxwebkit commands into build-webkit.
+if (isWx()) {
+    my @opts = ();
+    $ENV{"WEBKITOUTPUTDIR"} = productDir();
+    foreach (@ARGV) {
+        if ($_ eq "wxgc" || $_ eq "wxpython") {
+            push(@opts, $_);
+        }
+    }
+    if ($clean) {
+        push(@opts, "clean");
+    }
+    system "WebKitTools/wx/build-wxwebkit @opts";
+    exit exitStatus($?);
+}
+
+
+my $productDir = productDir();
+my @overrideFeatureDefinesOption = ();
+
+push @overrideFeatureDefinesOption, "ENABLE_DATABASE" if $databaseSupport;
+push @overrideFeatureDefinesOption, "ENABLE_DOM_STORAGE" if $domStorageSupport;
+push @overrideFeatureDefinesOption, "ENABLE_ICONDATABASE" if $iconDatabaseSupport;
+push @overrideFeatureDefinesOption, "ENABLE_OFFLINE_WEB_APPLICATIONS" if $offlineWebApplicationSupport;
+push @overrideFeatureDefinesOption, "ENABLE_SVG" if $svgSupport;
+push @overrideFeatureDefinesOption, "ENABLE_SVG_ANIMATION" if $svgAnimationSupport;
+push @overrideFeatureDefinesOption, "ENABLE_SVG_AS_IMAGE" if $svgAsImageSupport;
+push @overrideFeatureDefinesOption, "ENABLE_SVG_FILTERS" if $svgFiltersSupport;
+push @overrideFeatureDefinesOption, "ENABLE_SVG_FONTS" if $svgFontsSupport;
+push @overrideFeatureDefinesOption, "ENABLE_SVG_FOREIGN_OBJECT" if $svgForeignObjectSupport;
+push @overrideFeatureDefinesOption, "ENABLE_SVG_USE" if $svgUseSupport;
+push @overrideFeatureDefinesOption, "ENABLE_VIDEO" if $videoSupport;
+push @overrideFeatureDefinesOption, "ENABLE_XPATH" if $xpathSupport;
+push @overrideFeatureDefinesOption, "ENABLE_XSLT" if $xsltSupport;
+my $overrideFeatureDefinesString = "FEATURE_DEFINES=" . join(" ", @overrideFeatureDefinesOption);
+
+my @coverageSupportOption = ();
+if ($coverageSupport) {
+    push @coverageSupportOption, "GCC_GENERATE_TEST_COVERAGE_FILES=YES";
+    push @coverageSupportOption, "GCC_INSTRUMENT_PROGRAM_FLOW_ARCS=YES";
+    push @coverageSupportOption, "EXTRA_LINK= -ftest-coverage -fprofile-arcs";
+    push @coverageSupportOption, "OTHER_CFLAGS= -MD";
+    push @coverageSupportOption, "OTHER_LDFLAGS=\$(OTHER_LDFLAGS) -ftest-coverage -fprofile-arcs -framework AppKit";
+}
+
+# Check that all the project directories are there.
+my @projects = ("JavaScriptCore", "JavaScriptGlue", "WebCore", "WebKit");
+my @otherDirs = ("WebKitLibraries");
+for my $dir (@projects, @otherDirs) {
+    if (! -d $dir) {
+        die "Error: No $dir directory found. Please do a fresh checkout.\n";
+    }
+}
+
+my @options = ();
+
+if ($clean && isOSX()) {
+    push(@options, "-alltargets");
+    push(@options, "clean");
+}
+
+if ($buildSixtyFourBit && isOSX()) {
+    my $cpuVendor = `sysctl -n machdep.cpu.vendor`;
+    chomp $cpuVendor;
+
+    if ($buildUniversal) {
+        push(@options, "ARCHS=ppc ppc64 i386 x86_64");
+    } elsif ($cpuVendor eq "GenuineIntel") {
+        push(@options, "ARCHS=i386 x86_64");
+    } else {
+        push(@options, "ARCHS=ppc ppc64");
+    }
+} elsif ($buildUniversal && isOSX()) {
+    push(@options, "ARCHS=ppc i386");
+}
+
+# enable autotool options accordingly
+if (isGtk()) {
+    push @options, autotoolsFlag($databaseSupport, "database");
+    push @options, autotoolsFlag($domStorageSupport, "dom-storage");
+    push @options, autotoolsFlag($iconDatabaseSupport, "icon-database");
+    push @options, autotoolsFlag($offlineWebApplicationSupport, "offline-web-applications");
+    push @options, autotoolsFlag($svgSupport, "svg");
+    push @options, autotoolsFlag($svgAnimationSupport, "svg-animation");
+    push @options, autotoolsFlag($svgFiltersSupport, "svg-filters");
+    push @options, autotoolsFlag($svgForeignObjectSupport, "svg-foreign-object");
+    push @options, autotoolsFlag($svgFontsSupport, "svg-fonts");
+    push @options, autotoolsFlag($svgAsImageSupport, "svg-as-image");
+    push @options, autotoolsFlag($svgUseSupport, "svg-use-element");
+    push @options, autotoolsFlag($xpathSupport, "xpath");
+    push @options, autotoolsFlag($xsltSupport, "xslt");
+    push @options, autotoolsFlag($videoSupport, "video");
+    push @options, autotoolsFlag($coverageSupport, "coverage");
+}
+
+if (isOSX()) {
+
+    push(@options, XcodeOptions());
+
+    # Copy library and header from WebKitLibraries to a findable place in the product directory.
+    my $srcLib = "WebKitLibraries/libWebKitSystemInterfaceTiger.a";
+    my $lib = "$productDir/libWebKitSystemInterfaceTiger.a";
+    if (!-e $lib || -M $lib > -M $srcLib) {
+        print "Updating $lib\n";
+        system "ditto", $srcLib, $lib;
+        system "ranlib", $lib;
+    }
+
+    $srcLib = "WebKitLibraries/libWebKitSystemInterfaceLeopard.a";
+    $lib = "$productDir/libWebKitSystemInterfaceLeopard.a";
+    if (!-e $lib || -M $lib > -M $srcLib) {
+        print "Updating $lib\n";
+        system "ditto", $srcLib, $lib;
+        system "ranlib", $lib;
+    }
+
+    my $srcHeader = "WebKitLibraries/WebKitSystemInterface.h";
+    my $header = "$productDir/usr/local/include/WebKitSystemInterface.h";
+    if (!-e $header || -M $header > -M $srcHeader) {
+        print "Updating $header\n";
+        system "mkdir", "-p", "$productDir/usr/local/include";
+        system "ditto", $srcHeader, $header;
+    }
+
+    $srcLib = "WebKitLibraries/libWebCoreSQLite3.a";
+    $lib = "$productDir/libWebCoreSQLite3.a";
+    if (!-e $lib || -M $lib > -M $srcLib) {
+        print "Updating $lib\n";
+        system "ditto", $srcLib, $lib;
+        system "ranlib", $lib;
+    }
+
+    my $srcHeaderDir = "WebKitLibraries/WebCoreSQLite3";
+    my $headerDir = "$productDir/WebCoreSQLite3";
+    if (!-e $headerDir || -M $headerDir > -M $srcHeaderDir) {
+        print "Updating $headerDir\n";
+        system "ditto", $srcHeaderDir, $headerDir;
+    }
+}
+
+if (isCygwin()) {
+    # Copy WebKitSupportLibrary to the correct location in WebKitLibraries so it can be found.
+    # Will fail if WebKitSupportLibrary.zip is not in source root.
+    (system("perl WebKitTools/Scripts/update-webkit-support-libs") == 0) or die;
+}
+
+# Force re-link of existing libraries if different than expected
+removeLibraryDependingOnSVG("WebCore", $svgSupport);
+
+# Build, and abort if the build fails.
+for my $dir (@projects) {
+    chdir $dir or die;
+    my $result = 0;
+
+    if (isGtk()) {
+        if ($dir ne "WebKit") {
+            chdir ".." or die;
+            next;
+        }
+
+        $result = buildGtkProject($dir, $clean,  @options);
+    } elsif (isQt()) {
+        if ($dir ne "WebKit") {
+            chdir ".." or die;
+            next;
+        }
+        $result = buildQMakeQtProject($dir, $clean);
+    } elsif (isOSX()) {
+        $result = system "xcodebuild", "-project", "$dir.xcodeproj", @options, $overrideFeatureDefinesString, @coverageSupportOption, @ARGV;
+    } elsif (isCygwin()) {
+        if ($dir eq "WebKit") {
+            $result = buildVisualStudioProject("win/WebKit.vcproj/WebKit.sln", $clean);
+        }
+    }
+
+    if (exitStatus($result)) {
+        if (isCygwin()) {
+            print "\n\n===== BUILD FAILED ======\n\n";
+            my $scriptDir = relativeScriptsDir();
+            print "Please ensure you have run $scriptDir/update-webkit to install depenedencies.\n\n";
+            my $baseProductDir = baseProductDir();
+            print "You can view build errors by checking the BuildLog.htm files located at:\n$baseProductDir/obj/<project>/<config>.\n";
+        }
+        exit exitStatus($result);
+    }
+    chdir ".." or die;
+}
+
+# Don't report the "WebKit is now built" message after a clean operation.
+exit if $clean;
+
+# Write out congratulations message.
+
+my $launcherPath = launcherPath();
+my $launcherName = launcherName();
+
+print "\n";
+print "===========================================================\n";
+print " WebKit is now built. To run $launcherName with this newly-built\n";
+print " code, use the \"$launcherPath\" script.\n";
+if ($svgSupport) {
+    print "\n NOTE: WebKit has been built with SVG support enabled.\n";
+    print " $launcherName will have SVG viewing capabilities.\n";
+}
+if ($svgAnimationSupport or $svgFiltersSupport or $svgForeignObjectSupport or $svgFontsSupport or $svgAsImageSupport or $svgUseSupport) {
+    print " Your build supports the following (optional) SVG features: \n";
+    print "  * Basic SVG animation.\n" if $svgAnimationSupport;
+    print "  * SVG filters.\n" if $svgFiltersSupport;
+    print "  * SVG foreign object.\n" if $svgForeignObjectSupport;
+    print "  * SVG fonts.\n" if $svgFontsSupport;
+    print "  * SVG as image.\n" if $svgAsImageSupport;
+    print "  * SVG <use> support.\n" if $svgUseSupport;
+}
+print "===========================================================\n";
diff --git a/WebKitTools/Scripts/check-dom-results b/WebKitTools/Scripts/check-dom-results
new file mode 100755
index 0000000..0b32406
--- /dev/null
+++ b/WebKitTools/Scripts/check-dom-results
@@ -0,0 +1,141 @@
+#!/usr/bin/perl -w
+
+# Copyright (C) 2005 Apple Computer, Inc.  All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1.  Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer. 
+# 2.  Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution. 
+# 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+#     its contributors may be used to endorse or promote products derived
+#     from this software without specific prior written permission. 
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+# Script to check status of W3C DOM tests that are part of the WebKit tests.
+
+use strict;
+use FindBin;
+use Cwd;
+use lib $FindBin::Bin;
+use webkitdirs;
+
+chdirWebKit();
+
+my $verbose = $ARGV[0] && $ARGV[0] eq "-v";
+
+my $workingDir = getcwd();
+my $testDirectory = "$workingDir/LayoutTests";
+
+my @suites = ( {"name" => "DOM Level 1 Core   (html)", "directory" => "dom/html/level1/core"},
+               {"name" => "DOM Level 2 Core   (html)", "directory" => "dom/html/level2/core"},
+               {"name" => "DOM Level 2 Events (html)", "directory" => "dom/html/level2/events"},
+               {"name" => "DOM Level 2 HTML   (html)", "directory" => "dom/html/level2/html"},
+               {"name" => "DOM Level 1 Core   (xhtml)", "directory" => "dom/xhtml/level1/core"},
+               {"name" => "DOM Level 2 Core   (xhtml)", "directory" => "dom/xhtml/level2/core"},
+               {"name" => "DOM Level 2 Events (xhtml)", "directory" => "dom/xhtml/level2/events"},
+               {"name" => "DOM Level 2 HTML   (xhtml)", "directory" => "dom/xhtml/level2/html"},
+               {"name" => "DOM Level 3 Core   (xhtml)", "directory" => "dom/xhtml/level3/core"},
+               {"name" => "DOM Level 3 XPath  (svg)", "directory" => "dom/svg/level3/xpath"});
+
+my $totalCount = 0;
+my $totalSuccesses = 0;
+my $totalDisabled = 0;
+my $totalFailed = 0;
+
+foreach my $suite (@suites) {
+
+    my %suite = %$suite;
+    my $directory = $suite{"directory"};
+    my $name = $suite{"name"};
+    my @results = `find "${testDirectory}/${directory}" -name "*-expected.txt"`;
+    my @disabled = `find "${testDirectory}/${directory}" -name "*-disabled"`;
+
+    my @failures = ();
+    my $count = 0;
+
+    foreach my $result (@results) {
+        $count++;
+        my $success = 0;
+        open RESULT, "<$result";
+        while (<RESULT>) {
+            if (/Success/) {
+                $success = 1;
+                last;
+            }
+        }
+        close RESULT;
+        if (!$success) {
+            push @failures, $result;
+        }
+    }
+
+    my $disabledCount = (scalar @disabled);
+    my $failureCount = (scalar @failures);
+
+    $count += $disabledCount;
+
+    my $successCount = $count - $failureCount - $disabledCount;
+    my $percentage = (sprintf "%.1f", ($successCount * 100.0 / $count));
+    
+    if ($percentage == 100) {
+        print "${name}: all ${count} tests succeeded";
+    } else {
+        print "${name}: ${successCount} out of ${count} tests succeeded (${percentage}%)";
+    }
+    print " ($disabledCount disabled)" if $disabledCount;
+    print "\n";
+    if ($verbose) {
+        print "\n";
+        if (@disabled) {
+            print "    Disabled:\n";
+            
+            foreach my $failure (sort @disabled) {
+                $failure =~ s|.*/||;
+                $failure =~ s|-disabled||;
+                print "        ${directory}/${failure}";
+            }
+        }
+        if (@failures) {
+            print "    Failed:\n";
+            
+            foreach my $failure (sort @failures) {
+                $directory =~ m|^dom/(\w+)|;
+                my $extension = $1;
+                $failure =~ s|.*/||;
+                $failure =~ s|-expected\.txt|.${extension}|;
+                print "        ${directory}/${failure}";
+            }
+        }
+
+        print "\n";
+    }
+
+    $totalCount += $count;
+    $totalSuccesses += $successCount;
+    $totalDisabled += $disabledCount;
+    $totalFailed += $failureCount;
+}
+
+
+my $totalPercentage = (sprintf "%.1f", ($totalSuccesses * 100.0 / $totalCount));
+my $totalDisabledPercentage = (sprintf "%.1f", ($totalDisabled * 100.0 / $totalCount));
+my $totalFailedPercentage = (sprintf "%.1f", ($totalFailed * 100.0 / $totalCount));
+
+print "Total: ${totalSuccesses} out of ${totalCount} tests succeeded (${totalPercentage}%)\n";
+print "       ${totalDisabled} tests disabled (${totalDisabledPercentage}%)\n";
+print "       ${totalFailed} tests failed (${totalFailedPercentage}%)\n";
diff --git a/WebKitTools/Scripts/check-for-global-initializers b/WebKitTools/Scripts/check-for-global-initializers
new file mode 100755
index 0000000..493b40c
--- /dev/null
+++ b/WebKitTools/Scripts/check-for-global-initializers
@@ -0,0 +1,135 @@
+#!/usr/bin/perl
+
+# Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1.  Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer. 
+# 2.  Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution. 
+# 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+#     its contributors may be used to endorse or promote products derived
+#     from this software without specific prior written permission. 
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+# "check-for-global-initializers" script for WebKit Open Source Project
+
+# Intended to be invoked from an Xcode build step to check if there are
+# any global initializers in a target.
+
+use warnings;
+use strict;
+
+use File::Basename;
+
+sub touch($);
+
+my $arch = $ENV{'CURRENT_ARCH'};
+my $configuration = $ENV{'CONFIGURATION'};
+my $target = $ENV{'TARGET_NAME'};
+my $variant = $ENV{'CURRENT_VARIANT'};
+my $coverageBuild = $ENV{'WEBKIT_COVERAGE_BUILD'};
+my $debugRoot = $ENV{'WEBKIT_DEBUG_ROOT'};
+
+$arch = $ENV{'NATIVE_ARCH'} if !$arch; # for Xcode 2.1, which does not have CURRENT_ARCH
+$variant = "normal" if !$variant; # for Xcode 2.1, which does not have CURRENT_VARIANT
+
+my $executablePath = "$ENV{'TARGET_BUILD_DIR'}/$ENV{'EXECUTABLE_PATH'}";
+
+my $buildTimestampPath = $ENV{'TARGET_TEMP_DIR'} . "/" . basename($0) . ".timestamp";
+my $buildTimestampAge = -M $buildTimestampPath;
+
+touch($buildTimestampPath);
+
+my $list = $ENV{"LINK_FILE_LIST_${variant}_${arch}"};
+
+if (!open LIST, $list) {
+    print "Could not open $list\n";
+    exit 1;
+}
+
+my @files = <LIST>;
+chomp @files;
+close LIST;
+
+my $sawError = 0;
+
+for my $file (sort @files) {
+    if (defined $buildTimestampAge) {
+        my $fileAge = -M $file;
+        next if defined $fileAge && $fileAge > $buildTimestampAge;
+    }
+    if (!open NM, "(nm '$file' | sed 's/^/STDOUT:/') 2>&1 |") {
+        print "Could not open $file\n";
+        $sawError = 1;
+        next;
+    }
+    my $sawGlobal = 0;
+    while (<NM>) {
+        if (/^STDOUT:/) {
+            $sawGlobal = 1 if /__GLOBAL__I/;
+        } else {
+            print STDERR if $_ ne "nm: no name list\n";
+        }
+    }
+    close NM;
+    if ($sawGlobal) {
+        my $shortName = $file;
+        $shortName =~ s/.*\///;
+
+        # Special cases for files that have initializers in debug builds.
+        if ($configuration eq "Debug" or $variant eq "debug" or $debugRoot) {
+            if ($target eq "JavaScriptCore") {
+                next if $shortName eq "AllInOneFile.o";
+                next if $shortName eq "Opcode.o";
+                next if $shortName eq "StructureID.o";
+                next if $shortName eq "nodes.o";
+            }
+            if ($target eq "WebCore") {
+                next if $shortName eq "CachedPage.o";
+                next if $shortName eq "CachedResource.o";
+                next if $shortName eq "Frame.o";
+                next if $shortName eq "JSCustomSQLTransactionCallback.o";
+                next if $shortName eq "JSEventListener.o";
+                next if $shortName eq "Node.o";
+                next if $shortName eq "Page.o";
+                next if $shortName eq "Range.o";
+                next if $shortName eq "RenderObject.o";
+                next if $shortName eq "SubresourceLoader.o";
+                next if $shortName eq "SVGElementInstance.o";
+                next if $shortName eq "bidi.o";
+            }
+        }
+
+        print "$shortName has a global initializer in it! ($file)\n";
+        $sawError = 1;
+    }
+}
+
+if ($sawError and !$coverageBuild) {
+    unlink $executablePath;
+    exit 1;
+}
+
+exit 0;
+
+sub touch($)
+{
+    my ($path) = @_;
+    open(TOUCH, ">", $path) or die "$!";
+    close(TOUCH);
+}
diff --git a/WebKitTools/Scripts/check-for-weak-vtables b/WebKitTools/Scripts/check-for-weak-vtables
new file mode 100755
index 0000000..d274b01
--- /dev/null
+++ b/WebKitTools/Scripts/check-for-weak-vtables
@@ -0,0 +1,101 @@
+#!/usr/bin/perl
+
+# Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1.  Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer. 
+# 2.  Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution. 
+# 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+#     its contributors may be used to endorse or promote products derived
+#     from this software without specific prior written permission. 
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+# "check-for-weak-vtables" script for WebKit Open Source Project
+
+# Intended to be invoked from an Xcode build step to check if there are
+# any weak vtables in a target.
+
+use warnings;
+use strict;
+
+use File::Basename;
+
+sub touch($);
+
+my $arch = $ENV{'CURRENT_ARCH'};
+my $configuration = $ENV{'CONFIGURATION'};
+my $target = $ENV{'TARGET_NAME'};
+my $variant = $ENV{'CURRENT_VARIANT'};
+my $coverageBuild = $ENV{'WEBKIT_COVERAGE_BUILD'};
+my $debugRoot = $ENV{'WEBKIT_DEBUG_ROOT'};
+
+$arch = $ENV{'NATIVE_ARCH'} if !$arch; # for Xcode 2.1, which does not have CURRENT_ARCH
+$variant = "normal" if !$variant; # for Xcode 2.1, which does not have CURRENT_VARIANT
+
+my $executablePath = "$ENV{'TARGET_BUILD_DIR'}/$ENV{'EXECUTABLE_PATH'}";
+
+my $buildTimestampPath = $ENV{'TARGET_TEMP_DIR'} . "/" . basename($0) . ".timestamp";
+my $buildTimestampAge = -M $buildTimestampPath;
+my $executablePathAge = -M $executablePath;
+
+my $sawError = 0;
+
+if (!defined $executablePathAge || !defined $buildTimestampAge || $executablePathAge > $buildTimestampAge) {
+    if (!open NM, "(nm -m '$executablePath' | c++filt | sed 's/^/STDOUT:/') 2>&1 |") {
+        print "Could not open $executablePath\n";
+        $sawError = 1;
+        next;
+    }
+    my @weakVTableClasses = ();
+    while (<NM>) {
+        if (/^STDOUT:/) {
+            push @weakVTableClasses, $1 if /weak external vtable for (.*)$/;
+        } else {
+            print STDERR if $_ ne "nm: no name list\n";
+        }
+    }
+    close NM;
+    if (@weakVTableClasses) {
+        my $shortName = $executablePath;
+        $shortName =~ s/.*\///;
+
+        print "$shortName has a weak vtable in it ($executablePath)\n";
+        print "Fix by making sure the first virtual function in each of these classes is not an inline:\n";
+        for my $class (sort @weakVTableClasses) {
+            print "    $class\n";
+        }
+        $sawError = 1;
+    }
+}
+
+if ($sawError and !$coverageBuild) {
+    unlink $executablePath;
+    exit 1;
+}
+
+touch($buildTimestampPath);
+
+exit 0;
+
+sub touch($)
+{
+    my ($path) = @_;
+    open(TOUCH, ">", $path) or die "$!";
+    close(TOUCH);
+}
diff --git a/WebKitTools/Scripts/clean-header-guards b/WebKitTools/Scripts/clean-header-guards
new file mode 100755
index 0000000..2bad046
--- /dev/null
+++ b/WebKitTools/Scripts/clean-header-guards
@@ -0,0 +1,53 @@
+#!/usr/bin/ruby
+
+require 'find'
+require 'optparse'
+
+options = {}
+OptionParser.new do |opts|
+  opts.banner = "Usage: clean-header-guards [options]"
+  
+  opts.on("--prefix [PREFIX]", "Append a header prefix to all guards") do |prefix|
+    options[:prefix] = prefix
+  end
+end.parse!
+
+IgnoredFilenamePatterns = [
+  # ignore headers which are known not to have guard
+  /WebCorePrefix/, 
+  /ForwardingHeaders/,
+  %r|bindings/objc|, 
+  /vcproj/, # anything inside a vcproj is in the windows wasteland
+  
+  # we don't own any of these headers
+  %r|icu/unicode|,
+  %r|platform/graphics/cairo|,
+  %r|platform/image-decoders|,
+  
+  /config.h/ # changing this one sounds scary
+].freeze
+
+IgnoreFileNamesPattern = Regexp.union(*IgnoredFilenamePatterns).freeze
+
+Find::find(".") do |filename|
+  next unless filename =~ /\.h$/
+  next if filename.match(IgnoreFileNamesPattern)
+  
+  File.open(filename, "r+") do |file|
+    contents = file.read
+    match_results = contents.match(/#ifndef (\S+)\n#define \1/s)
+    if match_results
+      current_guard = match_results[1]
+      new_guard = File.basename(filename).sub('.', '_')
+      new_guard = options[:prefix] + '_' + new_guard  if options[:prefix]
+      contents.gsub!(/#{current_guard}\b/, new_guard)
+    else
+      puts "Ignoring #{filename}, failed to find existing header guards."
+    end
+    tmp_filename = filename + ".tmp"
+    File.open(tmp_filename, "w+") do |new_file|
+      new_file.write(contents)
+    end
+    File.rename tmp_filename, filename
+  end
+end
diff --git a/WebKitTools/Scripts/commit-log-editor b/WebKitTools/Scripts/commit-log-editor
new file mode 100755
index 0000000..939b28c
--- /dev/null
+++ b/WebKitTools/Scripts/commit-log-editor
@@ -0,0 +1,189 @@
+#!/usr/bin/perl -w
+
+# Copyright (C) 2006, 2007 Apple Inc.  All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1.  Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+# 2.  Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+# 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+#     its contributors may be used to endorse or promote products derived
+#     from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+# Script to put change log comments in as default check-in comment.
+
+use strict;
+use File::Basename;
+use File::Spec;
+use FindBin;
+use lib $FindBin::Bin;
+use VCSUtils;
+use webkitdirs;
+
+my $log = $ARGV[0];
+
+my $baseDir = baseProductDir();
+
+my $editor = $ENV{SVN_LOG_EDITOR};
+if (!$editor) {
+    $editor = $ENV{CVS_LOG_EDITOR};
+}
+if (!$editor) {
+    my $builtEditorApplication = "$baseDir/Release/Commit Log Editor.app/Contents/MacOS/Commit Log Editor";
+    $editor = $builtEditorApplication if -x $builtEditorApplication;
+}
+if (!$editor) {
+    my $builtEditorApplication = "$baseDir/Debug/Commit Log Editor.app/Contents/MacOS/Commit Log Editor";
+    $editor = $builtEditorApplication if -x $builtEditorApplication;
+}
+if (!$editor) {
+    my $installedEditorApplication = "$ENV{HOME}/Applications/Commit Log Editor.app/Contents/MacOS/Commit Log Editor";
+    $editor = $installedEditorApplication if -x $installedEditorApplication;
+}
+if (!$editor) {
+    $editor = $ENV{EDITOR} || "/usr/bin/vi";
+}
+
+my $inChangesToBeCommitted = !isGit();
+my @changeLogs = ();
+my $logContents = "";
+my $existingLog = 0;
+open LOG, $log or die;
+while (<LOG>) {
+    if (isGit()) {
+        if (/^# Changes to be committed:$/) {
+            $inChangesToBeCommitted = 1;
+        } elsif ($inChangesToBeCommitted && /^# \S/) {
+            $inChangesToBeCommitted = 0;
+        }
+    }
+
+    $logContents .= $_;
+    $existingLog = isGit() && !(/^#/ || /^\s*$/) unless $existingLog;
+
+    push @changeLogs, makeFilePathRelative($1) if $inChangesToBeCommitted && (/^M....(.*ChangeLog)$/ || /^#\tmodified:   (.*ChangeLog)/) && !/-ChangeLog/;
+}
+close LOG;
+
+# Don't change anything if there's already a log message
+# (as can happen with git-commit --amend)
+exec $editor, @ARGV if $existingLog;
+
+my $topLevel = topLevelSourceDirectory();
+
+my %changeLogSort;
+my %changeLogContents;
+for my $changeLog (@changeLogs) {
+    open CHANGELOG, $changeLog or die "Can't open $changeLog";
+    my $contents = "";
+    my $blankLines = "";
+    while (<CHANGELOG>) {
+        if (/^\S/) {
+            last if $contents;
+        }
+        if (/\S/) {
+            $contents .= $blankLines if $contents;
+            $blankLines = "";
+            $contents .= $_;
+        } else {
+            $blankLines .= $_;
+        }
+    }
+    close CHANGELOG;
+
+    $changeLog = File::Spec->abs2rel(File::Spec->rel2abs($changeLog), $topLevel);
+
+    my $label = dirname($changeLog);
+    $label = "top level" unless length $label;
+
+    my $sortKey = lc $label;
+    if ($label eq "top level") {
+        $sortKey = "";
+    } elsif ($label eq "Tools") {
+        $sortKey = "-, just after top level";
+    } elsif ($label eq "WebBrowser") {
+        $sortKey = lc "WebKit, WebBrowser after";
+    } elsif ($label eq "WebCore") {
+        $sortKey = lc "WebFoundation, WebCore after";
+    } elsif ($label eq "LayoutTests") {
+        $sortKey = lc "~, LayoutTests last";
+    }
+
+    $changeLogSort{$sortKey} = $label;
+    $changeLogContents{$label} = $contents;
+}
+
+my $first = 1;
+open NEWLOG, ">$log.edit" or die;
+for my $sortKey (sort keys %changeLogSort) {
+    my $label = $changeLogSort{$sortKey};
+    if (keys %changeLogSort > 1) {
+        print NEWLOG "\n" if !$first;
+        $first = 0;
+        print NEWLOG "$label:\n\n";
+    }
+    print NEWLOG $changeLogContents{$label};
+}
+print NEWLOG $logContents;
+close NEWLOG;
+
+system $editor, "$log.edit";
+
+open NEWLOG, "$log.edit" or exit;
+my $foundComment = 0;
+while (<NEWLOG>) {
+    $foundComment = 1 if (/\S/ && !/^CVS:/);
+}
+close NEWLOG;
+
+if ($foundComment) {
+    open NEWLOG, "$log.edit" or die;
+    open LOG, ">$log" or die;
+    while (<NEWLOG>) {
+        print LOG;
+    }
+    close LOG;
+    close NEWLOG;
+}
+
+unlink "$log.edit";
+
+sub topLevelSourceDirectory
+{
+    if (isGit()) {
+        chomp(my $gitDir = `git rev-parse --git-dir`);
+        return dirname($gitDir);
+    } elsif (isSVN()) {
+        open(INFO, "-|", qw(svn info)) or die;
+        my ($root, $url);
+        while (my $line = <INFO>) {
+            if ($line =~ /^Repository Root: (.*)$/) {
+                $root = $1;
+            } elsif ($line =~ /^URL: (.*)$/) {
+                $url = $1;
+            }
+        }
+        close(INFO);
+
+        my $path = $url;
+        $path =~ s/^\Q$root\E//;
+        $path =~ s/^\/?(branches\/[^\/]*|trunk)\/?//;
+        return File::Spec->rel2abs(File::Spec->catdir(map { ".." } File::Spec->splitdir($path)));
+    }
+}
diff --git a/WebKitTools/Scripts/compare-timing-files b/WebKitTools/Scripts/compare-timing-files
new file mode 100755
index 0000000..11b470b
--- /dev/null
+++ b/WebKitTools/Scripts/compare-timing-files
@@ -0,0 +1,88 @@
+#!/usr/bin/perl
+
+# Copyright (C) 2006 Apple Computer, Inc.  All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1.  Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+# 2.  Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+# 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+#     its contributors may be used to endorse or promote products derived
+#     from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+# This script takes two files that are lists of timings and compares them.
+
+use warnings;
+use strict;
+use Getopt::Long;
+
+my $usage = "compare-timing-files [-c|--count results] oldFile newFile";
+
+my $count = 1;
+GetOptions("c|count=i" => \$count);
+
+my ($file1, $file2) = @ARGV;
+die "$usage\n" unless ($file1 && $file2 && @ARGV == 2);
+
+my ($oldAverage, $oldRange, $oldRangePercent) = parseResults($file1);
+my ($newAverage, $newRange, $newRangePercent) = parseResults($file2);
+
+print "\n===== $file1 =====\n";
+if ($count == 1) {
+    print("fastest run: $oldAverage\n");
+} else {
+    print("average of fastest $count runs: $oldAverage\n");
+    printf("range of fastest $count runs: %.2f%% (%d)\n", $oldRangePercent, $oldRange);
+}
+
+print "\n===== $file2 =====\n";
+if ($count == 1) {
+    print("fastest run: $newAverage\n");
+} else {
+    print("average of fastest $count runs: $newAverage\n");
+    printf("range of fastest $count runs: %.2f%% (%d)\n", $newRangePercent, $newRange);
+}
+
+my $gainOrLoss = $newAverage <= $oldAverage ? "GAIN" : "LOSS";
+my $difference = abs($newAverage - $oldAverage);
+my $differencePercent = $difference / $oldAverage * 100;
+printf("\nperformance %s of %.2f%% (%.1f / %.1f)\n", $gainOrLoss, $differencePercent, $difference, $oldAverage);
+print "\n";
+
+sub parseResults
+{
+    my ($file) = @_;
+    
+    open(FILE, $file) or die "Couldn't open file: $file";
+    my @results = <FILE>;
+    close(FILE);
+
+    @results = sort(@results);
+    my $total = 0;
+    for (my $i = 0; $i < $count; $i++) {
+        $results[$i] =~ s/\D*//; # cut out non-digits
+        $total += $results[$i]; 
+    }
+    my $average = $total / $count;
+    my $range = $results[$count - 1] - $results[0];
+    my $rangePercent = $range / $results[$count - 1] * 100;
+
+    return ($average, $range, $rangePercent);
+}
+
diff --git a/WebKitTools/Scripts/create-exports b/WebKitTools/Scripts/create-exports
new file mode 100755
index 0000000..c645d55
--- /dev/null
+++ b/WebKitTools/Scripts/create-exports
@@ -0,0 +1,5 @@
+#!/usr/bin/perl -w
+
+while (<>) {
+    print "$1\n" if /^\s*\"(.+)\", referenced from:$/;
+}
diff --git a/WebKitTools/Scripts/debug-safari b/WebKitTools/Scripts/debug-safari
new file mode 100755
index 0000000..52e97fe
--- /dev/null
+++ b/WebKitTools/Scripts/debug-safari
@@ -0,0 +1,38 @@
+#!/usr/bin/perl -w
+
+# Copyright (C) 2007 Apple Inc. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1.  Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+# 2.  Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+# 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+#     its contributors may be used to endorse or promote products derived
+#     from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+# Script to run Safari in the platform's debugger for the WebKit Open Source Project.
+
+use strict;
+use FindBin;
+use lib $FindBin::Bin;
+use webkitdirs;
+
+setConfiguration();
+
+exit exitStatus(runSafari(1));
diff --git a/WebKitTools/Scripts/do-file-rename b/WebKitTools/Scripts/do-file-rename
new file mode 100755
index 0000000..ac5099e
--- /dev/null
+++ b/WebKitTools/Scripts/do-file-rename
@@ -0,0 +1,115 @@
+#!/usr/bin/perl -w
+
+# Copyright (C) 2006, 2008 Apple Inc. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1.  Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer. 
+# 2.  Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution. 
+# 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+#     its contributors may be used to endorse or promote products derived
+#     from this software without specific prior written permission. 
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+# Script to do file renaming.
+
+use strict;
+use FindBin;
+use lib $FindBin::Bin;
+use webkitdirs;
+use File::Find;
+
+setConfiguration();
+chdirWebKit();
+
+my %words;
+
+# find all files we want to process
+
+my @paths;
+find(\&wanted, "JavaScriptCore");
+find(\&wanted, "JavaScriptGlue");
+find(\&wanted, "WebCore");
+find(\&wanted, "WebKit");
+
+sub wanted
+{
+    my $file = $_;
+
+    if ($file eq "icu") {
+        $File::Find::prune = 1;
+        return;
+    }
+
+    if ($file =~ /^\../) {
+        $File::Find::prune = 1;
+        return;
+    }
+
+    return if $file =~ /^ChangeLog/;
+    return if -d $file;
+
+    push @paths, $File::Find::name;
+}
+
+my %renames = (
+);
+
+my %renamesContemplatedForTheFuture = (
+);
+
+# rename files
+
+my %newFile;
+for my $file (sort @paths) {
+    my $f = $file;
+    $f = "$1$renames{$2}" if $f =~ /^(.*\/)(\w+\.\w+)$/ && $renames{$2};
+    $newFile{$file} = $f if $f ne $file;
+}
+
+for my $file (sort @paths) {
+    if ($newFile{$file}) {
+        my $newFile = $newFile{$file};
+        print "Renaming $file to $newFile\n";
+        system "svn move $file $newFile";
+    }
+}
+
+# change all file contents
+
+for my $file (sort @paths) {
+    $file = $newFile{$file} if $newFile{$file};
+    my $contents;
+    {
+        local $/;
+        open FILE, $file or die;
+        $contents = <FILE>;
+        close FILE;
+    }
+    my $newContents = $contents;
+
+    for my $from (keys %renames) {
+        $newContents =~ s/\b\Q$from\E(?!\w)/$renames{$from}/g; # this " unconfuses Xcode syntax highlighting
+    }
+
+    if ($newContents ne $contents) {
+        open FILE, ">", $file or die;
+        print FILE $newContents;
+        close FILE;
+    }
+}
diff --git a/WebKitTools/Scripts/do-webcore-rename b/WebKitTools/Scripts/do-webcore-rename
new file mode 100755
index 0000000..edfe2dc
--- /dev/null
+++ b/WebKitTools/Scripts/do-webcore-rename
@@ -0,0 +1,199 @@
+#!/usr/bin/perl -w
+
+# Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1.  Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer. 
+# 2.  Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution. 
+# 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+#     its contributors may be used to endorse or promote products derived
+#     from this software without specific prior written permission. 
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+# Script to do a rename in JavaScriptCore, WebCore, and WebKit.
+
+use strict;
+use FindBin;
+use lib $FindBin::Bin;
+use webkitdirs;
+use File::Find;
+
+setConfiguration();
+chdirWebKit();
+
+my %words;
+
+# find all files we want to process
+
+my @paths;
+find(\&wanted, "JavaScriptCore");
+find(\&wanted, "JavaScriptGlue");
+find(\&wanted, "WebCore");
+find(\&wanted, "WebKit");
+
+sub wanted
+{
+    my $file = $_;
+
+    if ($file eq "icu") {
+        $File::Find::prune = 1;
+        return;
+    }
+
+    if ($file =~ /^\../) {
+        $File::Find::prune = 1;
+        return;
+    }
+
+    return if $file =~ /^ChangeLog/;
+    return if -d $file;
+
+    push @paths, $File::Find::name;
+}
+
+my %renames = (
+);
+
+my %renamesContemplatedForTheFuture = (
+    "StructureID" => "Structure",
+    "StructureIDChain" => "StructureChain",
+    "StructureIDs" => "Structures",
+    "StructureID_h" => "Structure_h",
+    "StructureIDChain_h" => "StructureChain_h",
+    "activationStructureID" => "activationStructure",
+    "createStructureID" => "createStructure",
+    "currStructureID" => "currStructure",
+    "derefStructureIDs" => "derefStructures",
+    "liveStructureIDSet" => "liveStructureSet",
+    "m_structureID" => "mm_structure",
+    "newStructureID" => "newStructureID",
+    "numberStructureID" => "numberStructure",
+    "oldStructureID" => "oldStructure",
+    "printStructureIDs" => "printStructures",
+    "refStructureIDs" => "refStructures",
+    "repatchGetByIdDefaultStructureID" => "repatchGetByIdDefaultStructure",
+    "repatchOffsetGetByIdStructureID" => "repatchOffsetGetByIdStructure",
+    "repatchOffsetPutByIdStructureID" => "repatchOffsetPutByIdStructure",
+    "sIDC" => "chain",
+    "setCachedStructureID" => "setCachedStructureID",
+    "staticScopeStructureID" => "staticScopeStructure",
+    "stringStructureID" => "stringStructure",
+    "structureID" => "structure",
+    "structureIDAddr" => "structureAddress",
+    "structureIDChain" => "structureChain",
+    "structureIDCounter" => "structureCounter",
+    "structureIDInstructionIndex" => "structureInstructionIndex",
+    "structureIDInstructions" => "structureInstructions",
+
+    "DOMObject" => "JSDOMObject",
+
+    "runtimeObjectGetter" => "pluginElementGetter",
+    "runtimeObjectPropertyGetter" => "pluginElementPropertyGetter",
+    "runtimeObjectCustomGetOwnPropertySlot" => "pluginElementCustomGetOwnPropertySlot",
+    "runtimeObjectCustomPut" => "pluginElementCustomPut",
+    "runtimeObjectImplementsCall" => "pluginElementImplementsCall",
+    "runtimeObjectCallAsFunction" => "pluginElementCallAsFunction",
+
+    "CLONE_CONTENTS" => "Clone",
+    "DELETE_CONTENTS" => "Delete",
+    "EXTRACT_CONTENTS" => "Extract",
+
+    "DateInstance" => "JSDate",
+    "ErrorInstance" => "JSError",
+
+    "ImageConstructorImp" => "JSImageConstructor",
+    "Navigator" => "JSNavigator",
+
+    "JSHTMLOptionElementConstructor" => "JSOptionConstructor",
+    "XSLTProcessorPrototypeTable" => "JSXSLTProcessorPrototypeTable",
+
+    "KURL" => "URL",
+    "KURLCFNet" => "URLCF",
+    "KURLHash" => "URLHash",
+    "KURLMac" => "URLMac",
+    "KURL_H_" => "URL_h",
+
+    "ThreadSafeShared" => "ThreadSafeRefCounted",
+    "TreeShared" => "TreeRefCounted",
+
+    "StringImpl" => "SharedString",
+
+    "RenderView" => "RenderViewport",
+
+    "ObjcFallbackObjectImp" => "ObjCFallbackObject",
+    "RuntimeObjectImp" => "ForeignObject",
+
+    "equalIgnoringCase" => "equalFoldingCase",
+
+    "FTPDirectoryTokenizer" => "FTPDirectoryDocumentBuilder",
+    "HTMLTokenizer" => "HTMLDocumentBuilder",
+    "ImageTokenizer" => "ImageDocumentBuilder",
+    "PluginTokenizer" => "PluginDocumentBuilder",
+    "TextTokenizer" => "TextDocumentBuilder",
+    "Tokenizer" => "DocumentBuilder",
+    "Tokenizer_h" => "DocumentBuilder_h",
+    "XMLTokenizer" => "XMLDocumentBuilder",
+    "isHTMLTokenizer" => "isHTMLDocumentBuilder",
+    "m_tokenizer" => "m_builder",
+    "createTokenizer" => "createBuilder",
+    "tokenizerProcessedData" => "documentBuilderProcessedData",
+);
+
+# rename files
+
+my %newFile;
+for my $file (sort @paths) {
+    my $f = $file;
+    $f = "$1$renames{$2}$3" if $f =~ /^(.*\/)(\w+)(\.\w+)$/ && $renames{$2};
+    if ($f ne $file) {
+        $newFile{$file} = $f;
+    }
+}
+
+for my $file (sort @paths) {
+    if ($newFile{$file}) {
+        my $newFile = $newFile{$file};
+        print "Renaming $file to $newFile\n";
+        system "svn move $file $newFile";
+    }
+}
+
+# change all file contents
+
+for my $file (sort @paths) {
+    $file = $newFile{$file} if $newFile{$file};
+    my $contents;
+    {
+        local $/;
+        open FILE, $file or die;
+        $contents = <FILE>;
+        close FILE;
+    }
+    my $newContents = $contents;
+
+    for my $from (keys %renames) {
+        $newContents =~ s/\b$from(?!["\w])/$renames{$from}/g; # this " unconfuses Xcode syntax highlighting
+    }
+
+    if ($newContents ne $contents) {
+        open FILE, ">", $file or die;
+        print FILE $newContents;
+        close FILE;
+    }
+}
diff --git a/WebKitTools/Scripts/extract-localizable-strings b/WebKitTools/Scripts/extract-localizable-strings
new file mode 100755
index 0000000..420624b
--- /dev/null
+++ b/WebKitTools/Scripts/extract-localizable-strings
@@ -0,0 +1,351 @@
+#!/usr/bin/perl -w
+
+# Copyright (C) 2006, 2007 Apple Inc.  All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1.  Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer. 
+# 2.  Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution. 
+# 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+#     its contributors may be used to endorse or promote products derived
+#     from this software without specific prior written permission. 
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+# This script is like the genstrings tool (minus most of the options) with these differences.
+#
+#    1) It uses the names UI_STRING and UI_STRING_WITH_KEY for the macros, rather than the macros
+#       from NSBundle.h, and doesn't support tables (although they would be easy to add).
+#    2) It supports UTF-8 in key strings (and hence uses "" strings rather than @"" strings;
+#       @"" strings only reliably support ASCII since they are decoded based on the system encoding
+#       at runtime, so give different results on US and Japanese systems for example).
+#    3) It looks for strings that are not marked for localization, using both macro names that are
+#       known to be used for debugging in Intrigue source code and an exceptions file.
+#    4) It finds the files to work on rather than taking them as parameters, and also uses a
+#       hardcoded location for both the output file and the exceptions file.
+#       It would have been nice to use the project to find the source files, but it's too hard to
+#       locate source files after parsing a .pbxproj file.
+
+# The exceptions file has a list of strings in quotes, filenames, and filename/string pairs separated by :.
+
+use strict;
+
+my %isDebugMacro = ( ASSERT_WITH_MESSAGE => 1, LOG_ERROR => 1, ERROR => 1, NSURL_ERROR => 1, FATAL => 1, LOG => 1, LOG_WARNING => 1, UI_STRING_LOCALIZE_LATER => 1, LPCTSTR_UI_STRING_LOCALIZE_LATER => 1, UNLOCALIZED_STRING => 1, UNLOCALIZED_LPCTSTR => 1, dprintf => 1, NSException => 1, NSLog => 1, printf => 1 );
+
+@ARGV >= 1 or die "Usage: extract-localizable-strings <exceptions file> [ directory... ]\nDid you mean to run extract-webkit-localizable-strings instead?\n";
+
+my $exceptionsFile = shift @ARGV;
+-f $exceptionsFile or die "Couldn't find exceptions file $exceptionsFile\n";
+
+my $fileToUpdate = shift @ARGV;
+-f $fileToUpdate or die "Couldn't find file to update $fileToUpdate\n";
+
+my @directories = ();
+my @directoriesToSkip = ();
+if (@ARGV < 1) {
+    push(@directories, ".");
+} else {
+    for my $dir (@ARGV) {
+        if ($dir =~ /^-(.*)$/) {
+            push @directoriesToSkip, $1;
+        } else {
+            push @directories, $dir;
+        }
+    }
+}
+
+my $sawError = 0;
+
+my $localizedCount = 0;
+my $keyCollisionCount = 0;
+my $notLocalizedCount = 0;
+my $NSLocalizeCount = 0;
+
+my %exception;
+my %usedException;
+
+if (open EXCEPTIONS, $exceptionsFile) {
+    while (<EXCEPTIONS>) {
+        chomp;
+        if (/^"([^\\"]|\\.)*"$/ or /^[-_\/\w.]+.(h|m|mm|c|cpp)$/ or /^[-_\/\w.]+.(h|m|mm|c|cpp):"([^\\"]|\\.)*"$/) {
+            if ($exception{$_}) {
+                print "$exceptionsFile:$.:exception for $_ appears twice\n";
+                print "$exceptionsFile:$exception{$_}:first appearance\n";
+            } else {
+                $exception{$_} = $.;
+            }
+        } else {
+            print "$exceptionsFile:$.:syntax error\n";
+        }
+    }
+    close EXCEPTIONS;
+}
+
+my $quotedDirectoriesString = '"' . join('" "', @directories) . '"';
+for my $dir (@directoriesToSkip) {
+    $quotedDirectoriesString .= ' -path "' . $dir . '" -prune';
+}
+
+my @files = ( split "\n", `find $quotedDirectoriesString -name "*.h" -o -name "*.m" -o -name "*.mm" -o -name "*.c" -o -name "*.cpp"` );
+
+for my $file (sort @files) {
+    next if $file =~ /\/WebLocalizableStrings\.h$/;
+    next if $file =~ /\/icu\//;
+
+    $file =~ s-^./--;
+
+    open SOURCE, $file or die "can't open $file\n";
+    
+    my $inComment = 0;
+    
+    my $expected = "";
+    my $macroLine;
+    my $macro;
+    my $UIString;
+    my $key;
+    my $comment;
+    
+    my $string;
+    my $stringLine;
+    my $nestingLevel;
+    
+    my $previousToken = "";
+
+    while (<SOURCE>) {
+        chomp;
+        
+        # Handle continued multi-line comment.
+        if ($inComment) {
+            next unless s-.*\*/--;
+            $inComment = 0;
+        }
+    
+        # Handle all the tokens in the line.
+        while (s-^\s*([#\w]+|/\*|//|[^#\w/'"()\[\],]+|.)--) {
+            my $token = $1;
+            
+            if ($token eq "\"") {
+                if ($expected and $expected ne "a quoted string") {
+                    print "$file:$.:ERROR:found a quoted string but expected $expected\n";
+                    $sawError = 1;
+                    $expected = "";
+                }
+                if (s-^(([^\\$token]|\\.)*?)$token--) {
+                    if (!defined $string) {
+                        $stringLine = $.;
+                        $string = $1;
+                    } else {
+                        $string .= $1;
+                    }
+                } else {
+                    print "$file:$.:ERROR:mismatched quotes\n";
+                    $sawError = 1;
+                    $_ = "";
+                }
+                next;
+            }
+            
+            if (defined $string) {
+handleString:
+                if ($expected) {
+                    if (!defined $UIString) {
+                        # FIXME: Validate UTF-8 here?
+                        $UIString = $string;
+                        $expected = ",";
+                    } elsif (($macro =~ /UI_STRING_KEY$/) and !defined $key) {
+                        # FIXME: Validate UTF-8 here?
+                        $key = $string;
+                        $expected = ",";
+                    } elsif (!defined $comment) {
+                        # FIXME: Validate UTF-8 here?
+                        $comment = $string;
+                        $expected = ")";
+                    }
+                } else {
+                    if (defined $nestingLevel) {
+                        # In a debug macro, no need to localize.
+                    } elsif ($previousToken eq "#include" or $previousToken eq "#import") {
+                        # File name, no need to localize.
+                    } elsif ($previousToken eq "extern" and $string eq "C") {
+                        # extern "C", no need to localize.
+                    } elsif ($string eq "") {
+                        # Empty string can sometimes be localized, but we need not complain if not.
+                    } elsif ($exception{$file}) {
+                        $usedException{$file} = 1;
+                    } elsif ($exception{"\"$string\""}) {
+                        $usedException{"\"$string\""} = 1;
+                    } elsif ($exception{"$file:\"$string\""}) {
+                        $usedException{"$file:\"$string\""} = 1;
+                    } else {
+                        print "$file:$stringLine:\"$string\" is not marked for localization\n";
+                        $notLocalizedCount++;
+                    }
+                }
+                $string = undef;
+                last if !defined $token;
+            }
+            
+            $previousToken = $token;
+
+            if ($token =~ /^NSLocalized/ && $token !~ /NSLocalizedDescriptionKey/ && $token !~ /NSLocalizedStringFromTableInBundle/) {
+                print "$file:$.:ERROR:found a use of an NSLocalized macro; not supported\n";
+                $nestingLevel = 0 if !defined $nestingLevel;
+                $sawError = 1;
+                $NSLocalizeCount++;
+            } elsif ($token eq "/*") {
+                if (!s-^.*?\*/--) {
+                    $_ = ""; # If the comment doesn't end, discard the result of the line and set flag
+                    $inComment = 1;
+                }
+            } elsif ($token eq "//") {
+                $_ = ""; # Discard the rest of the line
+            } elsif ($token eq "'") {
+                if (!s-([^\\]|\\.)'--) { #' <-- that single quote makes the Project Builder editor less confused
+                    print "$file:$.:ERROR:mismatched single quote\n";
+                    $sawError = 1;
+                    $_ = "";
+                }
+            } else {
+                if ($expected and $expected ne $token) {
+                    print "$file:$.:ERROR:found $token but expected $expected\n";
+                    $sawError = 1;
+                    $expected = "";
+                }
+                if ($token =~ /UI_STRING(_KEY)?$/) {
+                    $expected = "(";
+                    $macro = $token;
+                    $UIString = undef;
+                    $key = undef;
+                    $comment = undef;
+                    $macroLine = $.;
+                } elsif ($token eq "(" or $token eq "[") {
+                    ++$nestingLevel if defined $nestingLevel;
+                    $expected = "a quoted string" if $expected;
+                } elsif ($token eq ",") {
+                    $expected = "a quoted string" if $expected;
+                } elsif ($token eq ")" or $token eq "]") {
+                    $nestingLevel = undef if defined $nestingLevel && !--$nestingLevel;
+                    if ($expected) {
+                        $key = $UIString if !defined $key;
+                        HandleUIString($UIString, $key, $comment, $file, $macroLine);
+                        $macro = "";
+                        $expected = "";
+                        $localizedCount++;
+                    }
+                } elsif ($isDebugMacro{$token}) {
+                    $nestingLevel = 0 if !defined $nestingLevel;
+                }
+            }
+        }
+            
+    }
+    
+    goto handleString if defined $string;
+    
+    if ($expected) {
+        print "$file:ERROR:reached end of file but expected $expected\n";
+        $sawError = 1;
+    }
+    
+    close SOURCE;
+}
+
+my %stringByKey;
+my %commentByKey;
+my %fileByKey;
+my %lineByKey;
+
+sub HandleUIString
+{
+    my ($string, $key, $comment, $file, $line) = @_;
+
+    my $bad = 0;
+    if (grep { $_ == 0xFFFD } unpack "U*", $string) {
+        print "$file:$line:ERROR:string for translation has illegal UTF-8 -- most likely a problem with the Text Encoding of the source file\n";
+        $bad = 1;
+    }
+    if ($string ne $key && grep { $_ == 0xFFFD } unpack "U*", $key) {
+        print "$file:$line:ERROR:key has illegal UTF-8 -- most likely a problem with the Text Encoding of the source file\n";
+        $bad = 1;
+    }
+    if (grep { $_ == 0xFFFD } unpack "U*", $comment) {
+        print "$file:$line:ERROR:comment for translation has illegal UTF-8 -- most likely a problem with the Text Encoding of the source file\n";
+        $bad = 1;
+    }
+    if ($bad) {
+        $sawError = 1;
+        return;
+    }
+    
+    if ($stringByKey{$key} && $stringByKey{$key} ne $string) {
+        print "$file:$line:encountered the same key, \"$key\", twice, with different strings\n";
+        print "$fileByKey{$key}:$lineByKey{$key}:previous occurrence\n";
+        $keyCollisionCount++;
+        return;
+    }
+    if ($commentByKey{$key} && $commentByKey{$key} ne $comment) {
+        print "$file:$line:encountered the same key, \"$key\", twice, with different comments\n";
+        print "$fileByKey{$key}:$lineByKey{$key}:previous occurrence\n";
+        $keyCollisionCount++;
+        return;
+    }
+
+    $fileByKey{$key} = $file;
+    $lineByKey{$key} = $line;
+    $stringByKey{$key} = $string;
+    $commentByKey{$key} = $comment;
+}
+
+print "\n" if $sawError || $notLocalizedCount || $NSLocalizeCount;
+
+my @unusedExceptions = sort grep { !$usedException{$_} } keys %exception;
+if (@unusedExceptions) {
+    for my $unused (@unusedExceptions) {
+        print "$exceptionsFile:$exception{$unused}:exception $unused not used\n";
+    }
+    print "\n";
+}
+
+print "$localizedCount localizable strings\n" if $localizedCount;
+print "$keyCollisionCount key collisions\n" if $keyCollisionCount;
+print "$notLocalizedCount strings not marked for localization\n" if $notLocalizedCount;
+print "$NSLocalizeCount uses of NSLocalize\n" if $NSLocalizeCount;
+print scalar(@unusedExceptions), " unused exceptions\n" if @unusedExceptions;
+
+if ($sawError) {
+    print "\nErrors encountered. Exiting without writing to $fileToUpdate.\n";
+    exit 1;
+}
+
+my $localizedStrings = "";
+
+for my $key (sort keys %commentByKey) {
+    $localizedStrings .= "/* $commentByKey{$key} */\n\"$key\" = \"$stringByKey{$key}\";\n\n";
+}
+
+# Write out the strings file in UTF-16 with a BOM.
+utf8::decode($localizedStrings) if $^V ge chr(5).chr(8);
+my $output = pack "n*", (0xFEFF, unpack "U*", $localizedStrings);
+
+if (-e "$fileToUpdate") {
+    open STRINGS, ">", "$fileToUpdate" or die;
+    print STRINGS $output;
+    close STRINGS;
+} else {
+    print "$fileToUpdate does not exist\n";
+    exit 1;
+}
diff --git a/WebKitTools/Scripts/find-extra-includes b/WebKitTools/Scripts/find-extra-includes
new file mode 100755
index 0000000..1286cd5
--- /dev/null
+++ b/WebKitTools/Scripts/find-extra-includes
@@ -0,0 +1,102 @@
+#!/usr/bin/perl -w
+
+# Copyright (C) 2005 Apple Computer, Inc.  All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1.  Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer. 
+# 2.  Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution. 
+# 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+#     its contributors may be used to endorse or promote products derived
+#     from this software without specific prior written permission. 
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+# "find-extra-includes" script for Web Kit Open Source Project
+
+use strict;
+use File::Find;
+
+find(\&wanted, @ARGV ? @ARGV : ".");
+
+my %paths;
+my %includes;
+
+sub wanted
+{
+    my $file = $_;
+
+    if ($file eq "icu") {
+        $File::Find::prune = 1;
+        return;
+    }
+
+    if ($file !~ /^\./ && $file =~ /\.(h|cpp|c|mm|m)$/) {
+        $paths{$file} = $File::Find::name;
+        open FILE, $file or die;
+        while (<FILE>) {
+            if (m-^\s*#\s*(include|import)\s+["<]((\S+/)*)(\S+)[">]-) {
+                my $include = ($2 eq "sys/" ? $2 : "") . $4;
+                $includes{$file}{$include}++;
+            }
+        }
+        close FILE;
+    }
+}
+
+my %totalIncludes;
+
+sub fillOut
+{
+    my ($file) = @_;
+
+    return if defined $totalIncludes{$file};
+
+    for my $include (keys %{ $includes{$file} }) {
+        $totalIncludes{$file}{$include} = 1;
+        fillOut($include);
+        for my $i (keys %{ $totalIncludes{$include} }) {
+            $totalIncludes{$file}{$i} = 1;
+        }
+    }
+}
+
+sub check
+{
+    my ($file) = @_;
+
+    for my $include (keys %{ $includes{$file} }) {
+        fillOut($include);
+    }
+    for my $i1 (sort keys %{ $includes{$file} }) {
+        for my $i2 (keys %{ $includes{$file} }) {
+            next if $i1 eq $i2;
+            if ($totalIncludes{$i2}{$i1}) {
+                my $b1 = $i1;
+                my $b2 = $file;
+                $b1 =~ s/\..+$//;
+                $b2 =~ s/\..+$//;
+                print "$paths{$file} does not need to include $i1, because $i2 does\n" if $b1 ne $b2;
+                last;
+            }
+        }
+    }
+}
+
+for my $file (sort keys %includes) {
+    check($file);
+}
diff --git a/WebKitTools/Scripts/find-included-framework-headers b/WebKitTools/Scripts/find-included-framework-headers
new file mode 100755
index 0000000..3e7aaf6
--- /dev/null
+++ b/WebKitTools/Scripts/find-included-framework-headers
@@ -0,0 +1,10 @@
+#!/bin/sh
+
+FILE_EXTENSIONS_TO_SEARCH="cpp h m mm"
+
+for framework in $*; do
+    echo -e "\n$framework\n=================="
+    for ext in ${FILE_EXTENSIONS_TO_SEARCH}; do
+        find . -name "*.$ext" -exec grep $framework {} ';' | grep '\(include\|import\)' | sed -e 's|.*/\(.*\.h\).*|\1|'
+    done | sort | uniq
+done
diff --git a/WebKitTools/Scripts/gdb-safari b/WebKitTools/Scripts/gdb-safari
new file mode 100755
index 0000000..f87f965
--- /dev/null
+++ b/WebKitTools/Scripts/gdb-safari
@@ -0,0 +1,83 @@
+#!/usr/bin/perl -w
+
+# Copyright (C) 2005 Apple Computer, Inc.  All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1.  Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer. 
+# 2.  Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution. 
+# 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+#     its contributors may be used to endorse or promote products derived
+#     from this software without specific prior written permission. 
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+# Simplified "run under gdb" script for WebKit Open Source Project.
+
+use strict;
+use File::Temp qw/:mktemp/;
+use FindBin;
+use Getopt::Long;
+use lib $FindBin::Bin;
+use webkitdirs;
+
+my $programName = basename($0);
+my $showHelp = 0;
+my $run64Bit;
+
+my $usage = <<EOF;
+Usage: $programName [options]
+  --help                          Show this help message
+  --64-bit                        Run in 64-bit mode
+EOF
+
+my $getOptionsResult = GetOptions(
+    'help' => \$showHelp,
+    '64-bit!' => \$run64Bit
+);
+
+if (!$getOptionsResult || $showHelp) {
+    print STDERR $usage;
+    exit 1;
+}
+
+setRun64Bit($run64Bit);
+setConfiguration();
+my $productDir = productDir();
+my $safariPath = safariPath();
+
+# Check to see that gdb is in the usual place.
+my $gdbPath = "/usr/bin/gdb";
+die "Can't find gdb executable. Is gdb installed?\n" unless -x $gdbPath;
+
+# Check to see that all the frameworks are built.
+checkFrameworks();
+
+# Put a command to set DYLD_FRAMEWORK_PATH in a temp file.
+# Also set WEBKIT_UNSET_DYLD_FRAMEWORK_PATH to YES in this environment, so that
+# executables launched by Safari don't inherit using the new frameworks.
+my ($fh, $path) = mkstemp("/tmp/gdb-safari-XXXX");
+print $fh "set env DYLD_FRAMEWORK_PATH $productDir\n";
+print $fh "set env WEBKIT_UNSET_DYLD_FRAMEWORK_PATH YES\n";
+
+my @architectureFlags = ("-arch", preferredArchitecture()) if isOSX();
+# Start up Safari.
+print "Start Safari under gdb with DYLD_FRAMEWORK_PATH set to point to built WebKit in $productDir.\n";
+exec $gdbPath, "-x", $path, @architectureFlags, $safariPath or die;
+
+# Delete the temporary file.
+unlink0($fh, $path) or die "Error unlinking file $path safely"; 
diff --git a/WebKitTools/Scripts/generate-coverage-data b/WebKitTools/Scripts/generate-coverage-data
new file mode 100644
index 0000000..7ed36aa
--- /dev/null
+++ b/WebKitTools/Scripts/generate-coverage-data
@@ -0,0 +1,71 @@
+#!/usr/bin/perl -w
+
+# Copyright (C) 2005, 2006 Apple Computer, Inc.  All rights reserved.
+# Copyright (C) 2007 Holger Hans Peter Freyther.  All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1.  Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer. 
+# 2.  Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution. 
+# 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+#     its contributors may be used to endorse or promote products derived
+#     from this software without specific prior written permission. 
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+# Simple script to build, run and visualize coverage information
+
+use strict;
+use File::Basename;
+use File::Spec;
+use FindBin;
+use Getopt::Long qw(:config pass_through);
+use lib $FindBin::Bin;
+use webkitdirs;
+use POSIX;
+
+# Generate a name for our results
+my $svnVersion = determineCurrentSVNRevision();
+my @timeData = localtime(time);
+my $resultName = $svnVersion . "-" . join('_', @timeData);
+my @otherOptions = ();
+
+# Move to the source directory
+# Delete old gcov files
+# Compile WebKit and run the tests
+# Generate the coverage graph...
+# Upload
+
+$ENV{'WEBKIT_COVERAGE_BUILD'} = 1;
+chdirWebKit();
+
+# Clean-up old files
+print "Cleaning up\n";
+system("if [ -d WebKitBuild ]; then find WebKitBuild -name '*.gcda' -delete; fi;") == 0 or die;
+
+
+print "Building and testing\n";
+system("WebKitTools/Scripts/build-webkit", "--coverage", @ARGV) == 0 or die;
+system "WebKitTools/Scripts/run-webkit-tests", "--no-launch-safari";
+system "WebKitTools/Scripts/run-javascriptcore-tests", "--coverage", @ARGV;
+
+# Collect the data and generate a report
+print "Collecting coverage data\n";
+system("WebKitTools/CodeCoverage/run-generate-coverage-data", $resultName,  "WebKitBuild/Coverage") == 0 or die;
+system("WebKitTools/CodeCoverage/regenerate-coverage-display", "WebKitBuild/Coverage", "WebKitBuild/Coverage/html") == 0 or die;
+
+print "Done\n";
diff --git a/WebKitTools/Scripts/make-js-test-wrappers b/WebKitTools/Scripts/make-js-test-wrappers
new file mode 100755
index 0000000..4ac21ea
--- /dev/null
+++ b/WebKitTools/Scripts/make-js-test-wrappers
@@ -0,0 +1,159 @@
+#!/usr/bin/perl -w
+
+# Copyright (C) 2006, 2007, 2008 Apple Inc.  All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1.  Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer. 
+# 2.  Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution. 
+# 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+#     its contributors may be used to endorse or promote products derived
+#     from this software without specific prior written permission. 
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+# Script to generate HTML wrappers for JavaScript tests from templates
+
+use strict;
+
+use FindBin;
+use lib $FindBin::Bin;
+
+use File::Basename;
+use File::Find;
+use Getopt::Long;
+use webkitdirs;
+
+sub directoryFilter;
+sub findTemplateFiles(@);
+
+my $showHelp;
+
+my $result = GetOptions(
+    "help"       => \$showHelp,
+);
+
+if (!$result || $showHelp) {
+    print STDERR basename($0) . " [-h|--help] [path ...]\n";
+    exit 1;
+}
+
+setConfiguration();
+my $productDir = productDir();
+
+chdirWebKit();
+
+my @templates = findTemplateFiles(@ARGV);
+
+for my $tfile (@templates) {
+
+    my $tpath = $tfile;
+    $tpath =~ s:/resources/TEMPLATE.html$::;
+
+    print "${tpath}\n";
+
+    chdirWebKit();
+    chdir($tpath);
+
+    my @files;
+    my $fileFilter = sub {
+        push @files, $File::Find::name if substr($_, -3) eq ".js";
+    };
+    find({ preprocess => \&directoryFilter, wanted => $fileFilter }, "resources");
+
+    open TEMPLATE, "<resources/TEMPLATE.html";
+    my $template = do { local $/; <TEMPLATE> };
+    close TEMPLATE;
+
+    my $templateNegative = $template;
+    if (-e "resources/TEMPLATE-n.html") {
+        open TEMPLATE, "<resources/TEMPLATE-n.html";
+        $templateNegative = do { local $/; <TEMPLATE> };
+        close TEMPLATE;
+    }
+
+    for my $file (@files) {
+        next if $file =~ /js-test-.*\.js$/;
+        next if $file =~ /SVGTestCase\.js/;
+
+        next if $file =~ m:resources/NSResolver-exceptions\.js$:;
+        next if $file =~ m:resources/attr-case-sensitivity\.js$:;
+        next if $file =~ m:resources/codegen-temporaries-multiple-global-blocks-1\.js$:;
+        next if $file =~ m:resources/codegen-temporaries-multiple-global-blocks-2\.js$:;
+        next if $file =~ m:resources/constructors-cached-navigate\.js$:;
+        next if $file =~ m:resources/frame-loading-via-document-write\.js$:;
+        next if $file =~ m:resources/id-fastpath-almost-strict\.js$:;
+        next if $file =~ m:resources/id-fastpath-strict\.js$:;
+        next if $file =~ m:resources/intersectsNode\.js$:;
+        next if $file =~ m:resources/p-in-scope\.js$:;
+        next if $file =~ m:resources/script-element-gc\.js$:;
+        next if $file =~ m:resources/script-element-gc\.js$:;
+        next if $file =~ m:resources/script3\.js$:;
+        next if $file =~ m:resources/script4\.js$:;
+        next if $file =~ m:resources/script5\.js$:;
+        next if $file =~ m:resources/select-options-remove\.js$:;
+        next if $file =~ m:resources/shadow-offset\.js$:;
+        next if $file =~ m:resources/tabindex-focus-blur-all\.js$:;
+        next if $file =~ m:resources/use-instanceRoot-event-bubbling\.js$:;
+        next if $file =~ m:resources/use-instanceRoot-event-listeners\.js$:;
+        next if $file =~ m:resources/wrapper-identity-base\.js$:;
+        next if $file =~ m:resources/xhtml-scripts\.js$:;
+
+        my $html = $file;
+        $html =~ s:resources/(.*)\.js:$1.html:;
+        next if -f "$html-disabled";
+
+        system("grep -q 'successfullyParsed =' $file");
+        if ($? != 0) {
+            `echo "" >> "${file}"`;
+            `echo "var successfullyParsed = true;" >> "${file}"`;
+        }
+        
+        print "    ${html}\n";
+        open HTML, ">$html";
+        my $output = ($file =~ /-n\.js/) ? $templateNegative : $template;
+        $output =~ s:YOUR_JS_FILE_HERE:$file:;
+        print HTML $output;
+        
+        close HTML;
+    }
+}
+
+exit 0;
+
+sub directoryFilter
+{
+    return () if basename($File::Find::dir) eq ".svn";
+    return @_;
+}
+
+sub findTemplateFiles(@) {
+    my @args = @_;
+    my @templateFiles;
+
+    push @args, "LayoutTests" if scalar(@args) == 0;
+
+    my @paths = map { -f $_ ? dirname($_) : $_ } @args;
+
+    my $fileFilter = sub {
+        push @templateFiles, $File::Find::name if $_ eq "TEMPLATE.html";
+    };
+
+    find({ preprocess => \&directoryFilter, wanted => $fileFilter }, @paths);
+
+    return @templateFiles;
+}
diff --git a/WebKitTools/Scripts/num-cpus b/WebKitTools/Scripts/num-cpus
new file mode 100755
index 0000000..c5f28a1
--- /dev/null
+++ b/WebKitTools/Scripts/num-cpus
@@ -0,0 +1,16 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+
+use Win32API::Registry 0.21 qw( :ALL );
+
+
+my $key;
+my $i = 0;
+while (RegOpenKeyEx(HKEY_LOCAL_MACHINE, "HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\$i", 0, KEY_READ, $key)) {
+    $i++;
+    RegCloseKey($key);
+}
+
+print "$i\n"; 
diff --git a/WebKitTools/Scripts/parallelcl b/WebKitTools/Scripts/parallelcl
new file mode 100755
index 0000000..532079f
--- /dev/null
+++ b/WebKitTools/Scripts/parallelcl
@@ -0,0 +1,224 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+
+use File::Basename;
+use File::Spec;
+use File::Temp;
+use POSIX;
+
+sub makeJob(\@$);
+sub forkAndCompileFiles(\@$);
+sub Exec($);
+sub waitForChild(\@);
+sub cleanup(\@);
+
+my $debug = 0;
+
+chomp(my $clexe = `cygpath -u '$ENV{'VS80COMNTOOLS'}/../../VC/bin/cl.exe'`);
+
+if ($debug) {
+    print STDERR "Received " . @ARGV . " arguments:\n";
+    foreach my $arg (@ARGV) {
+        print STDERR "$arg\n";
+    }
+}
+
+my $commandFile;
+foreach my $arg (@ARGV) {
+    if ($arg =~ /^[\/-](E|EP|P)$/) {
+        print STDERR "The invoking process wants preprocessed source, so let's hand off this whole command to the real cl.exe\n" if $debug;
+        Exec("\"$clexe\" \"" . join('" "', @ARGV) . "\"");
+    } elsif ($arg =~ /^@(.*)$/) {
+        chomp($commandFile = `cygpath -u '$1'`);
+    }
+}
+
+die "No command file specified!" unless $commandFile;
+die "Couldn't find $commandFile!" unless -f $commandFile;
+
+my @sources;
+
+open(COMMAND, '<:raw:encoding(UTF16-LE):crlf:utf8', $commandFile) or die "Couldn't open $commandFile!";
+
+# The first line of the command file contains all the options to cl.exe plus the first (possibly quoted) filename
+my $firstLine = <COMMAND>;
+$firstLine =~ s/\r?\n$//;
+
+# To find the start of the first filename, look for either the last space on the line.
+# If the filename is quoted, the last character on the line will be a quote, so look for the quote before that.
+my $firstFileIndex;
+print STDERR "Last character of first line = '" . substr($firstLine, -1, 1) . "'\n" if $debug;
+if (substr($firstLine, -1, 1) eq '"') {
+    print STDERR "First file is quoted\n" if $debug;
+    $firstFileIndex = rindex($firstLine, '"', length($firstLine) - 2);
+} else {
+    print STDERR "First file is NOT quoted\n" if $debug;
+    $firstFileIndex = rindex($firstLine, ' ') + 1;
+}
+
+my $options = substr($firstLine, 0, $firstFileIndex) . join(' ', @ARGV[1 .. $#ARGV]);
+my $possibleFirstFile = substr($firstLine, $firstFileIndex);
+if ($possibleFirstFile =~ /\.(cpp|c)/) {
+    push(@sources, $possibleFirstFile);
+} else {
+    $options .= " $possibleFirstFile";
+}
+
+print STDERR "######## Found options $options ##########\n" if $debug;
+print STDERR "####### Found first source file $sources[0] ########\n" if @sources && $debug;
+
+# The rest of the lines of the command file just contain source files, one per line
+while (my $source = <COMMAND>) {
+    chomp($source);
+    $source =~ s/^\s+//;
+    $source =~ s/\s+$//;
+    push(@sources, $source) if length($source);
+}
+close(COMMAND);
+
+my $numSources = @sources;
+exit unless $numSources > 0;
+
+my $numJobs;
+if ($options =~ s/-j\s*([0-9]+)//) {
+    $numJobs = $1;
+} else {
+    chomp($numJobs = `num-cpus`);
+}
+
+print STDERR "\n\n####### RUNNING AT MOST $numJobs PARALLEL INSTANCES OF cl.exe ###########\n\n";# if $debug;
+
+# Magic determination of job size
+# The hope is that by splitting the source files up into 2*$numJobs pieces, we
+# won't suffer too much if one job finishes much more quickly than another.
+# However, we don't want to split it up too much due to cl.exe overhead, so set
+# the minimum job size to 5.
+my $jobSize = POSIX::ceil($numSources / (2 * $numJobs));
+$jobSize = $jobSize < 5 ? 5 : $jobSize;
+
+print STDERR "######## jobSize = $jobSize ##########\n" if $debug;
+
+# Sort the source files randomly so that we don't end up with big clumps of large files (aka SVG)
+sub fisher_yates_shuffle(\@)
+{
+    my ($array) = @_;
+    for (my $i = @{$array}; --$i; ) {
+        my $j = int(rand($i+1));
+        next if $i == $j;
+        @{$array}[$i,$j] = @{$array}[$j,$i];
+    }
+}
+
+fisher_yates_shuffle(@sources);    # permutes @array in place
+
+my @children;
+my @tmpFiles;
+my $status = 0;
+while (@sources) {
+    while (@sources && @children < $numJobs) {
+        my $pid;
+        my $tmpFile;
+        my $job = makeJob(@sources, $jobSize);
+        ($pid, $tmpFile) = forkAndCompileFiles(@{$job}, $options);
+
+        print STDERR "####### Spawned child with PID $pid and tmpFile $tmpFile ##########\n" if $debug;
+        push(@children, $pid);
+        push(@tmpFiles, $tmpFile);
+    }
+
+    $status |= waitForChild(@children);
+}
+
+while (@children) {
+    $status |= waitForChild(@children);
+}
+cleanup(@tmpFiles);
+
+exit WEXITSTATUS($status);
+
+
+sub makeJob(\@$)
+{
+    my ($files, $jobSize) = @_;
+
+    my @job;
+    if (@{$files} > ($jobSize * 1.5)) {
+        @job = splice(@{$files}, -$jobSize);
+    } else {
+        # Compile all the remaining files in this job to avoid having a small job later
+        @job = splice(@{$files});
+    }
+
+    return \@job;
+}
+
+sub forkAndCompileFiles(\@$)
+{
+    print STDERR "######## forkAndCompileFiles()\n" if $debug;
+    my ($files, $options) = @_;
+
+    if ($debug) {
+        foreach my $file (@{$files}) {
+            print STDERR "######## $file\n";
+        }
+    }
+
+    my (undef, $tmpFile) = File::Temp::tempfile('clcommandXXXXX', DIR => File::Spec->tmpdir, OPEN => 0);
+
+    my $pid = fork();
+    die "Fork failed" unless defined($pid);
+
+    unless ($pid) {
+        # Child process
+        open(TMP, '>:raw:encoding(UTF16-LE):crlf:utf8', $tmpFile) or die "Couldn't open $tmpFile";
+        print TMP "$options\n";
+        foreach my $file (@{$files}) {
+            print TMP "$file\n";
+        }
+        close(TMP);
+        
+        chomp(my $winTmpFile = `cygpath -m $tmpFile`);
+        Exec "\"$clexe\" \@\"$winTmpFile\"";
+    } else {
+        return ($pid, $tmpFile);
+    }
+}
+
+sub Exec($)
+{
+    my ($command) = @_;
+
+    print STDERR "Exec($command)\n" if $debug;
+
+    exec($command);
+}
+
+sub waitForChild(\@)
+{
+    my ($children) = @_;
+
+    return unless @{$children};
+
+    my $deceased = wait();
+    my $status = $?;
+    print STDERR "######## Child with PID $deceased finished ###########\n" if $debug;
+    for (my $i = 0; $i < @{$children}; $i++) {
+        if ($children->[$i] == $deceased) {
+            splice(@{$children}, $i, 1);
+            last;
+        }
+    }
+
+    return $status;
+}
+
+sub cleanup(\@)
+{
+    my ($tmpFiles) = @_;
+
+    foreach my $file (@{$tmpFiles}) {
+        unlink $file;
+    }
+}
diff --git a/WebKitTools/Scripts/parse-malloc-history b/WebKitTools/Scripts/parse-malloc-history
new file mode 100755
index 0000000..76ca74b
--- /dev/null
+++ b/WebKitTools/Scripts/parse-malloc-history
@@ -0,0 +1,154 @@
+#!/usr/bin/perl
+
+# Copyright (C) 2007 Apple Inc. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1.  Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer. 
+# 2.  Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution. 
+# 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+#     its contributors may be used to endorse or promote products derived
+#     from this software without specific prior written permission. 
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+# Parses the callstacks in a file with malloc_history formatted content, sorting
+# based on total number of bytes allocated, and filtering based on command-line
+# parameters.
+
+use Getopt::Long;
+use File::Basename;
+
+use strict;
+use warnings;
+
+sub commify($);
+
+sub main()
+{
+    my $usage =
+        "Usage: " . basename($0) . " [options] malloc_history.txt\n" .
+        "  --grep-regexp        Include only call stacks that match this regular expression.\n" .
+        "  --byte-minimum       Include only call stacks with allocation sizes >= this value.\n" .
+        "  --merge-regexp       Merge all call stacks that match this regular expression.\n" .
+        "  --merge-depth        Merge all call stacks that match at this stack depth and above.\n";
+
+    my $grepRegexp = "";
+    my $byteMinimum = "";
+    my @mergeRegexps = ();
+    my $mergeDepth = "";
+    my $getOptionsResult = GetOptions(
+        "grep-regexp:s" => \$grepRegexp,
+        "byte-minimum:i" => \$byteMinimum,
+        "merge-regexp:s" => \@mergeRegexps,
+        "merge-depth:i" => \$mergeDepth
+    );
+    my $fileName = $ARGV[0];
+    die $usage if (!$getOptionsResult || !$fileName);
+
+    open FILE, "<$fileName" or die "bad file: $fileName";
+    my @file = <FILE>;
+    close FILE;
+
+    my %callstacks = ();
+    my $byteCountTotal = 0;
+
+    for (my $i = 0; $i < @file; $i++) {
+        my $line = $file[$i];
+        my ($callCount, $byteCount);
+        
+        next if $line =~ /^\-/;
+
+        # First try malloc_history format
+        #   6 calls for 664 bytes thread_ffffffff |0x0 | start
+        ($callCount, $byteCount) = ($line =~ /(\d+) calls for (\d+) bytes/);
+        
+        # Then try leaks format
+        #   Leak: 0x0ac3ca40  size=48
+        #   0x00020001 0x00000001 0x00000000 0x00000000     ................
+        #   Call stack: [thread ffffffff]: | 0x0 | start
+        if (!$callCount || !$byteCount) {
+            $callCount = 1;
+            ($byteCount) = ($line =~ /Leak: [x[:xdigit:]]*  size=(\d+)/);
+
+            if ($byteCount) {
+                while (!($line =~ "Call stack: ")) {
+                    $i++;
+                    $line = $file[$i];
+                }
+            }
+        }
+        
+        # Then give up
+        next if (!$callCount || !$byteCount);
+        
+        $byteCountTotal += $byteCount;
+
+        next if ($grepRegexp && !($line =~ $grepRegexp));
+
+        my $callstackBegin = 0;
+        if ($mergeDepth) {
+            # count stack frames backwards from end of callstack
+            $callstackBegin = length($line);
+            for (my $pipeCount = 0; $pipeCount < $mergeDepth; $pipeCount++) {
+                my $rindexResult = rindex($line, "|", $callstackBegin - 1);
+                last if $rindexResult == -1;
+                $callstackBegin = $rindexResult;
+            }
+        } else {
+            # start at beginning of callstack
+            $callstackBegin = index($line, "|");
+        }
+
+        my $callstack = substr($line, $callstackBegin + 2); # + 2 skips "| "
+        for my $regexp (@mergeRegexps) {
+            if ($callstack =~ $regexp) {
+                $callstack = $regexp . "\n";
+                last;
+            }
+        }
+        
+        if (!$callstacks{$callstack}) {
+            $callstacks{$callstack} = {"callCount" => 0, "byteCount" => 0};
+        }
+
+        $callstacks{$callstack}{"callCount"} += $callCount;
+        $callstacks{$callstack}{"byteCount"} += $byteCount;
+    }
+
+    my $byteCountTotalReported = 0;
+    for my $callstack (sort { $callstacks{$b}{"byteCount"} <=> $callstacks{$a}{"byteCount"} } keys %callstacks) {
+        my $callCount = $callstacks{$callstack}{"callCount"};
+        my $byteCount = $callstacks{$callstack}{"byteCount"};
+        last if ($byteMinimum && $byteCount < $byteMinimum);
+
+        $byteCountTotalReported += $byteCount;
+        print commify($callCount) . " calls for " . commify($byteCount) . " bytes: $callstack\n";
+    }
+
+    print "total: " . commify($byteCountTotalReported) . " bytes (" . commify($byteCountTotal - $byteCountTotalReported) . " bytes excluded).\n";
+}
+
+exit(main());
+
+# Copied from perldoc -- please excuse the style
+sub commify($)
+{
+    local $_  = shift;
+    1 while s/^([-+]?\d+)(\d{3})/$1,$2/;
+    return $_;
+}
diff --git a/WebKitTools/Scripts/pdevenv b/WebKitTools/Scripts/pdevenv
new file mode 100755
index 0000000..1931211
--- /dev/null
+++ b/WebKitTools/Scripts/pdevenv
@@ -0,0 +1,25 @@
+#!/usr/bin/perl -w
+
+use strict;
+use warnings;
+
+use File::Temp qw/tempfile/;
+use FindBin;
+
+my ($fh, $path) = tempfile(UNLINK => 0, SUFFIX => '.cmd') or die;
+
+chomp(my $vcBin = `cygpath -w "$FindBin::Bin/../vcbin"`);
+
+print $fh "\@echo off\n\n";
+print $fh "call \"\%VS80COMNTOOLS\%\\vsvars32.bat\"\n\n";
+print $fh "set PATH=$vcBin;\%PATH\%\n\n";
+print $fh "IF EXIST \"\%VSINSTALLDIR\%\\Common7\\IDE\\devenv.com\" (devenv.com /useenv " . join(" ", @ARGV) . ") ELSE ";
+print $fh "VCExpress.exe /useenv " . join(" ", @ARGV) . "\n";
+
+close $fh;
+
+chmod 0755, $path;
+
+chomp($path = `cygpath -w -s '$path'`);
+
+exec("cmd /c \"call $path\"");
diff --git a/WebKitTools/Scripts/prepare-ChangeLog b/WebKitTools/Scripts/prepare-ChangeLog
new file mode 100755
index 0000000..ff4ce80
--- /dev/null
+++ b/WebKitTools/Scripts/prepare-ChangeLog
@@ -0,0 +1,1436 @@
+#!/usr/bin/perl -w
+# -*- Mode: perl; indent-tabs-mode: nil; c-basic-offset: 2  -*-
+
+#
+#  Copyright (C) 2000, 2001 Eazel, Inc.
+#  Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007 Apple Inc.  All rights reserved.
+#
+#  prepare-ChangeLog is free software; you can redistribute it and/or
+#  modify it under the terms of the GNU General Public
+#  License as published by the Free Software Foundation; either
+#  version 2 of the License, or (at your option) any later version.
+#
+#  prepare-ChangeLog is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#  General Public License for more details.
+#
+#  You should have received a copy of the GNU General Public
+#  License along with this program; if not, write to the Free
+#  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+
+
+# Perl script to create a ChangeLog entry with names of files
+# and functions from a diff.
+#
+# Darin Adler <[email protected]>, started 20 April 2000
+# Java support added by Maciej Stachowiak <[email protected]>
+# Objective-C, C++ and Objective-C++ support added by Maciej Stachowiak <[email protected]>
+# Git support added by Adam Roben <[email protected]>
+
+
+#
+# TODO:
+#   List functions that have been removed too.
+#   Decide what a good logical order is for the changed files
+#     other than a normal text "sort" (top level first?)
+#     (group directories?) (.h before .c?)
+#   Handle yacc source files too (other languages?).
+#   Help merge when there are ChangeLog conflicts or if there's
+#     already a partly written ChangeLog entry.
+#   Add command line option to put the ChangeLog into a separate
+#     file or just spew it out stdout.
+#   Add SVN version numbers for commit (can't do that until
+#     the changes are checked in, though).
+#   Work around diff stupidity where deleting a function that starts
+#     with a comment makes diff think that the following function
+#     has been changed (if the following function starts with a comment
+#     with the same first line, such as /**)
+#   Work around diff stupidity where deleting an entire function and
+#     the blank lines before it makes diff think you've changed the
+#     previous function.
+
+use strict;
+use warnings;
+
+use File::Basename;
+use File::Spec;
+use FindBin;
+use Getopt::Long;
+use lib $FindBin::Bin;
+use POSIX qw(strftime);
+use VCSUtils;
+
+sub changeLogDate($);
+sub firstDirectoryOrCwd();
+sub diffFromToString();
+sub diffCommand(@);
+sub statusCommand(@);
+sub createPatchCommand($);
+sub diffHeaderFormat();
+sub findOriginalFileFromSvn($);
+sub generateFileList(\@\@\%);
+sub gitConfig($);
+sub isModifiedStatus($);
+sub isAddedStatus($);
+sub isConflictStatus($);
+sub statusDescription($$);
+sub extractLineRange($);
+sub canonicalizePath($);
+sub testListForChangeLog(@);
+sub get_function_line_ranges($$);
+sub get_function_line_ranges_for_c($$);
+sub get_function_line_ranges_for_java($$);
+sub get_function_line_ranges_for_javascript($$);
+sub method_decl_to_selector($);
+sub processPaths(\@);
+sub reviewerAndDescriptionForGitCommit($);
+
+# Project time zone for Cupertino, CA, US
+my $changeLogTimeZone = "PST8PDT";
+
+my $gitCommit = 0;
+my $gitReviewer = "";
+my $openChangeLogs = 0;
+my $showHelp = 0;
+my $spewDiff = $ENV{"PREPARE_CHANGELOG_DIFF"};
+my $updateChangeLogs = 1;
+my $parseOptionsResult =
+    GetOptions("diff|d!" => \$spewDiff,
+               "git-commit:s" => \$gitCommit,
+               "git-reviewer:s" => \$gitReviewer,
+               "help|h!" => \$showHelp,
+               "open|o!" => \$openChangeLogs,
+               "update!" => \$updateChangeLogs);
+if (!$parseOptionsResult || $showHelp) {
+    print STDERR basename($0) . " [-d|--diff] [-h|--help] [-o|--open] [--git-commit=<committish>] [--git-reviewer=<name>] [svndir1 [svndir2 ...]]\n";
+    print STDERR "  -d|--diff      Spew diff to stdout when running\n";
+    print STDERR "  --git-commit   Populate the ChangeLogs from the specified git commit\n";
+    print STDERR "  --git-reviewer When populating the ChangeLogs from a git commit claim that the spcified name reviewed the change.\n";
+    print STDERR "                 This option is useful when the git commit lacks a Signed-Off-By: line\n";
+    print STDERR "  -h|--help      Show this help message\n";
+    print STDERR "  -o|--open      Open ChangeLogs in an editor when done\n";
+    print STDERR "  --[no-]update  Update ChangeLogs from svn before adding entry (default: update)\n";
+    exit 1;
+}
+
+my %paths = processPaths(@ARGV);
+
+my $isGit = isGitDirectory(firstDirectoryOrCwd());
+my $isSVN = isSVNDirectory(firstDirectoryOrCwd());
+
+$isSVN || $isGit || die "Couldn't determine your version control system.";
+
+# Find the list of modified files
+my @changed_files;
+my $changed_files_string;
+my %changed_line_ranges;
+my %function_lists;
+my @conflict_files;
+
+my $SVN = "svn";
+my $GIT = "git";
+
+my %supportedTestExtensions = map { $_ => 1 } qw(html shtml svg xml xhtml pl php);
+my @addedRegressionTests = ();
+my $didChangeRegressionTests = 0;
+
+generateFileList(@changed_files, @conflict_files, %function_lists);
+
+if (!@changed_files && !@conflict_files && !keys %function_lists) {
+    print STDERR "  No changes found.\n";
+    exit 1;
+}
+
+if (@conflict_files) {
+    print STDERR "  The following files have conflicts. Run prepare-ChangeLog again after fixing the conflicts:\n";
+    print STDERR join("\n", @conflict_files), "\n";
+    exit 1;
+}
+
+if (@changed_files) {
+    $changed_files_string = "'" . join ("' '", @changed_files) . "'";
+
+    # For each file, build a list of modified lines.
+    # Use line numbers from the "after" side of each diff.
+    print STDERR "  Reviewing diff to determine which lines changed.\n";
+    my $file;
+    open DIFF, "-|", diffCommand(@changed_files) or die "The diff failed: $!.\n";
+    while (<DIFF>) {
+        $file = makeFilePathRelative($1) if $_ =~ diffHeaderFormat();
+        if (defined $file) {
+            my ($start, $end) = extractLineRange($_);
+            if ($start >= 0 && $end >= 0) {
+                push @{$changed_line_ranges{$file}}, [ $start, $end ];
+            } elsif (/DO_NOT_COMMIT/) {
+                print STDERR "WARNING: file $file contains the string DO_NOT_COMMIT, line $.\n";
+            }
+        }
+    }
+    close DIFF;
+}
+
+# For each source file, convert line range to function list.
+if (%changed_line_ranges) {
+    print STDERR "  Extracting affected function names from source files.\n";
+    foreach my $file (keys %changed_line_ranges) {
+        # Only look for function names in certain source files.
+        next unless $file =~ /\.(c|cpp|m|mm|h|java|js)/;
+    
+        # Find all the functions in the file.
+        open SOURCE, $file or next;
+        my @function_ranges = get_function_line_ranges(\*SOURCE, $file);
+        close SOURCE;
+    
+        # Find all the modified functions.
+        my @functions;
+        my %saw_function;
+        my @change_ranges = (@{$changed_line_ranges{$file}}, []);
+        my @change_range = (0, 0);
+        FUNCTION: foreach my $function_range_ref (@function_ranges) {
+            my @function_range = @$function_range_ref;
+    
+            # Advance to successive change ranges.
+            for (;; @change_range = @{shift @change_ranges}) {
+                last FUNCTION unless @change_range;
+    
+                # If past this function, move on to the next one.
+                next FUNCTION if $change_range[0] > $function_range[1];
+    
+                # If an overlap with this function range, record the function name.
+                if ($change_range[1] >= $function_range[0]
+                    and $change_range[0] <= $function_range[1]) {
+                    if (!$saw_function{$function_range[2]}) {
+                        $saw_function{$function_range[2]} = 1;
+                        push @functions, $function_range[2];
+                    }
+                    next FUNCTION;
+                }
+            }
+        }
+    
+        # Format the list of functions now.
+
+        if (@functions) {
+            $function_lists{$file} = "" if !defined $function_lists{$file};
+            $function_lists{$file} .= "\n        (" . join("):\n        (", @functions) . "):";
+        }
+    }
+}
+
+# Get some parameters for the ChangeLog we are about to write.
+my $date = changeLogDate($changeLogTimeZone);
+my $name = $ENV{CHANGE_LOG_NAME}
+  || $ENV{REAL_NAME}
+  || gitConfig("user.name")
+  || (split /\s*,\s*/, (getpwuid $<)[6])[0]
+  || "set REAL_NAME environment variable";
+my $email_address = $ENV{CHANGE_LOG_EMAIL_ADDRESS}
+  || $ENV{EMAIL_ADDRESS}
+  || gitConfig("user.email")
+  || "set EMAIL_ADDRESS environment variable";
+
+if ($gitCommit) {
+    $name = `$GIT log --max-count=1 --pretty=\"format:%an\" \"$gitCommit\"`;
+    $email_address = `$GIT log --max-count=1 --pretty=\"format:%ae\" \"$gitCommit\"`;
+}
+
+# Remove trailing parenthesized notes from user name (bit of hack).
+$name =~ s/\(.*?\)\s*$//g;
+
+# Find the change logs.
+my %has_log;
+my %files;
+foreach my $file (sort keys %function_lists) {
+    my $prefix = $file;
+    my $has_log = 0;
+    while ($prefix) {
+        $prefix =~ s-/[^/]+/?$-/- or $prefix = "";
+        $has_log = $has_log{$prefix};
+        if (!defined $has_log) {
+            $has_log = -f "${prefix}ChangeLog";
+            $has_log{$prefix} = $has_log;
+        }
+        last if $has_log;
+    }
+    if (!$has_log) {
+        print STDERR "No ChangeLog found for $file.\n";
+    } else {
+        push @{$files{$prefix}}, $file;
+    }
+}
+
+# Get the latest ChangeLog files from svn.
+my @logs = ();
+foreach my $prefix (sort keys %files) {
+    push @logs, File::Spec->catfile($prefix || ".", "ChangeLog");
+}
+
+if (@logs && $updateChangeLogs && $isSVN) {
+    print STDERR "  Running 'svn update' to update ChangeLog files.\n";
+    open ERRORS, "-|", $SVN, "update", @logs
+        or die "The svn update of ChangeLog files failed: $!.\n";
+    my @conflictedChangeLogs;
+    while (my $line = <ERRORS>) {
+        print STDERR "    ", $line;
+        push @conflictedChangeLogs, $1 if $line =~ m/^C\s+(.+)\s*$/;
+    }
+    close ERRORS;
+
+    if (@conflictedChangeLogs) {
+        print STDERR "  Attempting to merge conflicted ChangeLogs.\n";
+        my $resolveChangeLogsPath = File::Spec->catfile(dirname($0), "resolve-ChangeLogs");
+        open RESOLVE, "-|", $resolveChangeLogsPath, "--no-warnings", @conflictedChangeLogs
+            or die "Could not open resolve-ChangeLogs script: $!.\n";
+        print STDERR "    $_" while <RESOLVE>;
+        close RESOLVE;
+    }
+}
+
+# Write out a new ChangeLog file.
+foreach my $prefix (sort keys %files) {
+    my $changeLogPath = File::Spec->catfile($prefix || ".", "ChangeLog");
+    print STDERR "  Editing the ${changeLogPath} file.\n";
+    open OLD_CHANGE_LOG, ${changeLogPath} or die "Could not open ${changeLogPath} file: $!.\n";
+    # It's less efficient to read the whole thing into memory than it would be
+    # to read it while we prepend to it later, but I like doing this part first.
+    my @old_change_log = <OLD_CHANGE_LOG>;
+    close OLD_CHANGE_LOG;
+    open CHANGE_LOG, "> ${changeLogPath}" or die "Could not write ${changeLogPath}\n.";
+    print CHANGE_LOG "$date  $name  <$email_address>\n\n";
+
+    my ($reviewer, $description) = reviewerAndDescriptionForGitCommit($gitCommit) if $gitCommit;
+    $reviewer = "NOBODY (OO" . "PS!)" if !$reviewer;
+
+    print CHANGE_LOG "        Reviewed by $reviewer.\n\n";
+    print CHANGE_LOG $description . "\n" if $description;
+
+    if ($prefix =~ m/WebCore/ || `pwd` =~ m/WebCore/) {
+        if ($didChangeRegressionTests) {
+            print CHANGE_LOG testListForChangeLog(sort @addedRegressionTests);
+        } else {
+            print CHANGE_LOG "        WARNING: NO TEST CASES ADDED OR CHANGED\n\n";
+        }
+    }
+
+    foreach my $file (sort @{$files{$prefix}}) {
+        my $file_stem = substr $file, length $prefix;
+        print CHANGE_LOG "        * $file_stem:$function_lists{$file}\n";
+    }
+    print CHANGE_LOG "\n", @old_change_log;
+    close CHANGE_LOG;
+}
+
+# Write out another diff.
+if ($spewDiff && @changed_files) {
+    print STDERR "  Running diff to help you write the ChangeLog entries.\n";
+    local $/ = undef; # local slurp mode
+    open DIFF, "-|", createPatchCommand($changed_files_string) or die "The diff failed: $!.\n";
+    print <DIFF>;
+    close DIFF;
+}
+
+# Open ChangeLogs.
+if ($openChangeLogs && @logs) {
+    print STDERR "  Opening the edited ChangeLog files.\n";
+    my $editor = $ENV{"CHANGE_LOG_EDIT_APPLICATION"};
+    if ($editor) {
+        system "open", "-a", $editor, @logs;
+    } else {
+        system "open", "-e", @logs;
+    }
+}
+
+# Done.
+exit;
+
+sub canonicalizePath($)
+{
+    my ($file) = @_;
+
+    # Remove extra slashes and '.' directories in path
+    $file = File::Spec->canonpath($file);
+
+    # Remove '..' directories in path
+    my @dirs = ();
+    foreach my $dir (File::Spec->splitdir($file)) {
+        if ($dir eq '..' && $#dirs >= 0 && $dirs[$#dirs] ne '..') {
+            pop(@dirs);
+        } else {
+            push(@dirs, $dir);
+        }
+    }
+    return ($#dirs >= 0) ? File::Spec->catdir(@dirs) : ".";
+}
+
+sub changeLogDate($)
+{
+    my ($timeZone) = @_;
+    my $savedTimeZone = $ENV{'TZ'};
+    # Set TZ temporarily so that localtime() is in that time zone
+    $ENV{'TZ'} = $timeZone;
+    my $date = strftime("%Y-%m-%d", localtime());
+    if (defined $savedTimeZone) {
+         $ENV{'TZ'} = $savedTimeZone;
+    } else {
+         delete $ENV{'TZ'};
+    }
+    return $date;
+}
+
+sub get_function_line_ranges($$)
+{
+    my ($file_handle, $file_name) = @_;
+
+    if ($file_name =~ /\.(c|cpp|m|mm|h)$/) {
+        return get_function_line_ranges_for_c ($file_handle, $file_name);
+    } elsif ($file_name =~ /\.java$/) {
+        return get_function_line_ranges_for_java ($file_handle, $file_name);
+    } elsif ($file_name =~ /\.js$/) {
+        return get_function_line_ranges_for_javascript ($file_handle, $file_name);
+    }
+    return ();
+}
+
+
+sub method_decl_to_selector($)
+{
+    (my $method_decl) = @_;
+
+    $_ = $method_decl;
+
+    if ((my $comment_stripped) = m-([^/]*)(//|/*).*-) {
+        $_ = $comment_stripped;
+    }
+
+    s/,\s*...//;
+
+    if (/:/) {
+        my @components = split /:/;
+        pop @components if (scalar @components > 1);
+        $_ = (join ':', map {s/.*[^[:word:]]//; scalar $_;} @components) . ':';
+    } else {
+        s/\s*$//;
+        s/.*[^[:word:]]//;
+    }
+
+    return $_;
+}
+
+
+
+# Read a file and get all the line ranges of the things that look like C functions.
+# A function name is the last word before an open parenthesis before the outer
+# level open brace. A function starts at the first character after the last close
+# brace or semicolon before the function name and ends at the close brace.
+# Comment handling is simple-minded but will work for all but pathological cases.
+#
+# Result is a list of triples: [ start_line, end_line, function_name ].
+
+sub get_function_line_ranges_for_c($$)
+{
+    my ($file_handle, $file_name) = @_;
+
+    my @ranges;
+
+    my $in_comment = 0;
+    my $in_macro = 0;
+    my $in_method_declaration = 0;
+    my $in_parentheses = 0;
+    my $in_braces = 0;
+    my $brace_start = 0;
+    my $brace_end = 0;
+    my $skip_til_brace_or_semicolon = 0;
+
+    my $word = "";
+    my $interface_name = "";
+
+    my $potential_method_char = "";
+    my $potential_method_spec = "";
+
+    my $potential_start = 0;
+    my $potential_name = "";
+
+    my $start = 0;
+    my $name = "";
+
+    my $next_word_could_be_namespace = 0;
+    my $potential_namespace = "";
+    my @namespaces;
+
+    while (<$file_handle>) {
+        # Handle continued multi-line comment.
+        if ($in_comment) {
+            next unless s-.*\*/--;
+            $in_comment = 0;
+        }
+
+        # Handle continued macro.
+        if ($in_macro) {
+            $in_macro = 0 unless /\\$/;
+            next;
+        }
+
+        # Handle start of macro (or any preprocessor directive).
+        if (/^\s*\#/) {
+            $in_macro = 1 if /^([^\\]|\\.)*\\$/;
+            next;
+        }
+
+        # Handle comments and quoted text.
+        while (m-(/\*|//|\'|\")-) { # \' and \" keep emacs perl mode happy
+            my $match = $1;
+            if ($match eq "/*") {
+                if (!s-/\*.*?\*/--) {
+                    s-/\*.*--;
+                    $in_comment = 1;
+                }
+            } elsif ($match eq "//") {
+                s-//.*--;
+            } else { # ' or "
+                if (!s-$match([^\\]|\\.)*?$match--) {
+                    warn "mismatched quotes at line $. in $file_name\n";
+                    s-$match.*--;
+                }
+            }
+        }
+
+
+        # continued method declaration
+        if ($in_method_declaration) {
+              my $original = $_;
+              my $method_cont = $_;
+
+              chomp $method_cont;
+              $method_cont =~ s/[;\{].*//;
+              $potential_method_spec = "${potential_method_spec} ${method_cont}";
+
+              $_ = $original;
+              if (/;/) {
+                  $potential_start = 0;
+                  $potential_method_spec = "";
+                  $potential_method_char = "";
+                  $in_method_declaration = 0;
+                  s/^[^;\{]*//;
+              } elsif (/{/) {
+                  my $selector = method_decl_to_selector ($potential_method_spec);
+                  $potential_name = "${potential_method_char}\[${interface_name} ${selector}\]";
+                  
+                  $potential_method_spec = "";
+                  $potential_method_char = "";
+                  $in_method_declaration = 0;
+  
+                  $_ = $original;
+                  s/^[^;{]*//;
+              } elsif (/\@end/) {
+                  $in_method_declaration = 0;
+                  $interface_name = "";
+                  $_ = $original;
+              } else {
+                  next;
+              }
+        }
+
+        
+        # start of method declaration
+        if ((my $method_char, my $method_spec) = m&^([-+])([^0-9;][^;]*);?$&) {
+            my $original = $_;
+
+            if ($interface_name) {
+                chomp $method_spec;
+                $method_spec =~ s/\{.*//;
+
+                $potential_method_char = $method_char;
+                $potential_method_spec = $method_spec;
+                $potential_start = $.;
+                $in_method_declaration = 1;
+            } else { 
+                warn "declaring a method but don't have interface on line $. in $file_name\n";
+            }
+            $_ = $original;
+            if (/\{/) {
+              my $selector = method_decl_to_selector ($potential_method_spec);
+              $potential_name = "${potential_method_char}\[${interface_name} ${selector}\]";
+              
+              $potential_method_spec = "";
+              $potential_method_char = "";
+              $in_method_declaration = 0;
+              $_ = $original;
+              s/^[^{]*//;
+            } elsif (/\@end/) {
+              $in_method_declaration = 0;
+              $interface_name = "";
+              $_ = $original;
+            } else {
+              next;
+            }
+        }
+
+
+        # Find function, interface and method names.
+        while (m&((?:[[:word:]]+::)*operator(?:[ \t]*\(\)|[^()]*)|[[:word:]:~]+|[(){}:;])|\@(?:implementation|interface|protocol)\s+(\w+)[^{]*&g) {
+            # interface name
+            if ($2) {
+                $interface_name = $2;
+                next;
+            }
+
+            # Open parenthesis.
+            if ($1 eq "(") {
+                $potential_name = $word unless $in_parentheses || $skip_til_brace_or_semicolon;
+                $in_parentheses++;
+                next;
+            }
+
+            # Close parenthesis.
+            if ($1 eq ")") {
+                $in_parentheses--;
+                next;
+            }
+
+            # C++ constructor initializers
+            if ($1 eq ":") {
+                  $skip_til_brace_or_semicolon = 1 unless ($in_parentheses || $in_braces);
+            }
+
+            # Open brace.
+            if ($1 eq "{") {
+                $skip_til_brace_or_semicolon = 0;
+
+                if ($potential_namespace) {
+                    push @namespaces, $potential_namespace;
+                    $potential_namespace = "";
+                    next;
+                }
+
+                # Promote potential name to real function name at the
+                # start of the outer level set of braces (function body?).
+                if (!$in_braces and $potential_start) {
+                    $start = $potential_start;
+                    $name = $potential_name;
+                    if (@namespaces && (length($name) < 2 || substr($name,1,1) ne "[")) {
+                        $name = join ('::', @namespaces, $name);
+                    }
+                }
+
+                $in_method_declaration = 0;
+
+                $brace_start = $. if (!$in_braces);
+                $in_braces++;
+                next;
+            }
+
+            # Close brace.
+            if ($1 eq "}") {
+                if (!$in_braces && @namespaces) {
+                    pop @namespaces;
+                    next;
+                }
+
+                $in_braces--;
+                $brace_end = $. if (!$in_braces);
+
+                # End of an outer level set of braces.
+                # This could be a function body.
+                if (!$in_braces and $name) {
+                    push @ranges, [ $start, $., $name ];
+                    $name = "";
+                }
+
+                $potential_start = 0;
+                $potential_name = "";
+                next;
+            }
+
+            # Semicolon.
+            if ($1 eq ";") {
+                $skip_til_brace_or_semicolon = 0;
+                $potential_start = 0;
+                $potential_name = "";
+                $in_method_declaration = 0;
+                next;
+            }
+
+            # Ignore "const" method qualifier.
+            if ($1 eq "const") {
+                next;
+            }
+
+            if ($1 eq "namespace" || $1 eq "class" || $1 eq "struct") {
+                $next_word_could_be_namespace = 1;
+                next;
+            }
+
+            # Word.
+            $word = $1;
+            if (!$skip_til_brace_or_semicolon) {
+                if ($next_word_could_be_namespace) {
+                    $potential_namespace = $word;
+                    $next_word_could_be_namespace = 0;
+                } elsif ($potential_namespace) {
+                    $potential_namespace = "";
+                }
+
+                if (!$in_parentheses) {
+                    $potential_start = 0;
+                    $potential_name = "";
+                }
+                if (!$potential_start) {
+                    $potential_start = $.;
+                    $potential_name = "";
+                }
+            }
+        }
+    }
+
+    warn "missing close braces in $file_name (probable start at $brace_start)\n" if ($in_braces > 0);
+    warn "too many close braces in $file_name (probable start at $brace_end)\n" if ($in_braces < 0);
+
+    warn "mismatched parentheses in $file_name\n" if $in_parentheses;
+
+    return @ranges;
+}
+
+
+
+# Read a file and get all the line ranges of the things that look like Java
+# classes, interfaces and methods.
+#
+# A class or interface name is the word that immediately follows
+# `class' or `interface' when followed by an open curly brace and not
+# a semicolon. It can appear at the top level, or inside another class
+# or interface block, but not inside a function block
+#
+# A class or interface starts at the first character after the first close
+# brace or after the function name and ends at the close brace.
+#
+# A function name is the last word before an open parenthesis before
+# an open brace rather than a semicolon. It can appear at top level or
+# inside a class or interface block, but not inside a function block.
+#
+# A function starts at the first character after the first close
+# brace or after the function name and ends at the close brace.
+#
+# Comment handling is simple-minded but will work for all but pathological cases.
+#
+# Result is a list of triples: [ start_line, end_line, function_name ].
+
+sub get_function_line_ranges_for_java($$)
+{
+    my ($file_handle, $file_name) = @_;
+
+    my @current_scopes;
+
+    my @ranges;
+
+    my $in_comment = 0;
+    my $in_macro = 0;
+    my $in_parentheses = 0;
+    my $in_braces = 0;
+    my $in_non_block_braces = 0;
+    my $class_or_interface_just_seen = 0;
+
+    my $word = "";
+
+    my $potential_start = 0;
+    my $potential_name = "";
+    my $potential_name_is_class_or_interface = 0;
+
+    my $start = 0;
+    my $name = "";
+    my $current_name_is_class_or_interface = 0;
+
+    while (<$file_handle>) {
+        # Handle continued multi-line comment.
+        if ($in_comment) {
+            next unless s-.*\*/--;
+            $in_comment = 0;
+        }
+
+        # Handle continued macro.
+        if ($in_macro) {
+            $in_macro = 0 unless /\\$/;
+            next;
+        }
+
+        # Handle start of macro (or any preprocessor directive).
+        if (/^\s*\#/) {
+            $in_macro = 1 if /^([^\\]|\\.)*\\$/;
+            next;
+        }
+
+        # Handle comments and quoted text.
+        while (m-(/\*|//|\'|\")-) { # \' and \" keep emacs perl mode happy
+            my $match = $1;
+            if ($match eq "/*") {
+                if (!s-/\*.*?\*/--) {
+                    s-/\*.*--;
+                    $in_comment = 1;
+                }
+            } elsif ($match eq "//") {
+                s-//.*--;
+            } else { # ' or "
+                if (!s-$match([^\\]|\\.)*?$match--) {
+                    warn "mismatched quotes at line $. in $file_name\n";
+                    s-$match.*--;
+                }
+            }
+        }
+
+        # Find function names.
+        while (m-(\w+|[(){};])-g) {
+            # Open parenthesis.
+            if ($1 eq "(") {
+                if (!$in_parentheses) {
+                    $potential_name = $word;
+                    $potential_name_is_class_or_interface = 0;
+                }
+                $in_parentheses++;
+                next;
+            }
+
+            # Close parenthesis.
+            if ($1 eq ")") {
+                $in_parentheses--;
+                next;
+            }
+
+            # Open brace.
+            if ($1 eq "{") {
+                # Promote potential name to real function name at the
+                # start of the outer level set of braces (function/class/interface body?).
+                if (!$in_non_block_braces
+                    and (!$in_braces or $current_name_is_class_or_interface)
+                    and $potential_start) {
+                    if ($name) {
+                          push @ranges, [ $start, ($. - 1),
+                                          join ('.', @current_scopes) ];
+                    }
+
+
+                    $current_name_is_class_or_interface = $potential_name_is_class_or_interface;
+
+                    $start = $potential_start;
+                    $name = $potential_name;
+
+                    push (@current_scopes, $name);
+                } else {
+                    $in_non_block_braces++;
+                }
+
+                $potential_name = "";
+                $potential_start = 0;
+
+                $in_braces++;
+                next;
+            }
+
+            # Close brace.
+            if ($1 eq "}") {
+                $in_braces--;
+
+                # End of an outer level set of braces.
+                # This could be a function body.
+                if (!$in_non_block_braces) {
+                    if ($name) {
+                        push @ranges, [ $start, $.,
+                                        join ('.', @current_scopes) ];
+
+                        pop (@current_scopes);
+
+                        if (@current_scopes) {
+                            $current_name_is_class_or_interface = 1;
+
+                            $start = $. + 1;
+                            $name =  $current_scopes[$#current_scopes-1];
+                        } else {
+                            $current_name_is_class_or_interface = 0;
+                            $start = 0;
+                            $name =  "";
+                        }
+                    }
+                } else {
+                    $in_non_block_braces-- if $in_non_block_braces;
+                }
+
+                $potential_start = 0;
+                $potential_name = "";
+                next;
+            }
+
+            # Semicolon.
+            if ($1 eq ";") {
+                $potential_start = 0;
+                $potential_name = "";
+                next;
+            }
+
+            if ($1 eq "class" or $1 eq "interface") {
+                $class_or_interface_just_seen = 1;
+                next;
+            }
+
+            # Word.
+            $word = $1;
+            if (!$in_parentheses) {
+                if ($class_or_interface_just_seen) {
+                    $potential_name = $word;
+                    $potential_start = $.;
+                    $class_or_interface_just_seen = 0;
+                    $potential_name_is_class_or_interface = 1;
+                    next;
+                }
+            }
+            if (!$potential_start) {
+                $potential_start = $.;
+                $potential_name = "";
+            }
+            $class_or_interface_just_seen = 0;
+        }
+    }
+
+    warn "mismatched braces in $file_name\n" if $in_braces;
+    warn "mismatched parentheses in $file_name\n" if $in_parentheses;
+
+    return @ranges;
+}
+
+
+
+# Read a file and get all the line ranges of the things that look like
+# JavaScript functions.
+#
+# A function name is the word that immediately follows `function' when
+# followed by an open curly brace. It can appear at the top level, or
+# inside other functions.
+#
+# An anonymous function name is the identifier chain immediately before
+# an assignment with the equals operator or object notation that has a
+# value starting with `function' followed by an open curly brace.
+#
+# A getter or setter name is the word that immediately follows `get' or
+# `set' when followed by an open curly brace .
+#
+# Comment handling is simple-minded but will work for all but pathological cases.
+#
+# Result is a list of triples: [ start_line, end_line, function_name ].
+
+sub get_function_line_ranges_for_javascript($$)
+{
+    my ($fileHandle, $fileName) = @_;
+
+    my @currentScopes;
+    my @currentIdentifiers;
+    my @currentFunctionNames;
+    my @currentFunctionDepths;
+    my @currentFunctionStartLines;
+
+    my @ranges;
+
+    my $inComment = 0;
+    my $parenthesesDepth = 0;
+    my $bracesDepth = 0;
+
+    my $functionJustSeen = 0;
+    my $getterJustSeen = 0;
+    my $setterJustSeen = 0;
+    my $assignmentJustSeen = 0;
+
+    my $word = "";
+
+    while (<$fileHandle>) {
+        # Handle continued multi-line comment.
+        if ($inComment) {
+            next unless s-.*\*/--;
+            $inComment = 0;
+        }
+
+        # Handle comments and quoted text.
+        while (m-(/\*|//|\'|\")-) { # \' and \" keep emacs perl mode happy
+            my $match = $1;
+            if ($match eq '/*') {
+                if (!s-/\*.*?\*/--) {
+                    s-/\*.*--;
+                    $inComment = 1;
+                }
+            } elsif ($match eq '//') {
+                s-//.*--;
+            } else { # ' or "
+                if (!s-$match([^\\]|\\.)*?$match--) {
+                    warn "mismatched quotes at line $. in $fileName\n";
+                    s-$match.*--;
+                }
+            }
+        }
+
+        # Find function names.
+        while (m-(\w+|[(){}=:;])-g) {
+            # Open parenthesis.
+            if ($1 eq '(') {
+                $parenthesesDepth++;
+                next;
+            }
+
+            # Close parenthesis.
+            if ($1 eq ')') {
+                $parenthesesDepth--;
+                next;
+            }
+
+            # Open brace.
+            if ($1 eq '{') {
+                push(@currentScopes, join(".", @currentIdentifiers));
+                @currentIdentifiers = ();
+
+                $bracesDepth++;
+                next;
+            }
+
+            # Close brace.
+            if ($1 eq '}') {
+                $bracesDepth--;
+
+                if (@currentFunctionDepths and $bracesDepth == $currentFunctionDepths[$#currentFunctionDepths]) {
+                    pop(@currentFunctionDepths);
+
+                    my $currentFunction = pop(@currentFunctionNames);
+                    my $start = pop(@currentFunctionStartLines);
+
+                    push(@ranges, [$start, $., $currentFunction]);
+                }
+
+                pop(@currentScopes);
+                @currentIdentifiers = ();
+
+                next;
+            }
+
+            # Semicolon.
+            if ($1 eq ';') {
+                @currentIdentifiers = ();
+                next;
+            }
+
+            # Function.
+            if ($1 eq 'function') {
+                $functionJustSeen = 1;
+
+                if ($assignmentJustSeen) {
+                    my $currentFunction = join('.', (@currentScopes, @currentIdentifiers));
+                    $currentFunction =~ s/\.{2,}/\./g; # Removes consecutive periods.
+
+                    push(@currentFunctionNames, $currentFunction);
+                    push(@currentFunctionDepths, $bracesDepth);
+                    push(@currentFunctionStartLines, $.);
+                }
+
+                next;
+            }
+
+            # Getter prefix.
+            if ($1 eq 'get') {
+                $getterJustSeen = 1;
+                next;
+            }
+
+            # Setter prefix.
+            if ($1 eq 'set') {
+                $setterJustSeen = 1;
+                next;
+            }
+
+            # Assignment operator.
+            if ($1 eq '=' or $1 eq ':') {
+                $assignmentJustSeen = 1;
+                next;
+            }
+
+            next if $parenthesesDepth;
+
+            # Word.
+            $word = $1;
+            $word = "get $word" if $getterJustSeen;
+            $word = "set $word" if $setterJustSeen;
+
+            if (($functionJustSeen and !$assignmentJustSeen) or $getterJustSeen or $setterJustSeen) {
+                push(@currentIdentifiers, $word);
+
+                my $currentFunction = join('.', (@currentScopes, @currentIdentifiers));
+                $currentFunction =~ s/\.{2,}/\./g; # Removes consecutive periods.
+
+                push(@currentFunctionNames, $currentFunction);
+                push(@currentFunctionDepths, $bracesDepth);
+                push(@currentFunctionStartLines, $.);
+            } elsif ($word ne 'if' and $word ne 'for' and $word ne 'do' and $word ne 'while' and $word ne 'which' and $word ne 'var') {
+                push(@currentIdentifiers, $word);
+            }
+
+            $functionJustSeen = 0;
+            $getterJustSeen = 0;
+            $setterJustSeen = 0;
+            $assignmentJustSeen = 0;
+        }
+    }
+
+    warn "mismatched braces in $fileName\n" if $bracesDepth;
+    warn "mismatched parentheses in $fileName\n" if $parenthesesDepth;
+
+    return @ranges;
+}
+
+
+sub processPaths(\@)
+{
+    my ($paths) = @_;
+    return ("." => 1) if (!@{$paths});
+
+    my %result = ();
+
+    for my $file (@{$paths}) {
+        die "can't handle absolute paths like \"$file\"\n" if File::Spec->file_name_is_absolute($file);
+        die "can't handle empty string path\n" if $file eq "";
+        die "can't handle path with single quote in the name like \"$file\"\n" if $file =~ /'/; # ' (keep Xcode syntax highlighting happy)
+
+        my $untouchedFile = $file;
+
+        $file = canonicalizePath($file);
+
+        die "can't handle paths with .. like \"$untouchedFile\"\n" if $file =~ m|/\.\./|;
+
+        $result{$file} = 1;
+    }
+
+    return ("." => 1) if ($result{"."});
+
+    # Remove any paths that also have a parent listed.
+    for my $path (keys %result) {
+        for (my $parent = dirname($path); $parent ne '.'; $parent = dirname($parent)) {
+            if ($result{$parent}) {
+                delete $result{$path};
+                last;
+            }
+        }
+    }
+
+    return %result;
+}
+
+sub diffFromToString()
+{
+    return "" if $isSVN;
+    return $gitCommit if $gitCommit =~ m/.+\.\..+/;
+    return "\"$gitCommit^\" \"$gitCommit\"" if $gitCommit;
+    return "HEAD" if $isGit;
+}
+
+sub diffCommand(@)
+{
+    my @paths = @_;
+
+    my $pathsString = "'" . join("' '", @paths) . "'"; 
+
+    my $command;
+    if ($isSVN) {
+        $command = "$SVN diff --diff-cmd diff -x -N $pathsString";
+    } elsif ($isGit) {
+        $command = "$GIT diff -U0 " . diffFromToString();
+        $command .= " -- $pathsString" unless $gitCommit;
+    }
+
+    return $command;
+}
+
+sub statusCommand(@)
+{
+    my @files = @_;
+
+    my $filesString = "'" . join ("' '", @files) . "'";
+    my $command;
+    if ($isSVN) {
+        $command = "$SVN stat $filesString";
+    } elsif ($isGit) {
+        $command = "$GIT diff -r --name-status -C -C -M " . diffFromToString();
+        $command .= " -- $filesString" unless $gitCommit;
+    }
+
+    return "$command 2>&1";
+}
+
+sub createPatchCommand($)
+{
+    my ($changedFilesString) = @_;
+
+    my $command;
+    if ($isSVN) {
+        $command = "'$FindBin::Bin/svn-create-patch' $changedFilesString";
+    } elsif ($isGit) {
+        $command = "$GIT diff -C -C -M " . diffFromToString();
+        $command .= " -- $changedFilesString" unless $gitCommit;
+    }
+
+    return $command;
+}
+
+sub diffHeaderFormat()
+{
+    return qr/^Index: (\S+)$/ if $isSVN;
+    return qr/^diff --git a\/.+ b\/(.+)$/ if $isGit;
+}
+
+sub findOriginalFileFromSvn($)
+{
+    my ($file) = @_;
+    my $baseUrl;
+    open INFO, "$SVN info . |" or die;
+    while (<INFO>) {
+        if (/^URL: (.+)/) {
+            $baseUrl = $1;
+            last;
+        }
+    }
+    close INFO;
+    my $sourceFile;
+    open INFO, "$SVN info '$file' |" or die;
+    while (<INFO>) {
+        if (/^Copied From URL: (.+)/) {
+            $sourceFile = File::Spec->abs2rel($1, $baseUrl);
+            last;
+        }
+    }
+    close INFO;
+    return $sourceFile;
+}
+
+sub generateFileList(\@\@\%)
+{
+    my ($changedFiles, $conflictFiles, $functionLists) = @_;
+    print STDERR "  Running status to find changed, added, or removed files.\n";
+    open STAT, "-|", statusCommand(keys %paths) or die "The status failed: $!.\n";
+    my $inGitCommitSection = 0;
+    while (<STAT>) {
+        my $status;
+        my $original;
+        my $file;
+
+        if ($isSVN) {
+            if (/^([ACDMR]).{5} (.+)$/) {
+                $status = $1;
+                $file = $2;
+                $original = findOriginalFileFromSvn($file) if substr($_, 3, 1) eq "+";
+            } else {
+                print;  # error output from svn stat
+            }
+        } elsif ($isGit) {
+            if (/^([ADM])\t(.+)$/) {
+                $status = $1;
+                $file = $2;
+            } elsif (/^([CR])[0-9]{1,3}\t([^\t]+)\t([^\t\n]+)$/) { # for example: R90%    newfile    oldfile
+                $status = $1;
+                $original = $2;
+                $file = $3;
+            } else {
+                print;  # error output from git diff
+            }
+        }
+
+        next unless $status;
+
+        $file = makeFilePathRelative($file);
+
+        if (isModifiedStatus($status) || isAddedStatus($status)) {
+            my @components = File::Spec->splitdir($file);
+            if ($components[0] eq "LayoutTests") {
+                $didChangeRegressionTests = 1;
+                push @addedRegressionTests, $file
+                    if isAddedStatus($status)
+                       && $file =~ /\.([a-zA-Z]+)$/
+                       && $supportedTestExtensions{lc($1)}
+                       && !scalar(grep(/^resources$/i, @components));
+            }
+            push @{$changedFiles}, $file if $components[$#components] ne "ChangeLog";
+        } elsif (isConflictStatus($status)) {
+            push @{$conflictFiles}, $file;
+        }
+        if (basename($file) ne "ChangeLog") {
+            my $description = statusDescription($status, $original);
+            $functionLists->{$file} = $description if defined $description;
+        }
+    }
+    close STAT;
+}
+
+sub gitConfig($)
+{
+    return unless $isGit;
+
+    my ($config) = @_;
+
+    my $result = `$GIT config $config`;
+    if (($? >> 8) != 0) {
+        $result = `$GIT repo-config $config`;
+    }
+    chomp $result;
+    return $result;
+}
+
+sub isModifiedStatus($)
+{
+    my ($status) = @_;
+
+    my %statusCodes = (
+        "M" => 1,
+    );
+
+    return $statusCodes{$status};
+}
+
+sub isAddedStatus($)
+{
+    my ($status) = @_;
+
+    my %statusCodes = (
+        "A" => 1,
+        "C" => $isGit,
+        "R" => 1,
+    );
+
+    return $statusCodes{$status};
+}
+
+sub isConflictStatus($)
+{
+    my ($status) = @_;
+
+    my %svn = (
+        "C" => 1,
+    );
+
+    my %git = (
+        "U" => 1,
+    );
+
+    return 0 if $gitCommit; # an existing commit cannot have conflicts
+    return $svn{$status} if $isSVN;
+    return $git{$status} if $isGit;
+}
+
+sub statusDescription($$)
+{
+    my ($status, $original) = @_;
+
+    my %svn = (
+        "A" => defined $original ? " Copied from \%s." : " Added.",
+        "D" => " Removed.",
+        "M" => "",
+        "R" => defined $original ? " Replaced with \%s." : " Replaced.",
+    );
+
+    my %git = %svn;
+    $git{"A"} = " Added.";
+    $git{"C"} = " Copied from \%s.";
+    $git{"R"} = " Renamed from \%s.";
+
+    return sprintf($svn{$status}, $original) if $isSVN && exists $svn{$status};
+    return sprintf($git{$status}, $original) if $isGit && exists $git{$status};
+    return undef;
+}
+
+sub extractLineRange($)
+{
+    my ($string) = @_;
+
+    my ($start, $end) = (-1, -1);
+
+    if ($isSVN && $string =~ /^\d+(,\d+)?[acd](\d+)(,(\d+))?/) {
+        $start = $2;
+        $end = $4 || $2;
+    } elsif ($isGit && $string =~ /^@@ -\d+(,\d+)? \+(\d+)(,(\d+))? @@/) {
+        $start = $2;
+        $end = defined($4) ? $4 + $2 - 1 : $2;
+    }
+
+    return ($start, $end);
+}
+
+sub firstDirectoryOrCwd()
+{
+    my $dir = ".";
+    my @dirs = keys(%paths);
+
+    $dir = -d $dirs[0] ? $dirs[0] : dirname($dirs[0]) if @dirs;
+
+    return $dir;
+}
+
+sub testListForChangeLog(@)
+{
+    my (@tests) = @_;
+
+    return "" unless @tests;
+
+    my $leadString = "        Test" . (@tests == 1 ? "" : "s") . ": ";
+    my $list = $leadString;
+    foreach my $i (0..$#tests) {
+        $list .= " " x length($leadString) if $i;
+        my $test = $tests[$i];
+        $test =~ s/^LayoutTests\///;
+        $list .= "$test\n";
+    }
+    $list .= "\n";
+
+    return $list;
+}
+
+sub reviewerAndDescriptionForGitCommit($)
+{
+    my ($commit) = @_;
+
+    my $description = '';
+    my $reviewer;
+
+    my @args = qw(rev-list --pretty);
+    push @args, '-1' if $commit !~ m/.+\.\..+/;
+    my $gitLog;
+    {
+        local $/ = undef;
+        open(GIT, "-|", $GIT, @args, $commit) || die;
+        $gitLog = <GIT>;
+        close(GIT);
+    }
+
+    my @commitLogs = split(/^[Cc]ommit [a-f0-9]{40}/m, $gitLog);
+    shift @commitLogs; # Remove initial blank commit log
+    my $commitLogCount = 0;
+    foreach my $commitLog (@commitLogs) {
+        $description .= "\n" if $commitLogCount;
+        $commitLogCount++;
+        my $inHeader = 1;
+        my @lines = split(/\n/, $commitLog);
+        shift @lines; # Remove initial blank line
+        foreach my $line (@lines) {
+            if ($inHeader) {
+                if (!$line) {
+                    $inHeader = 0;
+                }
+                next;
+            } elsif ($line =~ /[Ss]igned-[Oo]ff-[Bb]y: (.+)/) {
+                if (!$reviewer) {
+                    $reviewer = $1;
+                } else {
+                    $reviewer .= ", " . $1;
+                }
+            } elsif (length $line == 0) {
+                $description = $description . "\n";
+            } else {
+                $line =~ s/^\s*//;
+                $description = $description . "        " . $line . "\n";
+            }
+        }
+    }
+    if (!$reviewer) {
+      $reviewer = $gitReviewer;
+    }
+
+    return ($reviewer, $description);
+}
diff --git a/WebKitTools/Scripts/print-msvc-project-dependencies b/WebKitTools/Scripts/print-msvc-project-dependencies
new file mode 100755
index 0000000..dbc8402
--- /dev/null
+++ b/WebKitTools/Scripts/print-msvc-project-dependencies
@@ -0,0 +1,143 @@
+#!/usr/bin/perl -w
+
+# Copyright (C) 2008 Apple Inc. All Rights Reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+# OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+use strict;
+use File::Basename;
+
+sub printDependencyTree($);
+
+my $basename = basename($0);
+@ARGV or die "Usage: $basename sln1 [sln2 sln3...]";
+
+foreach my $sln (@ARGV) {
+    printDependencyTree($sln);
+}
+
+exit;
+
+sub printDependencyTree($)
+{
+    my ($sln) = @_;
+
+    unless (-f $sln) {
+        warn "Warning: Can't find $sln; skipping\n";
+        return;
+    }
+
+    unless (open SLN, "<", $sln) {
+        warn "Warning: Can't open $sln; skipping\n";
+        return;
+    }
+
+    my %projectsByUUID = ();
+    my $currentProject;
+
+    my $state = "initial";
+    foreach my $line (<SLN>) {
+        if ($state eq "initial") {
+            if ($line =~ /^Project\([^\)]+\) = "([^"]+)", "[^"]+", "([^"]+)"\r?$/) {
+                my $name = $1;
+                my $uuid = $2;
+                if (exists $projectsByUUID{$uuid}) {
+                    warn "Warning: Project $name appears more than once in $sln; using first definition\n";
+                    next;
+                }
+                $currentProject = {
+                    name => $name,
+                    uuid => $uuid,
+                    dependencies => {},
+                };
+                $projectsByUUID{$uuid} = $currentProject;
+
+                $state = "inProject";
+            }
+
+            next;
+        }
+
+        if ($state eq "inProject") {
+            defined($currentProject) or die;
+
+            if ($line =~ /^\s*ProjectSection\(ProjectDependencies\) = postProject\r?$/) {
+                $state = "inDependencies";
+            } elsif ($line =~ /^EndProject\r?$/) {
+                $currentProject = undef;
+                $state = "initial";
+            }
+
+            next;
+        }
+
+        if ($state eq "inDependencies") {
+            defined($currentProject) or die;
+
+            if ($line =~ /^\s*({[^}]+}) = ({[^}]+})\r?$/) {
+                my $uuid1 = $1;
+                my $uuid2 = $2;
+                if (exists $currentProject->{dependencies}->{$uuid1}) {
+                    warn "Warning: UUID $uuid1 listed more than once as dependency of project ", $currentProject->{name}, "\n";
+                    next;
+                }
+
+                $uuid1 eq $uuid2 or warn "Warning: UUIDs in depedency section of project ", $currentProject->{name}, " don't match: $uuid1 $uuid2; using first UUID\n";
+
+                $currentProject->{dependencies}->{$uuid1} = 1;
+            } elsif ($line =~ /^\s*EndProjectSection\r?$/) {
+                $state = "inProject";
+            }
+
+            next;
+        }
+    }
+
+    close SLN or warn "Warning: Can't close $sln\n";
+
+    my %projectsNotDependedUpon = %projectsByUUID;
+    CANDIDATE: foreach my $candidateUUID (keys %projectsByUUID) {
+        foreach my $projectUUID (keys %projectsByUUID) {
+            next if $candidateUUID eq $projectUUID;
+            foreach my $dependencyUUID (keys %{$projectsByUUID{$projectUUID}->{dependencies}}) {
+                if ($candidateUUID eq $dependencyUUID) {
+                    delete $projectsNotDependedUpon{$candidateUUID};
+                    next CANDIDATE;
+                }
+            }
+        }
+    }
+
+    foreach my $project (values %projectsNotDependedUpon) {
+        printProjectAndDependencies($project, 0, \%projectsByUUID);
+    }
+}
+
+sub printProjectAndDependencies
+{
+    my ($project, $indentLevel, $projectsByUUID) = @_;
+
+    print " " x $indentLevel, $project->{name}, "\n";
+    foreach my $dependencyUUID (keys %{$project->{dependencies}}) {
+        printProjectAndDependencies($projectsByUUID->{$dependencyUUID}, $indentLevel + 1, $projectsByUUID);
+    }
+}
diff --git a/WebKitTools/Scripts/report-include-statistics b/WebKitTools/Scripts/report-include-statistics
new file mode 100755
index 0000000..f81c3c3
--- /dev/null
+++ b/WebKitTools/Scripts/report-include-statistics
@@ -0,0 +1,114 @@
+#!/usr/bin/perl -w
+
+# Copyright (C) 2005, 2006 Apple Computer, Inc.  All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1.  Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer. 
+# 2.  Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution. 
+# 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+#     its contributors may be used to endorse or promote products derived
+#     from this software without specific prior written permission. 
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+# "report-include-statistics" script for Web Kit Open Source Project
+
+use strict;
+use File::Find;
+
+find(\&wanted, @ARGV ? @ARGV : ".");
+
+my %paths;
+my %sources;
+my %includes;
+
+sub wanted
+{
+    my $file = $_;
+
+    if ($file eq "icu") {
+        $File::Find::prune = 1;
+        return;
+    }
+
+    if ($file !~ /^\./ && $file =~ /\.(h|cpp|c|mm|m)$/) {
+        $paths{$file} = $File::Find::name;
+        $sources{$file} = $File::Find::name if $file !~ /\.h/;
+        open FILE, $file or die;
+        while (<FILE>) {
+            if (m-^\s*#\s*(include|import)\s+["<]((\S+/)*)(\S+)[">]-) {
+                my $include = ($2 eq "sys/" ? $2 : "") . $4;
+                $includes{$file}{$include}++;
+            }
+        }
+        close FILE;
+    }
+}
+
+my %totalIncludes;
+
+sub fillOut
+{
+    my ($file) = @_;
+
+    return if defined $totalIncludes{$file};
+
+    for my $include (keys %{ $includes{$file} }) {
+        $totalIncludes{$file}{$include} = 1;
+        fillOut($include);
+        for my $i (keys %{ $totalIncludes{$include} }) {
+            $totalIncludes{$file}{$i} = 1;
+        }
+    }
+}
+
+my %inclusionCounts;
+for my $file (keys %includes) {
+    $inclusionCounts{$file} = 0;
+    fillOut($file);
+}
+
+for my $file (keys %sources) {
+    for my $include (keys %{ $totalIncludes{$file} }) {
+        $inclusionCounts{$include}++;
+    }
+}
+
+for my $file (sort mostincludedcmp keys %includes) {
+    next if !$paths{$file};
+    my $count = $inclusionCounts{$file};
+    my $numIncludes = keys %{ $includes{$file} };
+    my $numTotalIncludes = keys %{ $totalIncludes{$file} };
+    print "$file is included $count times, includes $numIncludes files directly, $numTotalIncludes files total.\n"
+}
+
+# Sort most-included files first.
+sub mostincludedcmp($$)
+{
+    my ($filea, $fileb) = @_;
+
+    my $counta = $inclusionCounts{$filea} || 0;
+    my $countb = $inclusionCounts{$fileb} || 0;
+    return $countb <=> $counta if $counta != $countb;
+
+    my $ta = keys %{ $totalIncludes{$filea} };
+    my $tb = keys %{ $totalIncludes{$fileb} };
+    return $ta <=> $tb if $ta != $tb;
+
+    return $filea cmp $fileb;
+}
diff --git a/WebKitTools/Scripts/resolve-ChangeLogs b/WebKitTools/Scripts/resolve-ChangeLogs
new file mode 100755
index 0000000..58471ec
--- /dev/null
+++ b/WebKitTools/Scripts/resolve-ChangeLogs
@@ -0,0 +1,468 @@
+#!/usr/bin/perl -w
+
+# Copyright (C) 2007, 2008 Apple Inc.  All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1.  Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer. 
+# 2.  Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution. 
+# 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+#     its contributors may be used to endorse or promote products derived
+#     from this software without specific prior written permission. 
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+# Merge and resolve ChangeLog conflicts for svn and git repositories
+
+use strict;
+
+use FindBin;
+use lib $FindBin::Bin;
+
+use File::Basename;
+use File::Path;
+use File::Spec;
+use Getopt::Long;
+use POSIX;
+use VCSUtils;
+
+sub conflictFiles($);
+sub findChangeLog($);
+sub fixChangeLogPatch($);
+sub fixMergedChangeLogs($;@);
+sub fixOneMergedChangeLog($);
+sub mergeChanges($$$);
+sub parseFixMerged($$;$);
+sub removeChangeLogArguments();
+sub resolveChangeLog($);
+sub resolveConflict($);
+sub showStatus($;$);
+sub usageAndExit();
+
+my $SVN = "svn";
+my $GIT = "git";
+
+my $fixMerged;
+my $printWarnings = 1;
+my $showHelp;
+
+my $getOptionsResult = GetOptions(
+    'f|fix-merged:s' => \&parseFixMerged,
+    'h|help'         => \$showHelp,
+    'w|warnings!'    => \$printWarnings,
+);
+
+my @changeLogFiles = removeChangeLogArguments();
+
+if (scalar(@ARGV) > 0) {
+    print STDERR "ERROR: Files listed on command-line that are not ChangeLogs.\n";
+    undef $getOptionsResult;
+} elsif (!defined $fixMerged && scalar(@changeLogFiles) == 0) {
+    print STDERR "ERROR: No ChangeLog files listed on command-line.\n";
+    undef $getOptionsResult;
+} elsif (defined $fixMerged && !isGit()) {
+    print STDERR "ERROR: --fix-merged may only be used with a git repository\n";
+    undef $getOptionsResult;
+}
+
+sub usageAndExit()
+{
+    print STDERR <<__END__;
+Usage: @{[ basename($0) ]} [options] path/to/ChangeLog [path/to/another/ChangeLog ...]
+  -f|--fix-merged [revision-range] fix git-merged ChangeLog entries; if a revision-range
+                                   is specified, run git filter-branch on the range
+  -h|--help                        show this help message
+  -w|--[no-]warnings               show or suppress warnings (default: show warnings)
+__END__
+    exit 1;
+}
+
+if (!$getOptionsResult || $showHelp) {
+    usageAndExit();
+}
+
+if (defined $fixMerged && length($fixMerged) > 0) {
+    my $commitRange = $fixMerged;
+    $commitRange = $commitRange . "..HEAD" if index($commitRange, "..") < 0;
+    fixMergedChangeLogs($commitRange, @changeLogFiles);
+} elsif (@changeLogFiles) {
+    for my $file (@changeLogFiles) {
+        if (defined $fixMerged) {
+            fixOneMergedChangeLog($file);
+        } else {
+            resolveChangeLog($file);
+        }
+    }
+} else {
+    print STDERR "ERROR: Unknown combination of switches and arguments.\n";
+    usageAndExit();
+}
+
+exit 0;
+
+sub conflictFiles($)
+{
+    my ($file) = @_;
+    my $fileMine;
+    my $fileOlder;
+    my $fileNewer;
+
+    if (-e $file && -e "$file.orig" && -e "$file.rej") {
+        return ("$file.rej", "$file.orig", $file);
+    }
+
+    if (isSVN()) {
+        open STAT, "-|", $SVN, "status", $file || die;
+        my $status = <STAT>;
+        close STAT;
+        if (!$status || $status !~ m/^C\s+/) {
+            print STDERR "WARNING: ${file} is not in a conflicted state.\n" if $printWarnings;
+            return ();
+        }
+
+        $fileMine = "${file}.mine" if -e "${file}.mine";
+
+        my $currentRevision;
+        open INFO, "-|", $SVN, "info", $file || die;
+        while (my $line = <INFO>) {
+            $currentRevision = $1 if $line =~ m/^Revision: ([0-9]+)/;
+        }
+        close INFO;
+        $fileNewer = "${file}.r${currentRevision}" if -e "${file}.r${currentRevision}";
+
+        my @matchingFiles = grep { $_ ne $fileNewer } glob("${file}.r[0-9][0-9]*");
+        if (scalar(@matchingFiles) > 1) {
+            print STDERR "WARNING: Too many conflict files exist for ${file}!\n" if $printWarnings;
+        } else {
+            $fileOlder = shift @matchingFiles;
+        }
+    } elsif (isGit()) {
+        my $gitPrefix = `$GIT rev-parse --show-prefix`;
+        chomp $gitPrefix;
+        open GIT, "-|", $GIT, "ls-files", "--unmerged", $file || die;
+        while (my $line = <GIT>) {
+            my ($mode, $hash, $stage, $fileName) = split(' ', $line);
+            my $outputFile;
+            if ($stage == 1) {
+                $fileOlder = "${file}.BASE.$$";
+                $outputFile = $fileOlder;
+            } elsif ($stage == 2) {
+                $fileNewer = "${file}.LOCAL.$$";
+                $outputFile = $fileNewer;
+            } elsif ($stage == 3) {
+                $fileMine = "${file}.REMOTE.$$";
+                $outputFile = $fileMine;
+            } else {
+                die "Unknown file stage: $stage";
+            }
+            system("$GIT cat-file blob :${stage}:${gitPrefix}${file} > $outputFile");
+        }
+        close GIT;
+    } else {
+        die "Unknown version control system";
+    }
+
+    if (!$fileMine && !$fileOlder && !$fileNewer) {
+        print STDERR "WARNING: ${file} does not need merging.\n" if $printWarnings;
+    } elsif (!$fileMine || !$fileOlder || !$fileNewer) {
+        print STDERR "WARNING: ${file} is missing some conflict files.\n" if $printWarnings;
+    }
+
+    return ($fileMine, $fileOlder, $fileNewer);
+}
+
+sub findChangeLog($) {
+    return $_[0] if basename($_[0]) eq "ChangeLog";
+
+    my $file = File::Spec->catfile($_[0], "ChangeLog");
+    return $file if -d $_[0] and -e $file;
+
+    return undef;
+}
+
+sub fixChangeLogPatch($)
+{
+    my $patch = shift;
+    my $contextLineCount = 3;
+
+    return $patch if $patch !~ /\n@@ -1,(\d+) \+1,(\d+) @@\n( .*\n)+(\+.*\n)+( .*\n){$contextLineCount}$/m;
+    my ($oldLineCount, $newLineCount) = ($1, $2);
+    return $patch if $oldLineCount <= $contextLineCount;
+
+    # The diff(1) command is greedy when matching lines, so a new ChangeLog entry will
+    # have lines of context at the top of a patch when the existing entry has the same
+    # date and author as the new entry.  This nifty loop alters a ChangeLog patch so
+    # that the added lines ("+") in the patch always start at the beginning of the
+    # patch and there are no initial lines of context.
+    my $newPatch;
+    my $lineCountInState = 0;
+    my $oldContentLineCountReduction = $oldLineCount - $contextLineCount;
+    my $newContentLineCountWithoutContext = $newLineCount - $oldLineCount - $oldContentLineCountReduction;
+    my ($stateHeader, $statePreContext, $stateNewChanges, $statePostContext) = (1..4);
+    my $state = $stateHeader;
+    foreach my $line (split(/\n/, $patch)) {
+        $lineCountInState++;
+        if ($state == $stateHeader && $line =~ /^@@ -1,$oldLineCount \+1,$newLineCount @\@$/) {
+            $line = "@@ -1,$contextLineCount +1," . ($newLineCount - $oldContentLineCountReduction) . " @@";
+            $lineCountInState = 0;
+            $state = $statePreContext;
+        } elsif ($state == $statePreContext && substr($line, 0, 1) eq " ") {
+            $line = "+" . substr($line, 1);
+            if ($lineCountInState == $oldContentLineCountReduction) {
+                $lineCountInState = 0;
+                $state = $stateNewChanges;
+            }
+        } elsif ($state == $stateNewChanges && substr($line, 0, 1) eq "+") {
+            # No changes to these lines
+            if ($lineCountInState == $newContentLineCountWithoutContext) {
+                $lineCountInState = 0;
+                $state = $statePostContext;
+            }
+        } elsif ($state == $statePostContext) {
+            if (substr($line, 0, 1) eq "+" && $lineCountInState <= $oldContentLineCountReduction) {
+                $line = " " . substr($line, 1);
+            } elsif ($lineCountInState > $contextLineCount && substr($line, 0, 1) eq " ") {
+                next; # Discard
+            }
+        }
+        $newPatch .= $line . "\n";
+    }
+
+    return $newPatch;
+}
+
+sub fixMergedChangeLogs($;@)
+{
+    my $revisionRange = shift;
+    my @changedFiles = @_;
+
+    if (scalar(@changedFiles) < 1) {
+        # Read in list of files changed in $revisionRange
+        open GIT, "-|", $GIT, "diff", "--name-only", $revisionRange || die;
+        push @changedFiles, <GIT>;
+        close GIT || die;
+        die "No changed files in $revisionRange" if scalar(@changedFiles) < 1;
+        chomp @changedFiles;
+    }
+
+    my @changeLogs = grep { defined $_ } map { findChangeLog($_) } @changedFiles;
+    die "No changed ChangeLog files in $revisionRange" if scalar(@changeLogs) < 1;
+
+    system("$GIT filter-branch --tree-filter 'PREVIOUS_COMMIT=\`$GIT rev-parse \$GIT_COMMIT^\` && MAPPED_PREVIOUS_COMMIT=\`map \$PREVIOUS_COMMIT\` $0 -f \"" . join('" "', @changeLogs) . "\"' $revisionRange");
+
+    # On success, remove the backup refs directory
+    if (WEXITSTATUS($?) == 0) {
+        rmtree(qw(.git/refs/original));
+    }
+}
+
+sub fixOneMergedChangeLog($)
+{
+    my $file = shift;
+    my $patch;
+
+    # Read in patch for incorrectly merged ChangeLog entry
+    {
+        local $/ = undef;
+        open GIT, "-|", $GIT, "diff", ($ENV{GIT_COMMIT} || "HEAD") . "^", $file || die;
+        $patch = <GIT>;
+        close GIT || die;
+    }
+
+    # Always checkout the previous commit's copy of the ChangeLog
+    system($GIT, "checkout", $ENV{MAPPED_PREVIOUS_COMMIT} || "HEAD^", $file);
+
+    # The patch must have 0 or more lines of context, then 1 or more lines
+    # of additions, and then 1 or more lines of context.  If not, we skip it.
+    if ($patch =~ /\n@@ -(\d+),(\d+) \+(\d+),(\d+) @@\n( .*\n)*((\+.*\n)+)( .*\n)+$/m) {
+        # Copy the header from the original patch.
+        my $newPatch = substr($patch, 0, index($patch, "@@ -${1},${2} +${3},${4} @@"));
+
+        # Generate a new set of line numbers and patch lengths.  Our new
+        # patch will start with the lines for the fixed ChangeLog entry,
+        # then have 3 lines of context from the top of the current file to
+        # make the patch apply cleanly.
+        $newPatch .= "@@ -1,3 +1," . ($4 - $2 + 3) . " @@\n";
+
+        # We assume that top few lines of the ChangeLog entry are actually
+        # at the bottom of the list of added lines (due to the way the patch
+        # algorithm works), so we simply search through the lines until we
+        # find the date line, then move the rest of the lines to the top.
+        my @patchLines = map { $_ . "\n" } split(/\n/, $6);
+        foreach my $i (0 .. $#patchLines) {
+            if ($patchLines[$i] =~ /^\+\d{4}-\d{2}-\d{2}  /) {
+                unshift(@patchLines, splice(@patchLines, $i, scalar(@patchLines) - $i));
+                last;
+            }
+        }
+
+        $newPatch .= join("", @patchLines);
+
+        # Add 3 lines of context to the end
+        open FILE, "<", $file || die;
+        for (my $i = 0; $i < 3; $i++) {
+            $newPatch .= " " . <FILE>;
+        }
+        close FILE;
+
+        # Apply the new patch
+        open(PATCH, "| patch -p1 $file > /dev/null") || die;
+        print PATCH $newPatch;
+        close(PATCH) || die;
+
+        # Run "git add" on the fixed ChangeLog file
+        system($GIT, "add", $file);
+
+        showStatus($file, 1);
+    } elsif ($patch) {
+        # Restore the current copy of the ChangeLog file since we can't repatch it
+        system($GIT, "checkout", $ENV{GIT_COMMIT} || "HEAD", $file);
+        print STDERR "WARNING: Last change to ${file} could not be fixed and re-merged.\n" if $printWarnings;
+    }
+}
+
+sub mergeChanges($$$)
+{
+    my ($fileMine, $fileOlder, $fileNewer) = @_;
+
+    my $traditionalReject = $fileMine =~ /\.rej$/ ? 1 : 0;
+
+    local $/ = undef;
+
+    my $patch;
+    if ($traditionalReject) {
+        open(DIFF, "<", $fileMine);
+        $patch = <DIFF>;
+        close(DIFF);
+        rename($fileMine, "$fileMine.save");
+        rename($fileOlder, "$fileOlder.save");
+    } else {
+        open(DIFF, "-|", qw(diff -u), $fileOlder, $fileMine) || die;
+        $patch = <DIFF>;
+        close(DIFF);
+    }
+
+    unlink("${fileNewer}.orig");
+    unlink("${fileNewer}.rej");
+
+    open(PATCH, "| patch --fuzz=3 $fileNewer > /dev/null") || die;
+    print PATCH fixChangeLogPatch($patch);
+    close(PATCH);
+
+    my $result;
+
+    # Refuse to merge the patch if it did not apply cleanly
+    if (-e "${fileNewer}.rej") {
+        unlink("${fileNewer}.rej");
+        unlink($fileNewer);
+        rename("${fileNewer}.orig", $fileNewer);
+        $result = 0;
+    } else {
+        unlink("${fileNewer}.orig");
+        $result = 1;
+    }
+
+    if ($traditionalReject) {
+        rename("$fileMine.save", $fileMine);
+        rename("$fileOlder.save", $fileOlder);
+    }
+
+    return $result;
+}
+
+sub parseFixMerged($$;$)
+{
+    my ($switchName, $key, $value) = @_;
+    if (defined $key) {
+        if (defined findChangeLog($key)) {
+            unshift(@ARGV, $key);
+            $fixMerged = "";
+        } else {
+            $fixMerged = $key;
+        }
+    } else {
+        $fixMerged = "";
+    }
+}
+
+sub removeChangeLogArguments()
+{
+    my @results = ();
+
+    for (my $i = 0; $i < scalar(@ARGV); ) {
+        my $file = findChangeLog($ARGV[$i]);
+        if (defined $file) {
+            splice(@ARGV, $i, 1);
+            push @results, $file;
+        } else {
+            $i++;
+        }
+    }
+
+    return @results;
+}
+
+sub resolveChangeLog($)
+{
+    my ($file) = @_;
+
+    my ($fileMine, $fileOlder, $fileNewer) = conflictFiles($file);
+
+    return unless $fileMine && $fileOlder && $fileNewer;
+
+    if (mergeChanges($fileMine, $fileOlder, $fileNewer)) {
+        if ($file ne $fileNewer) {
+            unlink($file);
+            rename($fileNewer, $file) || die;
+        }
+        unlink($fileMine, $fileOlder);
+        resolveConflict($file);
+        showStatus($file, 1);
+    } else {
+        showStatus($file);
+        print STDERR "WARNING: ${file} could not be merged using fuzz level 3.\n" if $printWarnings;
+        unlink($fileMine, $fileOlder, $fileNewer) if isGit();
+    }
+}
+
+sub resolveConflict($)
+{
+    my ($file) = @_;
+
+    if (isSVN()) {
+        system($SVN, "resolved", $file);
+    } elsif (isGit()) {
+        system($GIT, "add", $file);
+    } else {
+        die "Unknown version control system";
+    }
+}
+
+sub showStatus($;$)
+{
+    my ($file, $isConflictResolved) = @_;
+
+    if (isSVN()) {
+        system($SVN, "status", $file);
+    } elsif (isGit()) {
+        my @args = qw(--name-status);
+        unshift @args, qw(--cached) if $isConflictResolved;
+        system($GIT, "diff", @args, $file);
+    } else {
+        die "Unknown version control system";
+    }
+}
diff --git a/WebKitTools/Scripts/run-drawtest b/WebKitTools/Scripts/run-drawtest
new file mode 100755
index 0000000..2cd61de
--- /dev/null
+++ b/WebKitTools/Scripts/run-drawtest
@@ -0,0 +1,47 @@
+#!/usr/bin/perl -w
+
+# Copyright (C) 2005 Apple Computer, Inc.  All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1.  Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer. 
+# 2.  Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution. 
+# 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+#     its contributors may be used to endorse or promote products derived
+#     from this software without specific prior written permission. 
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+# Simplified "run" script for WebKit Open Source Project.
+
+use strict;
+use FindBin;
+use lib $FindBin::Bin;
+use webkitdirs;
+
+setConfiguration();
+my $productDir = productDir();
+
+# Check to see that all the frameworks are built (w/ SVG support).
+checkFrameworks();
+checkWebCoreSVGSupport(1);
+
+# Set up DYLD_FRAMEWORK_PATH to point to the product directory.
+print "Start DrawTest with DYLD_FRAMEWORK_PATH set to point to built WebKit in $productDir.\n";
+$ENV{DYLD_FRAMEWORK_PATH} = $productDir;
+my $drawtestPath = "$productDir/DrawTest.app/Contents/MacOS/DrawTest";
+exec $drawtestPath or die;
diff --git a/WebKitTools/Scripts/run-iexploder-tests b/WebKitTools/Scripts/run-iexploder-tests
new file mode 100755
index 0000000..f5e8a6c
--- /dev/null
+++ b/WebKitTools/Scripts/run-iexploder-tests
@@ -0,0 +1,172 @@
+#!/usr/bin/perl
+
+# Copyright (C) 2006 Alexey Proskuryakov ([email protected])
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1.  Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer. 
+# 2.  Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution. 
+# 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+#     its contributors may be used to endorse or promote products derived
+#     from this software without specific prior written permission. 
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+# A script to semi-automatically run iExploder tests.
+
+use strict;
+use warnings;
+
+use Cwd;
+use FindBin;
+use Getopt::Long;
+use IPC::Open2;
+
+use lib $FindBin::Bin;
+use webkitdirs;
+
+sub openHTTPDIfNeeded();
+sub closeHTTPD();
+sub runSafariWithIExploder();
+
+# Argument handling
+my $guardMalloc = '';
+my $httpdPort = 8000;
+my $downloadTest;
+
+GetOptions(
+    'guard-malloc|g' => \$guardMalloc,
+    'get=s' => \$downloadTest,
+    'port=i' => \$httpdPort
+);
+
+
+setConfiguration();
+my $productDir = productDir();
+
+chdirWebKit();
+
+checkFrameworks();
+
+my $httpdOpen = 0;
+openHTTPDIfNeeded();
+
+if ($downloadTest) {
+    system "/usr/bin/curl -o ~/Desktop/iexploder$downloadTest.html \"http://127.0.0.1:$httpdPort/iexploder.cgi?lookup=1&test=$downloadTest\"";
+    print "Saved the test as iexploder$downloadTest.html on the desktop\n";
+} else {
+    runSafariWithIExploder();
+    print "Last generated tests:\n";
+    system "grep 'iexploder.cgi' /tmp/WebKit/access_log.txt | tail -n -5 | awk -F'[ =&\\?]' '{if (\$8 == \"lookup\") print \$11; else print \$9}'";
+}
+
+closeHTTPD();
+
+
+sub runSafariWithIExploder()
+{
+    my $redirectTo;
+    if (@ARGV) {
+        $redirectTo = "http://127.0.0.1:$httpdPort/iexploder.cgi?lookup=1&test=$ARGV[0]";
+    } else {
+        $redirectTo = "http://127.0.0.1:$httpdPort/index.html";
+    }
+
+    open REDIRECT_HTML, ">", "/tmp/WebKit/redirect.html" or die;
+    print REDIRECT_HTML "<html>\n";
+    print REDIRECT_HTML "    <head>\n";
+    print REDIRECT_HTML "        <meta http-equiv=\"refresh\" content=\"1;URL=$redirectTo\" />\n";
+    print REDIRECT_HTML "        <script type=\"text/javascript\">\n";
+    print REDIRECT_HTML "            document.location = \"$redirectTo\";\n";
+    print REDIRECT_HTML "        </script>\n";
+    print REDIRECT_HTML "    </head>\n";
+    print REDIRECT_HTML "    <body>\n";
+    print REDIRECT_HTML "    </body>\n";
+    print REDIRECT_HTML "</html>\n";
+    close REDIRECT_HTML;
+    
+    local %ENV;
+    $ENV{DYLD_INSERT_LIBRARIES} = "/usr/lib/libgmalloc.dylib" if $guardMalloc;
+    system "WebKitTools/Scripts/run-safari", "-NSOpen", "/tmp/WebKit/redirect.html";
+}
+
+sub openHTTPDIfNeeded()
+{
+    return if $httpdOpen;
+
+    mkdir "/tmp/WebKit";
+    
+    if (-f "/tmp/WebKit/httpd.pid") {
+        my $oldPid = `cat /tmp/WebKit/httpd.pid`;
+        chomp $oldPid;
+        if (0 != kill 0, $oldPid) {
+            print "\nhttpd is already running: pid $oldPid, killing...\n";
+            kill 15, $oldPid;
+            
+            my $retryCount = 20;
+            while ((0 != kill 0, $oldPid) && $retryCount) {
+                sleep 1;
+                --$retryCount;
+            }
+            
+            die "Timed out waiting for httpd to quit" unless $retryCount;
+        }
+    }
+    
+    my $testDirectory = getcwd() . "/LayoutTests";
+    my $iExploderDirectory = getcwd() . "/WebKitTools/iExploder";
+    my $httpdPath = "/usr/sbin/httpd";
+    my $httpdConfig = "$testDirectory/http/conf/httpd.conf";
+    $httpdConfig = "$testDirectory/http/conf/apache2-httpd.conf" if `$httpdPath -v` =~ m|Apache/2|;
+    my $documentRoot = "$iExploderDirectory/htdocs";
+    my $typesConfig = "$testDirectory/http/conf/mime.types";
+    my $sslCertificate = "$testDirectory/http/conf/webkit-httpd.pem";
+    my $listen = "127.0.0.1:$httpdPort";
+
+    open2(\*HTTPDIN, \*HTTPDOUT, $httpdPath, 
+        "-f", "$httpdConfig",
+        "-C", "DocumentRoot \"$documentRoot\"",
+        "-C", "Listen $listen",
+        "-c", "TypesConfig \"$typesConfig\"",
+        "-c", "CustomLog \"/tmp/WebKit/access_log.txt\" common",
+        "-c", "ErrorLog \"/tmp/WebKit/error_log.txt\"",
+        "-c", "SSLCertificateFile \"$sslCertificate\"",
+        # Apache wouldn't run CGIs with permissions==700 otherwise
+        "-c", "User \"#$<\"");
+
+    my $retryCount = 20;
+    while (system("/usr/bin/curl -q --silent --stderr - --output /dev/null $listen") && $retryCount) {
+        sleep 1;
+        --$retryCount;
+    }
+    
+    die "Timed out waiting for httpd to start" unless $retryCount;
+    
+    $httpdOpen = 1;
+}
+
+sub closeHTTPD()
+{
+    return if !$httpdOpen;
+
+    close HTTPDIN;
+    close HTTPDOUT;
+
+    kill 15, `cat /tmp/WebKit/httpd.pid` if -f "/tmp/WebKit/httpd.pid";
+
+    $httpdOpen = 0;
+}
diff --git a/WebKitTools/Scripts/run-javascriptcore-tests b/WebKitTools/Scripts/run-javascriptcore-tests
new file mode 100755
index 0000000..afd0ab4
--- /dev/null
+++ b/WebKitTools/Scripts/run-javascriptcore-tests
@@ -0,0 +1,189 @@
+#!/usr/bin/perl -w
+
+# Copyright (C) 2005 Apple Computer, Inc.  All rights reserved.
+# Copyright (C) 2007 Eric Seidel <[email protected]>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1.  Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer. 
+# 2.  Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution. 
+# 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+#     its contributors may be used to endorse or promote products derived
+#     from this software without specific prior written permission. 
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+# Script to run the Web Kit Open Source Project JavaScriptCore tests (adapted from Mozilla).
+
+use strict;
+use FindBin;
+use Getopt::Long qw(:config pass_through);
+use lib $FindBin::Bin;
+use webkitdirs;
+use POSIX;
+
+my $coverageSupport = 0;
+GetOptions('coverage!' => \$coverageSupport);
+
+my @coverageSupportOption = ();
+if ($coverageSupport) {
+    push @coverageSupportOption, "GCC_GENERATE_TEST_COVERAGE_FILES=YES";
+    push @coverageSupportOption, "GCC_INSTRUMENT_PROGRAM_FLOW_ARCS=YES";
+    push @coverageSupportOption, "EXTRA_LINK= -ftest-coverage -fprofile-arcs";
+    push @coverageSupportOption, "OTHER_CFLAGS= -MD";
+    push @coverageSupportOption, "OTHER_LDFLAGS= -ftest-coverage -fprofile-arcs -framework AppKit";
+}
+
+# determine configuration
+my $configuration;
+setConfiguration();
+$configuration = configuration();
+
+my @jsArgs;
+my @xcodeArgs;
+my $root;
+my $run64Bit;
+
+# pre-evaluate arguments.  jsDriver args have - preceding, xcode args do not.
+# special arguments
+#     --root=<path to webkit root> use pre-built root
+#     --gtk build gtk 
+#     --no-64-bit or --64-bit
+foreach my $arg(@ARGV) {
+    print $arg."\n";
+    if( $arg =~ /root=(.*)/ ){
+        $root = $1;
+    } elsif( $arg =~ /^--gtk$/i || $arg =~ /^--qt$/i || $arg =~ /^--wx$/i ){
+    } elsif( $arg =~ /(no-)?64-bit/ ) {
+        $run64Bit = !defined($1);
+    } elsif( $arg =~ /^-/ or !($arg =~/=/)){
+        push( @jsArgs, $arg );
+    } else {
+        push( @xcodeArgs, $arg );
+    }
+}
+
+setConfigurationProductDir(Cwd::abs_path($root)) if (defined($root));
+
+if (isOSX() && !isTiger()) {
+    my $preferredArch = preferredArchitecture("JavaScriptCore");
+    setRun64Bit($run64Bit);
+    my $arch = preferredArchitecture("JavaScriptCore");
+    if ($arch ne $preferredArch) {
+        push(@jsArgs, "-a", $arch);
+    }
+}
+
+if(!defined($root)){
+    chdirWebKit();
+    push(@xcodeArgs, "--" . $configuration);
+    
+    # FIXME: These should be stored per-config and ignored here
+    push(@xcodeArgs, "--qt")  if isQt();
+    push(@xcodeArgs, "--gtk")  if isGtk();
+    push(@xcodeArgs, "--wx")  if isWx();
+
+    my $arch = preferredArchitecture("JavaScriptCore");
+    push(@xcodeArgs, "ARCHS=$arch") if (isOSX());
+    
+    my $buildResult = system "perl", "WebKitTools/Scripts/build-jsc", @xcodeArgs;
+    if ($buildResult) {
+        print STDERR "Compiling jsc failed!\n";
+        exit exitStatus($buildResult);
+    }
+}
+
+# Find JavaScriptCore directory
+chdirWebKit();
+chdir("JavaScriptCore");
+
+my $productDir = productDir();
+chdir "tests/mozilla" or die;
+$productDir .= "/JavaScriptCore" if isQt();
+$productDir .= "/Programs" if isGtk();
+$ENV{DYLD_FRAMEWORK_PATH} = $productDir;
+setPathForRunningWebKitApp(\%ENV) if isCygwin();
+
+sub jscPath($)
+{
+    my ($productDir) = @_;
+    my $jscName = "jsc";
+    $jscName .= "_debug"  if (isCygwin() && ($configuration eq "Debug"));
+    return "$productDir/$jscName";
+}
+
+my $result = system "perl", "jsDriver.pl", "-e", "squirrelfish", "-s", jscPath($productDir), "-f", "actual.html", @jsArgs;
+exit exitStatus($result)  if $result;
+
+my %failures;
+
+open EXPECTED, "expected.html" or die;
+while (<EXPECTED>) {
+    last if /failures reported\.$/;
+}
+while (<EXPECTED>) {
+    chomp;
+    $failures{$_} = 1;
+}
+close EXPECTED;
+
+my %newFailures;
+
+open ACTUAL, "actual.html" or die;
+while (<ACTUAL>) {
+    last if /failures reported\.$/;
+}
+while (<ACTUAL>) {
+    chomp;
+    if ($failures{$_}) {
+        delete $failures{$_};
+    } else {
+        $newFailures{$_} = 1;
+    }
+}
+close ACTUAL;
+
+my $numNewFailures = keys %newFailures;
+if ($numNewFailures) {
+    print "\n** Danger, Will Robinson! Danger! The following failures have been introduced:\n";
+    foreach my $failure (sort keys %newFailures) {
+        print "\t$failure\n";
+    }
+}
+
+my $numOldFailures = keys %failures;
+if ($numOldFailures) {
+    print "\nYou fixed the following test";
+    print "s" if $numOldFailures != 1;
+    print ":\n";
+    foreach my $failure (sort keys %failures) {
+        print "\t$failure\n";
+    }
+}
+
+print "\n";
+
+print "$numNewFailures regression";
+print "s" if $numNewFailures != 1;
+print " found.\n";
+
+print "$numOldFailures test";
+print "s" if $numOldFailures != 1;
+print " fixed.\n";
+
+print "OK.\n" if $numNewFailures == 0;
+exit(1)  if $numNewFailures;
diff --git a/WebKitTools/Scripts/run-jsc b/WebKitTools/Scripts/run-jsc
new file mode 100755
index 0000000..20dc5e8
--- /dev/null
+++ b/WebKitTools/Scripts/run-jsc
@@ -0,0 +1,58 @@
+#!/usr/bin/perl
+
+# Copyright (C) 2006 Apple Computer, Inc.  All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1.  Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+# 2.  Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+# 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+#     its contributors may be used to endorse or promote products derived
+#     from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+# This script runs a list of scripts through jsc a specified number of times.
+
+use strict;
+use warnings;
+use FindBin;
+use lib $FindBin::Bin;
+use Getopt::Long;
+use webkitdirs;
+
+my $usage = "Usage: run-jsc [--count run_count] [--verbose] shell_file [file2...]";
+
+my $count = 1;
+my $verbose = 0;
+GetOptions("count|c=i" => \$count,
+           "verbose|v" => \$verbose);
+die "$usage\n" if (@ARGV < 1);
+
+my $jsc = productDir() . "/jsc @ARGV";
+$jsc .= " 2> /dev/null" unless $verbose;
+
+my $dyld = productDir();
+
+$ENV{"DYLD_FRAMEWORK_PATH"} = $dyld;
+print STDERR "Running $count time(s): DYLD_FRAMEWORK_PATH=$dyld $jsc\n";
+while ($count--) {
+    if (system("$jsc") != 0) {
+        last;
+    }
+}
+
diff --git a/WebKitTools/Scripts/run-launcher b/WebKitTools/Scripts/run-launcher
new file mode 100755
index 0000000..f2b58cb
--- /dev/null
+++ b/WebKitTools/Scripts/run-launcher
@@ -0,0 +1,70 @@
+#!/usr/bin/perl -w
+
+# Copyright (C) 2007 Apple Computer, Inc.  All rights reserved.
+# Copyright (C) 2007 Staikos Computing Services, Inc.  <[email protected]>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1.  Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer. 
+# 2.  Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution. 
+# 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+#     its contributors may be used to endorse or promote products derived
+#     from this software without specific prior written permission. 
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+# Simplified "run" script for WebKit Open Source Project.
+
+use strict;
+use File::Spec::Functions qw/catdir/;
+use File::Temp qw/tempfile/;
+use FindBin;
+use lib $FindBin::Bin;
+use webkitdirs;
+
+setConfiguration();
+my $productDir = productDir();
+my $launcherPath = productDir();
+my @args = @ARGV;
+
+# Check to see that all the frameworks are built.
+checkFrameworks();
+
+# Set paths according to the build system used
+if (isQt()) {
+    my $libDir = catdir(productDir(), 'lib');
+    $launcherPath = catdir($launcherPath, "bin", "QtLauncher");
+
+    # Set up LD_LIBRARY_PATH to point to the product directory.
+    print "Starting webkit launcher with LD_LIBRARY_PATH set to point to built WebKit in $libDir.\n";
+
+    $ENV{LD_LIBRARY_PATH} = $ENV{LD_LIBRARY_PATH} ? "$libDir:$ENV{LD_LIBRARY_PATH}" : $libDir;
+    $ENV{DYLD_LIBRARY_PATH} = $ENV{DYLD_LIBRARY_PATH} ? "$libDir:$ENV{DYLD_LIBRARY_PATH}" : $libDir;
+} else {
+
+    if (isGtk()) {
+        $launcherPath = catdir($launcherPath, "Programs", "GtkLauncher");
+        # Strip --gtk from the arg-list, since otherwise GtkLauncher will try to
+        # interpret it as a URL.
+        @args = grep(!/^(--gtk)$/, @args);
+    }
+
+    print "Starting webkit launcher.\n";
+}
+
+exec $launcherPath, @args or die;
+
diff --git a/WebKitTools/Scripts/run-leaks b/WebKitTools/Scripts/run-leaks
new file mode 100755
index 0000000..d8f89d3
--- /dev/null
+++ b/WebKitTools/Scripts/run-leaks
@@ -0,0 +1,212 @@
+#!/usr/bin/perl
+
+# Copyright (C) 2007 Apple Inc. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1.  Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer. 
+# 2.  Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution. 
+# 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+#     its contributors may be used to endorse or promote products derived
+#     from this software without specific prior written permission. 
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+# Script to run the Mac OS X leaks tool with more expressive '-exclude' lists.
+
+use strict;
+use warnings;
+
+use File::Basename;
+use Getopt::Long;
+
+sub runLeaks($);
+sub parseLeaksOutput(\@);
+sub removeMatchingRecords(\@$\@);
+sub reportError($);
+
+sub main()
+{
+    # Read options.
+    my $usage =
+        "Usage: " . basename($0) . " [options] pid | executable name\n" .
+        "  --exclude-callstack regexp   Exclude leaks whose call stacks match the regular expression 'regexp'.\n" .
+        "  --exclude-type regexp        Exclude leaks whose data types match the regular expression 'regexp'.\n" .
+        "  --help                       Show this help message.\n";
+
+    my @callStacksToExclude = ();
+    my @typesToExclude = ();
+    my $help = 0;
+
+    my $getOptionsResult = GetOptions(
+        'exclude-callstack:s' => \@callStacksToExclude,
+        'exclude-type:s' => \@typesToExclude,
+        'help' => \$help
+    );
+    my $pidOrExecutableName = $ARGV[0];
+
+    if (!$getOptionsResult || $help) {
+        print STDERR $usage;
+        return 1;
+    }
+
+    if (!$pidOrExecutableName) {
+        reportError("Missing argument: pid | executable.");
+        print STDERR $usage;
+        return 1;
+    }
+
+    # Run leaks tool.
+    my $leaksOutput = runLeaks($pidOrExecutableName);
+    if (!$leaksOutput) {
+        return 1;
+    }
+
+    my $leakList = parseLeaksOutput(@$leaksOutput);
+    if (!$leakList) {
+        return 1;
+    }
+
+    # Filter output.
+    my $leakCount = @$leakList;
+    removeMatchingRecords(@$leakList, "callStack", @callStacksToExclude);
+    removeMatchingRecords(@$leakList, "type", @typesToExclude);
+    my $excludeCount = $leakCount - @$leakList;
+
+    # Dump results.
+    print $leaksOutput->[0];
+    print $leaksOutput->[1];
+    foreach my $leak (@$leakList) {
+        print $leak->{"leaksOutput"};
+    }
+
+    if ($excludeCount) {
+        print "$excludeCount leaks excluded (not printed)\n";
+    }
+
+    return 0;
+}
+
+exit(main());
+
+# Returns the output of the leaks tool in list form.
+sub runLeaks($)
+{
+    my ($pidOrExecutableName) = @_;
+    
+    my @leaksOutput = `leaks $pidOrExecutableName`;
+    if (!@leaksOutput) {
+        reportError("Error running leaks tool.");
+        return;
+    }
+    
+    return \@leaksOutput;
+}
+
+# Returns a list of hash references with the keys { address, size, type, callStack, leaksOutput }
+sub parseLeaksOutput(\@)
+{
+    my ($leaksOutput) = @_;
+
+    # Format:
+    #   Process 00000: 1234 nodes malloced for 1234 KB
+    #   Process 00000: XX leaks for XXX total leaked bytes.    
+    #   Leak: 0x00000000 size=1234 [instance of 'blah']
+    #       0x00000000 0x00000000 0x00000000 0x00000000 a..d.e.e
+    #       ...
+    #       Call stack: leak_caller() | leak() | malloc
+    #
+    #   We treat every line except for  Process 00000: and Leak: as optional
+
+    my ($leakCount) = ($leaksOutput->[1] =~ /[[:blank:]]+([0-9]+)[[:blank:]]+leaks?/);
+    if (!defined($leakCount)) {
+        reportError("Could not parse leak count reported by leaks tool.");
+        return;
+    }
+
+    my @leakList = ();
+    for my $line (@$leaksOutput) {
+        next if $line =~ /^Process/;
+        next if $line =~ /^node buffer added/;
+        
+        if ($line =~ /^Leak: /) {
+            my ($address) = ($line =~ /Leak: ([[:xdigit:]x]+)/);
+            if (!defined($address)) {
+                reportError("Could not parse Leak address.");
+                return;
+            }
+
+            my ($size) = ($line =~ /size=([[:digit:]]+)/);
+            if (!defined($size)) {
+                reportError("Could not parse Leak size.");
+                return;
+            }
+
+            my ($type) = ($line =~ /'([^']+)'/); #'
+            if (!defined($type)) {
+                $type = ""; # The leaks tool sometimes omits the type.
+            }
+
+            my %leak = (
+                "address" => $address,
+                "size" => $size,
+                "type" => $type,
+                "callStack" => "", # The leaks tool sometimes omits the call stack.
+                "leaksOutput" => $line
+            );
+            push(@leakList, \%leak);
+        } else {
+            $leakList[$#leakList]->{"leaksOutput"} .= $line;
+            if ($line =~ /Call stack:/) {
+                $leakList[$#leakList]->{"callStack"} = $line;
+            }
+        }
+    }
+    
+    if (@leakList != $leakCount) {
+        my $parsedLeakCount = @leakList;
+        reportError("Parsed leak count($parsedLeakCount) does not match leak count reported by leaks tool($leakCount).");
+        return;
+    }
+
+    return \@leakList;
+}
+
+sub removeMatchingRecords(\@$\@)
+{
+    my ($recordList, $key, $regexpList) = @_;
+    
+    RECORD: for (my $i = 0; $i < @$recordList;) {
+        my $record = $recordList->[$i];
+
+        foreach my $regexp (@$regexpList) {
+            if ($record->{$key} =~ $regexp) {
+                splice(@$recordList, $i, 1);
+                next RECORD;
+            }
+        }
+        
+        $i++;
+    }
+}
+
+sub reportError($)
+{
+    my ($errorMessage) = @_;
+    
+    print STDERR basename($0) . ": $errorMessage\n";
+}
diff --git a/WebKitTools/Scripts/run-mangleme-tests b/WebKitTools/Scripts/run-mangleme-tests
new file mode 100755
index 0000000..93b7894
--- /dev/null
+++ b/WebKitTools/Scripts/run-mangleme-tests
@@ -0,0 +1,175 @@
+#!/usr/bin/perl
+
+# Copyright (C) 2006 Alexey Proskuryakov ([email protected])
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1.  Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer. 
+# 2.  Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution. 
+# 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+#     its contributors may be used to endorse or promote products derived
+#     from this software without specific prior written permission. 
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+# A script to semi-automatically run mangleme tests.
+
+use strict;
+use warnings;
+
+use Cwd;
+use FindBin;
+use Getopt::Long;
+use IPC::Open2;
+
+use lib $FindBin::Bin;
+use webkitdirs;
+
+sub openHTTPDIfNeeded();
+sub closeHTTPD();
+sub runSafariWithMangleme();
+
+# Argument handling
+my $guardMalloc = '';
+my $httpdPort = 8000;
+my $downloadTest;
+
+GetOptions(
+    'guard-malloc|g' => \$guardMalloc,
+    'get=s' => \$downloadTest,
+    'port=i' => \$httpdPort
+);
+
+
+setConfiguration();
+my $productDir = productDir();
+
+chdirWebKit();
+
+checkFrameworks();
+
+mkdir "WebKitBuild/mangleme";
+(system "/usr/bin/make", "-C", "WebKitTools/mangleme") == 0 or die;
+
+my $httpdOpen = 0;
+openHTTPDIfNeeded();
+
+if ($downloadTest) {
+    system "/usr/bin/curl -o ~/Desktop/mangleme$downloadTest.html http://127.0.0.1:$httpdPort/remangle.cgi?$downloadTest";
+    print "Saved the test as mangleme$downloadTest.html on the desktop\n";
+} else {
+    runSafariWithMangleme();
+    print "Last generated tests:\n";
+    system "grep 'Mangle attempt' /tmp/WebKit/error_log.txt | tail -n -5 | awk ' {print \$4}'";
+}
+
+closeHTTPD();
+
+
+sub runSafariWithMangleme()
+{
+    my $redirectTo;
+    if (@ARGV) {
+        $redirectTo = "http://127.0.0.1:$httpdPort/remangle.cgi?$ARGV[0]";
+    } else {
+        $redirectTo = "http://127.0.0.1:$httpdPort/mangle.cgi";
+    }
+
+    open REDIRECT_HTML, ">", "/tmp/WebKit/redirect.html" or die;
+    print REDIRECT_HTML "<html>\n";
+    print REDIRECT_HTML "    <head>\n";
+    print REDIRECT_HTML "        <meta http-equiv=\"refresh\" content=\"1;URL=$redirectTo\" />\n";
+    print REDIRECT_HTML "        <script type=\"text/javascript\">\n";
+    print REDIRECT_HTML "            document.location = \"$redirectTo\";\n";
+    print REDIRECT_HTML "        </script>\n";
+    print REDIRECT_HTML "    </head>\n";
+    print REDIRECT_HTML "    <body>\n";
+    print REDIRECT_HTML "    </body>\n";
+    print REDIRECT_HTML "</html>\n";
+    close REDIRECT_HTML;
+    
+    local %ENV;
+    $ENV{DYLD_INSERT_LIBRARIES} = "/usr/lib/libgmalloc.dylib" if $guardMalloc;
+    system "WebKitTools/Scripts/run-safari", "-NSOpen", "/tmp/WebKit/redirect.html";
+}
+
+sub openHTTPDIfNeeded()
+{
+    return if $httpdOpen;
+
+    mkdir "/tmp/WebKit";
+    
+    if (-f "/tmp/WebKit/httpd.pid") {
+        my $oldPid = `cat /tmp/WebKit/httpd.pid`;
+        chomp $oldPid;
+        if (0 != kill 0, $oldPid) {
+            print "\nhttpd is already running: pid $oldPid, killing...\n";
+            kill 15, $oldPid;
+            
+            my $retryCount = 20;
+            while ((0 != kill 0, $oldPid) && $retryCount) {
+                sleep 1;
+                --$retryCount;
+            }
+            
+            die "Timed out waiting for httpd to quit" unless $retryCount;
+        }
+    }
+    
+    my $testDirectory = getcwd() . "/LayoutTests";
+    my $manglemeDirectory = getcwd() . "/WebKitBuild/mangleme";
+    my $httpdPath = "/usr/sbin/httpd";
+    my $httpdConfig = "$testDirectory/http/conf/httpd.conf";
+    $httpdConfig = "$testDirectory/http/conf/apache2-httpd.conf" if `$httpdPath -v` =~ m|Apache/2|;
+    my $documentRoot = "$manglemeDirectory";
+    my $typesConfig = "$testDirectory/http/conf/mime.types";
+    my $sslCertificate = "$testDirectory/http/conf/webkit-httpd.pem";
+    my $listen = "127.0.0.1:$httpdPort";
+
+    open2(\*HTTPDIN, \*HTTPDOUT, $httpdPath, 
+        "-f", "$httpdConfig",
+        "-C", "DocumentRoot \"$documentRoot\"",
+        "-C", "Listen $listen",
+        "-c", "TypesConfig \"$typesConfig\"",
+        "-c", "CustomLog \"/tmp/WebKit/access_log.txt\" common",
+        "-c", "ErrorLog \"/tmp/WebKit/error_log.txt\"",
+        "-c", "SSLCertificateFile \"$sslCertificate\"",
+        # Apache wouldn't run CGIs with permissions==700 otherwise
+        "-c", "User \"#$<\"");
+
+    my $retryCount = 20;
+    while (system("/usr/bin/curl -q --silent --stderr - --output /dev/null $listen") && $retryCount) {
+        sleep 1;
+        --$retryCount;
+    }
+    
+    die "Timed out waiting for httpd to start" unless $retryCount;
+    
+    $httpdOpen = 1;
+}
+
+sub closeHTTPD()
+{
+    return if !$httpdOpen;
+
+    close HTTPDIN;
+    close HTTPDOUT;
+
+    kill 15, `cat /tmp/WebKit/httpd.pid` if -f "/tmp/WebKit/httpd.pid";
+
+    $httpdOpen = 0;
+}
diff --git a/WebKitTools/Scripts/run-pageloadtest b/WebKitTools/Scripts/run-pageloadtest
new file mode 100755
index 0000000..ad6daa1
--- /dev/null
+++ b/WebKitTools/Scripts/run-pageloadtest
@@ -0,0 +1,92 @@
+#!/usr/bin/perl
+
+# Copyright (C) 2006 Eric Seidel ([email protected])
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1.  Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer. 
+# 2.  Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution. 
+# 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+#     its contributors may be used to endorse or promote products derived
+#     from this software without specific prior written permission. 
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+# Script to run the WebKit Open Source Project page load tests (PLTs).
+
+# Run all the tests passed in on the command line.
+
+use strict;
+use warnings;
+
+use File::Basename;
+use File::Spec;
+use FindBin;
+use Getopt::Long;
+
+use lib $FindBin::Bin;
+use webkitdirs;
+
+# Argument handling
+my $testName = 'svg';
+my $showHelp = 0;
+
+my $usage =
+    "Usage: " . basename($0) . "[options] testName\n" .
+    "  --help                  Show this help message\n";
+
+my $getOptionsResult = GetOptions('help' => \$showHelp);
+
+if (!$getOptionsResult || $showHelp) {
+    print STDERR $usage;
+    exit 1;
+}
+
+$testName = shift @ARGV if (@ARGV);
+
+my $safariExecutablePath = safariPath();
+my $safariResourcePath = File::Spec->catdir(dirname(dirname($safariExecutablePath)), "Resources");
+
+# Check to see that all the frameworks are built.
+checkFrameworks();
+
+chdirWebKit();
+
+if ($testName eq 'svg') {
+    my $suiteFile = "PageLoadTests/$testName/$testName.pltsuite";
+    my $webkitPath = sourceDir();
+    `cat "$suiteFile" | perl -pe 's|WEBKIT_PATH|$webkitPath|' > $safariResourcePath/$testName.pltsuite`
+}
+
+die "Please copy ${testName}.pltsuite to ${safariResourcePath}/${testName}.pltsuite"
+    if (! -f "${safariResourcePath}/${testName}.pltsuite");
+
+setConfiguration();
+
+my $productDir = productDir();
+
+# Set up DYLD_FRAMEWORK_PATH to point to the product directory.
+print "Starting Safari with DYLD_FRAMEWORK_PATH set to point to built WebKit in $productDir.\n";
+$ENV{DYLD_FRAMEWORK_PATH} = $productDir;
+$ENV{WEBKIT_UNSET_DYLD_FRAMEWORK_PATH} = "YES";
+
+my @testCommands = ('activate');
+# Autovicki would clear history, we skip that here as this is likely an active user account
+@testCommands = (@testCommands, ("run $testName", 'emptyCache', 'wait 30'));
+@testCommands = (@testCommands, (("run $testName", 'wait 10') x 3));
+my $testCommandsString = join('; ', @testCommands);
+exec $safariExecutablePath, '--test-commands', $testCommandsString or die;
diff --git a/WebKitTools/Scripts/run-safari b/WebKitTools/Scripts/run-safari
new file mode 100755
index 0000000..f31fed3
--- /dev/null
+++ b/WebKitTools/Scripts/run-safari
@@ -0,0 +1,63 @@
+#!/usr/bin/perl -w
+
+# Copyright (C) 2005, 2007 Apple Inc. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1.  Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer. 
+# 2.  Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution. 
+# 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+#     its contributors may be used to endorse or promote products derived
+#     from this software without specific prior written permission. 
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+# Simplified "run" script for WebKit Open Source Project.
+
+use strict;
+use FindBin;
+use Getopt::Long qw(:config pass_through);
+use lib $FindBin::Bin;
+use webkitdirs;
+
+my $programName = basename($0);
+my $showHelp = 0;
+my $run64Bit;
+
+my $usage = <<EOF;
+Usage: $programName [options]
+  --help                          Show this help message
+  --64-bit                        Run in 64-bit mode
+EOF
+
+my $getOptionsResult = GetOptions(
+    'help' => \$showHelp,
+    '64-bit!' => \$run64Bit
+);
+
+if (!$getOptionsResult || $showHelp) {
+    print STDERR $usage;
+    exit 1;
+}
+
+setRun64Bit($run64Bit);
+setConfiguration();
+
+# Check to see that all the frameworks are built.
+checkFrameworks();
+
+exit exitStatus(runSafari());
diff --git a/WebKitTools/Scripts/run-sunspider b/WebKitTools/Scripts/run-sunspider
new file mode 100755
index 0000000..2e58418
--- /dev/null
+++ b/WebKitTools/Scripts/run-sunspider
@@ -0,0 +1,131 @@
+#!/usr/bin/perl -w
+
+# Copyright (C) 2007 Apple Inc. All rights reserved.
+# Copyright (C) 2007 Eric Seidel <[email protected]>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+# OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+
+use strict;
+use FindBin;
+use Getopt::Long qw(:config pass_through);
+use lib $FindBin::Bin;
+use webkitdirs;
+use POSIX;
+
+# determine configuration, but default to "Release" instead of last-used configuration
+setConfiguration("Release");
+setConfiguration();
+my $configuration = configuration();
+
+my $root;
+my $testRuns = 10; # This number may be different from what sunspider defaults to (that's OK)
+my $runShark = 0;
+my $runShark20 = 0;
+my $runSharkCache = 0;
+my $ubench = 0;
+my $v8 = 0;
+my $setBaseline = 0;
+my $showHelp = 0;
+my $testsPattern;
+
+my $programName = basename($0);
+my $usage = <<EOF;
+Usage: $programName [options] [options to pass to build system]
+  --help            Show this help message
+  --set-baseline    Set baseline for future comparisons
+  --root            Path to root tools build
+  --runs            Number of times to run tests (default: $testRuns)
+  --tests           Only run tests matching provided pattern
+  --shark           Sample with the Mac OS X "Shark" performance testing tool (implies --runs=1)
+  --shark20         Like --shark, but with a 20 microsecond sampling interval
+  --shark-cache     Like --shark, but performs a L2 cache-miss sample instead of time sample
+  --ubench          Use microbenchmark suite instead of regular tests (to check for core execution regressions)
+  --v8              Use the V8 benchmark suite.
+EOF
+
+GetOptions('root=s' => sub { my ($x, $value) = @_; $root = $value; setConfigurationProductDir(Cwd::abs_path($root)); },
+           'runs=i' => \$testRuns,
+           'set-baseline' => \$setBaseline,
+           'shark' => \$runShark,
+           'shark20' => \$runShark20,
+           'shark-cache' => \$runSharkCache,
+           'ubench' => \$ubench,
+           'v8' => \$v8,
+           'tests=s' => \$testsPattern,
+           'help' => \$showHelp);
+
+if ($showHelp) {
+   print STDERR $usage;
+   exit 1;
+}
+
+sub buildJSC
+{
+    if (!defined($root)){
+        push(@ARGV,  "--" . $configuration);
+        
+        chdirWebKit();
+        my $buildResult = system "WebKitTools/Scripts/build-jsc", @ARGV;
+        if ($buildResult) {
+            print STDERR "Compiling jsc failed!\n";
+            exit exitStatus($buildResult);
+        }
+    }
+}
+
+sub setupEnvironmentForExecution($)
+{
+    my ($productDir) = @_;
+    print "Starting sunspider with DYLD_FRAMEWORK_PATH set to point to built JavaScriptCore in $productDir.\n";
+    $ENV{DYLD_FRAMEWORK_PATH} = $productDir;
+    # FIXME: Other platforms may wish to augment this method to use LD_LIBRARY_PATH, etc.
+}
+
+sub jscPath($)
+{
+    my ($productDir) = @_;
+    my $jscName = "jsc";
+    $jscName .= "_debug"  if (isCygwin() && ($configuration eq "Debug"));
+    return "$productDir/$jscName";
+}
+
+buildJSC();
+
+chdirWebKit();
+chdir("SunSpider");
+
+my $productDir = productDir();
+# FIXME: This hack should be pushed down into productDir()
+$productDir .= "/JavaScriptCore" if (isQt() or isGtk());
+
+setupEnvironmentForExecution($productDir);
+my @args = ("--shell", jscPath($productDir), "--runs", $testRuns);
+# This code could be removed if we chose to pass extra args to sunspider instead of Xcode
+push @args, "--set-baseline" if $setBaseline;
+push @args, "--shark" if $runShark;
+push @args, "--shark20" if $runShark20;
+push @args, "--shark-cache" if $runSharkCache;
+push @args, "--ubench" if $ubench;
+push @args, "--v8" if $v8;
+push @args, "--tests", $testsPattern if $testsPattern;
+
+exec "./sunspider", @args;
diff --git a/WebKitTools/Scripts/run-webkit-app b/WebKitTools/Scripts/run-webkit-app
new file mode 100755
index 0000000..36b9a58
--- /dev/null
+++ b/WebKitTools/Scripts/run-webkit-app
@@ -0,0 +1,50 @@
+#!/usr/bin/perl -w
+
+# Copyright (C) 2005 Apple Computer, Inc.  All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1.  Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer. 
+# 2.  Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution. 
+# 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+#     its contributors may be used to endorse or promote products derived
+#     from this software without specific prior written permission. 
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+# Simplified "run" script for Web Kit Open Source Project.
+
+use strict;
+use FindBin;
+use lib $FindBin::Bin;
+use webkitdirs;
+
+setConfiguration();
+my $productDir = productDir();
+
+die "Did not specify an application to open (e.g. run-webkit-app AppName).\n" unless length($ARGV[0]) > 0;
+
+# Check to see that all the frameworks are built.
+checkFrameworks();
+
+# Set up DYLD_FRAMEWORK_PATH to point to the product directory.
+print "Start $ARGV[0] with DYLD_FRAMEWORK_PATH set to point to built WebKit in $productDir.\n";
+$ENV{DYLD_FRAMEWORK_PATH} = $productDir;
+$ENV{WEBKIT_UNSET_DYLD_FRAMEWORK_PATH} = "YES";
+
+unshift(@ARGV, "-a");
+exec "open", @ARGV;
diff --git a/WebKitTools/Scripts/run-webkit-httpd b/WebKitTools/Scripts/run-webkit-httpd
new file mode 100755
index 0000000..a64eef6
--- /dev/null
+++ b/WebKitTools/Scripts/run-webkit-httpd
@@ -0,0 +1,127 @@
+#!/usr/bin/perl
+
+# Copyright (C) 2005, 2006, 2007 Apple Inc.  All rights reserved.
+# Copyright (C) 2006 Alexey Proskuryakov ([email protected])
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1.  Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer. 
+# 2.  Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution. 
+# 3.  Neither the name of Apple Inc. ("Apple") nor the names of
+#     its contributors may be used to endorse or promote products derived
+#     from this software without specific prior written permission. 
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+# Script to run Apache with the same configuration as used in http layout tests.
+
+use strict;
+use warnings;
+
+use Cwd;
+use File::Basename;
+use Getopt::Long;
+use FindBin;
+
+use lib $FindBin::Bin;
+use webkitdirs;
+
+# Argument handling
+my $httpdPort = 8000;
+my $allInterfaces = 0;
+my $showHelp;
+
+my $result = GetOptions(
+    'all-interfaces|a' => \$allInterfaces,
+    'help|h' => \$showHelp,
+    'port=i' => \$httpdPort,
+);
+
+if (!$result || @ARGV || $showHelp) {
+    print "Usage: " . basename($0) . " [options]\n";
+    print "  -a|--all-interfaces  Bind to all interfaces\n";
+    print "  -h|--help            Show this help message\n";
+    print "  -p|--port NNNN       Bind to port NNNN\n";
+    exit 1;
+}
+
+setConfiguration();
+my $productDir = productDir();
+chdirWebKit();
+
+mkdir "/tmp/WebKit";
+
+if (-f "/tmp/WebKit/httpd.pid") {
+    my $oldPid = `cat /tmp/WebKit/httpd.pid`;
+    chomp $oldPid;
+    if (0 != kill 0, $oldPid) {
+        print "\nhttpd is already running: pid $oldPid, killing...\n";
+        kill 15, $oldPid;
+        
+        my $retryCount = 20;
+        while ((0 != kill 0, $oldPid) && $retryCount) {
+            sleep 1;
+            --$retryCount;
+        }
+        
+        die "Timed out waiting for httpd to quit" unless $retryCount;
+    }
+}
+
+my $testDirectory = getcwd() . "/LayoutTests";
+my $httpdPath = "/usr/sbin/httpd";
+$httpdPath = "/usr/sbin/apache2" if isDebianBased();
+my $httpdConfig = "$testDirectory/http/conf/httpd.conf";
+$httpdConfig = "$testDirectory/http/conf/cygwin-httpd.conf" if isCygwin();
+$httpdConfig = "$testDirectory/http/conf/apache2-httpd.conf" if `$httpdPath -v` =~ m|Apache/2|;
+$httpdConfig = "$testDirectory/http/conf/apache2-debian-httpd.conf" if isDebianBased();
+my $documentRoot = "$testDirectory/http/tests";
+my $typesConfig = "$testDirectory/http/conf/mime.types";
+my $sslCertificate = "$testDirectory/http/conf/webkit-httpd.pem";
+
+my $listen = "127.0.0.1:$httpdPort";
+$listen = "$httpdPort" if ($allInterfaces);
+
+if ($allInterfaces) {
+    print "Starting httpd on port $httpdPort (all interfaces)...\n";
+} else {
+    print "Starting httpd on <http://$listen/>...\n";
+}
+print "Press Ctrl+C to stop it.\n\n";
+
+my @args = (
+    "-f", "$httpdConfig",
+    "-C", "DocumentRoot \"$documentRoot\"",
+    "-C", "Listen $listen",
+    "-c", "TypesConfig \"$typesConfig\"",
+    "-c", "CustomLog |/usr/bin/tee common",
+    "-c", "ErrorLog |/usr/bin/tee",
+    # Apache wouldn't run CGIs with permissions==700 otherwise.
+    "-c", "User \"#$<\"",
+    # Run in single-process mode, do not detach from the controlling terminal.
+    "-X",
+    # Disable Keep-Alive support. Makes testing in multiple browsers easier (no need to wait
+    # for another browser's connection to expire).
+    "-c", "KeepAlive 0"
+);
+
+# FIXME: Enable this on Windows once <rdar://problem/5345985> is fixed
+push(@args, "-c", "SSLCertificateFile \"$sslCertificate\"") unless isCygwin();
+
+system($httpdPath, @args);
+
+unlink "/tmp/WebKit/httpd.pid";
diff --git a/WebKitTools/Scripts/run-webkit-nightly.cmd b/WebKitTools/Scripts/run-webkit-nightly.cmd
new file mode 100755
index 0000000..93037ab
--- /dev/null
+++ b/WebKitTools/Scripts/run-webkit-nightly.cmd
@@ -0,0 +1,10 @@
+@echo off
+set script="%TMP%\run-webkit-nightly2.cmd"
+set vsvars="%VS80COMNTOOLS%\vsvars32.bat"
+if exist %vsvars% (
+    copy %vsvars% "%script%"
+) else (
+    del "%script%"
+)
+FindSafari.exe %1 /printSafariLauncher >> "%script%"
+call %script%
diff --git a/WebKitTools/Scripts/run-webkit-tests b/WebKitTools/Scripts/run-webkit-tests
new file mode 100755
index 0000000..4f129b7
--- /dev/null
+++ b/WebKitTools/Scripts/run-webkit-tests
@@ -0,0 +1,1862 @@
+#!/usr/bin/perl
+
+# Copyright (C) 2005, 2006, 2007 Apple Inc. All rights reserved.
+# Copyright (C) 2006 Alexey Proskuryakov ([email protected])
+# Copyright (C) 2007 Matt Lilek ([email protected])
+# Copyright (C) 2007 Eric Seidel <[email protected]>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1.  Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer. 
+# 2.  Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution. 
+# 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+#     its contributors may be used to endorse or promote products derived
+#     from this software without specific prior written permission. 
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+# Script to run the WebKit Open Source Project layout tests.
+
+# Run all the tests passed in on the command line.
+# If no tests are passed, find all the .html, .shtml, .xml, .xhtml, .pl, .php (and svg) files in the test directory.
+
+# Run each text.
+# Compare against the existing file xxx-expected.txt.
+# If there is a mismatch, generate xxx-actual.txt and xxx-diffs.txt.
+
+# At the end, report:
+#   the number of tests that got the expected results
+#   the number of tests that ran, but did not get the expected results
+#   the number of tests that failed to run
+#   the number of tests that were run but had no expected results to compare against
+
+use strict;
+use warnings;
+
+use Cwd;
+use Fcntl qw(F_GETFL F_SETFL O_NONBLOCK);
+use File::Basename;
+use File::Copy;
+use File::Find;
+use File::Path;
+use File::Spec;
+use File::Spec::Functions;
+use FindBin;
+use Getopt::Long;
+use IPC::Open2;
+use IPC::Open3;
+use Time::HiRes qw(time usleep);
+
+use List::Util 'shuffle';
+
+use lib $FindBin::Bin;
+use webkitdirs;
+use POSIX;
+
+sub openDumpTool();
+sub closeDumpTool();
+sub dumpToolDidCrash();
+sub closeHTTPD();
+sub countAndPrintLeaks($$$);
+sub fileNameWithNumber($$);
+sub numericcmp($$);
+sub openHTTPDIfNeeded();
+sub pathcmp($$);
+sub processIgnoreTests($);
+sub slowestcmp($$);
+sub splitpath($);
+sub stripExtension($);
+sub isTextOnlyTest($);
+sub expectedDirectoryForTest($;$;$);
+sub countFinishedTest($$$$);
+sub testCrashedOrTimedOut($$$$$);
+sub sampleDumpTool();
+sub printFailureMessageForTest($$);
+sub toURL($);
+sub toWindowsPath($);
+sub closeCygpaths();
+sub validateSkippedArg($$;$);
+sub htmlForResultsSection(\@$&);
+sub deleteExpectedAndActualResults($);
+sub recordActualResultsAndDiff($$);
+sub buildPlatformHierarchy();
+sub epiloguesAndPrologues($$);
+sub parseLeaksandPrintUniqueLeaks();
+sub readFromDumpToolWithTimer(*;$);
+sub setFileHandleNonBlocking(*$);
+sub writeToFile($$);
+
+# Argument handling
+my $addPlatformExceptions = 0;
+my $complexText = 0;
+my $configuration = configuration();
+my $guardMalloc = '';
+my $httpdPort = 8000;
+my $httpdSSLPort = 8443;
+my $ignoreTests = '';
+my $launchSafari = 1;
+my $platform;
+my $pixelTests = '';
+my $quiet = '';
+my $report10Slowest = 0;
+my $resetResults = 0;
+my $shouldCheckLeaks = 0;
+my $showHelp = 0;
+my $testsPerDumpTool;
+my $testHTTP = 1;
+my $testMedia = 1;
+my $testResultsDirectory = "/tmp/layout-test-results";
+my $threaded = 0;
+my $tolerance = 0;
+my $treatSkipped = "default";
+my $verbose = 0;
+my $useValgrind = 0;
+my $strictTesting = 0;
+my $generateNewResults = 1;
+my $stripEditingCallbacks = isCygwin();
+my $runSample = 1;
+my $root;
+my $reverseTests = 0;
+my $randomizeTests = 0;
+my $mergeDepth;
+my @leaksFilenames;
+my $run64Bit;
+
+# Default to --no-http for Qt, Gtk and wx for now.
+$testHTTP = 0 if (isQt() || isGtk() || isWx());
+
+my $expectedTag = "expected";
+my $actualTag = "actual";
+my $diffsTag = "diffs";
+my $errorTag = "stderr";
+
+if (isTiger()) {
+    $platform = "mac-tiger";
+} elsif (isLeopard()) {
+    $platform = "mac-leopard";
+} elsif (isSnowLeopard()) {
+    $platform = "mac-snowleopard";
+} elsif (isOSX()) {
+    $platform = "mac";
+} elsif (isQt()) {
+    $platform = "qt";
+} elsif (isGtk()) {
+    $platform = "gtk";
+} elsif (isCygwin()) {
+    $platform = "win";
+}
+
+if (!defined($platform)) {
+    print "WARNING: Your platform is not recognized. Any platform-specific results will be generated in platform/undefined.\n";
+    $platform = "undefined";
+}
+
+my $programName = basename($0);
+my $launchSafariDefault = $launchSafari ? "launch" : "do not launch";
+my $httpDefault = $testHTTP ? "run" : "do not run";
+my $sampleDefault = $runSample ? "run" : "do not run";
+
+# FIXME: "--strict" should be renamed to qt-mac-comparison, or something along those lines.
+my $usage = <<EOF;
+Usage: $programName [options] [testdir|testpath ...]
+  --add-platform-exceptions       Put new results for non-platform-specific failing tests into the platform-specific results directory
+  --complex-text                  Use the complex text code path for all text (Mac OS X and Windows only)
+  -c|--configuration config       Set DumpRenderTree build configuration
+  -g|--guard-malloc               Enable malloc guard
+  --help                          Show this help message
+  --[no-]http                     Run (or do not run) http tests (default: $httpDefault)
+  -i|--ignore-tests               Comma-separated list of directories or tests to ignore
+  --[no-]launch-safari            Launch (or do not launch) Safari to display test results (default: $launchSafariDefault)
+  -l|--leaks                      Enable leaks checking
+  --[no-]new-test-results         Generate results for new tests
+  -p|--pixel-tests                Enable pixel tests
+  --tolerance t                   Ignore image differences less than this percentage (implies --pixel-tests)
+  --platform                      Override the detected platform to use for tests and results (default: $platform)
+  --port                          Web server port to use with http tests
+  -q|--quiet                      Less verbose output
+  --reset-results                 Reset ALL results (including pixel tests if --pixel-tests is set)
+  -o|--results-directory          Output results directory (default: $testResultsDirectory)
+  --random                        Run the tests in a random order
+  --reverse                       Run the tests in reverse alphabetical order
+  --root                          Path to root tools build
+  --[no-]sample-on-timeout        Run sample on timeout (default: $sampleDefault) (Mac OS X only)
+  -1|--singly                     Isolate each test case run (implies --verbose)
+  --skipped=[default|ignore|only] Specifies how to treat the Skipped file
+                                     default: Tests/directories listed in the Skipped file are not tested
+                                     ignore:  The Skipped file is ignored
+                                     only:    Only those tests/directories listed in the Skipped file will be run
+  --slowest                       Report the 10 slowest tests
+  --strict                        Do a comparison with the output on Mac (Qt only)
+  --[no-]strip-editing-callbacks  Remove editing callbacks from expected results
+  -t|--threaded                   Run a concurrent JavaScript thead with each test
+  --valgrind                      Run DumpRenderTree inside valgrind (Qt/Linux only)
+  -v|--verbose                    More verbose output (overrides --quiet)
+  -m|--merge-leak-depth arg       Merges leak callStacks and prints the number of unique leaks beneath a callstack depth of arg.  Defaults to 5.
+  --64-bit                        run in 64bit mode
+EOF
+
+# Process @ARGV for configuration switches before calling GetOptions()
+$configuration = passedConfiguration() || configuration();
+
+my $getOptionsResult = GetOptions(
+    'complex-text' => \$complexText,
+    'c|configuration=s' => \$configuration,
+    'guard-malloc|g' => \$guardMalloc,
+    'help' => \$showHelp,
+    'http!' => \$testHTTP,
+    'ignore-tests|i=s' => \$ignoreTests,
+    'launch-safari!' => \$launchSafari,
+    'leaks|l' => \$shouldCheckLeaks,
+    'pixel-tests|p' => \$pixelTests,
+    'platform=s' => \$platform,
+    'port=i' => \$httpdPort,
+    'quiet|q' => \$quiet,
+    'reset-results' => \$resetResults,
+    'new-test-results!' => \$generateNewResults,
+    'results-directory|o=s' => \$testResultsDirectory,
+    'singly|1' => sub { $testsPerDumpTool = 1; },
+    'nthly=i' => \$testsPerDumpTool,
+    'skipped=s' => \&validateSkippedArg,
+    'slowest' => \$report10Slowest,
+    'threaded|t' => \$threaded,
+    'tolerance=f' => \$tolerance,
+    'verbose|v' => \$verbose,
+    'valgrind' => \$useValgrind,
+    'sample-on-timeout!' => \$runSample,
+    'strict' => \$strictTesting,
+    'strip-editing-callbacks!' => \$stripEditingCallbacks,
+    'random' => \$randomizeTests,
+    'reverse' => \$reverseTests,
+    'root=s' => \$root,
+    'add-platform-exceptions' => \$addPlatformExceptions,
+    'merge-leak-depth|m:5' => \$mergeDepth,
+    '64-bit!' => \$run64Bit
+);
+
+if (!$getOptionsResult || $showHelp) {
+    print STDERR $usage;
+    exit 1;
+}
+
+my $ignoreSkipped = $treatSkipped eq "ignore";
+my $skippedOnly = $treatSkipped eq "only";
+
+!$skippedOnly || @ARGV == 0 or die "--skipped=only cannot be used when tests are specified on the command line.";
+
+setConfiguration($configuration);
+
+my $configurationOption = "--" . lc($configuration);
+
+$pixelTests = 1 if $tolerance > 0;
+
+$testsPerDumpTool = 1000 if !$testsPerDumpTool;
+
+$verbose = 1 if $testsPerDumpTool == 1;
+
+if ($shouldCheckLeaks && $testsPerDumpTool > 1000) {
+    print STDERR "\nWARNING: Running more than 1000 tests at a time with MallocStackLogging enabled may cause a crash.\n\n";
+}
+
+# Stack logging does not play well with QuickTime on Tiger (rdar://problem/5537157)
+$testMedia = 0 if $shouldCheckLeaks && isTiger();
+
+setConfigurationProductDir(Cwd::abs_path($root)) if (defined($root));
+my $productDir = productDir();
+$productDir .= "/bin" if isQt();
+$productDir .= "/Programs" if isGtk();
+setRun64Bit($run64Bit);
+
+chdirWebKit();
+
+if (!defined($root)) {
+    # Push the parameters to build-dumprendertree as an array
+    my @args;
+    push(@args, $configurationOption);
+    push(@args, "--qt")  if isQt();
+    push(@args, "--gtk")  if isGtk();
+
+    if (isOSX()) {
+        my $arch = preferredArchitecture();
+        push(@args, "ARCHS=$arch");
+    }
+
+    my $buildResult = system "WebKitTools/Scripts/build-dumprendertree", @args;
+    if ($buildResult) {
+        print STDERR "Compiling DumpRenderTree failed!\n";
+        exit exitStatus($buildResult);
+    }
+}
+
+my $dumpToolName = "DumpRenderTree";
+$dumpToolName .= "_debug" if isCygwin() && $configuration ne "Release";
+my $dumpTool = "$productDir/$dumpToolName";
+die "can't find executable $dumpToolName (looked in $productDir)\n" unless -x $dumpTool;
+
+my $imageDiffTool = "$productDir/ImageDiff";
+$imageDiffTool .= "_debug" if isCygwin() && $configuration ne "Release";
+die "can't find executable $imageDiffTool (looked in $productDir)\n" if $pixelTests && !-x $imageDiffTool;
+
+checkFrameworks() unless isCygwin();
+
+my $layoutTestsName = "LayoutTests";
+my $testDirectory = File::Spec->rel2abs($layoutTestsName);
+my $expectedDirectory = $testDirectory;
+my $platformBaseDirectory = catdir($testDirectory, "platform");
+my $platformTestDirectory = catdir($platformBaseDirectory, $platform);
+my @platformHierarchy = buildPlatformHierarchy();
+
+$expectedDirectory = $ENV{"WebKitExpectedTestResultsDirectory"} if $ENV{"WebKitExpectedTestResultsDirectory"};
+
+my $testResults = catfile($testResultsDirectory, "results.html");
+
+print "Running tests from $testDirectory\n";
+
+my @tests = ();
+my %testType = ();
+
+system "ln", "-s", $testDirectory, "/tmp/LayoutTests" unless -x "/tmp/LayoutTests";
+
+my %ignoredFiles = ();
+my %ignoredDirectories = map { $_ => 1 } qw(platform);
+my %ignoredLocalDirectories = map { $_ => 1 } qw(.svn _svn resources);
+my %supportedFileExtensions = map { $_ => 1 } qw(html shtml xml xhtml pl php);
+if (checkWebCoreSVGSupport(0)) { 
+    $supportedFileExtensions{'svg'} = 1;
+} elsif (isCygwin()) {
+    # FIXME: We should fix webkitdirs.pm:hasSVGSupport() to do the correct
+    # check for Windows instead of forcing this here.
+    $supportedFileExtensions{'svg'} = 1;
+} else {
+    $ignoredLocalDirectories{'svg'} = 1;
+}
+if (!$testHTTP) {
+    $ignoredDirectories{'http'} = 1;
+}
+
+if (!$testMedia) {
+    $ignoredDirectories{'media'} = 1;
+    $ignoredDirectories{'http/tests/media'} = 1;
+}
+
+if ($ignoreTests) {
+    processIgnoreTests($ignoreTests);
+}
+
+if (!$ignoreSkipped) {
+    foreach my $level (@platformHierarchy) {
+        if (open SKIPPED, "<", "$level/Skipped") {
+            if ($verbose && !$skippedOnly) {
+                my ($dir, $name) = splitpath($level);
+                print "Skipped tests in $name:\n";
+            }
+
+            while (<SKIPPED>) {
+                my $skipped = $_;
+                chomp $skipped;
+                $skipped =~ s/^[ \n\r]+//;
+                $skipped =~ s/[ \n\r]+$//;
+                if ($skipped && $skipped !~ /^#/) {
+                    if ($skippedOnly) {
+                        push(@ARGV, $skipped);
+                    } else {
+                        if ($verbose) {
+                            print "    $skipped\n";
+                        }
+                        processIgnoreTests($skipped);
+                    }
+                }
+            }
+            close SKIPPED;
+        }
+    }
+}
+
+
+my $directoryFilter = sub {
+    return () if exists $ignoredLocalDirectories{basename($File::Find::dir)};
+    return () if exists $ignoredDirectories{File::Spec->abs2rel($File::Find::dir, $testDirectory)};
+    return @_;
+};
+
+my $fileFilter = sub {
+    my $filename = $_;
+    if ($filename =~ /\.([^.]+)$/) {
+        if (exists $supportedFileExtensions{$1}) {
+            my $path = File::Spec->abs2rel(catfile($File::Find::dir, $filename), $testDirectory);
+            push @tests, $path if !exists $ignoredFiles{$path};
+        }
+    }
+};
+
+for my $test (@ARGV) {
+    $test =~ s/^($layoutTestsName|$testDirectory)\///;
+    my $fullPath = catfile($testDirectory, $test);
+    if (file_name_is_absolute($test)) {
+        print "can't run test $test outside $testDirectory\n";
+    } elsif (-f $fullPath) {
+        my ($filename, $pathname, $fileExtension) = fileparse($test, qr{\.[^.]+$});
+        if (!exists $supportedFileExtensions{substr($fileExtension, 1)}) {
+            print "test $test does not have a supported extension\n";
+        } elsif ($testHTTP || $pathname !~ /^http\//) {
+            push @tests, $test;
+        }
+    } elsif (-d $fullPath) {
+        find({ preprocess => $directoryFilter, wanted => $fileFilter }, $fullPath);
+
+        for my $level (@platformHierarchy) {
+            my $platformPath = catfile($level, $test);
+            find({ preprocess => $directoryFilter, wanted => $fileFilter }, $platformPath) if (-d $platformPath);
+        }
+    } else {
+        print "test $test not found\n";
+    }
+}
+if (!scalar @ARGV) {
+    find({ preprocess => $directoryFilter, wanted => $fileFilter }, $testDirectory);
+
+    for my $level (@platformHierarchy) {
+        find({ preprocess => $directoryFilter, wanted => $fileFilter }, $level);
+    }
+}
+
+die "no tests to run\n" if !@tests;
+
+@tests = sort pathcmp @tests;
+
+my %counts;
+my %tests;
+my %imagesPresent;
+my %imageDifferences;
+my %durations;
+my $count = 0;
+my $leaksOutputFileNumber = 1;
+my $totalLeaks = 0;
+
+my @toolArgs = ();
+push @toolArgs, "--pixel-tests" if $pixelTests;
+push @toolArgs, "--threaded" if $threaded;
+push @toolArgs, "--complex-text" if $complexText;
+push @toolArgs, "-";
+
+my @diffToolArgs = ();
+push @diffToolArgs, "--tolerance", $tolerance;
+
+$| = 1;
+
+my $imageDiffToolPID;
+if ($pixelTests) {
+    local %ENV;
+    $ENV{MallocStackLogging} = 1 if $shouldCheckLeaks;
+    $imageDiffToolPID = open2(\*DIFFIN, \*DIFFOUT, $imageDiffTool, @diffToolArgs) or die "unable to open $imageDiffTool\n";
+    $ENV{MallocStackLogging} = 0 if $shouldCheckLeaks;
+}
+
+my $dumpToolPID;
+my $isDumpToolOpen = 0;
+my $dumpToolCrashed = 0;
+
+my $atLineStart = 1;
+my $lastDirectory = "";
+
+my $isHttpdOpen = 0;
+
+sub catch_pipe { $dumpToolCrashed = 1; }
+$SIG{"PIPE"} = "catch_pipe";
+
+print "Testing ", scalar @tests, " test cases.\n";
+my $overallStartTime = time;
+
+my %expectedResultPaths;
+
+# Reverse the tests
+@tests = reverse @tests if $reverseTests;
+
+# Shuffle the array
+@tests = shuffle(@tests) if $randomizeTests;
+
+for my $test (@tests) {
+    next if $test eq 'results.html';
+
+    my $newDumpTool = not $isDumpToolOpen;
+    openDumpTool();
+
+    my $base = stripExtension($test);
+    my $expectedExtension = ".txt";
+    
+    my $dir = $base;
+    $dir =~ s|/[^/]+$||;
+
+    if ($newDumpTool || $dir ne $lastDirectory) {
+        foreach my $logue (epiloguesAndPrologues($newDumpTool ? "" : $lastDirectory, $dir)) {
+            if (isCygwin()) {
+                $logue = toWindowsPath($logue);
+            } else {
+                $logue = canonpath($logue);
+            }
+            if ($verbose) {
+                print "running epilogue or prologue $logue\n";
+            }
+            print OUT "$logue\n";
+            # Throw away output from DumpRenderTree.
+            # Once for the test output and once for pixel results (empty)
+            while (<IN>) {
+                last if /#EOF/;
+            }
+            while (<IN>) {
+                last if /#EOF/;
+            }
+        }
+    }
+
+    if ($verbose) {
+        print "running $test -> ";
+        $atLineStart = 0;
+    } elsif (!$quiet) {
+        if ($dir ne $lastDirectory) {
+            print "\n" unless $atLineStart;
+            print "$dir ";
+        }
+        print ".";
+        $atLineStart = 0;
+    }
+
+    $lastDirectory = $dir;
+
+    my $result;
+
+    my $startTime = time if $report10Slowest;
+
+    # Try to read expected hash file for pixel tests
+    my $suffixExpectedHash = "";
+    if ($pixelTests && !$resetResults) {
+        my $expectedPixelDir = expectedDirectoryForTest($base, 0, "png");
+        if (open EXPECTEDHASH, "$expectedPixelDir/$base-$expectedTag.checksum") {
+            my $expectedHash = <EXPECTEDHASH>;
+            chomp($expectedHash);
+            close EXPECTEDHASH;
+            
+            # Format expected hash into a suffix string that is appended to the path / URL passed to DRT
+            $suffixExpectedHash = "'$expectedHash";
+        }
+    }
+
+    if ($test !~ /^http\//) {
+        my $testPath = "$testDirectory/$test";
+        if (isCygwin()) {
+            $testPath = toWindowsPath($testPath);
+        } else {
+            $testPath = canonpath($testPath);
+        }
+        print OUT "$testPath$suffixExpectedHash\n";
+    } else {
+        openHTTPDIfNeeded();
+        if ($test !~ /^http\/tests\/local\// && $test !~ /^http\/tests\/ssl\// && $test !~ /^http\/tests\/media\//) {
+            my $path = canonpath($test);
+            $path =~ s/^http\/tests\///;
+            print OUT "http://127.0.0.1:$httpdPort/$path$suffixExpectedHash\n";
+        } elsif ($test =~ /^http\/tests\/ssl\//) {
+            my $path = canonpath($test);
+            $path =~ s/^http\/tests\///;
+            print OUT "https://127.0.0.1:$httpdSSLPort/$path$suffixExpectedHash\n";
+        } else {
+            my $testPath = "$testDirectory/$test";
+            if (isCygwin()) {
+                $testPath = toWindowsPath($testPath);
+            } else {
+                $testPath = canonpath($testPath);
+            }
+            print OUT "$testPath$suffixExpectedHash\n";
+        }
+    }
+
+    # DumpRenderTree is expected to dump two "blocks" to stdout for each test.
+    # Each block is terminated by a #EOF on a line by itself.
+    # The first block is the output of the test (in text, RenderTree or other formats).
+    # The second block is for optional pixel data in PNG format, and may be empty if
+    # pixel tests are not being run, or the test does not dump pixels (e.g. text tests).
+    
+    my $actualRead = readFromDumpToolWithTimer(IN);
+    my $errorRead = readFromDumpToolWithTimer(ERROR, $actualRead->{status} eq "timedOut");
+
+    my $actual = $actualRead->{output};
+    my $error = $errorRead->{output};
+
+    $expectedExtension = $actualRead->{extension};
+    my $expectedFileName = "$base-$expectedTag.$expectedExtension";
+
+    my $isText = isTextOnlyTest($actual);
+
+    my $expectedDir = expectedDirectoryForTest($base, $isText, $expectedExtension);
+    $expectedResultPaths{$base} = "$expectedDir/$expectedFileName";
+
+    unless ($actualRead->{status} eq "success" && $errorRead->{status} eq "success") {
+        my $crashed = $actualRead->{status} eq "crashed" || $errorRead->{status} eq "crashed";
+        testCrashedOrTimedOut($test, $base, $crashed, $actual, $error);
+        countFinishedTest($test, $base, $crashed ? "crash" : "timedout", 0);
+        next;
+     }
+
+    $durations{$test} = time - $startTime if $report10Slowest;
+
+    my $expected;
+
+    if (!$resetResults && open EXPECTED, "<", "$expectedDir/$expectedFileName") {
+        $expected = "";
+        while (<EXPECTED>) {
+            next if $stripEditingCallbacks && $_ =~ /^EDITING DELEGATE:/;
+            $expected .= $_;
+        }
+        close EXPECTED;
+    }
+    my $expectedMac;
+    if (!isOSX() && $strictTesting && !$isText) {
+      if (!$resetResults && open EXPECTED, "<", "$testDirectory/platform/mac/$expectedFileName") {
+        $expectedMac = "";
+        while (<EXPECTED>) {
+          $expectedMac .= $_;
+        }
+        close EXPECTED;
+      }
+    }
+
+    if ($shouldCheckLeaks && $testsPerDumpTool == 1) {
+        print "        $test -> ";
+    }
+
+    my $actualPNG = "";
+    my $diffPNG = "";
+    my $diffPercentage = "";
+    my $diffResult = "passed";
+
+    my $actualHash = "";
+    my $expectedHash = "";
+    my $actualPNGSize = 0;
+
+    while (<IN>) {
+        last if /#EOF/;
+        if (/ActualHash: ([a-f0-9]{32})/) {
+            $actualHash = $1;
+        } elsif (/ExpectedHash: ([a-f0-9]{32})/) {
+            $expectedHash = $1;
+        } elsif (/Content-Length: (\d+)\s*/) {
+            $actualPNGSize = $1;
+            read(IN, $actualPNG, $actualPNGSize);
+        }
+    }
+
+    if ($verbose && $pixelTests && !$resetResults && $actualPNGSize) {
+        if ($actualHash eq "" && $expectedHash eq "") {
+            printFailureMessageForTest($test, "WARNING: actual & expected pixel hashes are missing!");
+        } elsif ($actualHash eq "") {
+            printFailureMessageForTest($test, "WARNING: actual pixel hash is missing!");
+        } elsif ($expectedHash eq "") {
+            printFailureMessageForTest($test, "WARNING: expected pixel hash is missing!");
+        }
+    }
+
+    if ($actualPNGSize > 0) {
+        my $expectedPixelDir = expectedDirectoryForTest($base, 0, "png");
+
+        if (!$resetResults && ($expectedHash ne $actualHash || ($actualHash eq "" && $expectedHash eq ""))) {
+            if (-f "$expectedPixelDir/$base-$expectedTag.png") {
+                my $expectedPNGSize = -s "$expectedPixelDir/$base-$expectedTag.png";
+                my $expectedPNG = "";
+                open EXPECTEDPNG, "$expectedPixelDir/$base-$expectedTag.png";
+                read(EXPECTEDPNG, $expectedPNG, $expectedPNGSize);
+
+                print DIFFOUT "Content-Length: $actualPNGSize\n";
+                print DIFFOUT $actualPNG;
+
+                print DIFFOUT "Content-Length: $expectedPNGSize\n";
+                print DIFFOUT $expectedPNG;
+
+                while (<DIFFIN>) {
+                    last if /^error/ || /^diff:/;
+                    if (/Content-Length: (\d+)\s*/) {
+                        read(DIFFIN, $diffPNG, $1);
+                    }
+                }
+
+                if (/^diff: (.+)% (passed|failed)/) {
+                    $diffPercentage = $1;
+                    $imageDifferences{$base} = $diffPercentage;
+                    $diffResult = $2;
+                }
+                
+                if ($diffPercentage == 0) {
+                    printFailureMessageForTest($test, "pixel hash failed (but pixel test still passes)");
+                }
+            } elsif ($verbose) {
+                printFailureMessageForTest($test, "WARNING: expected image is missing!");
+            }
+        }
+
+        if ($resetResults || !-f "$expectedPixelDir/$base-$expectedTag.png") {
+            mkpath catfile($expectedPixelDir, dirname($base)) if $testDirectory ne $expectedPixelDir;
+            writeToFile("$expectedPixelDir/$base-$expectedTag.png", $actualPNG);
+        }
+
+        if ($actualHash ne "" && ($resetResults || !-f "$expectedPixelDir/$base-$expectedTag.checksum")) {
+            writeToFile("$expectedPixelDir/$base-$expectedTag.checksum", $actualHash);
+        }
+    }
+
+    if (!isOSX() && $strictTesting && !$isText) {
+      if (defined $expectedMac) {
+        my $simplified_actual;
+        $simplified_actual = $actual;
+        $simplified_actual =~ s/at \(-?[0-9]+,-?[0-9]+\) *//g;
+        $simplified_actual =~ s/size -?[0-9]+x-?[0-9]+ *//g;
+        $simplified_actual =~ s/text run width -?[0-9]+: //g;
+        $simplified_actual =~ s/text run width -?[0-9]+ [a-zA-Z ]+: //g;
+        $simplified_actual =~ s/RenderButton {BUTTON} .*/RenderButton {BUTTON}/g;
+        $simplified_actual =~ s/RenderImage {INPUT} .*/RenderImage {INPUT}/g;
+        $simplified_actual =~ s/RenderBlock {INPUT} .*/RenderBlock {INPUT}/g;
+        $simplified_actual =~ s/RenderTextControl {INPUT} .*/RenderTextControl {INPUT}/g;
+        $simplified_actual =~ s/\([0-9]+px/px/g;
+        $simplified_actual =~ s/ *" *\n +" */ /g;
+        $simplified_actual =~ s/" +$/"/g;
+
+        $simplified_actual =~ s/- /-/g;
+        $simplified_actual =~ s/\n( *)"\s+/\n$1"/g;
+        $simplified_actual =~ s/\s+"\n/"\n/g;
+        
+        $expectedMac =~ s/at \(-?[0-9]+,-?[0-9]+\) *//g;
+        $expectedMac =~ s/size -?[0-9]+x-?[0-9]+ *//g;
+        $expectedMac =~ s/text run width -?[0-9]+: //g;
+        $expectedMac =~ s/text run width -?[0-9]+ [a-zA-Z ]+: //g;
+        $expectedMac =~ s/RenderButton {BUTTON} .*/RenderButton {BUTTON}/g;
+        $expectedMac =~ s/RenderImage {INPUT} .*/RenderImage {INPUT}/g;
+        $expectedMac =~ s/RenderBlock {INPUT} .*/RenderBlock {INPUT}/g;
+        $expectedMac =~ s/RenderTextControl {INPUT} .*/RenderTextControl {INPUT}/g;
+        $expectedMac =~ s/\([0-9]+px/px/g;
+        $expectedMac =~ s/ *" *\n +" */ /g;
+        $expectedMac =~ s/" +$/"/g;
+
+        $expectedMac =~ s/- /-/g;
+        $expectedMac =~ s/\n( *)"\s+/\n$1"/g;
+        $expectedMac =~ s/\s+"\n/"\n/g;
+        
+        if ($simplified_actual ne $expectedMac) {
+          writeToFile("/tmp/actual.txt", $simplified_actual);
+          writeToFile("/tmp/expected.txt", $expectedMac);
+          system "diff -u \"/tmp/expected.txt\" \"/tmp/actual.txt\" > \"/tmp/simplified.diff\"";
+
+          $diffResult = "failed";
+          if ($verbose) {
+            print "\n";
+            system "cat /tmp/simplified.diff";
+            print "failed!!!!!";
+          }
+        }
+      }
+    }
+
+    if (dumpToolDidCrash()) {
+        $result = "crash";
+        testCrashedOrTimedOut($test, $base, 1, $actual, $error);
+    } elsif (!defined $expected) {
+        if ($verbose) {
+            print "new " . ($resetResults ? "result" : "test") ."\n";
+            $atLineStart = 1;
+        }
+        $result = "new";
+
+        if ($generateNewResults || $resetResults) {
+            mkpath catfile($expectedDir, dirname($base)) if $testDirectory ne $expectedDir;
+            writeToFile("$expectedDir/$expectedFileName", $actual);
+        }
+        deleteExpectedAndActualResults($base);
+        unless ($resetResults) {
+            # Always print the file name for new tests, as they will probably need some manual inspection.
+            # in verbose mode we already printed the test case, so no need to do it again.
+            unless ($verbose) {
+                print "\n" unless $atLineStart;
+                print "$test -> ";
+            }
+            my $resultsDir = catdir($expectedDir, dirname($base));
+            print "new (results generated in $resultsDir)\n";
+            $atLineStart = 1;
+        }
+    } elsif ($actual eq $expected && $diffResult eq "passed") {
+        if ($verbose) {
+            print "succeeded\n";
+            $atLineStart = 1;
+        }
+        $result = "match";
+        deleteExpectedAndActualResults($base);
+    } else {
+        $result = "mismatch";
+
+        my $message = $actual eq $expected ? "pixel test failed" : "failed";
+
+        if ($actual ne $expected && $addPlatformExceptions) {
+            my $testBase = catfile($testDirectory, $base);
+            my $expectedBase = catfile($expectedDir, $base);
+            my $testIsMaximallyPlatformSpecific = $testBase =~ m|^\Q$platformTestDirectory\E/|;
+            my $expectedResultIsMaximallyPlatformSpecific = $expectedBase =~ m|^\Q$platformTestDirectory\E/|;
+            if (!$testIsMaximallyPlatformSpecific && !$expectedResultIsMaximallyPlatformSpecific) {
+                mkpath catfile($platformTestDirectory, dirname($base));
+                my $expectedFile = catfile($platformTestDirectory, "$expectedFileName");
+                writeToFile("$expectedFile", $actual);
+                $message .= " (results generated in $platformTestDirectory)";
+            }
+        }
+
+        printFailureMessageForTest($test, $message);
+
+        my $dir = "$testResultsDirectory/$base";
+        $dir =~ s|/([^/]+)$|| or die "Failed to find test name from base\n";
+        my $testName = $1;
+        mkpath $dir;
+
+        deleteExpectedAndActualResults($base);
+        recordActualResultsAndDiff($base, $actual);
+
+        if ($pixelTests && $diffPNG && $diffPNG ne "") {
+            $imagesPresent{$base} = 1;
+
+            writeToFile("$testResultsDirectory/$base-$actualTag.png", $actualPNG);
+            writeToFile("$testResultsDirectory/$base-$diffsTag.png", $diffPNG);
+
+            my $expectedPixelDir = expectedDirectoryForTest($base, 0, "png");
+            copy("$expectedPixelDir/$base-$expectedTag.png", "$testResultsDirectory/$base-$expectedTag.png");
+
+            open DIFFHTML, ">$testResultsDirectory/$base-$diffsTag.html" or die;
+            print DIFFHTML "<html>\n";
+            print DIFFHTML "<head>\n";
+            print DIFFHTML "<title>$base Image Compare</title>\n";
+            print DIFFHTML "<script language=\"Javascript\" type=\"text/javascript\">\n";
+            print DIFFHTML "var currentImage = 0;\n";
+            print DIFFHTML "var imageNames = new Array(\"Actual\", \"Expected\");\n";
+            print DIFFHTML "var imagePaths = new Array(\"$testName-$actualTag.png\", \"$testName-$expectedTag.png\");\n";
+            if (-f "$testDirectory/$base-w3c.png") {
+                copy("$testDirectory/$base-w3c.png", "$testResultsDirectory/$base-w3c.png");
+                print DIFFHTML "imageNames.push(\"W3C\");\n";
+                print DIFFHTML "imagePaths.push(\"$testName-w3c.png\");\n";
+            }
+            print DIFFHTML "function animateImage() {\n";
+            print DIFFHTML "    var image = document.getElementById(\"animatedImage\");\n";
+            print DIFFHTML "    var imageText = document.getElementById(\"imageText\");\n";
+            print DIFFHTML "    image.src = imagePaths[currentImage];\n";
+            print DIFFHTML "    imageText.innerHTML = imageNames[currentImage] + \" Image\";\n";
+            print DIFFHTML "    currentImage = (currentImage + 1) % imageNames.length;\n";
+            print DIFFHTML "    setTimeout('animateImage()',2000);\n";
+            print DIFFHTML "}\n";
+            print DIFFHTML "</script>\n";
+            print DIFFHTML "</head>\n";
+            print DIFFHTML "<body onLoad=\"animateImage();\">\n";
+            print DIFFHTML "<table>\n";
+            if ($diffPercentage) {
+                print DIFFHTML "<tr>\n";
+                print DIFFHTML "<td>Difference between images: <a href=\"$testName-$diffsTag.png\">$diffPercentage%</a></td>\n";
+                print DIFFHTML "</tr>\n";
+            }
+            print DIFFHTML "<tr>\n";
+            print DIFFHTML "<td><a href=\"" . toURL("$testDirectory/$test") . "\">test file</a></td>\n";
+            print DIFFHTML "</tr>\n";
+            print DIFFHTML "<tr>\n";
+            print DIFFHTML "<td id=\"imageText\" style=\"text-weight: bold;\">Actual Image</td>\n";
+            print DIFFHTML "</tr>\n";
+            print DIFFHTML "<tr>\n";
+            print DIFFHTML "<td><img src=\"$testName-$actualTag.png\" id=\"animatedImage\"></td>\n";
+            print DIFFHTML "</tr>\n";
+            print DIFFHTML "</table>\n";
+            print DIFFHTML "</body>\n";
+            print DIFFHTML "</html>\n";
+        }
+    }
+
+    if ($error) {
+        my $dir = "$testResultsDirectory/$base";
+        $dir =~ s|/([^/]+)$|| or die "Failed to find test name from base\n";
+        mkpath $dir;
+        
+        writeToFile("$testResultsDirectory/$base-$errorTag.txt", $error);
+        
+        $counts{error}++;
+        push @{$tests{error}}, $test;
+    }
+
+    countFinishedTest($test, $base, $result, $isText);
+}
+printf "\n%0.2fs total testing time\n", (time - $overallStartTime) . "";
+
+!$isDumpToolOpen || die "Failed to close $dumpToolName.\n";
+
+closeHTTPD();
+
+# Because multiple instances of this script are running concurrently we cannot 
+# safely delete this symlink.
+# system "rm /tmp/LayoutTests";
+
+# FIXME: Do we really want to check the image-comparison tool for leaks every time?
+if ($shouldCheckLeaks && $pixelTests) {
+    $totalLeaks += countAndPrintLeaks("ImageDiff", $imageDiffToolPID, "$testResultsDirectory/ImageDiff-leaks.txt");
+}
+
+if ($totalLeaks) {
+    if ($mergeDepth) {
+        parseLeaksandPrintUniqueLeaks();
+    }
+    else { 
+        print "\nWARNING: $totalLeaks total leaks found!\n";
+        print "See above for individual leaks results.\n" if ($leaksOutputFileNumber > 2);
+    }
+}
+
+close IN;
+close OUT;
+close ERROR;
+
+if ($report10Slowest) {
+    print "\n\nThe 10 slowest tests:\n\n";
+    my $count = 0;
+    for my $test (sort slowestcmp keys %durations) {
+        printf "%0.2f secs: %s\n", $durations{$test}, $test;
+        last if ++$count == 10;
+    }
+}
+
+print "\n";
+
+if ($skippedOnly && $counts{"match"}) {
+    print "The following tests are in the Skipped file (" . File::Spec->abs2rel("$platformTestDirectory/Skipped", $testDirectory) . "), but succeeded:\n";
+    foreach my $test (@{$tests{"match"}}) {
+        print "  $test\n";
+    }
+}
+
+if ($resetResults || ($counts{match} && $counts{match} == $count)) {
+    print "all $count test cases succeeded\n";
+    unlink $testResults;
+    exit;
+}
+
+
+my %text = (
+    match => "succeeded",
+    mismatch => "had incorrect layout",
+    new => "were new",
+    timedout => "timed out",
+    crash => "crashed",
+    error => "had stderr output"
+);
+
+for my $type ("match", "mismatch", "new", "timedout", "crash", "error") {
+    my $c = $counts{$type};
+    if ($c) {
+        my $t = $text{$type};
+        my $message;
+        if ($c == 1) {
+            $t =~ s/were/was/;
+            $message = sprintf "1 test case (%d%%) %s\n", 1 * 100 / $count, $t;
+        } else {
+            $message = sprintf "%d test cases (%d%%) %s\n", $c, $c * 100 / $count, $t;
+        }
+        $message =~ s-\(0%\)-(<1%)-;
+        print $message;
+    }
+}
+
+mkpath $testResultsDirectory;
+
+open HTML, ">", $testResults or die;
+print HTML "<html>\n";
+print HTML "<head>\n";
+print HTML "<title>Layout Test Results</title>\n";
+print HTML "</head>\n";
+print HTML "<body>\n";
+
+print HTML htmlForResultsSection(@{$tests{mismatch}}, "Tests where results did not match expected results", \&linksForMismatchTest);
+print HTML htmlForResultsSection(@{$tests{timedout}}, "Tests that timed out", \&linksForErrorTest);
+print HTML htmlForResultsSection(@{$tests{crash}}, "Tests that caused the DumpRenderTree tool to crash", \&linksForErrorTest);
+print HTML htmlForResultsSection(@{$tests{error}}, "Tests that had stderr output", \&linksForErrorTest);
+print HTML htmlForResultsSection(@{$tests{new}}, "Tests that had no expected results (probably new)", \&linksForNewTest);
+
+print HTML "</body>\n";
+print HTML "</html>\n";
+close HTML;
+
+if (isQt()) {
+  system "WebKitTools/Scripts/run-launcher", "--qt", $configurationOption, $testResults if $launchSafari;
+} elsif (isGtk()) {
+  system "WebKitTools/Scripts/run-launcher", "--gtk", $configurationOption, $testResults if $launchSafari;
+} elsif (isCygwin()) {
+  system "cygstart", $testResults if $launchSafari;
+} else {
+  system "WebKitTools/Scripts/run-safari", $configurationOption, "-NSOpen", $testResults if $launchSafari;
+}
+
+closeCygpaths() if isCygwin();
+
+exit 1;
+
+sub countAndPrintLeaks($$$)
+{
+    my ($dumpToolName, $dumpToolPID, $leaksFilePath) = @_;
+
+    print "\n" unless $atLineStart;
+    $atLineStart = 1;
+
+    # We are excluding the following reported leaks so they don't get in our way when looking for WebKit leaks:
+    # This allows us ignore known leaks and only be alerted when new leaks occur. Some leaks are in the old
+    # versions of the system frameworks that are being used by the leaks bots. Even though a leak has been
+    # fixed, it will be listed here until the bot has been updated with the newer frameworks.
+
+    my @typesToExclude = (
+    );
+
+    my @callStacksToExclude = (
+        "Flash_EnforceLocalSecurity" # leaks in Flash plug-in code, rdar://problem/4449747
+    );
+
+    if (isTiger()) {
+        # Leak list for the version of Tiger used on the build bot.
+        push @callStacksToExclude, (
+            "CFRunLoopRunSpecific \\| malloc_zone_malloc", "CFRunLoopRunSpecific \\| CFAllocatorAllocate ", # leak in CFRunLoopRunSpecific, rdar://problem/4670839
+            "CGImageSourceGetPropertiesAtIndex", # leak in ImageIO, rdar://problem/4628809
+            "FOGetCoveredUnicodeChars", # leak in ATS, rdar://problem/3943604
+            "GetLineDirectionPreference", "InitUnicodeUtilities", # leaks tool falsely reporting leak in CFNotificationCenterAddObserver, rdar://problem/4964790
+            "ICCFPrefWrapper::GetPrefDictionary", # leaks in Internet Config. code, rdar://problem/4449794
+            "NSHTTPURLProtocol setResponseHeader:", # leak in multipart/mixed-replace handling in Foundation, no Radar, but fixed in Leopard
+            "NSURLCache cachedResponseForRequest", # leak in CFURL cache, rdar://problem/4768430
+            "PCFragPrepareClosureFromFile", # leak in Code Fragment Manager, rdar://problem/3426998
+            "WebCore::Selection::toRange", # bug in 'leaks', rdar://problem/4967949
+            "WebCore::SubresourceLoader::create", # bug in 'leaks', rdar://problem/4985806
+            "_CFPreferencesDomainDeepCopyDictionary", # leak in CFPreferences, rdar://problem/4220786
+            "_objc_msgForward", # leak in NSSpellChecker, rdar://problem/4965278
+            "gldGetString", # leak in OpenGL, rdar://problem/5013699
+            "_setDefaultUserInfoFromURL", # leak in NSHTTPAuthenticator, rdar://problem/5546453 
+            "SSLHandshake", # leak in SSL, rdar://problem/5546440 
+            "SecCertificateCreateFromData", # leak in SSL code, rdar://problem/4464397
+        );
+        push @typesToExclude, (
+            "THRD", # bug in 'leaks', rdar://problem/3387783
+            "DRHT", # ditto (endian little hate i)
+        );
+    }
+
+    if (isLeopard()) {
+        # Leak list for the version of Leopard used on the build bot.
+        push @callStacksToExclude, (
+            "CFHTTPMessageAppendBytes", # leak in CFNetwork, rdar://problem/5435912
+            "sendDidReceiveDataCallback", # leak in CFNetwork, rdar://problem/5441619
+            "_CFHTTPReadStreamReadMark", # leak in CFNetwork, rdar://problem/5441468
+            "httpProtocolStart", # leak in CFNetwork, rdar://problem/5468837
+            "_CFURLConnectionSendCallbacks", # leak in CFNetwork, rdar://problem/5441600
+            "DispatchQTMsg", # leak in QuickTime, PPC only, rdar://problem/5667132
+            "QTMovieContentView createVisualContext", # leak in QuickTime, PPC only, rdar://problem/5667132
+            "_CopyArchitecturesForJVMVersion", # leak in Java, rdar://problem/5910823
+        );
+    }
+
+    my $leaksTool = sourceDir() . "/WebKitTools/Scripts/run-leaks";
+    my $excludeString = "--exclude-callstack '" . (join "' --exclude-callstack '", @callStacksToExclude) . "'";
+    $excludeString .= " --exclude-type '" . (join "' --exclude-type '", @typesToExclude) . "'" if @typesToExclude;
+
+    print " ? checking for leaks in $dumpToolName\n";
+    my $leaksOutput = `$leaksTool $excludeString $dumpToolPID`;
+    my ($count, $bytes) = $leaksOutput =~ /Process $dumpToolPID: (\d+) leaks? for (\d+) total/;
+    my ($excluded) = $leaksOutput =~ /(\d+) leaks? excluded/;
+
+    my $adjustedCount = $count;
+    $adjustedCount -= $excluded if $excluded;
+
+    if (!$adjustedCount) {
+        print " - no leaks found\n";
+        unlink $leaksFilePath;
+        return 0;
+    } else {
+        my $dir = $leaksFilePath;
+        $dir =~ s|/[^/]+$|| or die;
+        mkpath $dir;
+
+        if ($excluded) {
+            print " + $adjustedCount leaks ($bytes bytes including $excluded excluded leaks) were found, details in $leaksFilePath\n";
+        } else {
+            print " + $count leaks ($bytes bytes) were found, details in $leaksFilePath\n";
+        }
+
+        writeToFile($leaksFilePath, $leaksOutput);
+        
+        push( @leaksFilenames, $leaksFilePath );
+    }
+
+    return $adjustedCount;
+}
+
+sub writeToFile($$)
+{
+    my ($filePath, $contents) = @_;
+    open NEWFILE, ">", "$filePath" or die "could not create $filePath\n";
+    print NEWFILE $contents;
+    close NEWFILE;
+}
+
+# Break up a path into the directory (with slash) and base name.
+sub splitpath($)
+{
+    my ($path) = @_;
+
+    my $pathSeparator = "/";
+    my $dirname = dirname($path) . $pathSeparator;
+    $dirname = "" if $dirname eq "." . $pathSeparator;
+
+    return ($dirname, basename($path));
+}
+
+# Sort first by directory, then by file, so all paths in one directory are grouped
+# rather than being interspersed with items from subdirectories.
+# Use numericcmp to sort directory and filenames to make order logical.
+sub pathcmp($$)
+{
+    my ($patha, $pathb) = @_;
+
+    my ($dira, $namea) = splitpath($patha);
+    my ($dirb, $nameb) = splitpath($pathb);
+
+    return numericcmp($dira, $dirb) if $dira ne $dirb;
+    return numericcmp($namea, $nameb);
+}
+
+# Sort numeric parts of strings as numbers, other parts as strings.
+# Makes 1.33 come after 1.3, which is cool.
+sub numericcmp($$)
+{
+    my ($aa, $bb) = @_;
+
+    my @a = split /(\d+)/, $aa;
+    my @b = split /(\d+)/, $bb;
+
+    # Compare one chunk at a time.
+    # Each chunk is either all numeric digits, or all not numeric digits.
+    while (@a && @b) {
+        my $a = shift @a;
+        my $b = shift @b;
+        
+        # Use numeric comparison if chunks are non-equal numbers.
+        return $a <=> $b if $a =~ /^\d/ && $b =~ /^\d/ && $a != $b;
+
+        # Use string comparison if chunks are any other kind of non-equal string.
+        return $a cmp $b if $a ne $b;
+    }
+    
+    # One of the two is now empty; compare lengths for result in this case.
+    return @a <=> @b;
+}
+
+# Sort slowest tests first.
+sub slowestcmp($$)
+{
+    my ($testa, $testb) = @_;
+
+    my $dura = $durations{$testa};
+    my $durb = $durations{$testb};
+    return $durb <=> $dura if $dura != $durb;
+    return pathcmp($testa, $testb);
+}
+
+sub openDumpTool()
+{
+    return if $isDumpToolOpen;
+
+    # Save some requires variables for the linux environment...
+    my $homeDir = $ENV{'HOME'};
+    my $libraryPath = $ENV{'LD_LIBRARY_PATH'};
+    my $dyldLibraryPath = $ENV{'DYLD_LIBRARY_PATH'};
+    my $dbusAddress = $ENV{'DBUS_SESSION_BUS_ADDRESS'};
+    my $display = $ENV{'DISPLAY'};
+    my $testfonts = $ENV{'WEBKIT_TESTFONTS'};
+
+    my $homeDrive = $ENV{'HOMEDRIVE'};
+    my $homePath = $ENV{'HOMEPATH'};
+        
+    local %ENV;
+    if (isQt() || isGtk()) {
+        if (defined $display) {
+            $ENV{DISPLAY} = $display;
+        } else {
+            $ENV{DISPLAY} = ":1";
+        }
+        $ENV{'WEBKIT_TESTFONTS'} = $testfonts if defined($testfonts);
+        $ENV{HOME} = $homeDir;
+        if (defined $libraryPath) {
+            $ENV{LD_LIBRARY_PATH} = $libraryPath;
+        }
+        if (defined $dyldLibraryPath) {
+            $ENV{DYLD_LIBRARY_PATH} = $dyldLibraryPath;
+        }
+        if (defined $dbusAddress) {
+            $ENV{DBUS_SESSION_BUS_ADDRESS} = $dbusAddress;
+        }
+    }
+    $ENV{DYLD_FRAMEWORK_PATH} = $productDir;
+    $ENV{XML_CATALOG_FILES} = ""; # work around missing /etc/catalog <rdar://problem/4292995>
+    $ENV{DYLD_INSERT_LIBRARIES} = "/usr/lib/libgmalloc.dylib" if $guardMalloc;
+    
+    if (isCygwin()) {
+        $ENV{HOMEDRIVE} = $homeDrive;
+        $ENV{HOMEPATH} = $homePath;
+        if ($testfonts) {
+            $ENV{WEBKIT_TESTFONTS} = $testfonts;
+        }
+        setPathForRunningWebKitApp(\%ENV) if isCygwin();
+    }
+
+    exportArchPreference();
+
+    my @args = @toolArgs;
+    unshift @args, $dumpTool;
+    if (isOSX and !isTiger()) {
+        unshift @args, "arch";
+    }
+    if ($useValgrind) {
+        unshift @args, "valgrind";
+    } 
+    
+    $ENV{MallocStackLogging} = 1 if $shouldCheckLeaks;
+    $dumpToolPID = open3(\*OUT, \*IN, \*ERROR, @args) or die "Failed to start tool: $dumpTool\n";
+    $ENV{MallocStackLogging} = 0 if $shouldCheckLeaks;
+    $isDumpToolOpen = 1;
+    $dumpToolCrashed = 0;
+}
+
+sub closeDumpTool()
+{
+    return if !$isDumpToolOpen;
+
+    close IN;
+    close OUT;
+    waitpid $dumpToolPID, 0;
+    
+    # check for WebCore counter leaks.
+    if ($shouldCheckLeaks) {
+        while (<ERROR>) {
+            print;
+        }
+    }
+    close ERROR;
+    $isDumpToolOpen = 0;
+}
+
+sub dumpToolDidCrash()
+{
+    return 1 if $dumpToolCrashed;
+    return 0 unless $isDumpToolOpen;
+
+    my $pid = waitpid(-1, WNOHANG);
+    return 1 if ($pid == $dumpToolPID);
+
+    # On Mac OS X, crashing may be significantly delayed by crash reporter.
+    return 0 unless isOSX();
+
+    my $tryingToExit = 0;
+    open PS, "ps -o state -p $dumpToolPID |";
+    <PS>; # skip header
+    $tryingToExit = 1 if <PS> =~ /E/;
+    close PS;
+    return $tryingToExit;
+}
+
+sub openHTTPDIfNeeded()
+{
+    return if $isHttpdOpen;
+
+    mkdir "/tmp/WebKit";
+    
+    if (-f "/tmp/WebKit/httpd.pid") {
+        my $oldPid = `cat /tmp/WebKit/httpd.pid`;
+        chomp $oldPid;
+        if (0 != kill 0, $oldPid) {
+            print "\nhttpd is already running: pid $oldPid, killing...\n";
+            kill 15, $oldPid;
+            
+            my $retryCount = 20;
+            while ((0 != kill 0, $oldPid) && $retryCount) {
+                sleep 1;
+                --$retryCount;
+            }
+            
+            die "Timed out waiting for httpd to quit" unless $retryCount;
+        }
+    }
+    
+    my $httpdPath = "/usr/sbin/httpd";
+    my $httpdConfig;
+    if (isCygwin()) {
+        my $windowsConfDirectory = "$testDirectory/http/conf/";
+        unless (-x "/usr/lib/apache/libphp4.dll") {
+            copy("$windowsConfDirectory/libphp4.dll", "/usr/lib/apache/libphp4.dll");
+            chmod(0755, "/usr/lib/apache/libphp4.dll");
+        }
+        $httpdConfig = "$windowsConfDirectory/cygwin-httpd.conf";
+    } elsif (isDebianBased()) {
+        $httpdPath = "/usr/sbin/apache2";
+        $httpdConfig = "$testDirectory/http/conf/apache2-debian-httpd.conf";
+    } else {
+        $httpdConfig = "$testDirectory/http/conf/httpd.conf";
+        $httpdConfig = "$testDirectory/http/conf/apache2-httpd.conf" if `$httpdPath -v` =~ m|Apache/2|;
+    }
+    my $documentRoot = "$testDirectory/http/tests";
+    my $typesConfig = "$testDirectory/http/conf/mime.types";
+    my $listen = "127.0.0.1:$httpdPort";
+    my $absTestResultsDirectory = File::Spec->rel2abs(glob $testResultsDirectory);
+    my $sslCertificate = "$testDirectory/http/conf/webkit-httpd.pem";
+
+    mkpath $absTestResultsDirectory;
+
+    my @args = (
+        "-f", "$httpdConfig",
+        "-C", "DocumentRoot \"$documentRoot\"",
+        "-C", "Listen $listen",
+        "-c", "TypesConfig \"$typesConfig\"",
+        "-c", "CustomLog \"$absTestResultsDirectory/access_log.txt\" common",
+        "-c", "ErrorLog \"$absTestResultsDirectory/error_log.txt\"",
+        # Apache wouldn't run CGIs with permissions==700 otherwise
+        "-c", "User \"#$<\""
+    );
+
+    # FIXME: Enable this on Windows once <rdar://problem/5345985> is fixed
+    push(@args, "-c", "SSLCertificateFile \"$sslCertificate\"") unless isCygwin();
+
+    open2(\*HTTPDIN, \*HTTPDOUT, $httpdPath, @args);
+
+    my $retryCount = 20;
+    while (system("/usr/bin/curl -q --silent --stderr - --output /dev/null $listen") && $retryCount) {
+        sleep 1;
+        --$retryCount;
+    }
+    
+    die "Timed out waiting for httpd to start" unless $retryCount;
+    
+    $isHttpdOpen = 1;
+}
+
+sub closeHTTPD()
+{
+    return if !$isHttpdOpen;
+
+    close HTTPDIN;
+    close HTTPDOUT;
+
+    kill 15, `cat /tmp/WebKit/httpd.pid` if -f "/tmp/WebKit/httpd.pid";
+
+    $isHttpdOpen = 0;
+}
+
+sub fileNameWithNumber($$)
+{
+    my ($base, $number) = @_;
+    return "$base$number" if ($number > 1);
+    return $base;
+}
+
+sub processIgnoreTests($) {
+    my @ignoreList = split(/\s*,\s*/, shift);
+    my $addIgnoredDirectories = sub {
+        return () if exists $ignoredLocalDirectories{basename($File::Find::dir)};
+        $ignoredDirectories{File::Spec->abs2rel($File::Find::dir, $testDirectory)} = 1;
+        return @_;
+    };
+    foreach my $item (@ignoreList) {
+        my $path = catfile($testDirectory, $item); 
+        if (-d $path) {
+            $ignoredDirectories{$item} = 1;
+            find({ preprocess => $addIgnoredDirectories, wanted => sub {} }, $path);
+        }
+        elsif (-f $path) {
+            $ignoredFiles{$item} = 1;
+        }
+        else {
+            print "ignoring '$item' on ignore-tests list\n";
+        }
+    }
+}
+
+sub stripExtension($)
+{
+    my ($test) = @_;
+
+    $test =~ s/\.[a-zA-Z]+$//;
+    return $test;
+}
+
+sub isTextOnlyTest($)
+{
+    my ($actual) = @_;
+    my $isText;
+    if ($actual =~ /^layer at/ms) {
+        $isText = 0;
+    } else {
+        $isText = 1;
+    }
+    return $isText;
+}
+
+sub expectedDirectoryForTest($;$;$)
+{
+    my ($base, $isText, $expectedExtension) = @_;
+
+    my @directories = @platformHierarchy;
+    push @directories, map { catdir($platformBaseDirectory, $_) } qw(mac-leopard mac) if isCygwin();
+    push @directories, $expectedDirectory;
+
+    # If we already have expected results, just return their location.
+    foreach my $directory (@directories) {
+        return $directory if (-f "$directory/$base-$expectedTag.$expectedExtension");
+    }
+
+    # For platform-specific tests, the results should go right next to the test itself.
+    # Note: The return value of this subroutine will be concatenated with $base
+    # to determine the location of the new results, so returning $expectedDirectory
+    # will put the results right next to the test.
+    # FIXME: We want to allow platform/mac tests with platform/mac-leopard results,
+    # so this needs to be enhanced.
+    return $expectedDirectory if $base =~ /^platform/;
+
+    # For cross-platform tests, text-only results should go in the cross-platform directory,
+    # while render tree dumps should go in the least-specific platform directory.
+    return $isText ? $expectedDirectory : $platformHierarchy[$#platformHierarchy];
+}
+
+sub countFinishedTest($$$$) {
+    my ($test, $base, $result, $isText) = @_;
+
+    if (($count + 1) % $testsPerDumpTool == 0 || $count == $#tests) {
+        if ($shouldCheckLeaks) {
+            my $fileName;
+            if ($testsPerDumpTool == 1) {
+                $fileName = "$testResultsDirectory/$base-leaks.txt";
+            } else {
+                $fileName = "$testResultsDirectory/" . fileNameWithNumber($dumpToolName, $leaksOutputFileNumber) . "-leaks.txt";
+            }
+            my $leakCount = countAndPrintLeaks($dumpToolName, $dumpToolPID, $fileName);
+            $totalLeaks += $leakCount;
+            $leaksOutputFileNumber++ if ($leakCount);
+        }
+
+        closeDumpTool();
+    }
+    
+    $count++;
+    $counts{$result}++;
+    push @{$tests{$result}}, $test;
+    $testType{$test} = $isText;
+}
+
+sub testCrashedOrTimedOut($$$$$)
+{
+    my ($test, $base, $didCrash, $actual, $error) = @_;
+
+    printFailureMessageForTest($test, $didCrash ? "crashed" : "timed out");
+
+    sampleDumpTool() unless $didCrash;
+
+    my $dir = "$testResultsDirectory/$base";
+    $dir =~ s|/([^/]+)$|| or die "Failed to find test name from base\n";
+    mkpath $dir;
+
+    deleteExpectedAndActualResults($base);
+
+    if (defined($error) && length($error)) {
+        writeToFile("$testResultsDirectory/$base-$errorTag.txt", $error);
+    }
+
+    recordActualResultsAndDiff($base, $actual);
+
+    kill 9, $dumpToolPID unless $didCrash;
+
+    closeDumpTool();
+}
+
+sub printFailureMessageForTest($$)
+{
+    my ($test, $description) = @_;
+
+    unless ($verbose) {
+        print "\n" unless $atLineStart;
+        print "$test -> ";
+    }
+    print "$description\n";
+    $atLineStart = 1;
+}
+
+my %cygpaths = ();
+
+sub openCygpathIfNeeded($)
+{
+    my ($options) = @_;
+
+    return unless isCygwin();
+    return $cygpaths{$options} if $cygpaths{$options} && $cygpaths{$options}->{"open"};
+
+    local (*CYGPATHIN, *CYGPATHOUT);
+    my $pid = open2(\*CYGPATHIN, \*CYGPATHOUT, "cygpath -f - $options");
+    my $cygpath =  {
+        "pid" => $pid,
+        "in" => *CYGPATHIN,
+        "out" => *CYGPATHOUT,
+        "open" => 1
+    };
+
+    $cygpaths{$options} = $cygpath;
+
+    return $cygpath;
+}
+
+sub closeCygpaths()
+{
+    return unless isCygwin();
+
+    foreach my $cygpath (values(%cygpaths)) {
+        close $cygpath->{"in"};
+        close $cygpath->{"out"};
+        waitpid($cygpath->{"pid"}, 0);
+        $cygpath->{"open"} = 0;
+
+    }
+}
+
+sub convertPathUsingCygpath($$)
+{
+    my ($path, $options) = @_;
+
+    my $cygpath = openCygpathIfNeeded($options);
+    local *inFH = $cygpath->{"in"};
+    local *outFH = $cygpath->{"out"};
+    print outFH $path . "\n";
+    chomp(my $convertedPath = <inFH>);
+    return $convertedPath;
+}
+
+sub toWindowsPath($)
+{
+    my ($path) = @_;
+    return unless isCygwin();
+
+    return convertPathUsingCygpath($path, "-w");
+}
+
+sub toURL($)
+{
+    my ($path) = @_;
+    return $path unless isCygwin();
+    
+    return "file:///" . convertPathUsingCygpath($path, "-m");
+}
+
+sub validateSkippedArg($$;$)
+{
+    my ($option, $value, $value2) = @_;
+    my %validSkippedValues = map { $_ => 1 } qw(default ignore only);
+    $value = lc($value);
+    die "Invalid argument '" . $value . "' for option $option" unless $validSkippedValues{$value};
+    $treatSkipped = $value;
+}
+
+sub htmlForResultsSection(\@$&)
+{
+    my ($tests, $description, $linkGetter) = @_;
+
+    my @html = ();
+    return join("\n", @html) unless @{$tests};
+
+    push @html, "<p>$description:</p>";
+    push @html, "<table>";
+    foreach my $test (@{$tests}) {
+        push @html, "<tr>";
+        push @html, "<td><a href=\"" . toURL("$testDirectory/$test") . "\">$test</a></td>";
+        foreach my $link (@{&{$linkGetter}($test)}) {
+            push @html, "<td><a href=\"$link->{href}\">$link->{text}</a></td>";
+        }
+        push @html, "</tr>";
+    }
+    push @html, "</table>";
+
+    return join("\n", @html);
+}
+
+sub linksForExpectedAndActualResults($)
+{
+    my ($base) = @_;
+
+    my @links = ();
+
+    return \@links unless -s "$testResultsDirectory/$base-$diffsTag.txt";
+    
+    my $expectedResultPath = $expectedResultPaths{$base};
+    my ($expectedResultFileName, $expectedResultsDirectory, $expectedResultExtension) = fileparse($expectedResultPath, qr{\.[^.]+$});
+
+    push @links, { href => "$base-$expectedTag$expectedResultExtension", text => "expected" };
+    push @links, { href => "$base-$actualTag$expectedResultExtension", text => "actual" };
+    push @links, { href => "$base-$diffsTag.txt", text => "diffs" };
+
+    return \@links;
+}
+
+sub linksForMismatchTest
+{
+    my ($test) = @_;
+
+    my @links = ();
+
+    my $base = stripExtension($test);
+
+    push @links, @{linksForExpectedAndActualResults($base)};
+    return \@links unless $pixelTests && $imagesPresent{$base};
+
+    push @links, { href => "$base-$expectedTag.png", text => "expected image" };
+    push @links, { href => "$base-$diffsTag.html", text => "image diffs" };
+    push @links, { href => "$base-$diffsTag.png", text => "$imageDifferences{$base}%" };
+
+    return \@links;
+}
+
+sub linksForErrorTest
+{
+    my ($test) = @_;
+
+    my @links = ();
+
+    my $base = stripExtension($test);
+
+    push @links, @{linksForExpectedAndActualResults($base)};
+    push @links, { href => "$base-$errorTag.txt", text => "stderr" };
+
+    return \@links;
+}
+
+sub linksForNewTest
+{
+    my ($test) = @_;
+
+    my @links = ();
+
+    my $base = stripExtension($test);
+    my $expectedResultPath = $expectedResultPaths{$base};
+    my $expectedResultPathMinusExtension = stripExtension($expectedResultPath);
+
+    push @links, { href => toURL($expectedResultPath), text => "results" };
+    if ($pixelTests && -f "$expectedResultPathMinusExtension.png") {
+        push @links, { href => toURL("$expectedResultPathMinusExtension.png"), text => "image" };
+    }
+
+    return \@links;
+}
+
+sub deleteExpectedAndActualResults($)
+{
+    my ($base) = @_;
+
+    unlink "$testResultsDirectory/$base-$actualTag.txt";
+    unlink "$testResultsDirectory/$base-$diffsTag.txt";
+    unlink "$testResultsDirectory/$base-$errorTag.txt";
+}
+
+sub recordActualResultsAndDiff($$)
+{
+    my ($base, $actualResults) = @_;
+
+    return unless defined($actualResults) && length($actualResults);
+
+    my $expectedResultPath = $expectedResultPaths{$base};
+    my ($expectedResultFileNameMinusExtension, $expectedResultDirectoryPath, $expectedResultExtension) = fileparse($expectedResultPath, qr{\.[^.]+$});
+    my $actualResultsPath = "$testResultsDirectory/$base-$actualTag$expectedResultExtension";
+    my $copiedExpectedResultsPath = "$testResultsDirectory/$base-$expectedTag$expectedResultExtension";
+    writeToFile("$actualResultsPath", $actualResults);
+    copy("$expectedResultPath", "$copiedExpectedResultsPath");
+
+    system "diff -u \"$copiedExpectedResultsPath\" \"$actualResultsPath\" > \"$testResultsDirectory/$base-$diffsTag.txt\"";
+}
+
+sub buildPlatformHierarchy()
+{
+    mkpath($platformTestDirectory) if ($platform eq "undefined" && !-d "$platformTestDirectory");
+
+    my @platforms = split('-', $platform);
+    my @hierarchy;
+    for (my $i=0; $i < @platforms; $i++) {
+        my $scoped = catdir($platformBaseDirectory, join('-', @platforms[0..($#platforms - $i)]));
+        push(@hierarchy, $scoped) if (-d $scoped);
+    }
+
+    return @hierarchy;
+}
+
+sub epiloguesAndPrologues($$) {
+    my ($lastDirectory, $directory) = @_;
+    my @lastComponents = split('/', $lastDirectory);
+    my @components = split('/', $directory);
+
+    while (@lastComponents) {
+        if (!defined($components[0]) || $lastComponents[0] ne $components[0]) {
+            last;
+        }
+        shift @components;
+        shift @lastComponents;
+    }
+
+    my @result;
+    my $leaving = $lastDirectory;
+    foreach (@lastComponents) {
+        my $epilogue = $leaving . "/resources/run-webkit-tests-epilogue.html";
+        foreach (@platformHierarchy) {
+            push @result, catdir($_, $epilogue) if (stat(catdir($_, $epilogue)));
+        }
+        push @result, catdir($testDirectory, $epilogue) if (stat(catdir($testDirectory, $epilogue)));
+        $leaving =~ s|(^\|/)[^/]+$||;
+    }
+
+    my $entering = $leaving;
+    foreach (@components) {
+        $entering .= '/' . $_;
+        my $prologue = $entering . "/resources/run-webkit-tests-prologue.html";
+        push @result, catdir($testDirectory, $prologue) if (stat(catdir($testDirectory, $prologue)));
+        foreach (reverse @platformHierarchy) {
+            push @result, catdir($_, $prologue) if (stat(catdir($_, $prologue)));
+        }
+    }
+    return @result;
+}
+    
+sub parseLeaksandPrintUniqueLeaks() {
+    return unless @leaksFilenames;
+     
+    my $mergedFilenames = join " ", @leaksFilenames;
+    my $parseMallocHistoryTool = sourceDir() . "/WebKitTools/Scripts/parse-malloc-history";
+    
+    open MERGED_LEAKS, "cat $mergedFilenames | $parseMallocHistoryTool --merge-depth $mergeDepth  - |" ;
+    my @leakLines = <MERGED_LEAKS>;
+    close MERGED_LEAKS;
+    
+    my $uniqueLeakCount = 0;
+    my $totalBytes;
+    foreach my $line (@leakLines) {
+        ++$uniqueLeakCount if ($line =~ /^(\d*)\scalls/);
+        $totalBytes = $1 if $line =~ /^total\:\s(.*)\s\(/;
+    }
+    
+    print "\nWARNING: $totalLeaks total leaks found for a total of $totalBytes!\n";
+    print "WARNING: $uniqueLeakCount unique leaks found!\n";
+    print "See above for individual leaks results.\n" if ($leaksOutputFileNumber > 2);
+    
+}
+
+sub extensionForMimeType($)
+{
+    my ($mimeType) = @_;
+
+    if ($mimeType eq "application/x-webarchive") {
+        return "webarchive";
+    } elsif ($mimeType eq "application/pdf") {
+        return "pdf";
+    }
+    return "txt";
+}
+
+# Read up to the first #EOF (the content block of the test), or until detecting crashes or timeouts.
+sub readFromDumpToolWithTimer(*;$)
+{
+    my ($fh, $dontWaitForTimeOut) = @_;
+
+    setFileHandleNonBlocking($fh, 1);
+
+    my $maximumSecondsWithoutOutput = 60;
+    $maximumSecondsWithoutOutput *= 10 if $guardMalloc;
+    my $microsecondsToWaitBeforeReadingAgain = 1000;
+
+    my $timeOfLastSuccessfulRead = time;
+
+    my @output = ();
+    my $status = "success";
+    my $mimeType = "text/plain";
+    # We don't have a very good way to know when the "headers" stop
+    # and the content starts, so we use this as a hack:
+    my $haveSeenContentType = 0;
+
+    while (1) {
+        if (time - $timeOfLastSuccessfulRead > $maximumSecondsWithoutOutput) {
+            $status = dumpToolDidCrash() ? "crashed" : "timedOut";
+            last;
+        }
+
+        my $line = readline($fh);
+        if (!defined($line)) {
+            if ($! != EAGAIN) {
+                $status = "crashed";
+                last;
+            }
+
+            if ($dontWaitForTimeOut) {
+                last;
+            }
+
+            # No data ready
+            usleep($microsecondsToWaitBeforeReadingAgain);
+            next;
+        }
+
+        $timeOfLastSuccessfulRead = time;
+        
+        if (!$haveSeenContentType && $line =~ /^Content-Type: (\S+)$/) {
+            $mimeType = $1;
+            $haveSeenContentType = 1;
+            next;
+        }
+        last  if ($line =~ /#EOF/);
+        
+        push @output, $line;
+    }
+
+    setFileHandleNonBlocking($fh, 0);
+    return {
+        output => join("", @output),
+        status => $status,
+        mimeType => $mimeType,
+        extension => extensionForMimeType($mimeType)
+    };
+}
+
+sub setFileHandleNonBlocking(*$)
+{
+    my ($fh, $nonBlocking) = @_;
+
+    my $flags = fcntl($fh, F_GETFL, 0) or die "Couldn't get filehandle flags";
+
+    if ($nonBlocking) {
+        $flags |= O_NONBLOCK;
+    } else {
+        $flags &= ~O_NONBLOCK;
+    }
+
+    fcntl($fh, F_SETFL, $flags) or die "Couldn't set filehandle flags";
+
+    return 1;
+}
+
+sub sampleDumpTool()
+{
+    return unless isOSX();
+    return unless $runSample;
+
+    my $outputDirectory = "$ENV{HOME}/Library/Logs/DumpRenderTree";
+    -d $outputDirectory or mkdir $outputDirectory;
+
+    my $outputFile = "$outputDirectory/HangReport.txt";
+    system "/usr/bin/sample", $dumpToolPID, qw(10 10 -file), $outputFile;
+}
diff --git a/WebKitTools/Scripts/set-webkit-configuration b/WebKitTools/Scripts/set-webkit-configuration
new file mode 100755
index 0000000..8735140
--- /dev/null
+++ b/WebKitTools/Scripts/set-webkit-configuration
@@ -0,0 +1,41 @@
+#!/usr/bin/perl -w
+
+# Copyright (C) 2005 Apple Computer, Inc.  All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1.  Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer. 
+# 2.  Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution. 
+# 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+#     its contributors may be used to endorse or promote products derived
+#     from this software without specific prior written permission. 
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+use strict;
+use FindBin;
+use lib $FindBin::Bin;
+use webkitdirs;
+
+my $configuration = passedConfiguration();
+die "Please specify either --debug or --release.\n" if !$configuration;
+
+my $baseProductDir = baseProductDir();
+system "mkdir", "-p", "$baseProductDir";
+open CONFIGURATION, ">", "$baseProductDir/Configuration" or die;
+print CONFIGURATION $configuration;
+close CONFIGURATION;
diff --git a/WebKitTools/Scripts/sort-Xcode-project-file b/WebKitTools/Scripts/sort-Xcode-project-file
new file mode 100755
index 0000000..a35fe73
--- /dev/null
+++ b/WebKitTools/Scripts/sort-Xcode-project-file
@@ -0,0 +1,114 @@
+#!/usr/bin/perl -w
+
+# Copyright (C) 2007 Apple Inc.  All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1.  Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer. 
+# 2.  Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution. 
+# 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+#     its contributors may be used to endorse or promote products derived
+#     from this software without specific prior written permission. 
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+# Script to sort "files=(...);" sections in Xcode project.pbxproj files
+
+use strict;
+
+use File::Basename;
+use File::Temp qw(tempfile);
+use Getopt::Long;
+
+sub sortByFileName($$);
+
+my $printWarnings = 1;
+my $showHelp;
+
+my $getOptionsResult = GetOptions(
+    'h|help'         => \$showHelp,
+    'w|warnings!'    => \$printWarnings,
+);
+
+if (scalar(@ARGV) == 0) {
+    print STDERR "ERROR: No Xcode project files (project.pbxproj) listed on command-line.\n";
+    undef $getOptionsResult;
+}
+
+if (!$getOptionsResult || $showHelp) {
+    print STDERR <<__END__;
+Usage: @{[ basename($0) ]} [options] path/to/project.pbxproj [path/to/project.pbxproj ...]
+  -h|--help           show this help message
+  -w|--[no-]warnings  show or suppress warnings (default: show warnings)
+__END__
+    exit 1;
+}
+
+for my $projectFile (@ARGV) {
+    if (basename($projectFile) ne "project.pbxproj") {
+        print STDERR "WARNING: Not an Xcode project file: $projectFile\n" if $printWarnings;
+        next;
+    }
+
+    my ($OUT, $tempFileName) = tempfile(
+        basename($projectFile) . "-XXXXXXXX",
+        DIR => dirname($projectFile),
+        UNLINK => 0,
+    );
+
+    # Clean up temp file in case of die()
+    $SIG{__DIE__} = sub {
+        close(IN);
+        close($OUT);
+        unlink($tempFileName);
+    };
+
+    open(IN, "< $projectFile") || die "Could not open $projectFile: $!";
+    while (my $line = <IN>) {
+        if ($line =~ /^(\s*)files = \(\s*$/) {
+            print $OUT $line;
+            my $endMarker = $1 . ");";
+            my @files;
+            while (my $fileLine = <IN>) {
+                if ($fileLine =~ /^\Q$endMarker\E\s*$/) {
+                    $endMarker = $fileLine;
+                    last;
+                }
+                push @files, $fileLine;
+            }
+            print $OUT sort sortByFileName @files;
+            print $OUT $endMarker;
+        } else {
+            print $OUT $line;
+        }
+    }
+    close(IN);
+    close($OUT);
+
+    unlink($projectFile) || die "Could not delete $projectFile: $!";
+    rename($tempFileName, $projectFile) || die "Could not rename $tempFileName to $projectFile: $!";
+}
+
+exit 0;
+
+sub sortByFileName($$)
+{
+    my ($a, $b) = @_;
+    my $aFileName = $1 if $a =~ /^\s*[A-Z0-9]{24} \/\* (.+) in /;
+    my $bFileName = $1 if $b =~ /^\s*[A-Z0-9]{24} \/\* (.+) in /;
+    return $aFileName cmp $bFileName;
+}
diff --git a/WebKitTools/Scripts/split-file-by-class b/WebKitTools/Scripts/split-file-by-class
new file mode 100755
index 0000000..b6aeb68
--- /dev/null
+++ b/WebKitTools/Scripts/split-file-by-class
@@ -0,0 +1,159 @@
+#!/usr/bin/perl -w
+
+# Copyright (C) 2006 Apple Computer, Inc.  All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1.  Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer. 
+# 2.  Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution. 
+# 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+#     its contributors may be used to endorse or promote products derived
+#     from this software without specific prior written permission. 
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+# Used for splitting a single file into multiple class files
+# Usage: split-class <header file>
+
+use strict;
+use File::Copy;
+use FindBin;
+use lib $FindBin::Bin;
+use SpacingHeuristics;
+
+
+for my $filename (@ARGV) {
+
+    $filename =~ m/^(\w+)\.h$/ or die "Command line args must be .h files.\n";
+    my $basename = $1;
+
+    open(OLDFILE, "<", $filename) or die "File does not exist: $filename\n";
+    print "Splitting class $filename.{h,cpp}:\n";
+    
+    my $currentClassName = "";
+    my $classIndent = "";
+    my $fileContent = "";
+    my %classDefs = ();
+    while (my $line = <OLDFILE>) {
+        if ($currentClassName) {
+            $classDefs{$currentClassName} .= $line;
+            if ($line =~ /^$classIndent};\s*$/) {
+                $currentClassName = "";
+            }
+        } else {
+            if ($line =~ /^(\s*)class\s+(\w+)\s+[^;]*$/) {
+                $classIndent = $1;
+                $currentClassName = $2;
+                $classDefs{$currentClassName} .= $line;
+                $fileContent .= "###CLASS###$currentClassName\n";
+            } else {
+                $fileContent .= $line;
+            }
+        }
+    }
+    close(OLDFILE);
+    
+    if (scalar(keys(%classDefs)) == 1) { # degenerate case
+        my ($classname) = keys(%classDefs);
+        if (!($classname eq $basename)) {
+            print "Skipping $filename, already correctly named.\n";
+        } else {
+            print "$filename only includes one class, renaming to $classname.h\n";
+            system("svn rm --force $classname.h") if (-r "$classname.h");
+            system "svn mv $basename.h $classname.h";
+        }
+    } else {
+        while (my ($classname, $classDef) = each(%classDefs)) {
+            if (($classname eq $basename)) {
+                print "Skipping $filename, already correctly named.\n";
+            } else {
+                print "Using SVN to copy $basename.{h,cpp} to $classname.{h,cpp}\n";
+                
+                system("svn rm --force $classname.h") if (-r "$classname.h");
+                system "svn cp $basename.h $classname.h";
+                
+                system("svn rm --force $classname.cpp") if (-r "$classname.cpp");
+                system "svn cp $basename.cpp $classname.cpp";
+            }
+            
+            print "Fixing $classname.h as much as possible.\n";
+            open(NEWHEADER, ">", "$classname.h") or die "File does not exist: $filename\n";
+            my @lines = split("\n", $fileContent);
+            foreach my $line (@lines) {
+                if ($line =~ /^###CLASS###(\w+)/) {
+                    if ($1 eq $classname) {
+                        print NEWHEADER $classDef . "\n";
+                    }
+                } else {
+                    print NEWHEADER $line . "\n";
+                }
+            }
+            close(NEWHEADER);
+            
+            print "Fixing $classname.cpp as much as possible.\n";
+            copy("$classname.cpp", "$classname.cpp.original");
+            open(OLDCPP, "<", "$classname.cpp.original") or die "Failed to copy file for reading: $filename\n";
+            open(NEWCPP, ">", "$classname.cpp") or die "File does not exist: $filename\n";
+            my $insideMemberFunction = 0;
+            my $shouldPrintMemberFunction = 0;
+            resetSpacingHeuristics();
+            while (my $line = <OLDCPP>) {
+                if ($insideMemberFunction) {
+                    if ($shouldPrintMemberFunction) {
+                        print NEWCPP $line;
+                        #setPreviousAllowedLine($line);
+                    } else {
+                        ignoringLine($line);
+                    }
+                    if ($line =~ /^}\s*$/) {
+                        $insideMemberFunction = 0;
+                    }
+                } elsif ($line =~ /$filename/) {
+                    print NEWCPP "#include \"config.h\"\n";
+                    print NEWCPP "#include \"$classname.h\"\n";
+                } elsif ($line =~ /#include/ || $line =~ /#import/) {
+                    next; # skip includes, they're generally wrong or unecessary anyway.
+                } else {
+                    $line =~ s/DOM:://;
+                    $line =~ s/khtml:://;
+                    $line =~ s/namespace DOM/namespace WebCore/;
+                    $line =~ s/namespace khtml/namespace WebCore/;
+                    
+                    if ($line =~ /^(.*?\s+)?(\*|&)?(\w+)::(~)?\w+\s*\(/) {
+                        $insideMemberFunction = 1;
+                        $shouldPrintMemberFunction = ($classname eq $3);
+                        if ($shouldPrintMemberFunction) {
+                            printPendingEmptyLines(*NEWCPP, $line);
+                            print NEWCPP $line;
+                        }
+                    } else {
+                        next if isOnlyWhiteSpace($line);
+                        next if ($line =~ m/------------/);
+                        printPendingEmptyLines(*NEWCPP, $line);
+                        applySpacingHeuristicsAndPrint(*NEWCPP, $line);
+                    }
+                }
+            }
+            close(NEWCPP);
+            close(OLDCPP);
+            unlink("$classname.cpp.original");
+        }
+    }
+    
+    print "Opening new files...\n";
+    system("open " . join(".* ", keys(%classDefs)) . ".*");
+}
\ No newline at end of file
diff --git a/WebKitTools/Scripts/sunspider-compare-results b/WebKitTools/Scripts/sunspider-compare-results
new file mode 100755
index 0000000..ec0863a
--- /dev/null
+++ b/WebKitTools/Scripts/sunspider-compare-results
@@ -0,0 +1,101 @@
+#!/usr/bin/perl -w
+
+# Copyright (C) 2007 Apple Inc. All rights reserved.
+# Copyright (C) 2007 Eric Seidel <[email protected]>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+# OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+
+use strict;
+use File::Spec;
+use FindBin;
+use Getopt::Long qw(:config pass_through);
+use lib $FindBin::Bin;
+use webkitdirs;
+use POSIX;
+
+# determine configuration, but default to "Release" instead of last-used configuration to match run-sunspider
+setConfiguration("Release");
+setConfiguration();
+my $configuration = configuration();
+
+my $root;
+my $showHelp = 0;
+
+my $programName = basename($0);
+my $usage = <<EOF;
+Usage: $programName [options] FILE FILE
+  --help        Show this help message
+  --root        Path to root tools build
+EOF
+
+GetOptions('root=s' => sub { my ($argName, $value); setConfigurationProductDir(Cwd::abs_path($value)); },
+           'help' => \$showHelp);
+
+if ($showHelp) {
+   print STDERR $usage;
+   exit 1;
+}
+
+@ARGV = map { File::Spec->rel2abs($_) } @ARGV;
+
+sub buildJSC
+{
+    if (!defined($root)){
+        chdirWebKit();
+        my $buildResult = system "WebKitTools/Scripts/build-jsc", "--" . $configuration;
+        if ($buildResult) {
+            print STDERR "Compiling jsc failed!\n";
+            exit WEXITSTATUS($buildResult);
+        }
+    }
+}
+
+sub setupEnvironmentForExecution($)
+{
+    my ($productDir) = @_;
+    print "Starting sunspider-compare-results with DYLD_FRAMEWORK_PATH set to point to built JavaScriptCore in $productDir.\n";
+    $ENV{DYLD_FRAMEWORK_PATH} = $productDir;
+    # FIXME: Other platforms may wish to augment this method to use LD_LIBRARY_PATH, etc.
+}
+
+sub jscPath($)
+{
+    my ($productDir) = @_;
+    my $jscName = "jsc";
+    $jscName .= "_debug"  if (isCygwin() && ($configuration eq "Debug"));
+    return "$productDir/$jscName";
+}
+
+buildJSC();
+
+chdirWebKit();
+chdir("SunSpider");
+
+my $productDir = productDir();
+# FIXME: This hack should be pushed down into productDir()
+$productDir .= "/JavaScriptCore" if (isQt() or isGtk());
+
+setupEnvironmentForExecution($productDir);
+my @args = ("--shell", jscPath($productDir));
+# This code could be removed if we chose to pass extra args to sunspider instead of Xcode
+
+exec "./sunspider-compare-results", @args, @ARGV;
diff --git a/WebKitTools/Scripts/svn-apply b/WebKitTools/Scripts/svn-apply
new file mode 100755
index 0000000..d43d525
--- /dev/null
+++ b/WebKitTools/Scripts/svn-apply
@@ -0,0 +1,443 @@
+#!/usr/bin/perl -w
+
+# Copyright (C) 2005, 2006, 2007 Apple Inc.  All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1.  Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer. 
+# 2.  Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution. 
+# 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+#     its contributors may be used to endorse or promote products derived
+#     from this software without specific prior written permission. 
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+# "patch" script for WebKit Open Source Project, used to apply patches.
+
+# Differences from invoking "patch -p0":
+#
+#   Handles added files (does a svn add with logic to handle local changes).
+#   Handles added directories (does a svn add).
+#   Handles removed files (does a svn rm with logic to handle local changes).
+#   Handles removed directories--those with no more files or directories left in them
+#       (does a svn rm).
+#   Has mode where it will roll back to svn version numbers in the patch file so svn
+#       can do a 3-way merge.
+#   Paths from Index: lines are used rather than the paths on the patch lines, which
+#       makes patches generated by "cvs diff" work (increasingly unimportant since we
+#       use Subversion now).
+#   ChangeLog patches use --fuzz=3 to prevent rejects, and the entry date is set in
+#       the patch to today's date using $changeLogTimeZone.
+#   Handles binary files (requires patches made by svn-create-patch).
+#   Handles copied and moved files (requires patches made by svn-create-patch).
+#   Handles git-diff patches (without binary changes) created at the top-level directory
+#
+# Missing features:
+#
+#   Handle property changes.
+#   Handle copied and moved directories (would require patches made by svn-create-patch).
+#   When doing a removal, check that old file matches what's being removed.
+#   Notice a patch that's being applied at the "wrong level" and make it work anyway.
+#   Do a dry run on the whole patch and don't do anything if part of the patch is
+#       going to fail (probably too strict unless we exclude ChangeLog).
+#   Handle git-diff patches with binary changes
+
+use strict;
+use warnings;
+
+use Cwd;
+use Digest::MD5;
+use File::Basename;
+use File::Spec;
+use Getopt::Long;
+use MIME::Base64;
+use POSIX qw(strftime);
+
+sub addDirectoriesIfNeeded($);
+sub applyPatch($$;$);
+sub checksum($);
+sub fixChangeLogPatch($);
+sub gitdiff2svndiff($);
+sub handleBinaryChange($$);
+sub isDirectoryEmptyForRemoval($);
+sub patch($);
+sub removeDirectoriesIfNeeded();
+sub setChangeLogDateAndReviewer($$);
+sub svnStatus($);
+
+# Project time zone for Cupertino, CA, US
+my $changeLogTimeZone = "PST8PDT";
+
+my $merge = 0;
+my $showHelp = 0;
+my $reviewer;
+if (!GetOptions("merge!" => \$merge, "help!" => \$showHelp, "reviewer=s" => \$reviewer) || $showHelp) {
+    print STDERR basename($0) . " [-h|--help] [-m|--merge] [-r|--reviewer name] patch1 [patch2 ...]\n";
+    exit 1;
+}
+
+my %removeDirectoryIgnoreList = (
+    '.' => 1,
+    '..' => 1,
+    '.svn' => 1,
+    '_svn' => 1,
+);
+
+my %checkedDirectories;
+my %copiedFiles;
+my @patches;
+my %versions;
+
+my $copiedFromPath;
+my $filter;
+my $indexPath;
+my $patch;
+while (<>) {
+    s/([\n\r]+)$//mg;
+    my $eol = $1;
+    if (!defined($indexPath) && m#^diff --git a/#) {
+        $filter = \&gitdiff2svndiff;
+    }
+    $_ = &$filter($_) if $filter;
+    if (/^Index: (.+)/) {
+        $indexPath = $1;
+        if ($patch) {
+            if (!$copiedFromPath) {
+                push @patches, $patch;
+            }
+            $copiedFromPath = "";
+            $patch = "";
+        }
+    }
+    if ($indexPath) {
+        # Fix paths on diff, ---, and +++ lines to match preceding Index: line.
+        s/\S+$/$indexPath/ if /^diff/;
+        s/^--- \S+/--- $indexPath/;
+        if (/^--- .+\(from (\S+):(\d+)\)$/) {
+            $copiedFromPath = $1;
+            $copiedFiles{$indexPath} = $copiedFromPath;
+            $versions{$copiedFromPath} = $2 if ($2 != 0);
+        }
+        elsif (/^--- .+\(revision (\d+)\)$/) {
+            $versions{$indexPath} = $1 if ($1 != 0);
+        }
+        if (s/^\+\+\+ \S+/+++ $indexPath/) {
+            $indexPath = "";
+        }
+    }
+    $patch .= $_;
+    $patch .= $eol;
+}
+
+if ($patch && !$copiedFromPath) {
+    push @patches, $patch;
+}
+
+if ($merge) {
+    for my $file (sort keys %versions) {
+        print "Getting version $versions{$file} of $file\n";
+        system "svn", "update", "-r", $versions{$file}, $file;
+    }
+}
+
+# Handle copied and moved files first since moved files may have their source deleted before the move.
+for my $file (keys %copiedFiles) {
+    addDirectoriesIfNeeded(dirname($file));
+    system "svn", "copy", $copiedFiles{$file}, $file;
+}
+
+for $patch (@patches) {
+    patch($patch);
+}
+
+removeDirectoriesIfNeeded();
+
+exit 0;
+
+sub addDirectoriesIfNeeded($)
+{
+    my ($path) = @_;
+    my @dirs = File::Spec->splitdir($path);
+    my $dir = ".";
+    while (scalar @dirs) {
+        $dir = File::Spec->catdir($dir, shift @dirs);
+        next if exists $checkedDirectories{$dir};
+        if (! -e $dir) {
+            mkdir $dir or die "Failed to create required directory '$dir' for path '$path'\n";
+            system "svn", "add", $dir;
+            $checkedDirectories{$dir} = 1;
+        }
+        elsif (-d $dir) {
+            my $svnOutput = svnStatus($dir);
+            if ($svnOutput && $svnOutput =~ m#\?\s+$dir\n#) {
+                system "svn", "add", $dir;
+            }
+            $checkedDirectories{$dir} = 1;
+        }
+        else {
+            die "'$dir' is not a directory";
+        }
+    }
+}
+
+sub applyPatch($$;$)
+{
+    my ($patch, $fullPath, $options) = @_;
+    $options = [] if (! $options);
+    my $command = "patch " . join(" ", "-p0", @{$options});
+    open PATCH, "| $command" or die "Failed to patch $fullPath\n";
+    print PATCH $patch;
+    close PATCH;
+}
+
+sub checksum($)
+{
+    my $file = shift;
+    open(FILE, $file) or die "Can't open '$file': $!";
+    binmode(FILE);
+    my $checksum = Digest::MD5->new->addfile(*FILE)->hexdigest();
+    close(FILE);
+    return $checksum;
+}
+
+sub fixChangeLogPatch($)
+{
+    my $patch = shift;
+    my $contextLineCount = 3;
+
+    return $patch if $patch !~ /\n@@ -1,(\d+) \+1,(\d+) @@\n( .*\n)+(\+.*\n)+( .*\n){$contextLineCount}$/m;
+    my ($oldLineCount, $newLineCount) = ($1, $2);
+    return $patch if $oldLineCount <= $contextLineCount;
+
+    # The diff(1) command is greedy when matching lines, so a new ChangeLog entry will
+    # have lines of context at the top of a patch when the existing entry has the same
+    # date and author as the new entry.  This nifty loop alters a ChangeLog patch so
+    # that the added lines ("+") in the patch always start at the beginning of the
+    # patch and there are no initial lines of context.
+    my $newPatch;
+    my $lineCountInState = 0;
+    my $oldContentLineCountReduction = $oldLineCount - $contextLineCount;
+    my $newContentLineCountWithoutContext = $newLineCount - $oldLineCount - $oldContentLineCountReduction;
+    my ($stateHeader, $statePreContext, $stateNewChanges, $statePostContext) = (1..4);
+    my $state = $stateHeader;
+    foreach my $line (split(/\n/, $patch)) {
+        $lineCountInState++;
+        if ($state == $stateHeader && $line =~ /^@@ -1,$oldLineCount \+1,$newLineCount @\@$/) {
+            $line = "@@ -1,$contextLineCount +1," . ($newLineCount - $oldContentLineCountReduction) . " @@";
+            $lineCountInState = 0;
+            $state = $statePreContext;
+        } elsif ($state == $statePreContext && substr($line, 0, 1) eq " ") {
+            $line = "+" . substr($line, 1);
+            if ($lineCountInState == $oldContentLineCountReduction) {
+                $lineCountInState = 0;
+                $state = $stateNewChanges;
+            }
+        } elsif ($state == $stateNewChanges && substr($line, 0, 1) eq "+") {
+            # No changes to these lines
+            if ($lineCountInState == $newContentLineCountWithoutContext) {
+                $lineCountInState = 0;
+                $state = $statePostContext;
+            }
+        } elsif ($state == $statePostContext) {
+            if (substr($line, 0, 1) eq "+" && $lineCountInState <= $oldContentLineCountReduction) {
+                $line = " " . substr($line, 1);
+            } elsif ($lineCountInState > $contextLineCount && substr($line, 0, 1) eq " ") {
+                next; # Discard
+            }
+        }
+        $newPatch .= $line . "\n";
+    }
+
+    return $newPatch;
+}
+
+sub gitdiff2svndiff($)
+{
+    $_ = shift @_;
+    if (m#^diff --git a/(.+) b/(.+)#) {
+        return "Index: $1";
+    } elsif (m/^new file.*/) {
+        return "";
+    } elsif (m#^index [0-9a-f]{7}\.\.[0-9a-f]{7} [0-9]{6}#) {
+        return "===================================================================";
+    } elsif (m#^--- a/(.+)#) {
+        return "--- $1";
+    } elsif (m#^\+\+\+ b/(.+)#) {
+        return "+++ $1";
+    }
+    return $_;
+}
+
+sub handleBinaryChange($$)
+{
+    my ($fullPath, $contents) = @_;
+    if ($contents =~ m#((\n[A-Za-z0-9+/]{76})+\n[A-Za-z0-9+/=]{4,76}\n)#) {
+        # Addition or Modification
+        open FILE, ">", $fullPath or die;
+        print FILE decode_base64($1);
+        close FILE;
+        my $svnOutput = svnStatus($fullPath);
+        if ($svnOutput && substr($svnOutput, 0, 1) eq "?") {
+            # Addition
+            system "svn", "add", $fullPath;
+        } else {
+            # Modification
+            print $svnOutput if $svnOutput;
+        }
+    } else {
+        # Deletion
+        system "svn", "rm", $fullPath;
+    }
+}
+
+sub isDirectoryEmptyForRemoval($)
+{
+    my ($dir) = @_;
+    my $directoryIsEmpty = 1;
+    opendir DIR, $dir or die "Could not open '$dir' to list files: $?";
+    for (my $item = readdir DIR; $item && $directoryIsEmpty; $item = readdir DIR) {
+        next if exists $removeDirectoryIgnoreList{$item};
+        if (! -d File::Spec->catdir($dir, $item)) {
+            $directoryIsEmpty = 0;
+        } else {
+            my $svnOutput = svnStatus(File::Spec->catdir($dir, $item));
+            next if $svnOutput && substr($svnOutput, 0, 1) eq "D";
+            $directoryIsEmpty = 0;
+        }
+    }
+    closedir DIR;
+    return $directoryIsEmpty;
+}
+
+sub patch($)
+{
+    my ($patch) = @_;
+    return if !$patch;
+
+    unless ($patch =~ m|^Index: ([^\n]+)|) {
+        my $separator = '-' x 67;
+        warn "Failed to find 'Index:' in:\n$separator\n$patch\n$separator\n";
+        return;
+    }
+    my $fullPath = $1;
+
+    my $deletion = 0;
+    my $addition = 0;
+    my $isBinary = 0;
+
+    $addition = 1 if $patch =~ /\n--- .+\(revision 0\)\n/;
+    $deletion = 1 if $patch =~ /\n@@ .* \+0,0 @@/;
+    $isBinary = 1 if $patch =~ /\nCannot display: file marked as a binary type\./;
+
+    if (!$addition && !$deletion && !$isBinary) {
+        # Standard patch, patch tool can handle this.
+        if (basename($fullPath) eq "ChangeLog") {
+            my $changeLogDotOrigExisted = -f "${fullPath}.orig";
+            applyPatch(setChangeLogDateAndReviewer(fixChangeLogPatch($patch), $reviewer), $fullPath, ["--fuzz=3"]);
+            unlink("${fullPath}.orig") if (! $changeLogDotOrigExisted);
+        } else {
+            applyPatch($patch, $fullPath);
+        }
+    } else {
+        # Either a deletion, an addition or a binary change.
+
+        addDirectoriesIfNeeded(dirname($fullPath));
+
+        if ($isBinary) {
+            # Binary change
+            handleBinaryChange($fullPath, $patch);
+        } elsif ($deletion) {
+            # Deletion
+            applyPatch($patch, $fullPath, ["--force"]);
+            system "svn", "rm", "--force", $fullPath;
+        } else {
+            # Addition
+            rename($fullPath, "$fullPath.orig") if -e $fullPath;
+            applyPatch($patch, $fullPath);
+            unlink("$fullPath.orig") if -e "$fullPath.orig" && checksum($fullPath) eq checksum("$fullPath.orig");
+            system "svn", "add", $fullPath;
+            system "svn", "stat", "$fullPath.orig" if -e "$fullPath.orig";
+        }
+    }
+}
+
+sub removeDirectoriesIfNeeded()
+{
+    foreach my $dir (reverse sort keys %checkedDirectories) {
+        if (isDirectoryEmptyForRemoval($dir)) {
+            my $svnOutput;
+            open SVN, "svn rm '$dir' |" or die;
+            # Only save the last line since Subversion lists all changed statuses below $dir
+            while (<SVN>) {
+                $svnOutput = $_;
+            }
+            close SVN;
+            print $svnOutput if $svnOutput;
+        }
+    }
+}
+
+sub setChangeLogDateAndReviewer($$)
+{
+    my $patch = shift;
+    my $reviewer = shift;
+    my $savedTimeZone = $ENV{'TZ'};
+    # Set TZ temporarily so that localtime() is in that time zone
+    $ENV{'TZ'} = $changeLogTimeZone;
+    my $newDate = strftime("%Y-%m-%d", localtime());
+    if (defined $savedTimeZone) {
+         $ENV{'TZ'} = $savedTimeZone;
+    } else {
+         delete $ENV{'TZ'};
+    }
+    $patch =~ s/(\n\+)\d{4}-[^-]{2}-[^-]{2}(  )/$1$newDate$2/;
+    if (defined($reviewer)) {
+        $patch =~ s/NOBODY \(OOPS!\)/$reviewer/;
+    }
+    return $patch;
+}
+
+sub svnStatus($)
+{
+    my ($fullPath) = @_;
+    my $svnStatus;
+    open SVN, "svn status --non-interactive --non-recursive '$fullPath' |" or die;
+    if (-d $fullPath) {
+        # When running "svn stat" on a directory, we can't assume that only one
+        # status will be returned (since any files with a status below the
+        # directory will be returned), and we can't assume that the directory will
+        # be first (since any files with unknown status will be listed first).
+        my $normalizedFullPath = File::Spec->catdir(File::Spec->splitdir($fullPath));
+        while (<SVN>) {
+            chomp;
+            my $normalizedStatPath = File::Spec->catdir(File::Spec->splitdir(substr($_, 7)));
+            if ($normalizedFullPath eq $normalizedStatPath) {
+                $svnStatus = $_;
+                last;
+            }
+        }
+        # Read the rest of the svn command output to avoid a broken pipe warning.
+        local $/ = undef;
+        <SVN>;
+    }
+    else {
+        # Files will have only one status returned.
+        $svnStatus = <SVN>;
+    }
+    close SVN;
+    return $svnStatus;
+}
diff --git a/WebKitTools/Scripts/svn-create-patch b/WebKitTools/Scripts/svn-create-patch
new file mode 100755
index 0000000..365737a
--- /dev/null
+++ b/WebKitTools/Scripts/svn-create-patch
@@ -0,0 +1,442 @@
+#!/usr/bin/perl -w
+
+# Copyright (C) 2005, 2006 Apple Computer, Inc.  All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1.  Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer. 
+# 2.  Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution. 
+# 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+#     its contributors may be used to endorse or promote products derived
+#     from this software without specific prior written permission. 
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+# Extended "svn diff" script for WebKit Open Source Project, used to make patches.
+
+# Differences from standard "svn diff":
+#
+#   Uses the real diff, not svn's built-in diff.
+#   Always passes "-p" to diff so it will try to include function names.
+#   Handles binary files (encoded as a base64 chunk of text).
+#   Sorts the diffs alphabetically by text files, then binary files.
+#   Handles copied and moved files.
+#
+# Missing features:
+#
+#   Handle copied and moved directories.
+
+use strict;
+use warnings;
+
+use Config;
+use Cwd;
+use File::Basename;
+use File::Spec;
+use File::stat;
+use Getopt::Long;
+use MIME::Base64;
+use POSIX qw(:errno_h);
+use Time::gmtime;
+
+sub binarycmp($$);
+sub canonicalizePath($);
+sub findBaseUrl($);
+sub findMimeType($;$);
+sub findModificationType($);
+sub findSourceFileAndRevision($);
+sub fixChangeLogPatch($);
+sub generateDiff($);
+sub generateFileList($\%);
+sub isBinaryMimeType($);
+sub manufacturePatchForAdditionWithHistory($);
+sub numericcmp($$);
+sub outputBinaryContent($);
+sub patchpathcmp($$);
+sub pathcmp($$);
+sub processPaths(\@);
+sub splitpath($);
+sub testfilecmp($$);
+
+$ENV{'LC_ALL'} = 'C';
+
+my $showHelp;
+
+my $result = GetOptions(
+    "help"       => \$showHelp,
+);
+if (!$result || $showHelp) {
+    print STDERR basename($0) . " [-h|--help] [svndir1 [svndir2 ...]]\n";
+    exit 1;
+}
+
+# Sort the diffs for easier reviewing.
+my %paths = processPaths(@ARGV);
+
+# Generate a list of files requiring diffs.
+my %diffFiles;
+for my $path (keys %paths) {
+    generateFileList($path, %diffFiles);
+}
+
+# Generate the diffs, in a order chosen for easy reviewing.
+for my $path (sort patchpathcmp values %diffFiles) {
+    generateDiff($path);
+}
+
+exit 0;
+
+# Overall sort, considering multiple criteria.
+sub patchpathcmp($$)
+{
+    my ($a, $b) = @_;
+
+    # All binary files come after all non-binary files.
+    my $result = binarycmp($a, $b);
+    return $result if $result;
+
+    # All test files come after all non-test files.
+    $result = testfilecmp($a, $b);
+    return $result if $result;
+
+    # Final sort is a "smart" sort by directory and file name.
+    return pathcmp($a, $b);
+}
+
+# Sort so text files appear before binary files.
+sub binarycmp($$)
+{
+    my ($fileDataA, $fileDataB) = @_;
+    return $fileDataA->{isBinary} <=> $fileDataB->{isBinary};
+}
+
+sub canonicalizePath($)
+{
+    my ($file) = @_;
+
+    # Remove extra slashes and '.' directories in path
+    $file = File::Spec->canonpath($file);
+
+    # Remove '..' directories in path
+    my @dirs = ();
+    foreach my $dir (File::Spec->splitdir($file)) {
+        if ($dir eq '..' && $#dirs >= 0 && $dirs[$#dirs] ne '..') {
+            pop(@dirs);
+        } else {
+            push(@dirs, $dir);
+        }
+    }
+    return ($#dirs >= 0) ? File::Spec->catdir(@dirs) : ".";
+}
+
+sub findBaseUrl($)
+{
+    my ($infoPath) = @_;
+    my $baseUrl;
+    open INFO, "svn info '$infoPath' |" or die;
+    while (<INFO>) {
+        if (/^URL: (.+)/) {
+            $baseUrl = $1;
+            last;
+        }
+    }
+    close INFO;
+    return $baseUrl;
+}
+
+sub findMimeType($;$)
+{
+    my ($file, $revision) = @_;
+    my $args = $revision ? "--revision $revision" : "";
+    open PROPGET, "svn propget svn:mime-type $args '$file' |" or die;
+    my $mimeType = <PROPGET>;
+    close PROPGET;
+    chomp $mimeType if $mimeType;
+    return $mimeType;
+}
+
+sub findModificationType($)
+{
+    my ($stat) = @_;
+    my $fileStat = substr($stat, 0, 1);
+    my $propertyStat = substr($stat, 1, 1);
+    if ($fileStat eq "A") {
+        my $additionWithHistory = substr($stat, 3, 1);
+        return $additionWithHistory eq "+" ? "additionWithHistory" : "addition";
+    }
+    return "modification" if ($fileStat eq "M" || $propertyStat eq "M");
+    return "deletion" if ($fileStat eq "D");
+    return undef;
+}
+
+sub findSourceFileAndRevision($)
+{
+    my ($file) = @_;
+    my $baseUrl = findBaseUrl(".");
+    my $sourceFile;
+    my $sourceRevision;
+    open INFO, "svn info '$file' |" or die;
+    while (<INFO>) {
+        if (/^Copied From URL: (.+)/) {
+            $sourceFile = File::Spec->abs2rel($1, $baseUrl);
+        } elsif (/^Copied From Rev: ([0-9]+)/) {
+            $sourceRevision = $1;
+        }
+    }
+    close INFO;
+    return ($sourceFile, $sourceRevision);
+}
+
+sub fixChangeLogPatch($)
+{
+    my $patch = shift;
+    my $contextLineCount = 3;
+
+    return $patch if $patch !~ /\n@@ -1,(\d+) \+1,(\d+) @@\n( .*\n)+(\+.*\n)+( .*\n){$contextLineCount}$/m;
+    my ($oldLineCount, $newLineCount) = ($1, $2);
+    return $patch if $oldLineCount <= $contextLineCount;
+
+    # The diff(1) command is greedy when matching lines, so a new ChangeLog entry will
+    # have lines of context at the top of a patch when the existing entry has the same
+    # date and author as the new entry.  This nifty loop alters a ChangeLog patch so
+    # that the added lines ("+") in the patch always start at the beginning of the
+    # patch and there are no initial lines of context.
+    my $newPatch;
+    my $lineCountInState = 0;
+    my $oldContentLineCountReduction = $oldLineCount - $contextLineCount;
+    my $newContentLineCountWithoutContext = $newLineCount - $oldLineCount - $oldContentLineCountReduction;
+    my ($stateHeader, $statePreContext, $stateNewChanges, $statePostContext) = (1..4);
+    my $state = $stateHeader;
+    foreach my $line (split(/\n/, $patch)) {
+        $lineCountInState++;
+        if ($state == $stateHeader && $line =~ /^@@ -1,$oldLineCount \+1,$newLineCount @\@$/) {
+            $line = "@@ -1,$contextLineCount +1," . ($newLineCount - $oldContentLineCountReduction) . " @@";
+            $lineCountInState = 0;
+            $state = $statePreContext;
+        } elsif ($state == $statePreContext && substr($line, 0, 1) eq " ") {
+            $line = "+" . substr($line, 1);
+            if ($lineCountInState == $oldContentLineCountReduction) {
+                $lineCountInState = 0;
+                $state = $stateNewChanges;
+            }
+        } elsif ($state == $stateNewChanges && substr($line, 0, 1) eq "+") {
+            # No changes to these lines
+            if ($lineCountInState == $newContentLineCountWithoutContext) {
+                $lineCountInState = 0;
+                $state = $statePostContext;
+            }
+        } elsif ($state == $statePostContext) {
+            if (substr($line, 0, 1) eq "+" && $lineCountInState <= $oldContentLineCountReduction) {
+                $line = " " . substr($line, 1);
+            } elsif ($lineCountInState > $contextLineCount && substr($line, 0, 1) eq " ") {
+                next; # Discard
+            }
+        }
+        $newPatch .= $line . "\n";
+    }
+
+    return $newPatch;
+}
+
+sub generateDiff($)
+{
+    my ($fileData) = @_;
+    my $file = $fileData->{path};
+    my $patch;
+    if ($fileData->{modificationType} eq "additionWithHistory") {
+        manufacturePatchForAdditionWithHistory($fileData);
+    }
+    open DIFF, "svn diff --diff-cmd diff -x -uaNp '$file' |" or die;
+    while (<DIFF>) {
+        $patch .= $_;
+    }
+    close DIFF;
+    $patch = fixChangeLogPatch($patch) if basename($file) eq "ChangeLog";
+    print $patch if $patch;
+    if ($fileData->{isBinary}) {
+        print "\n" if ($patch && $patch =~ m/\n\S+$/m);
+        outputBinaryContent($file);
+    }
+}
+
+sub generateFileList($\%)
+{
+    my ($statPath, $diffFiles) = @_;
+    my %testDirectories = map { $_ => 1 } qw(LayoutTests);
+    open STAT, "svn stat '$statPath' |" or die;
+    while (my $line = <STAT>) {
+        chomp $line;
+        my $stat = substr($line, 0, 7);
+        my $path = substr($line, 7);
+        next if -d $path;
+        my $modificationType = findModificationType($stat);
+        if ($modificationType) {
+            $diffFiles->{$path}->{path} = $path;
+            $diffFiles->{$path}->{modificationType} = $modificationType;
+            $diffFiles->{$path}->{isBinary} = isBinaryMimeType($path);
+            $diffFiles->{$path}->{isTestFile} = exists $testDirectories{(File::Spec->splitdir($path))[0]} ? 1 : 0;
+            if ($modificationType eq "additionWithHistory") {
+                my ($sourceFile, $sourceRevision) = findSourceFileAndRevision($path);
+                $diffFiles->{$path}->{sourceFile} = $sourceFile;
+                $diffFiles->{$path}->{sourceRevision} = $sourceRevision;
+            }
+        } else {
+            print STDERR $line, "\n";
+        }
+    }
+    close STAT;
+}
+
+sub isBinaryMimeType($)
+{
+    my ($file) = @_;
+    my $mimeType = findMimeType($file);
+    return 0 if (!$mimeType || substr($mimeType, 0, 5) eq "text/");
+    return 1;
+}
+
+sub manufacturePatchForAdditionWithHistory($)
+{
+    my ($fileData) = @_;
+    my $file = $fileData->{path};
+    print "Index: ${file}\n";
+    print "=" x 67, "\n";
+    my $sourceFile = $fileData->{sourceFile};
+    my $sourceRevision = $fileData->{sourceRevision};
+    print "--- ${file}\t(revision ${sourceRevision})\t(from ${sourceFile}:${sourceRevision})\n";
+    print "+++ ${file}\t(working copy)\n";
+    if ($fileData->{isBinary}) {
+        print "\nCannot display: file marked as a binary type.\n";
+        my $mimeType = findMimeType($file, $sourceRevision);
+        print "svn:mime-type = ${mimeType}\n\n";
+    } else {
+        print `svn cat ${sourceFile} | diff -u /dev/null - | tail -n +3`;
+    }
+}
+
+# Sort numeric parts of strings as numbers, other parts as strings.
+# Makes 1.33 come after 1.3, which is cool.
+sub numericcmp($$)
+{
+    my ($aa, $bb) = @_;
+
+    my @a = split /(\d+)/, $aa;
+    my @b = split /(\d+)/, $bb;
+
+    # Compare one chunk at a time.
+    # Each chunk is either all numeric digits, or all not numeric digits.
+    while (@a && @b) {
+        my $a = shift @a;
+        my $b = shift @b;
+        
+        # Use numeric comparison if chunks are non-equal numbers.
+        return $a <=> $b if $a =~ /^\d/ && $b =~ /^\d/ && $a != $b;
+
+        # Use string comparison if chunks are any other kind of non-equal string.
+        return $a cmp $b if $a ne $b;
+    }
+    
+    # One of the two is now empty; compare lengths for result in this case.
+    return @a <=> @b;
+}
+
+sub outputBinaryContent($)
+{
+    my ($path) = @_;
+    # Deletion
+    return if (! -e $path);
+    # Addition or Modification
+    my $buffer;
+    open BINARY, $path  or die;
+    while (read(BINARY, $buffer, 60*57)) {
+        print encode_base64($buffer);
+    }
+    close BINARY;
+    print "\n";
+}
+
+# Sort first by directory, then by file, so all paths in one directory are grouped
+# rather than being interspersed with items from subdirectories.
+# Use numericcmp to sort directory and filenames to make order logical.
+# Also include a special case for ChangeLog, which comes first in any directory.
+sub pathcmp($$)
+{
+    my ($fileDataA, $fileDataB) = @_;
+
+    my ($dira, $namea) = splitpath($fileDataA->{path});
+    my ($dirb, $nameb) = splitpath($fileDataB->{path});
+
+    return numericcmp($dira, $dirb) if $dira ne $dirb;
+    return -1 if $namea eq "ChangeLog" && $nameb ne "ChangeLog";
+    return +1 if $namea ne "ChangeLog" && $nameb eq "ChangeLog";
+    return numericcmp($namea, $nameb);
+}
+
+sub processPaths(\@)
+{
+    my ($paths) = @_;
+    return ("." => 1) if (!@{$paths});
+
+    my %result = ();
+
+    for my $file (@{$paths}) {
+        die "can't handle absolute paths like \"$file\"\n" if File::Spec->file_name_is_absolute($file);
+        die "can't handle empty string path\n" if $file eq "";
+        die "can't handle path with single quote in the name like \"$file\"\n" if $file =~ /'/; # ' (keep Xcode syntax highlighting happy)
+
+        my $untouchedFile = $file;
+
+        $file = canonicalizePath($file);
+
+        die "can't handle paths with .. like \"$untouchedFile\"\n" if $file =~ m|/\.\./|;
+
+        $result{$file} = 1;
+    }
+
+    return ("." => 1) if ($result{"."});
+
+    # Remove any paths that also have a parent listed.
+    for my $path (keys %result) {
+        for (my $parent = dirname($path); $parent ne '.'; $parent = dirname($parent)) {
+            if ($result{$parent}) {
+                delete $result{$path};
+                last;
+            }
+        }
+    }
+
+    return %result;
+}
+
+# Break up a path into the directory (with slash) and base name.
+sub splitpath($)
+{
+    my ($path) = @_;
+
+    my $pathSeparator = "/";
+    my $dirname = dirname($path) . $pathSeparator;
+    $dirname = "" if $dirname eq "." . $pathSeparator;
+
+    return ($dirname, basename($path));
+}
+
+# Sort so source code files appear before test files.
+sub testfilecmp($$)
+{
+    my ($fileDataA, $fileDataB) = @_;
+    return $fileDataA->{isTestFile} <=> $fileDataB->{isTestFile};
+}
diff --git a/WebKitTools/Scripts/svn-unapply b/WebKitTools/Scripts/svn-unapply
new file mode 100755
index 0000000..11e3ddb
--- /dev/null
+++ b/WebKitTools/Scripts/svn-unapply
@@ -0,0 +1,374 @@
+#!/usr/bin/perl -w
+
+# Copyright (C) 2005, 2006, 2007 Apple Inc.  All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1.  Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer. 
+# 2.  Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution. 
+# 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+#     its contributors may be used to endorse or promote products derived
+#     from this software without specific prior written permission. 
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+# "unpatch" script for Web Kit Open Source Project, used to remove patches.
+
+# Differences from invoking "patch -p0 -R":
+#
+#   Handles added files (does a svn revert with additional logic to handle local changes). 
+#   Handles added directories (does a svn revert and a rmdir).
+#   Handles removed files (does a svn revert with additional logic to handle local changes). 
+#   Handles removed directories (does a svn revert). 
+#   Paths from Index: lines are used rather than the paths on the patch lines, which
+#       makes patches generated by "cvs diff" work (increasingly unimportant since we
+#       use Subversion now).
+#   ChangeLog patches use --fuzz=3 to prevent rejects, and the entry date is reset in
+#       the patch before it is applied (svn-apply sets it when applying a patch).
+#   Handles binary files (requires patches made by svn-create-patch).
+#   Handles copied and moved files (requires patches made by svn-create-patch).
+#   Handles git-diff patches (without binary changes) created at the top-level directory
+#
+# Missing features:
+#
+#   Handle property changes.
+#   Handle copied and moved directories (would require patches made by svn-create-patch).
+#   Use version numbers in the patch file and do a 3-way merge.
+#   When reversing an addition, check that the file matches what's being removed.
+#   Notice a patch that's being unapplied at the "wrong level" and make it work anyway.
+#   Do a dry run on the whole patch and don't do anything if part of the patch is
+#       going to fail (probably too strict unless we exclude ChangeLog).
+#   Handle git-diff patches with binary changes
+
+use strict;
+use warnings;
+
+use Cwd;
+use Digest::MD5;
+use Fcntl qw(:DEFAULT :seek);
+use File::Basename;
+use File::Spec;
+use File::Temp qw(tempfile);
+use Getopt::Long;
+
+sub checksum($);
+sub fixChangeLogPatch($);
+sub gitdiff2svndiff($);
+sub patch($);
+sub revertDirectories();
+sub svnStatus($);
+sub unapplyPatch($$;$);
+sub unsetChangeLogDate($$);
+
+my $showHelp = 0;
+if (!GetOptions("help!" => \$showHelp) || $showHelp) {
+    print STDERR basename($0) . " [-h|--help] patch1 [patch2 ...]\n";
+    exit 1;
+}
+
+my @copiedFiles;
+my %directoriesToCheck;
+
+my $copiedFromPath;
+my $filter;
+my $indexPath;
+my $patch;
+while (<>) {
+    s/([\n\r]+)$//mg;
+    my $eol = $1;
+    if (!defined($indexPath) && m#^diff --git a/#) {
+        $filter = \&gitdiff2svndiff;
+    }
+    $_ = &$filter($_) if $filter;
+    if (/^Index: (.*)/) {
+        $indexPath = $1;
+        if ($patch) {
+            if ($copiedFromPath) {
+                push @copiedFiles, $patch;
+            } else {
+                patch($patch);
+            }
+            $copiedFromPath = "";
+            $patch = "";
+        }
+    }
+    if ($indexPath) {
+        # Fix paths on diff, ---, and +++ lines to match preceding Index: line.
+        s/^--- \S+/--- $indexPath/;
+        if (/^--- .+\(from (\S+):\d+\)$/) {
+            $copiedFromPath = $1;
+        }
+        if (s/^\+\+\+ \S+/+++ $indexPath/) {
+            $indexPath = "";
+        }
+    }
+    $patch .= $_;
+    $patch .= $eol;
+}
+
+if ($patch) {
+    if ($copiedFromPath) {
+        push @copiedFiles, $patch;
+    } else {
+        patch($patch);
+    }
+}
+
+# Handle copied and moved files last since they may have had post-copy changes that have now been unapplied
+for $patch (@copiedFiles) {
+    patch($patch);
+}
+
+revertDirectories();
+
+exit 0;
+
+sub checksum($)
+{
+    my $file = shift;
+    open(FILE, $file) or die "Can't open '$file': $!";
+    binmode(FILE);
+    my $checksum = Digest::MD5->new->addfile(*FILE)->hexdigest();
+    close(FILE);
+    return $checksum;
+}
+
+sub fixChangeLogPatch($)
+{
+    my $patch = shift;
+    my $contextLineCount = 3;
+
+    return $patch if $patch !~ /\n@@ -1,(\d+) \+1,(\d+) @@\n( .*\n)+(\+.*\n)+( .*\n){$contextLineCount}$/m;
+    my ($oldLineCount, $newLineCount) = ($1, $2);
+    return $patch if $oldLineCount <= $contextLineCount;
+
+    # The diff(1) command is greedy when matching lines, so a new ChangeLog entry will
+    # have lines of context at the top of a patch when the existing entry has the same
+    # date and author as the new entry.  This nifty loop alters a ChangeLog patch so
+    # that the added lines ("+") in the patch always start at the beginning of the
+    # patch and there are no initial lines of context.
+    my $newPatch;
+    my $lineCountInState = 0;
+    my $oldContentLineCountReduction = $oldLineCount - $contextLineCount;
+    my $newContentLineCountWithoutContext = $newLineCount - $oldLineCount - $oldContentLineCountReduction;
+    my ($stateHeader, $statePreContext, $stateNewChanges, $statePostContext) = (1..4);
+    my $state = $stateHeader;
+    foreach my $line (split(/\n/, $patch)) {
+        $lineCountInState++;
+        if ($state == $stateHeader && $line =~ /^@@ -1,$oldLineCount \+1,$newLineCount @\@$/) {
+            $line = "@@ -1,$contextLineCount +1," . ($newLineCount - $oldContentLineCountReduction) . " @@";
+            $lineCountInState = 0;
+            $state = $statePreContext;
+        } elsif ($state == $statePreContext && substr($line, 0, 1) eq " ") {
+            $line = "+" . substr($line, 1);
+            if ($lineCountInState == $oldContentLineCountReduction) {
+                $lineCountInState = 0;
+                $state = $stateNewChanges;
+            }
+        } elsif ($state == $stateNewChanges && substr($line, 0, 1) eq "+") {
+            # No changes to these lines
+            if ($lineCountInState == $newContentLineCountWithoutContext) {
+                $lineCountInState = 0;
+                $state = $statePostContext;
+            }
+        } elsif ($state == $statePostContext) {
+            if (substr($line, 0, 1) eq "+" && $lineCountInState <= $oldContentLineCountReduction) {
+                $line = " " . substr($line, 1);
+            } elsif ($lineCountInState > $contextLineCount && substr($line, 0, 1) eq " ") {
+                next; # Discard
+            }
+        }
+        $newPatch .= $line . "\n";
+    }
+
+    return $newPatch;
+}
+
+sub gitdiff2svndiff($)
+{
+    $_ = shift @_;
+    if (m#^diff --git a/(.+) b/(.+)#) {
+        return "Index: $1";
+    } elsif (m/^new file.*/) {
+        return "";
+    } elsif (m#^index [0-9a-f]{7}\.\.[0-9a-f]{7} [0-9]{6}#) {
+        return "===================================================================";
+    } elsif (m#^--- a/(.+)#) {
+        return "--- $1";
+    } elsif (m#^\+\+\+ b/(.+)#) {
+        return "+++ $1";
+    }
+    return $_;
+}
+
+sub patch($)
+{
+    my ($patch) = @_;
+    return if !$patch;
+
+    unless ($patch =~ m|^Index: ([^\n]+)|) {
+        my $separator = '-' x 67;
+        warn "Failed to find 'Index:' in:\n$separator\n$patch\n$separator\n";
+        return;
+    }
+    my $fullPath = $1;
+    $directoriesToCheck{dirname($fullPath)} = 1;
+
+    my $deletion = 0;
+    my $addition = 0;
+    my $isBinary = 0;
+
+    $addition = 1 if ($patch =~ /\n--- .+\(revision 0\)\n/ || $patch =~ /\n@@ -0,0 .* @@/);
+    $deletion = 1 if $patch =~ /\n@@ .* \+0,0 @@/;
+    $isBinary = 1 if $patch =~ /\nCannot display: file marked as a binary type\./;
+
+    if (!$addition && !$deletion && !$isBinary) {
+        # Standard patch, patch tool can handle this.
+        if (basename($fullPath) eq "ChangeLog") {
+            my $changeLogDotOrigExisted = -f "${fullPath}.orig";
+            unapplyPatch(unsetChangeLogDate($fullPath, fixChangeLogPatch($patch)), $fullPath, ["--fuzz=3"]);
+            unlink("${fullPath}.orig") if (! $changeLogDotOrigExisted);
+        } else {
+            unapplyPatch($patch, $fullPath);
+        }
+    } else {
+        # Either a deletion, an addition or a binary change.
+
+        if ($isBinary) {
+            # Reverse binary change
+            unlink($fullPath) if (-e $fullPath);
+            system "svn", "revert", $fullPath;
+        } elsif ($deletion) {
+            # Reverse deletion
+            rename($fullPath, "$fullPath.orig") if -e $fullPath;
+
+            unapplyPatch($patch, $fullPath);
+
+            # If we don't ask for the filehandle here, we always get a warning.
+            my ($fh, $tempPath) = tempfile(basename($fullPath) . "-XXXXXXXX",
+                                           DIR => dirname($fullPath), UNLINK => 1);
+            close($fh);
+
+            # Keep the version from the patch in case it's different from svn.
+            rename($fullPath, $tempPath);
+            system "svn", "revert", $fullPath;
+            rename($tempPath, $fullPath);
+
+            # This works around a bug in the svn client.
+            # [Issue 1960] file modifications get lost due to FAT 2s time resolution
+            # http://subversion.tigris.org/issues/show_bug.cgi?id=1960
+            system "touch", $fullPath;
+
+            # Remove $fullPath.orig if it is the same as $fullPath
+            unlink("$fullPath.orig") if -e "$fullPath.orig" && checksum($fullPath) eq checksum("$fullPath.orig");
+
+            # Show status if the file is modifed
+            system "svn", "stat", $fullPath;
+        } else {
+            # Reverse addition
+            unapplyPatch($patch, $fullPath, ["--force"]);
+            unlink($fullPath) if -z $fullPath;
+            system "svn", "revert", $fullPath;
+        }
+    }
+}
+
+sub revertDirectories()
+{
+    my %checkedDirectories;
+    foreach my $path (reverse sort keys %directoriesToCheck) {
+        my @dirs = File::Spec->splitdir($path);
+        while (scalar @dirs) {
+            my $dir = File::Spec->catdir(@dirs);
+            pop(@dirs);
+            next if (exists $checkedDirectories{$dir});
+            if (-d $dir) {
+                my $svnOutput = svnStatus($dir);
+                if ($svnOutput && $svnOutput =~ m#A\s+$dir\n#) {
+                   system "svn", "revert", $dir;
+                   rmdir $dir;
+                }
+                elsif ($svnOutput && $svnOutput =~ m#D\s+$dir\n#) {
+                   system "svn", "revert", $dir;
+                }
+                else {
+                    # Modification
+                    print $svnOutput if $svnOutput;
+                }
+                $checkedDirectories{$dir} = 1;
+            }
+            else {
+                die "'$dir' is not a directory";
+            }
+        }
+    }
+}
+
+sub svnStatus($)
+{
+    my ($fullPath) = @_;
+    my $svnStatus;
+    open SVN, "svn status --non-interactive --non-recursive '$fullPath' |" or die;
+    if (-d $fullPath) {
+        # When running "svn stat" on a directory, we can't assume that only one
+        # status will be returned (since any files with a status below the
+        # directory will be returned), and we can't assume that the directory will
+        # be first (since any files with unknown status will be listed first).
+        my $normalizedFullPath = File::Spec->catdir(File::Spec->splitdir($fullPath));
+        while (<SVN>) {
+            chomp;
+            my $normalizedStatPath = File::Spec->catdir(File::Spec->splitdir(substr($_, 7)));
+            if ($normalizedFullPath eq $normalizedStatPath) {
+                $svnStatus = $_;
+                last;
+            }
+        }
+        # Read the rest of the svn command output to avoid a broken pipe warning.
+        local $/ = undef;
+        <SVN>;
+    }
+    else {
+        # Files will have only one status returned.
+        $svnStatus = <SVN>;
+    }
+    close SVN;
+    return $svnStatus;
+}
+
+sub unapplyPatch($$;$)
+{
+    my ($patch, $fullPath, $options) = @_;
+    $options = [] if (! $options);
+    my $command = "patch " . join(" ", "-p0", "-R", @{$options});
+    open PATCH, "| $command" or die "Failed to patch $fullPath: $!";
+    print PATCH $patch;
+    close PATCH;
+}
+
+sub unsetChangeLogDate($$)
+{
+    my $fullPath = shift;
+    my $patch = shift;
+    my $newDate;
+    sysopen(CHANGELOG, $fullPath, O_RDONLY) or die "Failed to open $fullPath: $!";
+    sysseek(CHANGELOG, 0, SEEK_SET);
+    my $byteCount = sysread(CHANGELOG, $newDate, 10);
+    die "Failed reading $fullPath: $!" if !$byteCount || $byteCount != 10;
+    close(CHANGELOG);
+    $patch =~ s/(\n\+)\d{4}-[^-]{2}-[^-]{2}(  )/$1$newDate$2/;
+    return $patch;
+}
diff --git a/WebKitTools/Scripts/update-iexploder-cssproperties b/WebKitTools/Scripts/update-iexploder-cssproperties
new file mode 100755
index 0000000..b7ae6cb
--- /dev/null
+++ b/WebKitTools/Scripts/update-iexploder-cssproperties
@@ -0,0 +1,112 @@
+#!/usr/bin/perl
+
+# Copyright (C) 2007 Apple Inc.  All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1.  Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer. 
+# 2.  Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution. 
+# 3.  Neither the name of Apple Inc. ("Apple") nor the names of
+#     its contributors may be used to endorse or promote products derived
+#     from this software without specific prior written permission. 
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+# This script updates WebKitTools/iExploder/htdocs/cssproperties.in based on
+# WebCore/css/CSSPropertyNames.in.
+
+use warnings;
+use strict;
+
+use FindBin;
+use lib $FindBin::Bin;
+use webkitdirs;
+
+use File::Spec;
+
+sub generateSectionFromCSSPropertyNamesFile();
+sub readiExploderFile();
+sub svnRevision($);
+sub writeiExploderFile();
+
+my $iExploderFile = File::Spec->catfile(sourceDir(), split("/", "WebKitTools/iExploder/htdocs/cssproperties.in"));
+my $cssPropertyNamesFile = File::Spec->catfile(sourceDir(), split("/", "WebCore/css/CSSPropertyNames.in"));
+
+my @sections = readiExploderFile();
+$sections[0] = generateSectionFromCSSPropertyNamesFile();
+writeiExploderFile();
+
+print `svn stat $iExploderFile`;
+print "Successfully updated!\n";
+
+exit 0;
+
+sub generateSectionFromCSSPropertyNamesFile()
+{
+    my $revision = svnRevision($cssPropertyNamesFile);
+    my $path = File::Spec->abs2rel($cssPropertyNamesFile, sourceDir());
+    my $result = "# From WebKit svn r" . $revision . " (" . $path . ")\n";
+
+    my @properties = ();
+
+    open(IN, $cssPropertyNamesFile) || die "$!";
+    while (my $l = <IN>) {
+        chomp $l;
+        next if $l =~ m/^\s*#/ || $l =~ m/^\s*$/;
+        push(@properties, $l);
+    }
+    close(IN);
+
+    $result .= join("\n", sort { $a cmp $b } @properties) . "\n\n";
+
+    return $result;
+}
+
+sub readiExploderFile()
+{
+    my @sections = ();
+    local $/ = "\n\n";
+
+    open(IN, $iExploderFile) || die "$!";
+    @sections = <IN>;
+    close(IN);
+
+    return @sections;
+}
+
+sub svnRevision($)
+{
+    my ($file) = @_;
+    my $revision = "";
+
+    open INFO, "svn info '$file' |" or die;
+    while (<INFO>) {
+        if (/^Revision: (.+)/) {
+            $revision = $1;
+        }
+    }
+    close INFO;
+
+    return $revision ? $revision : "UNKNOWN";
+}
+
+sub writeiExploderFile()
+{
+    open(OUT, "> $iExploderFile") || die "$!";
+    print OUT join("", @sections);
+    close(OUT);
+}
diff --git a/WebKitTools/Scripts/update-javascriptcore-test-results b/WebKitTools/Scripts/update-javascriptcore-test-results
new file mode 100755
index 0000000..dd8b9b6
--- /dev/null
+++ b/WebKitTools/Scripts/update-javascriptcore-test-results
@@ -0,0 +1,73 @@
+#!/usr/bin/perl -w
+
+# Copyright (C) 2005, 2007 Apple Inc. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1.  Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer. 
+# 2.  Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution. 
+# 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+#     its contributors may be used to endorse or promote products derived
+#     from this software without specific prior written permission. 
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+use strict;
+use FindBin;
+use Getopt::Long;
+use lib $FindBin::Bin;
+use webkitdirs;
+
+chdirWebKit();
+chdir "JavaScriptCore/tests/mozilla" or die;
+
+my $force = 0;
+GetOptions('force' => \$force);
+
+open EXPECTED, "expected.html" or die;
+while (<EXPECTED>) {
+    last if /failures reported\.$/;
+}
+my %expected;
+while (<EXPECTED>) {
+    chomp;
+    $expected{$_} = 1;
+}
+close EXPECTED;
+
+open ACTUAL, "actual.html" or die;
+my $actual;
+while (<ACTUAL>) {
+    $actual .= $_;
+    last if /failures reported\.$/;
+}
+my $failed = 0;
+while (<ACTUAL>) {
+    $actual .= $_;
+    chomp;
+    if (!$expected{$_}) {
+        $failed = 1;
+        print "failure not expected: $_\n";
+    }
+}
+close ACTUAL;
+
+die "won't update, failures introduced\n" if $failed && !$force;
+
+open EXPECTED, ">expected.html";
+print EXPECTED $actual;
+close EXPECTED;
diff --git a/WebKitTools/Scripts/update-sources-list.py b/WebKitTools/Scripts/update-sources-list.py
new file mode 100644
index 0000000..e565059
--- /dev/null
+++ b/WebKitTools/Scripts/update-sources-list.py
@@ -0,0 +1,93 @@
+#!/usr/bin/python
+
+# Copyright (C) 2007 Kevin Ollivier  All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+# OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# Make sure any port-independent files added to the Bakefile are
+# added to GTK, QT, etc. so that file updates can happen in one place.
+
+import os, sys
+from xml.dom import minidom
+
+scriptDir = os.path.abspath(sys.path[0])
+wkroot = os.path.abspath(os.path.join(scriptDir, "../.."))
+
+def getWebCoreFilesDict():
+    """
+    This method parses the WebCoreSources.bkl file, which has a list of all sources not specific
+    to any port, and returns the result as a dictionary with items of the form
+    (groupName, groupFiles). 
+    """
+    sources = {}
+    sources_prefix = "WEBCORE_"
+    filepath = os.path.join(wkroot, "WebCore/WebCoreSources.bkl")
+    assert(os.path.exists(filepath))
+    
+    doc = minidom.parse(filepath)
+    for sourceGroup in doc.getElementsByTagName("set"):
+        groupName = ""
+        if sourceGroup.attributes.has_key("var"):
+            groupName = sourceGroup.attributes["var"].value
+            groupName = groupName.replace(sources_prefix, "")
+            
+        sourcesList = []
+        for node in sourceGroup.childNodes:
+            if node.nodeType == node.TEXT_NODE:
+                sourcesText = node.nodeValue.strip()
+                sourcesList = sourcesText.split("\n")
+                
+        assert(groupName != "")
+        assert(sourcesList != [])
+        
+        sources[groupName] = sourcesList
+        
+    return sources
+
+def generateWebCoreSourcesGTKAndQT(sources):
+    """
+    Convert the dictionary obtained from getWebCoreFilesDict() into a Unix makefile syntax,
+    which IIUC is suitable for both GTK and QT build systems. To take advantage of this,
+    QT and GTK would have to include the file "WebCore/sources.inc" into their makefiles.
+    """
+    makefileString = ""
+    
+    for key in sources.keys():
+        makefileString += key + "+="
+        for source in sources[key]:
+            makefileString += " \\\n\t\t" + source.strip()
+            
+        makefileString += "\n\n"
+    
+    makefileString += "BASE_SOURCES +="
+    for key in sources.keys():
+        makefileString += " \\\n\t\t" + key
+    
+    outfile = os.path.join(wkroot, "WebCore/sources.inc")
+    sourcefile = open(outfile, "w")
+    sourcefile.write(makefileString)
+    sourcefile.close()
+    
+sources = getWebCoreFilesDict()
+generateWebCoreSourcesGTKAndQT(sources)
+
+# Coming soon - MSVC and hopefully XCode support!
diff --git a/WebKitTools/Scripts/update-webkit b/WebKitTools/Scripts/update-webkit
new file mode 100755
index 0000000..e0c0d82
--- /dev/null
+++ b/WebKitTools/Scripts/update-webkit
@@ -0,0 +1,92 @@
+#!/usr/bin/perl -w
+
+# Copyright (C) 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1.  Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer. 
+# 2.  Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution. 
+# 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+#     its contributors may be used to endorse or promote products derived
+#     from this software without specific prior written permission. 
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+# Update script for Web Kit Open Source Project.
+
+use strict;
+use FindBin;
+use lib $FindBin::Bin;
+use File::Basename;
+use File::Spec;
+use Getopt::Long;
+use webkitdirs;
+
+sub runSvnUpdate();
+
+# Handle options
+my $quiet = '';
+my $showHelp;
+
+my $getOptionsResult = GetOptions(
+    'h|help'  => \$showHelp,
+    'q|quiet' => \$quiet,
+); 
+
+if (!$getOptionsResult || $showHelp) {
+    print STDERR <<__END__;
+Usage: @{[ basename($0) ]} [options]
+  -h|--help   show the help message
+  -q|--quiet  pass -q to svn update for quiet updates
+__END__
+    exit 1;
+}
+
+my @svnOptions = ();
+push @svnOptions, '-q' if $quiet;
+
+chdirWebKit();
+print "Updating OpenSource\n" unless $quiet;
+runSvnUpdate();
+
+if (-d "../Internal") {
+    chdir("../Internal");
+    print "Updating Internal\n" unless $quiet;
+    runSvnUpdate();
+} elsif (isCygwin()) {
+    system("perl", "WebKitTools/Scripts/update-webkit-auxiliary-libs") == 0 or die;
+}
+
+exit 0;
+
+sub runSvnUpdate()
+{
+    open UPDATE, "-|", "svn", "update", @svnOptions or die;
+    my @conflictedChangeLogs;
+    while (my $line = <UPDATE>) {
+        print $line;
+        push @conflictedChangeLogs, $1 if $line =~ m/^C\s+(.+)\s*$/ && basename($1) eq "ChangeLog";
+    }
+    close UPDATE or die;
+
+    if (@conflictedChangeLogs) {
+        print "Attempting to merge conflicted ChangeLogs.\n";
+        my $resolveChangeLogsPath = File::Spec->catfile(dirname($0), "resolve-ChangeLogs");
+        (system($resolveChangeLogsPath, "--no-warnings", @conflictedChangeLogs) == 0)
+            or die "Could not open resolve-ChangeLogs script: $!.\n";
+    }
+}
diff --git a/WebKitTools/Scripts/update-webkit-auxiliary-libs b/WebKitTools/Scripts/update-webkit-auxiliary-libs
new file mode 100755
index 0000000..1d6943c
--- /dev/null
+++ b/WebKitTools/Scripts/update-webkit-auxiliary-libs
@@ -0,0 +1,121 @@
+#!/usr/bin/perl -w
+
+# Copyright (C) 2005, 2006, 2007 Apple Computer, Inc.  All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1.  Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer. 
+# 2.  Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution. 
+# 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+#     its contributors may be used to endorse or promote products derived
+#     from this software without specific prior written permission. 
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+# Updates a development environment to the new WebKitAuxiliaryLibrary
+
+use strict;
+use warnings;
+
+use HTTP::Date qw(str2time);
+use File::Find;
+use File::Temp;
+use File::Spec;
+use FindBin;
+use lib $FindBin::Bin;
+use webkitdirs;
+
+sub lastModifiedToUnixTime($);
+
+# Time in seconds that the new zip file must be newer than the old for us to
+# consider them to be different. If the difference in modification time is less
+# than this threshold, we assume that the files are the same. We need this
+# because the zip file is served from a set of mirrors with slightly different
+# Last-Modified times.
+my $newnessThreshold = 30;
+
+my $sourceDir = sourceDir();
+my $file = "WebKitAuxiliaryLibrary";
+my $zipFile = "$file.zip"; 
+my $auxiliaryLibsURL = "http://developer.apple.com/opensource/internet/$zipFile";
+my $webkitLibrariesDir = toUnixPath($ENV{'WEBKITLIBRARIESDIR'}) || "$sourceDir/WebKitLibraries/win";
+my $tmpDir = File::Spec->rel2abs(File::Temp::tempdir("webkitlibsXXXXXXX", TMPDIR => 1, CLEANUP => 1));
+
+print "Checking Last-Modified date of $zipFile...\n";
+
+my $result = system "curl -s -I $auxiliaryLibsURL | grep Last-Modified > \"$tmpDir/$file.headers\"";
+print STDERR "Couldn't check Last-Modified date of new $zipFile.\n" if $result;
+
+if (!$result && open NEW, "$tmpDir/$file.headers") {
+    my $new = lastModifiedToUnixTime(<NEW>);
+    close NEW;
+
+    if (defined $new && open OLD, "$webkitLibrariesDir/$file.headers") {
+        my $old = lastModifiedToUnixTime(<OLD>);
+        close OLD;
+        if (defined $old && abs($new - $old) < $newnessThreshold) {
+            print "Current $file is up to date\n";
+            exit 0;
+        }
+    }
+}
+
+print "Downloading $zipFile...\n\n";
+$result = system "curl -o \"$tmpDir/$zipFile\" $auxiliaryLibsURL";
+die "Couldn't download $zipFile!" if $result;
+
+$result = system "unzip", "-q", "-d", $tmpDir, "$tmpDir/$zipFile";
+die "Couldn't unzip $zipFile." if $result;
+
+print "\nInstalling $file...\n";
+
+sub wanted
+{
+    my $relativeName = File::Spec->abs2rel($File::Find::name, "$tmpDir/$file/win");
+    my $destination = "$webkitLibrariesDir/$relativeName";
+
+    if (-d $_) {
+        mkdir $destination;
+        return;
+    }
+
+    system "cp", $_, $destination;
+}
+
+File::Find::find(\&wanted, "$tmpDir/$file");
+
+$result = system "mv", "$tmpDir/$file.headers", $webkitLibrariesDir;
+print STDERR "Couldn't move $file.headers to $webkitLibrariesDir" . ".\n" if $result;
+
+print "The $file has been sucessfully installed in\n $webkitLibrariesDir\n";
+exit;
+
+sub toUnixPath
+{
+    my $path = shift;
+    return unless $path;
+    chomp($path = `cygpath -u '$path'`);
+    return $path;
+}
+
+sub lastModifiedToUnixTime($)
+{
+    my ($str) = @_;
+
+    $str =~ /^Last-Modified: (.*)$/ or return;
+    return str2time($1);
+}
diff --git a/WebKitTools/Scripts/update-webkit-localizable-strings b/WebKitTools/Scripts/update-webkit-localizable-strings
new file mode 100755
index 0000000..350bf21
--- /dev/null
+++ b/WebKitTools/Scripts/update-webkit-localizable-strings
@@ -0,0 +1,46 @@
+#!/usr/bin/perl -w
+
+# Copyright (C) 2006, 2007 Apple Inc.  All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1.  Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer. 
+# 2.  Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution. 
+# 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+#     its contributors may be used to endorse or promote products derived
+#     from this software without specific prior written permission. 
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+use strict;
+use warnings;
+
+use File::Basename;
+use FindBin;
+use lib $FindBin::Bin;
+use webkitdirs;
+
+my @directoriesToScan = ("WebKit/mac", "WebKit/win");
+my $fileToUpdate = "WebKit/English.lproj/Localizable.strings";
+my $exceptionsFile = "WebKit/StringsNotToBeLocalized.txt";
+
+@ARGV == 0 or die "Usage: " . basename($0) . "\n";
+
+chdirWebKit();
+
+system "sort -u $exceptionsFile -o $exceptionsFile";
+exec "extract-localizable-strings", $exceptionsFile, $fileToUpdate, @directoriesToScan;
diff --git a/WebKitTools/Scripts/update-webkit-support-libs b/WebKitTools/Scripts/update-webkit-support-libs
new file mode 100755
index 0000000..e9c302b
--- /dev/null
+++ b/WebKitTools/Scripts/update-webkit-support-libs
@@ -0,0 +1,105 @@
+#!/usr/bin/perl -w
+
+# Copyright (C) 2005, 2006, 2007 Apple Computer, Inc.  All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1.  Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer. 
+# 2.  Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution. 
+# 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+#     its contributors may be used to endorse or promote products derived
+#     from this software without specific prior written permission. 
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+# Updates a development environment to the new WebKitSupportLibrary
+
+use strict;
+use warnings;
+
+use File::Find;
+use File::Temp;
+use File::Spec;
+use FindBin;
+use lib $FindBin::Bin;
+use webkitdirs;
+
+my $sourceDir = sourceDir();
+my $file = "WebKitSupportLibrary";
+my $zipFile = "$file.zip"; 
+my $zipDirectory = toUnixPath($ENV{'WEBKITSUPPORTLIBRARIESZIPDIR'}) || $sourceDir;
+my $pathToZip = File::Spec->catfile($zipDirectory, $zipFile);
+my $webkitLibrariesDir = toUnixPath($ENV{'WEBKITLIBRARIESDIR'}) || "$sourceDir/WebKitLibraries/win";
+my $tmpDir = File::Spec->rel2abs(File::Temp::tempdir("webkitlibsXXXXXXX", TMPDIR => 1, CLEANUP => 1));
+
+# Make sure the file zipfile exists before doing anything.
+die "$zipFile could not be found in your root source directory.  Please\n" .
+    "download it from http://developer.apple.com/opensource/internet/webkit_sptlib_agree.html and place it in \n" .
+    "$sourceDir\n and then run update-webkit again.\n" unless (-f "$pathToZip");
+
+print "Checking mod-date of $zipFile...\n";
+open MOD, ">$tmpDir/$file.modified" or die "Couldn't open $tmpDir/$file.modified for writing";
+print MOD (stat $pathToZip)[9] . "\n";
+close MOD;
+
+if (open NEW, "$tmpDir/$file.modified") {
+    my $new = <NEW>;
+    close NEW;
+
+    if (open OLD, "$webkitLibrariesDir/$file.modified") {
+        my $old = <OLD>;
+        close OLD;
+        if ($old eq $new) {
+            print "Current $file is up to date\n";
+            exit 0;
+        }
+    }
+}
+
+my $result = system "unzip", "-q", "-d", $tmpDir, $pathToZip;
+die "Couldn't unzip $zipFile." if $result;
+
+print "\nInstalling $file...\n";
+
+sub wanted
+{
+    my $relativeName = File::Spec->abs2rel($File::Find::name, "$tmpDir/$file/win");
+    my $destination = "$webkitLibrariesDir/$relativeName";
+
+    if (-d $_) {
+        mkdir $destination;
+        return;
+    }
+
+    system "cp", $_, $destination;
+}
+
+File::Find::find(\&wanted, "$tmpDir/$file");
+
+$result = system "mv", "$tmpDir/$file.modified", $webkitLibrariesDir;
+print STDERR "Couldn't move $file.modified to $webkitLibrariesDir" . ".\n" if $result;
+
+print "The $file has been sucessfully installed in\n $webkitLibrariesDir\n";
+exit;
+
+sub toUnixPath
+{
+    my $path = shift;
+    return unless $path;
+    chomp($path = `cygpath -u '$path'`);
+    return $path;
+}
diff --git a/WebKitTools/Scripts/webkitdirs.pm b/WebKitTools/Scripts/webkitdirs.pm
new file mode 100644
index 0000000..728e7c0
--- /dev/null
+++ b/WebKitTools/Scripts/webkitdirs.pm
@@ -0,0 +1,984 @@
+# Copyright (C) 2005, 2006, 2007 Apple Inc. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1.  Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer. 
+# 2.  Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution. 
+# 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+#     its contributors may be used to endorse or promote products derived
+#     from this software without specific prior written permission. 
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+# Module to share code to get to WebKit directories.
+
+use strict;
+use warnings;
+use FindBin;
+use File::Basename;
+use POSIX;
+use VCSUtils;
+
+BEGIN {
+   use Exporter   ();
+   our ($VERSION, @ISA, @EXPORT, @EXPORT_OK, %EXPORT_TAGS);
+   $VERSION     = 1.00;
+   @ISA         = qw(Exporter);
+   @EXPORT      = qw(&chdirWebKit &baseProductDir &productDir &XcodeOptions &XcodeOptionString &XcodeOptionStringNoConfig &passedConfiguration &setConfiguration &safariPath &checkFrameworks &currentSVNRevision);
+   %EXPORT_TAGS = ( );
+   @EXPORT_OK   = ();
+}
+
+our @EXPORT_OK;
+
+my $baseProductDir;
+my @baseProductDirOption;
+my $configuration;
+my $configurationForVisualStudio;
+my $configurationProductDir;
+my $sourceDir;
+my $currentSVNRevision;
+my $osXVersion;
+my $isQt;
+my $isGtk;
+my $isWx;
+my $forceRun64Bit;
+
+# Variables for Win32 support
+my $vcBuildPath;
+my $windowsTmpPath;
+
+sub determineSourceDir
+{
+    return if $sourceDir;
+    $sourceDir = $FindBin::Bin;
+    $sourceDir =~ s|/+$||; # Remove trailing '/' as we would die later
+
+    # walks up path checking each directory to see if it is the main WebKit project dir, 
+    # defined by containing JavaScriptCore, WebCore, and WebKit
+    until ((-d "$sourceDir/JavaScriptCore" && -d "$sourceDir/WebCore" && -d "$sourceDir/WebKit") || (-d "$sourceDir/Internal" && -d "$sourceDir/OpenSource"))
+    {
+        if ($sourceDir !~ s|/[^/]+$||) {
+            die "Could not find top level webkit directory above source directory using FindBin.\n";
+        }
+    }
+
+    $sourceDir = "$sourceDir/OpenSource" if -d "$sourceDir/OpenSource";
+}
+
+# used for scripts which are stored in a non-standard location
+sub setSourceDir($)
+{
+    ($sourceDir) = @_;
+}
+
+sub determineBaseProductDir
+{
+    return if defined $baseProductDir;
+    determineSourceDir();
+    if (isOSX()) {
+        open PRODUCT, "defaults read com.apple.Xcode PBXApplicationwideBuildSettings 2> /dev/null |" or die;
+        $baseProductDir = join '', <PRODUCT>;
+        close PRODUCT;
+
+        $baseProductDir = $1 if $baseProductDir =~ /SYMROOT\s*=\s*\"(.*?)\";/s;
+        undef $baseProductDir unless $baseProductDir =~ /^\//;
+
+        if (!defined($baseProductDir)) {
+            open PRODUCT, "defaults read com.apple.Xcode PBXProductDirectory 2> /dev/null |" or die;
+            $baseProductDir = <PRODUCT>;
+            close PRODUCT;
+            if ($baseProductDir) {
+                chomp $baseProductDir;
+                undef $baseProductDir unless $baseProductDir =~ /^\//;
+            }
+        }
+    } else {
+        $baseProductDir = $ENV{"WEBKITOUTPUTDIR"};
+        if (isCygwin() && $baseProductDir) {
+            my $unixBuildPath = `cygpath --unix \"$baseProductDir\"`;
+            chomp $unixBuildPath;
+            $baseProductDir = $unixBuildPath;
+        }
+    }
+
+    if ($baseProductDir && isOSX()) {
+        $baseProductDir =~ s|^\Q$(SRCROOT)/..\E$|$sourceDir|;
+        $baseProductDir =~ s|^\Q$(SRCROOT)/../|$sourceDir/|;
+        $baseProductDir =~ s|^~/|$ENV{HOME}/|;
+        die "Can't handle Xcode product directory with a ~ in it.\n" if $baseProductDir =~ /~/;
+        die "Can't handle Xcode product directory with a variable in it.\n" if $baseProductDir =~ /\$/;
+        @baseProductDirOption = ();
+    }
+
+    if (!defined($baseProductDir)) {
+        $baseProductDir = "$sourceDir/WebKitBuild";
+
+        if (isGit() && isGitBranchBuild()) {
+            my $branch = gitBranch();
+            $baseProductDir = "$baseProductDir/$branch";
+        }
+
+        @baseProductDirOption = ("SYMROOT=$baseProductDir", "OBJROOT=$baseProductDir") if (isOSX());
+        if (isCygwin()) {
+            my $dosBuildPath = `cygpath --windows \"$baseProductDir\"`;
+            chomp $dosBuildPath;
+            $ENV{"WEBKITOUTPUTDIR"} = $dosBuildPath;
+        }
+    }
+}
+
+sub setBaseProductDir($)
+{
+    ($baseProductDir) = @_;
+}
+
+sub determineConfiguration
+{
+    return if defined $configuration;
+    determineBaseProductDir();
+    if (open CONFIGURATION, "$baseProductDir/Configuration") {
+        $configuration = <CONFIGURATION>;
+        close CONFIGURATION;
+    }
+    if ($configuration) {
+        chomp $configuration;
+        # compatibility for people who have old Configuration files
+        $configuration = "Release" if $configuration eq "Deployment";
+        $configuration = "Debug" if $configuration eq "Development";
+    } else {
+        $configuration = "Release";
+    }
+}
+
+sub determineConfigurationForVisualStudio
+{
+    return if defined $configurationForVisualStudio;
+    determineConfiguration();
+    $configurationForVisualStudio = $configuration;
+    return unless $configuration eq "Debug";
+    setupCygwinEnv();
+    chomp(my $dir = `cygpath -ua '$ENV{WEBKITLIBRARIESDIR}'`);
+    $configurationForVisualStudio = "Debug_Internal" if -f "$dir/bin/CoreFoundation_debug.dll";
+}
+
+sub determineConfigurationProductDir
+{
+    return if defined $configurationProductDir;
+    determineBaseProductDir();
+    determineConfiguration();
+    if (isCygwin() && !isWx()) {
+        $configurationProductDir = "$baseProductDir/bin";
+    } else {
+        $configurationProductDir = "$baseProductDir/$configuration";
+    }
+}
+
+sub setConfigurationProductDir($)
+{
+    ($configurationProductDir) = @_;
+}
+
+sub determineCurrentSVNRevision
+{
+    return if defined $currentSVNRevision;
+    determineSourceDir();
+    my $svnInfo = `LC_ALL=C svn info $sourceDir | grep Revision:`;
+    ($currentSVNRevision) = ($svnInfo =~ m/Revision: (\d+).*/g);
+    die "Unable to determine current SVN revision in $sourceDir" unless (defined $currentSVNRevision);
+    return $currentSVNRevision;
+}
+
+
+sub chdirWebKit
+{
+    determineSourceDir();
+    chdir $sourceDir or die;
+}
+
+sub baseProductDir
+{
+    determineBaseProductDir();
+    return $baseProductDir;
+}
+
+sub sourceDir
+{
+    determineSourceDir();
+    return $sourceDir;
+}
+
+sub productDir
+{
+    determineConfigurationProductDir();
+    return $configurationProductDir;
+}
+
+sub configuration()
+{
+    determineConfiguration();
+    return $configuration;
+}
+
+sub configurationForVisualStudio()
+{
+    determineConfigurationForVisualStudio();
+    return $configurationForVisualStudio;
+}
+
+sub currentSVNRevision
+{
+    determineCurrentSVNRevision();
+    return $currentSVNRevision;
+}
+
+sub XcodeOptions
+{
+    determineBaseProductDir();
+    determineConfiguration();
+    return (@baseProductDirOption, "-configuration", $configuration);
+}
+
+sub XcodeOptionString
+{
+    return join " ", XcodeOptions();
+}
+
+sub XcodeOptionStringNoConfig
+{
+    return join " ", @baseProductDirOption;
+}
+
+my $passedConfiguration;
+my $searchedForPassedConfiguration;
+sub determinePassedConfiguration
+{
+    return if $searchedForPassedConfiguration;
+    $searchedForPassedConfiguration = 1;
+
+    my $isWinCairo = grep(/^--cairo-win32$/i, @ARGV);
+
+    for my $i (0 .. $#ARGV) {
+        my $opt = $ARGV[$i];
+        if ($opt =~ /^--debug$/i || $opt =~ /^--devel/i) {
+            splice(@ARGV, $i, 1);
+            $passedConfiguration = "Debug";
+            $passedConfiguration .= "_Cairo" if ($isWinCairo && isCygwin());
+            return;
+        }
+        if ($opt =~ /^--release$/i || $opt =~ /^--deploy/i) {
+            splice(@ARGV, $i, 1);
+            $passedConfiguration = "Release";
+            $passedConfiguration .= "_Cairo" if ($isWinCairo && isCygwin());
+            return;
+        }
+        if ($opt =~ /^--profil(e|ing)$/i) {
+            splice(@ARGV, $i, 1);
+            $passedConfiguration = "Profiling";
+            $passedConfiguration .= "_Cairo" if ($isWinCairo && isCygwin());
+            return;
+        }
+    }
+    $passedConfiguration = undef;
+}
+
+sub passedConfiguration
+{
+    determinePassedConfiguration();
+    return $passedConfiguration;
+}
+
+sub setConfiguration
+{
+    if (my $config = shift @_) {
+        $configuration = $config;
+        return;
+    }
+
+    determinePassedConfiguration();
+    $configuration = $passedConfiguration if $passedConfiguration;
+}
+
+sub safariPathFromSafariBundle
+{
+    my ($safariBundle) = @_;
+
+    return "$safariBundle/Contents/MacOS/Safari" if isOSX();
+    return $safariBundle if isCygwin();
+}
+
+sub installedSafariPath
+{
+    my $safariBundle;
+
+    if (isOSX()) {
+        $safariBundle = "/Applications/Safari.app";
+    } elsif (isCygwin()) {
+        $safariBundle = `"$configurationProductDir/FindSafari.exe"`;
+        $safariBundle =~ s/[\r\n]+$//;
+        $safariBundle = `cygpath -u '$safariBundle'`;
+        $safariBundle =~ s/[\r\n]+$//;
+        $safariBundle .= "Safari.exe";
+    }
+
+    return safariPathFromSafariBundle($safariBundle);
+}
+
+# Locate Safari.
+sub safariPath
+{
+    # Use WEBKIT_SAFARI environment variable if present.
+    my $safariBundle = $ENV{WEBKIT_SAFARI};
+    if (!$safariBundle) {
+        determineConfigurationProductDir();
+        # Use Safari.app in product directory if present (good for Safari development team).
+        if (isOSX() && -d "$configurationProductDir/Safari.app") {
+            $safariBundle = "$configurationProductDir/Safari.app";
+        } elsif (isCygwin() && -x "$configurationProductDir/bin/Safari.exe") {
+            $safariBundle = "$configurationProductDir/bin/Safari.exe";
+        } else {
+            return installedSafariPath();
+        }
+    }
+    my $safariPath = safariPathFromSafariBundle($safariBundle);
+    die "Can't find executable at $safariPath.\n" if isOSX() && !-x $safariPath;
+    return $safariPath;
+}
+
+sub builtDylibPathForName
+{
+    my $framework = shift;
+    determineConfigurationProductDir();
+    if (isQt() or isGtk()) {
+        return "$configurationProductDir/$framework";
+    }
+    if (isOSX()) {
+        return "$configurationProductDir/$framework.framework/Versions/A/$framework";
+    }
+    if (isCygwin()) {
+        if ($framework eq "JavaScriptCore") {
+                return "$baseProductDir/lib/$framework.lib";
+        } else {
+            return "$baseProductDir/$framework.intermediate/$configuration/$framework.intermediate/$framework.lib";
+        }
+    }
+
+    die "Unsupported platform, can't determine built library locations.";
+}
+
+# Check to see that all the frameworks are built.
+sub checkFrameworks
+{
+    return if isCygwin();
+    my @frameworks = ("JavaScriptCore", "WebCore");
+    push(@frameworks, "WebKit") if isOSX();
+    for my $framework (@frameworks) {
+        my $path = builtDylibPathForName($framework);
+        die "Can't find built framework at \"$path\".\n" unless -x $path;
+    }
+}
+
+sub hasSVGSupport
+{
+    return 0 if isCygwin();
+
+    my $path = shift;
+
+    if (isQt()) {
+        return 1;
+    }
+
+    if (isGtk() and $path =~ /WebCore/) {
+        $path .= "/../.libs/webkit-1.0.so";
+    }
+
+    my $hasSVGSupport = 0;
+    if (-e $path) {
+        open NM, "-|", "nm", $path or die;
+        while (<NM>) {
+            $hasSVGSupport = 1 if /SVGElement/;
+        }
+        close NM;
+    }
+    return $hasSVGSupport;
+}
+
+sub removeLibraryDependingOnSVG
+{
+    my $frameworkName = shift;
+    my $shouldHaveSVG = shift;
+
+    my $path = builtDylibPathForName($frameworkName);
+    return unless -x $path;
+
+    my $hasSVG = hasSVGSupport($path);
+    system "rm -f $path" if ($shouldHaveSVG xor $hasSVG);
+}
+
+sub checkWebCoreSVGSupport
+{
+    my $required = shift;
+    my $framework = "WebCore";
+    my $path = builtDylibPathForName($framework);
+    my $hasSVG = hasSVGSupport($path);
+    if ($required && !$hasSVG) {
+        die "$framework at \"$path\" does not include SVG Support, please run build-webkit --svg\n";
+    }
+    return $hasSVG;
+}
+
+sub isQt()
+{
+    determineIsQt();
+    return $isQt;
+}
+
+sub checkArgv($)
+{
+    my $argToCheck = shift;
+    foreach my $opt (@ARGV) {
+        if ($opt =~ /^$argToCheck/i ) {
+            @ARGV = grep(!/^$argToCheck/i, @ARGV);
+            return 1;
+        }
+    }
+    return 0;
+}
+
+sub determineIsQt()
+{
+    return if defined($isQt);
+
+    # Allow override in case QTDIR is not set.
+    if (checkArgv("--qt")) {
+        $isQt = 1;
+        return;
+    }
+
+    # The presence of QTDIR only means Qt if --gtk is not on the command-line
+    if (isGtk()) {
+        $isQt = 0;
+        return;
+    }
+    
+    $isQt = defined($ENV{'QTDIR'});
+}
+
+sub isGtk()
+{
+    determineIsGtk();
+    return $isGtk;
+}
+
+sub determineIsGtk()
+{
+    return if defined($isGtk);
+
+    if (checkArgv("--gtk")) {
+        $isGtk = 1;
+    } else {
+        $isGtk = 0;
+    }
+}
+
+sub isWx()
+{
+    determineIsWx();
+    return $isWx;
+}
+
+sub determineIsWx()
+{
+    return if defined($isWx);
+
+    if (checkArgv("--wx")) {
+        $isWx = 1;
+    } else {
+        $isWx = 0;
+    }
+}
+
+# Determine if this is debian, ubuntu, linspire, or something similar.
+sub isDebianBased()
+{
+    return -e "/etc/debian_version";
+}
+
+sub isCygwin()
+{
+    return ($^O eq "cygwin") || 0;
+}
+
+sub isDarwin()
+{
+    return ($^O eq "darwin") || 0;
+}
+
+# isOSX() only returns true for Apple's port, not for other ports that can be
+# built/run on OS X.
+sub isOSX()
+{
+    return isDarwin() unless (isQt() or isGtk() or isWx());
+    return 0;
+}
+
+sub determineOSXVersion()
+{
+    return if $osXVersion;
+
+    if (!isOSX()) {
+        $osXVersion = -1;
+        return;
+    }
+
+    my $version = `sw_vers -productVersion`;
+    my @splitVersion = split(/\./, $version);
+    @splitVersion >= 2 or die "Invalid version $version";
+    $osXVersion = {
+            "major" => $splitVersion[0],
+            "minor" => $splitVersion[1],
+            "subminor" => (defined($splitVersion[2]) ? $splitVersion[2] : 0),
+    };
+}
+
+sub osXVersion()
+{
+    determineOSXVersion();
+    return $osXVersion;
+}
+
+sub isTiger()
+{
+    return isOSX() && osXVersion()->{"minor"} == 4;
+}
+
+sub isLeopard()
+{
+    return isOSX() && osXVersion()->{"minor"} == 5;
+}
+
+sub isSnowLeopard()
+{
+    return isOSX() && osXVersion()->{"minor"} == 6;
+}
+
+sub relativeScriptsDir()
+{
+    my $scriptDir = File::Spec->catpath("", File::Spec->abs2rel(dirname($0), getcwd()), "");
+    if ($scriptDir eq "") {
+        $scriptDir = ".";
+    }
+    return $scriptDir;
+}
+
+sub launcherPath()
+{
+    my $relativeScriptsPath = relativeScriptsDir();
+    if (isGtk() || isQt()) {
+        return "$relativeScriptsPath/run-launcher";
+    } elsif (isOSX() || isCygwin()) {
+        return "$relativeScriptsPath/run-safari";
+    }
+}
+
+sub launcherName()
+{
+    if (isGtk()) {
+        return "GtkLauncher";
+    } elsif (isQt()) {
+        return "QtLauncher";
+    } elsif (isOSX() || isCygwin()) {
+        return "Safari";
+    }
+}
+
+sub checkRequiredSystemConfig
+{
+    if (isOSX()) {
+        chomp(my $productVersion = `sw_vers -productVersion`);
+        if ($productVersion lt "10.4") {
+            print "*************************************************************\n";
+            print "Mac OS X Version 10.4.0 or later is required to build WebKit.\n";
+            print "You have " . $productVersion . ", thus the build will most likely fail.\n";
+            print "*************************************************************\n";
+        }
+        my $xcodeVersion = `xcodebuild -version`;
+        if ($xcodeVersion !~ /DevToolsCore-(\d+)/ || $1 < 747) {
+            print "*************************************************************\n";
+            print "Xcode Version 2.3 or later is required to build WebKit.\n";
+            print "You have an earlier version of Xcode, thus the build will\n";
+            print "most likely fail.  The latest Xcode is available from the web:\n";
+            print "http://developer.apple.com/tools/xcode\n";
+            print "*************************************************************\n";
+        }
+    } elsif (isGtk() or isQt() or isWx()) {
+        my @cmds = qw(flex bison gperf);
+        my @missing = ();
+        foreach my $cmd (@cmds) {
+            if (not `$cmd --version`) {
+                push @missing, $cmd;
+            }
+        }
+        if (@missing) {
+            my $list = join ", ", @missing;
+            die "ERROR: $list missing but required to build WebKit.\n";
+        }
+    }
+    # Win32 and other platforms may want to check for minimum config
+}
+
+sub setupCygwinEnv()
+{
+    return if !isCygwin();
+    return if $vcBuildPath;
+
+    my $programFilesPath = `cygpath "$ENV{'PROGRAMFILES'}"`;
+    chomp $programFilesPath;
+    $vcBuildPath = "$programFilesPath/Microsoft Visual Studio 8/Common7/IDE/devenv.com";
+    if (! -e $vcBuildPath) {
+        # VC++ not found, try VC++ Express
+        my $vsInstallDir;
+        if ($ENV{'VSINSTALLDIR'}) {
+            $vsInstallDir = $ENV{'VSINSTALLDIR'};
+        } else {
+            $programFilesPath = $ENV{'PROGRAMFILES'} || "C:\\Program Files";
+            $vsInstallDir = "$programFilesPath/Microsoft Visual Studio 8";
+        }
+        $vsInstallDir = `cygpath "$vsInstallDir"`;
+        chomp $vsInstallDir;
+        $vcBuildPath = "$vsInstallDir/Common7/IDE/VCExpress.exe";
+        if (! -e $vcBuildPath) {
+            print "*************************************************************\n";
+            print "Cannot find '$vcBuildPath'\n";
+            print "Please execute the file 'vcvars32.bat' from\n";
+            print "'$programFilesPath\\Microsoft Visual Studio 8\\VC\\bin\\'\n";
+            print "to setup the necessary environment variables.\n";
+            print "*************************************************************\n";
+            die;
+        }
+    }
+
+    my $qtSDKPath = "$programFilesPath/QuickTime SDK";
+    if (0 && ! -e $qtSDKPath) {
+        print "*************************************************************\n";
+        print "Cannot find '$qtSDKPath'\n";
+        print "Please download the QuickTime SDK for Windows from\n";
+        print "http://developer.apple.com/quicktime/download/\n";
+        print "*************************************************************\n";
+        die;
+    }
+    
+    chomp($ENV{'WEBKITLIBRARIESDIR'} = `cygpath -wa "$sourceDir/WebKitLibraries/win"`) unless $ENV{'WEBKITLIBRARIESDIR'};
+
+    $windowsTmpPath = `cygpath -w /tmp`;
+    chomp $windowsTmpPath;
+    print "Building results into: ", baseProductDir(), "\n";
+    print "WEBKITOUTPUTDIR is set to: ", $ENV{"WEBKITOUTPUTDIR"}, "\n";
+    print "WEBKITLIBRARIESDIR is set to: ", $ENV{"WEBKITLIBRARIESDIR"}, "\n";
+}
+
+sub buildVisualStudioProject
+{
+    my ($project, $clean) = @_;
+    setupCygwinEnv();
+
+    my $config = configurationForVisualStudio();
+
+    chomp(my $winProjectPath = `cygpath -w "$project"`);
+    
+    my $command = "/build";
+    if ($clean) {
+        $command = "/clean";
+    }
+
+    print "$vcBuildPath $winProjectPath /build $config\n";
+    return system $vcBuildPath, $winProjectPath, $command, $config;
+}
+
+sub retrieveQMakespecVar
+{
+    my $mkspec = $_[0];
+    my $varname = $_[1];
+
+    my $compiler = "unknown";
+    #print "retrieveMakespecVar " . $mkspec . ", " . $varname . "\n";
+
+    local *SPEC;
+    open SPEC, "<$mkspec" or return "make";
+    while (<SPEC>) {
+        if ($_ =~ /\s*include\((.+)\)/) {
+            # open the included mkspec
+            my $oldcwd = getcwd();
+            (my $volume, my $directories, my $file) = File::Spec->splitpath($mkspec);
+            chdir "$volume$directories";
+            $compiler = retrieveQMakespecVar($1, $varname);
+            chdir $oldcwd;
+        } elsif ($_ =~ /$varname\s*=\s*([^\s]+)/) {
+            $compiler = $1;
+            last;
+        }
+    }
+    close SPEC;
+    return $compiler;
+}
+
+sub qtMakeCommand($)
+{
+    my ($qmakebin) = @_;
+    chomp(my $mkspec = `$qmakebin -query QMAKE_MKSPECS`);
+    $mkspec .= "/default";
+    my $compiler = retrieveQMakespecVar("$mkspec/qmake.conf", "QMAKE_CC");
+
+    #print "default spec: " . $mkspec . "\n";
+    #print "compiler found: " . $compiler . "\n";
+
+    if ($compiler eq "cl") {
+        return "nmake";
+    }
+
+    return "make";
+}
+
+sub autotoolsFlag($$)
+{
+    my ($flag, $feature) = @_;
+    my $prefix = $flag ? "--enable" : "--disable";
+
+    return $prefix . '-' . $feature;
+}
+
+sub buildAutotoolsProject($@)
+{
+    my ($clean, @buildArgs) = @_;
+
+    my $make = 'make';
+    my $dir = productDir();
+    my $config = passedConfiguration() || configuration();
+    my $prefix = $ENV{"WebKitInstallationPrefix"};
+
+    # check if configuration is Debug
+    if ($config =~ m/debug/i) {
+        push @buildArgs, "--enable-debug";
+    } else {
+        push @buildArgs, "--disable-debug";
+    }
+
+    if (! -d $dir) {
+        system "mkdir", "-p", "$dir";
+        if (! -d $dir) {
+            die "Failed to create build directory " . $dir;
+        }
+    }
+
+    chdir $dir or die "Failed to cd into " . $dir . "\n";
+
+    my $result;
+    if ($clean) {
+        $result = system $make, "distclean";
+        return 0;
+    }
+
+    print "Calling configure in " . $dir . "\n\n";
+    print "Installation directory: $prefix\n" if(defined($prefix));
+     
+    $result = system "$sourceDir/autogen.sh", @buildArgs;
+    if ($result ne 0) {
+        die "Failed to setup build environment using 'autotools'!\n";
+    }
+
+    $result = system $make;
+    if ($result ne 0) {
+        die "\nFailed to build WebKit using '$make'!\n";
+    }
+
+    chdir ".." or die;
+    return $result;
+}
+
+sub buildQMakeProject($@)
+{
+    my ($clean, @buildArgs) = @_;
+
+    push @buildArgs, "-r";
+
+    my $qmakebin = "qmake"; # Allow override of the qmake binary from $PATH
+    for my $i (0 .. $#ARGV) {
+        my $opt = $ARGV[$i];
+        if ($opt =~ /^--qmake=(.*)/i ) {
+            $qmakebin = $1;
+        } elsif ($opt =~ /^--qmakearg=(.*)/i ) {
+            push @buildArgs, $1;
+        }
+    }
+
+    my $make = qtMakeCommand($qmakebin);
+    my $config = configuration();
+    my $prefix = $ENV{"WebKitInstallationPrefix"};
+
+    push @buildArgs, "OUTPUT_DIR=" . baseProductDir() . "/$config";
+    push @buildArgs, sourceDir() . "/WebKit.pro";
+    if ($config =~ m/debug/i) {
+        push @buildArgs, "CONFIG-=release";
+        push @buildArgs, "CONFIG+=debug";
+    } else {
+        push @buildArgs, "CONFIG+=release";
+        push @buildArgs, "CONFIG-=debug";
+    }
+
+    my $dir = baseProductDir();
+    if (! -d $dir) {
+        system "mkdir", "-p", "$dir";
+        if (! -d $dir) {
+            die "Failed to create product directory " . $dir;
+        }
+    }
+    $dir = $dir . "/$config";
+    if (! -d $dir) {
+        system "mkdir", "-p", "$dir";
+        if (! -d $dir) {
+            die "Failed to create build directory " . $dir;
+        }
+    }
+
+    chdir $dir or die "Failed to cd into " . $dir . "\n";
+
+    print "Calling '$qmakebin @buildArgs' in " . $dir . "\n\n";
+    print "Installation directory: $prefix\n" if(defined($prefix));
+
+    my $result = system $qmakebin, @buildArgs;
+    if ($result ne 0) {
+       die "Failed to setup build environment using $qmakebin!\n";
+    }
+
+    if ($clean) {
+      $result = system "$make distclean";
+    } else {
+      $result = system "$make";
+    }
+
+    chdir ".." or die;
+    return $result;
+}
+
+sub buildQMakeQtProject($$)
+{
+    my ($project, $clean) = @_;
+
+    my @buildArgs = ("CONFIG+=qt-port");
+    return buildQMakeProject($clean, @buildArgs);
+}
+
+sub buildGtkProject($$@)
+{
+    my ($project, $clean, @buildArgs) = @_;
+
+    if ($project ne "WebKit") {
+        die "The Gtk port builds JavaScriptCore, WebCore and WebKit in one shot! Only call it for 'WebKit'.\n";
+    }
+
+    return buildAutotoolsProject($clean, @buildArgs);
+}
+
+sub setPathForRunningWebKitApp
+{
+    my ($env) = @_;
+
+    return unless isCygwin();
+
+    $env->{PATH} = join(':', productDir(), dirname(installedSafariPath()), $env->{PATH} || "");
+}
+
+sub exitStatus($)
+{
+    my ($returnvalue) = @_;
+    if ($^O eq "MSWin32") {
+        return $returnvalue >> 8;
+    }
+    return WEXITSTATUS($returnvalue);
+}
+
+sub runSafari
+{
+    my ($debugger) = @_;
+
+    if (isOSX()) {
+        return system "$FindBin::Bin/gdb-safari", @ARGV if $debugger;
+
+        my $productDir = productDir();
+        print "Starting Safari with DYLD_FRAMEWORK_PATH set to point to built WebKit in $productDir.\n";
+        $ENV{DYLD_FRAMEWORK_PATH} = $productDir;
+        $ENV{WEBKIT_UNSET_DYLD_FRAMEWORK_PATH} = "YES";
+        exportArchPreference();
+        if (!isTiger()) {
+            return system "arch", safariPath(), @ARGV;
+        } else {
+            return system safariPath(), @ARGV;
+        }
+    }
+
+    if (isCygwin()) {
+        my $script = "run-webkit-nightly.cmd";
+        my $result = system "cp", "$FindBin::Bin/$script", productDir();
+        return $result if $result;
+
+        my $cwd = getcwd();
+        chdir productDir();
+
+        my $debuggerFlag = $debugger ? "/debugger" : "";
+        $result = system "cmd", "/c", "call $script $debuggerFlag";
+        chdir $cwd;
+        return $result;
+    }
+
+    return 1;
+}
+
+sub setRun64Bit($)
+{
+    ($forceRun64Bit) = @_;
+}
+
+sub preferredArchitecture
+{
+    return unless isOSX();
+    
+    my $framework = shift;
+    $framework = "WebKit" if !defined($framework);
+
+    my $currentArchitecture = `arch`;
+    chomp($currentArchitecture);
+
+    my $run64Bit = 0;
+    if (!defined($forceRun64Bit)) {
+        my $frameworkPath = builtDylibPathForName($framework);
+        die "Couldn't find path for $framework" if !defined($frameworkPath);
+        # The binary is 64-bit if one of the architectures it contains has "64" in the name
+        $run64Bit = `lipo -info "$frameworkPath"` =~ /(are|architecture):.*64/;
+    }
+
+    if ($forceRun64Bit or $run64Bit) {
+        return ($currentArchitecture eq "i386") ? "x86_64" : "ppc64";
+    }
+    return $currentArchitecture;
+}
+
+sub exportArchPreference
+{
+    $ENV{ARCHPREFERENCE} = preferredArchitecture() if isOSX();
+}
+
+1;
diff --git a/WebKitTools/Scripts/wkstyle b/WebKitTools/Scripts/wkstyle
new file mode 100755
index 0000000..4b3447f
--- /dev/null
+++ b/WebKitTools/Scripts/wkstyle
@@ -0,0 +1,89 @@
+
+# Copyright (C) 2006 Michael Emmel<[email protected]>  All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1.  Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+# 2.  Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+# 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+#     its contributors may be used to endorse or promote products derived
+#     from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+cmdcpp="astyle \
+--unpad=paren \
+--style=linux \
+--brackets=linux \
+--indent=spaces=4 \
+--indent-switches \
+--convert-tabs" 
+
+cmdh="astyle \
+--unpad=paren \
+--style=linux \
+--brackets=break \
+--indent=spaces=4 \
+--convert-tabs" 
+
+#astyle does not support unpadding so we use sed
+for i in $@
+do
+echo $i
+
+ext=`echo $i|awk -F . '{print $NF}'`
+
+cmd=$cmdcpp
+
+if [ $ext == "h" ] ; then
+    cmd=$cmdh
+fi
+
+$cmd $i
+
+#first print the changes we are making
+sed  -n -e '
+/( .*/p  
+s/( /(/gp   
+/*. )/p
+s/ )/)/gp   
+#supress printing this
+#/^namespace WebCore/{
+#N
+#s/\n{/ {/p
+#}
+' $i 
+
+#do it for real
+sed -e '
+#unpad leading spaces
+s/( /(/g
+#unpad traling spaces
+s/ )/)/g
+#fixup the namspec decl
+/^namespace WebCore/{
+N
+s/\n{/ {/
+}
+#fixup extra tab in constructor initalizer
+/^ \+,/{s/^    //}
+/^ \+:/{s/^    //}
+' $i > $i.sed
+mv $i.sed $i
+done
+
+