diff --git a/tasks/MigrateSiteTreeLinkingTask.php b/tasks/MigrateSiteTreeLinkingTask.php
new file mode 100755
index 000000000..9a0b49e46
--- /dev/null
+++ b/tasks/MigrateSiteTreeLinkingTask.php
@@ -0,0 +1,54 @@
+ID
+ ));
+
+ foreach($tracking as $link) {
+ $linked = DataObject::get_by_id('SiteTree', $link['ChildID']);
+
+ $page->{$link['FieldName']} = preg_replace (
+ "/href *= *([\"']?){$linked->URLSegment}\/?/i",
+ "href=$1[sitetree_link id={$linked->ID}]",
+ $page->{$link['FieldName']},
+ -1,
+ $replaced
+ );
+
+ if($replaced) {
+ $page->write();
+ $links += $replaced;
+ }
+ }
+
+ $pages++;
+ }
+
+ echo "Rewrote $links link(s) on $pages page(s) to use shortcodes.\n";
+ }
+
+}
\ No newline at end of file
diff --git a/tests/tasks/MigrateSiteTreeLinkingTaskTest.php b/tests/tasks/MigrateSiteTreeLinkingTaskTest.php
new file mode 100755
index 000000000..5f10dab07
--- /dev/null
+++ b/tests/tasks/MigrateSiteTreeLinkingTaskTest.php
@@ -0,0 +1,80 @@
+run(null);
+
+ $this->assertEquals (
+ "Rewrote 9 link(s) on 5 page(s) to use shortcodes.\n",
+ ob_get_contents(),
+ 'Rewritten links are correctly reported'
+ );
+ ob_end_clean();
+
+ $homeID = $this->idFromFixture('SiteTree', 'home');
+ $aboutID = $this->idFromFixture('SiteTree', 'about');
+ $staffID = $this->idFromFixture('SiteTree', 'staff');
+ $actionID = $this->idFromFixture('SiteTree', 'action');
+ $hashID = $this->idFromFixture('SiteTree', 'hash_link');
+
+ $homeContent = sprintf (
+ 'AboutStaffExternal Link',
+ $aboutID,
+ $staffID
+ );
+ $aboutContent = sprintf (
+ 'HomeStaff',
+ $homeID,
+ $staffID
+ );
+ $staffContent = sprintf (
+ 'HomeAbout',
+ $homeID,
+ $aboutID
+ );
+ $actionContent = sprintf (
+ 'Search Form', $homeID
+ );
+ $hashLinkContent = sprintf (
+ 'HomeAbout',
+ $homeID,
+ $aboutID
+ );
+
+ $this->assertEquals (
+ $homeContent,
+ DataObject::get_by_id('SiteTree', $homeID)->Content,
+ 'HTML URLSegment links are rewritten.'
+ );
+ $this->assertEquals (
+ $aboutContent,
+ DataObject::get_by_id('SiteTree', $aboutID)->Content
+ );
+ $this->assertEquals (
+ $staffContent,
+ DataObject::get_by_id('SiteTree', $staffID)->Content
+ );
+ $this->assertEquals (
+ $actionContent,
+ DataObject::get_by_id('SiteTree', $actionID)->Content,
+ 'Links to actions on pages are rewritten correctly.'
+ );
+ $this->assertEquals (
+ $hashLinkContent,
+ DataObject::get_by_id('SiteTree', $hashID)->Content,
+ 'Hash/anchor links are correctly handled.'
+ );
+ }
+
+}
\ No newline at end of file
diff --git a/tests/tasks/MigrateSiteTreeLinkingTaskTest.yml b/tests/tasks/MigrateSiteTreeLinkingTaskTest.yml
new file mode 100755
index 000000000..ab81c2160
--- /dev/null
+++ b/tests/tasks/MigrateSiteTreeLinkingTaskTest.yml
@@ -0,0 +1,67 @@
+SiteTree:
+ home:
+ Title: Home Page
+ URLSegment: home
+ Content: 'AboutStaffExternal Link'
+ about:
+ Title: About Us
+ URLSegment: about
+ Content: HomeStaff
+ staff:
+ Title: Staff
+ URLSegment: staff
+ Content: HomeAbout
+ Parent: =>SiteTree.about
+ action:
+ Title: Action Link
+ URLSegment: action
+ Content: Search Form
+ hash_link:
+ Title: Hash Link
+ URLSegment: hash-link
+ Content: 'HomeAbout'
+ admin_link:
+ Title: Admin Link
+ URLSegment: admin-link
+ Content: Admin
+ no_links:
+ Title: No Links
+ URLSemgment: No Links
+
+SiteTree_LinkTracking:
+ home_about:
+ SiteTreeID: =>SiteTree.home
+ ChildID: =>SiteTree.about
+ FieldName: Content
+ home_staff:
+ SiteTreeID: =>SiteTree.home
+ ChildID: =>SiteTree.staff
+ FieldName: Content
+ about_home:
+ SiteTreeID: =>SiteTree.about
+ ChildID: =>SiteTree.home
+ FieldName: Content
+ about_staff:
+ SiteTreeID: =>SiteTree.about
+ ChildID: =>SiteTree.staff
+ FieldName: Content
+ staff_home:
+ SiteTreeID: =>SiteTree.staff
+ ChildID: =>SiteTree.home
+ FieldName: Content
+ staff_about:
+ SiteTreeID: =>SiteTree.staff
+ ChildID: =>SiteTree.about
+ FieldName: Content
+ action_home:
+ SiteTreeID: =>SiteTree.action
+ ChildID: =>SiteTree.home
+ FieldName: Content
+ hash_link_home:
+ SiteTreeID: =>SiteTree.hash_link
+ ChildID: =>SiteTree.home
+ FieldName: Content
+ hash_link_about:
+ SiteTreeID: =>SiteTree.hash_link
+ ChildID: =>SiteTree.about
+ FieldName: Content