diff --git a/org.eclipse.mylyn.ide.dev/developer/archive/contributors.html b/org.eclipse.mylyn.ide.dev/developer/archive/contributors.html
deleted file mode 100644
index 3c02db9..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/archive/contributors.html
+++ /dev/null
@@ -1,156 +0,0 @@
-<HTML>
-<HEAD>
-  <META HTTP-EQUIV="EXPIRES" CONTENT="0">
-  <META HTTP-EQUIV="" CONTENT="">
-  <TITLE>Mylar</TITLE>
-<style>
-<!--
-
-/********************************************************************
- * TOP LEVEL  
- ********************************************************************/
-A:link { color:#4756AC; }
-A:visited { color:#4756AC; }
-/* A:visited { color:#60657B; } */
-A:hover { color:#711616}
-BODY { 
-	background-color:white;
-	margin-left: 10px; 
-} 
-P {
-	font:13px Verdana, Arial, Helvetica, sans-serif; 
-	margin-right: 10px;
-	margin-left: 10px;
-}
-
-PRE { font:13px "Courier", sans-serif; }  
-
-/********************************************************************
- * SPAN LEVEL     
- ********************************************************************/
-
-B { font-weight:bold; }
-STRONG { font-weight:bold; }
-CODE { font:13px "Courier", sans-serif; }
-
-/********************************************************************
- * HEADINGS      
- ********************************************************************/
-H1 { font:20px Verdana, Helvetica, sans-serif; 
-	color:black; 
-	font-weight:bold; 
-	margin-left: 10px;
-}	
-
-H2 { font:18px Verdana, Arial, Helvetica, sans-serif; 
-	color:black; 
-	font-weight:bold; 
-	margin-left: 10px;
-}
-
-H3 { font:16px Verdana, Arial, Helvetica, sans-serif; 
-	color:black; 
-	font-weight:bold; 
-	margin-left: 10px;
-}
-H4 { font:13px Verdana, Arial, Helvetica, sans-serif; 
-	color:black; 
-	font-weight:bold; 
-	margin-left: 10px;
-}
-
-/********************************************************************
- * LISTS & TABLES
- ********************************************************************/
-LI { font:13px Verdana, Arial, Helvetica, sans-serif; }
-
-UL { font:13px Verdana, Arial, Helvetica, sans-serif; }
-
-OL { font:13px Verdana, Arial, Helvetica, sans-serif; }
-DT { font:13px Verdana, Arial, Helvetica, sans-serif; font-weight:bold; }
-DD { font:13px Verdana, Arial, Helvetica, sans-serif; }       
-
-TD { font:13px Verdana, Arial, Helvetica, sans-serif; }
-
-TH { font:13px Verdana, Arial, Helvetica, sans-serif; 
-	font-weight:bold;
-	text-align:center;
-}
-
-
-/********************************************************************
- * FORMS   
- ********************************************************************/
- 
-.searchInput       { color: #666666; border: 1px solid; background: none;
-              font:11px Verdana, Arial, Helvetica, sans-serif;
-              padding-left: 3; padding-top: 2; padding-bottom: 3; }
- 
-/********************************************************************
- * CLASSES                                                          * 
- ********************************************************************/
-
-.navBarSection { font:10px Verdana, Arial, Helvetica, sans-serif; font-weight:bold;}
-
-.navBarSubSection { font:10px Verdana, Arial, Helvetica, sans-serif; }
-.fancyHeading { font:20px Chantilly, Arial, Helvetica, sans-serif; 
-	margin-right: 10px;
-	color:#6f7a92;
-	margin-left: 10px;
-} 
-
-.indentedParagraph { font:13px Verdana, Arial, Helvetica, sans-serif; 
-	margin-right: 10px;
-	text-align:left; 
-	margin-left: 30px;
-}
- 
-.footer {
-	font:10px Verdana, Arial, Helvetica, sans-serif;  
-	color:#888888; 
-	text-align:left
-}
-
-.figureTitle { font:13px Verdana, Arial, Helvetica, sans-serif; 
-	text-align:justify; 
-	text-align:center
-}
-
-.copyrightNotice { font:10px Verdana, Arial, Helvetica, sans-serif; color:#999999; }
-
-.smallHeading { font:13px Verdana, Arial, Helvetica, sans-serif; font-weight:bold; }
-
-.tinyHeading { font:11px Verdana, Arial, Helvetica, sans-serif;  font-weight:bold; }
-
-.newsText { font:11px Verdana, Arial, Helvetica, sans-serif; }
-
-.smallParagraph { font:11px Verdana, Arial, Helvetica, sans-serif;  }
-
-.code { }
-
-.command { }
-
-.codeindent { margin-left: 30px; }
-
-.commandindent { margin-left: 30px;	}
--->
-</style>
-
-<SCRIPT>
-  </SCRIPT>
-</HEAD>
-<BODY LINK="#4756AC" VLINK="#60657B" BGCOLOR="#FFFFFF">					
-						
-      <p>Non-committer contributions to Mylar (last updated June 17, 2005)</p>
-		<ul>
-			<li>org.eclipse.mylar.tasks<ul>
-				<li>Ken Sueda (<a href="mailto:ksueda@cs.ubc.ca">ksueda@cs.ubc.ca</a>)<ul>
-					<li>2005-06-17: contributed task serialization as xml and 
-					improvements to task list view</li>
-				</ul>
-				</li>
-			</ul>
-			</li>
-		</ul>
-    </body>
-</html>
\ No newline at end of file
diff --git a/org.eclipse.mylyn.ide.dev/developer/archive/issue-trackers.html b/org.eclipse.mylyn.ide.dev/developer/archive/issue-trackers.html
deleted file mode 100644
index a928c88..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/archive/issue-trackers.html
+++ /dev/null
@@ -1,205 +0,0 @@
-<html>
-
-<head>
-<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
-<title>Mylar Issue Tracker Requirements</title>
-</head>
-
-<body>
-
-<div id="globalWrapper">
-	<div id="column-content">
-		<div id="content">
-			<h1 class="firstHeading">Mylar Issue Tracker Requirements</h1>
-			<div id="bodyContent">
-				History
-				<ul>
-					<li>2005-11-25: Initial draft (Brock Janiczak and Mik 
-					Kersten) </li>
-				</ul>
-				<p><b>General</b> </p>
-				<ul>
-					<li>Associate a repository with a project, credentials 
-					stored in keyring. UI is a project properties page specified 
-					by provider. 
-					</li>
-					<li>Possibly provide view showing all repositories, where 
-					each provider can populate repository nodes with contets 
-					(e.g. products, reports). 
-					</li>
-					<li>Should be able to discover new repositories by checking 
-					out a project. 
-					<ul>
-						<li>Mik: Brock, could you provide more detail on this 
-						one? </li>
-						<li><font color="#6600cc">Consider the case of a user 
-						that is new to a project.&nbsp; It would be really nice if 
-						all they had to do was check out a project from CVS/SVN 
-						and the tracker instance is created and associated with 
-						the project automatically.&nbsp; I was expecting to store 
-						this information as a project scoped preference (so it 
-						can be checked in to version control).&nbsp; Another option 
-						is to have a a file (like the team PSF file) that can be 
-						imported to create the required tracker instances and 
-						attempt to connect each project to its appropriate 
-						instance.</font> </li>
-						<li><font color="#6600cc">Also, most issue trackers have 
-						some way to partition bugs into groups (that can relate 
-						to a project atrifact).&nbsp; It would be nice if this could 
-						also be associated with the project so when an issue is 
-						created in the context of a project the component (or 
-						whatever your tracker calls it) can be defaulted.</font> 
-						</li>
-					</ul>
-					<p>&nbsp;</li>
-					<li>No coupling to mylar core or UI. </li>
-				</ul>
-				<p><b>Queries</b> </p>
-				<ul>
-					<li>Provide a general notion of a query and parameters, hits 
-					returned, and a persistance mechanism (a first cut at this 
-					is already in mylar.tasklist). 
-					</li>
-					<li>Provide incoming/outgoing status notification. </li>
-				</ul>
-				<p><b>Editing Reports</b> </p>
-				<ul>
-					<li>Basic mode of embedding browser when opening issue. 
-					</li>
-					<li>Generic issue editor similar to Mylar's Bugzilla one, 
-					based on attributes and comments. </li>
-				</ul>
-				<p><b>Text</b> </p>
-				<ul>
-					<li>Hyperlink issue number in text editors. 
-					<ul>
-						<li>Brock: Berhaps we could have Team support for this? 
-						SVN could store the info in properties and CVS in a 
-						file. 
-						</li>
-						<li>Mik: isn't it enough just to look up the repository 
-						associated with the project? </li>
-						<li><font color="#6600cc">It is possible to open a 
-						resource directly from the history view or the 
-						repository view.&nbsp; In these cases there is no project.</font></li>
-					</ul>
-					</li>
-				</ul>
-				<p><b>Source Repositories</b> </p>
-				<ul>
-					<li>Provide hyperlink support in the history view 
-					<ul>
-						<li>Mik: This may be better as a popup action, which 
-						Mylar already has. But hyperlink could work as well. 
-						</li>
-						<li><font color="#6600cc">A popup action is fine when 
-						there is only one bug referenced in the commit comment, 
-						but some people (like myself) sometimes check in a 
-						change that relates to multiple issues.&nbsp; I probably 
-						shouldn't, but i do :)</font></li>
-					</ul>
-					</li>
-					<li>Populate commit comment with issue details. 
-					<ul>
-						<li>Brock: (Possible use the new template stuff? Ie a 
-						dynamic template) 
-						</li>
-						<li><font color="#6600cc">Just clarifying this as it 
-						makes no sense at all...&nbsp; In 3.2 CVS supports static 
-						templates.&nbsp; The user just creates a chunk of text and it 
-						can be added into the commit dialog.&nbsp; I can't see why 
-						this template support can't be updated to support 
-						'active' templates.&nbsp; You select a 'bug' template and a 
-						dialog pops up asking you to enter (or search for) a 
-						bug.&nbsp; These values will then be inserted into the 
-						template before it is added to the commit dialog.&nbsp; I 
-						think this would be of more value than the current 
-						static templates.&nbsp; I would be willing to look at 
-						providing a patch to Team/CVS for this one.&nbsp; btw, I will 
-						try and convince them to push it down to the Team level 
-						so the same templates can be used for all team providers 
-						(it seems to make sense).</font></li>
-					</ul>
-					</li>
-					<li>Perform some sort of Issue workflow action on commit 
-					(probably resolve) 
-					<ul>
-						<li>Brock: CVS has no support for any of this yet. They 
-						would probably accept patches for most of this. If some 
-						of this could be moved to Team, even better. All 
-						repositories have a commit process and all have a 
-						revision history. 
-						</li>
-						<li><font color="#6600cc">again, what was I on?&nbsp; I 
-						basically wanted a post commit hook so we could perform 
-						an action against the issue tracker.&nbsp; The obvious thing 
-						to do is comment/resolve an issue.&nbsp; Perhaps i was asking 
-						for a team level commit dialog???</font></li>
-					</ul>
-					</li>
-				</ul>
-				<p><b>Mylar</b> </p>
-				<ul>
-					<li>What are the requirements for Mylar? 
-					<ul>
-						<li>Brock: It really only needs to get a list of issue 
-						from a query. The query implementation and UI need to be 
-						provider specific unless the query is always &quot;my bugs&quot;. 
-						I don't see a problem with adding a Mylar/Issue Tracker 
-						bridge to do this. 
-						</li>
-						<li>Mik: The main thing Mylar needs is for there to be a 
-						single high quality Tasks view that makes it easy to 
-						work with local tasks, reports, and queries, and for 
-						that to be consisntent across providers. What it layers 
-						on to that is the ability to activate contexts. It also 
-						needs a mechanism for attaching context to issues, and 
-						retrieving them from issues. From a source and feature 
-						perspective the task functionality should be decoupled 
-						from Mylar (and it is, i.e. you can use the Mylar Tasks 
-						view and Bugzilla support without the Mylar UI). But 
-						Mylar is all about a very task-centric view of the 
-						world, and as such the UIs will be highly 
-						interdependent. </li>
-						<li><font color="#6600cc">I am not sure how to support 
-						local issues yet.&nbsp; It is almost as if we need another 
-						view to show local issues (the platform task view would 
-						be perfect)</font><br>
-&nbsp;</li>
-						<li><font color="#6600cc">I have been thinking about the 
-						best way to structure the UI.&nbsp; The issue tracker as it 
-						currently stands is no good.&nbsp; I was considering having 
-						two separate views; A &quot;Repository browser&quot; and an issue 
-						list.&nbsp; The common navigator stuff that is coming for 3.2 
-						would be perfect for the repository browser.&nbsp; We could 
-						have a top level (project level) item for the issue 
-						trackers as well as a node in each project that has an 
-						attached provider.&nbsp; This seems to be a more logical 
-						thing to do and puts the issue information right where 
-						the user needs it.</font></li>
-					</ul>
-					</li>
-				</ul>
-				<p><b>Use Cases</b> </p>
-				<ul>
-					<li>Work with bugs and queries within Eclipse. 
-					</li>
-					<li>Work with Mylar's task contexts (layers on above). </li>
-					<li><font color="#6600cc">As a user, one thing i would 
-					*love* is to have a list of active searches.&nbsp; These will 
-					update every so often and let me know when there are new 
-					matches (or changes).&nbsp; This way i don't have to be 
-					distracted by emails.&nbsp; Being able to switch between a set of 
-					issues without re-running the query would also be nice.</font></li>
-				</ul>
-				<!-- Saved in parser cache with key wiki:pcache:idhash:1317-0!1!0!0!!en!2 and timestamp 20051130154503 -->
-				<div class="printfooter">
-&nbsp;</div>
-				<!-- end content --></div>
-		</div>
-	</div>
-</div>
-
-</body>
-
-</html>
diff --git a/org.eclipse.mylyn.ide.dev/developer/archive/tests-manual.html b/org.eclipse.mylyn.ide.dev/developer/archive/tests-manual.html
deleted file mode 100644
index bcd019f..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/archive/tests-manual.html
+++ /dev/null
@@ -1,226 +0,0 @@
-<html>
-  <body>
-    <h2>&nbsp;</h2>
-	<p align="center"><font size="4">DEPRECATED</font></p>
-	<p><font size="4">This information is now maintained here: http://wiki.eclipse.org/index.php/Mylar_Testing</font></p>
-	<h2>&nbsp;</h2>
-	<h2><strike>Mylar Manual Tests</strike></h2>
-	<p><b>Help</b></p>
-	<ul>
-		<li><b>&nbsp;</b>Help &gt; Help Contents &gt; Mylar &gt; New and Noteworthy&nbsp;&nbsp; 
-		[ ensure updated ]</li>
-	</ul>
-	<p><b>Bugzilla Client</b></p>
-	
-	<ul>
-		<li>Offline Reports<ul>
-		<li><font color="#FF6600">Ensure that when a bug report is opened offline that has no offline 
-		data the bug page reads: &quot;Repository task data not available, please 
-		synchronize.&quot; (Aug 17, 2006 [0.6.2] page reads &quot;Could not download 
-		task data...&quot;</font></li>
-		<li>In the case of migration ensure that offline reports still open correctly (if not 
-		lost completely).</li>
-	</ul>
-		</li>
-		<li>Editor Hyperlinking - URL Hyperlinks, Bug hyperlinks (bug# 123, bug 12312,  
-		task# 1, task 12, duplicate bug links), stack trace links</li>
-		<li>Editor menu/commands - Cut/Copy/Paste/Select-all&nbsp; from menu and 
-		using shortcut keys</li>
-		<li>Repository Search&nbsp;&nbsp; (Search &gt; Search... &gt; Repository Search tab)<ul>
-			<li>Repository search page<ul>
-				<li>Ensure warning if no repository exists.</li>
-				<li>Cycle through available repository search pages ensuring 
-				that they populate with the last search performed on the 
-				respective repository</li>
-				<li>Ensure other repository types search pages appear when 
-				selected</li>
-			</ul></li>
-			<li>Repository Search Results View<ul>
-				<li>Test opening non-local report (Bug should open in bugzilla 
-				editor (blue bin icon) and the browser tab should be available)</li>
-				<li>Test opening report with local data (Bug should open in 
-				bugzilla editor (clipboard with blue bin overlay icon) and the 
-				Planning tab and Browser tab should be available)</li>
-			</ul></li>
-		</ul></li>
-		<li>Bugzilla Query Wizard</li> (Tasklist)<ul>
-			<li>Create new query</li>
-			<li>Open query to see that parameters are still there</li>
-			<li>Check for error handling (enter invalid number in max returned etc)</li>
-		</ul></li>
-		<li>New Bug submission (valid credentials)<ul>
-			<li>Test new bug submission for each Bugzilla server version</li>
-		</ul></li>
-		<li>Update of Repository Configuration<ul>
-		<li>Test from TaskRepositoriesView context menu</li>
-		<li>Test from BugzillaProductPage</li>
-		<li>A dialog should be produced in either case when an io or login 
-		exceptions occur.</li>
-		<li>Configuration caching<ul>
-			<li>Run new bug wizard, update products...</li>
-			<li>Restart eclipse, rerun wizard, products should appear immediately</li>
-		</ul></li>
-	</ul>
-		</li>
-		<li>New Bug submission (invalid credentials)<ul>
-			<li>Remove username and password from a repository configuration in the 
-		Task Repositories view</li>
-			<li>Initiate new repository task action</li>
-			<li>Select repository with missing credentials</li>
-			<li>Upon submitting new bug editor user is 
-			presented with credentials error dialog</li>
-		</ul></li>
-		<li>New Bug submission (invalid password)<ul>
-			<li>Make repository password invalid in Task Repositories view.</li>
-			<li>Initiate new repository task action.</li>
-			<li>Select repository with invalid password</li>
-			<li>Error Dialog presented on product update or selection of Next: The 
-		user name or password you entered is not valid...</li>
-		</ul></li>
-		<li>Submission of changes to a Bugzilla report should result in all 
-		parent queries being re-synchronized as well as the task itself being 
-		synchronized</li>
-		<li>Ensure submission of comment doesn't remove any depends on / blocks 
-		bugs</li>
-		<li>Submission of changes to existing bug with invalid repository 
-		credentials<ul>
-			<li>Mylar Bugzilla Client Dialog: Bugzilla could not post your bug since your login name or password is incorrect.
-		Ensure proper repository configuration in Task Repositories view.</li>
-		</ul></li>
-		<li><font color="#FF6600">Bug Compare (ensure attribute compare works) 
-		(July 31, 2006 [0.6.1] - Compare button removed)</font></li>
-		<li>Synchronize from context menu (invalid userid and password)<ul>
-			<li><font color="#FF6600">Report Download Failed Dialog: Ensure proper repository 
-		configuration in Task Repositories view. (Aug 17, 2006 [0.6.2] - 
-			currently upon failure the task remains italic and if the error is 
-			not an io related exception it is logged.)</font></li>
-		</ul></li>
-		<li>Synchronizing while disconnected should not put errors in the 
-		eclipse log</li>
-		<li>Reports &gt; Task list notification<ul>
-			<li>Open, modify, save, should have outgoing decorator<ul>
-				<li>Case synchronize: should get option to override local changes<ul>
-					<li>If overriding, overlay and changes go away</li>
-					<li>If no override, get conflict icon to show</li>
-				</ul></li>
-				<li>Case open: should retain outgoing overlay</li>
-				<li>Case edit and save again: outgoing overlay remains (should 
-				not receive conflict warning)</li>
-				<li>Case submit: outgoing overlay should disappear (should be no incoming 
-		upon synchronize)</li>
-			</ul></li>
-			<li>Task in CONFLICT state<ul>
-				<li>Case open: remains with conflict decorator</li>
-				<li>Case synchronize: should get option to override local changes<ul>
-					<li>Case overriding: overlay and changes go away</li>
-					<li>Case no override: changes remain, conflict decorator appears</li>
-				</ul></li>
-				<li>Case edit: Currently state switches to OUTGOING which is 
-				correct for now because we migrate their comment into the new 
-				report<br>&nbsp;</li>
-			</ul>
-			<p></li>
-			<li>Query hits not yet downloaded<ul>
-				<li>Case open: report downloaded (task icon appears), no decoration</li>
-				<li>Case synchronize: report downloaded (task icon appears), no 
-				decoration<br>&nbsp;</li>
-			</ul></li>
-			<li>Open report&nbsp; in external editor and add a comment.<ul>
-				<li>Case synchronize: incoming decoration should appear on task<ul>
-					<li>Case open: task opens with new content, no decoration</li>
-					<li>Case open (bug editor already open):&nbsp; 
-					User presented with dialog asking if they want to reopen 
-					with latest version</li>
-					<li>Case Background Synchronization incoming state remains</li>
-				</ul></li>
-				<li>Case open: task opens with offline content, user asked if 
-				they want to refresh with incoming content.<br>&nbsp;</li>
-			</ul></li>
-			<li>Open, modify, save, should have outgoing decorator, open report in 
-		external browser, add comment<ul>
-				<li>Case open: Outgoing decorator remains</li>
-				<li>Case Submit: Dialog:Possible problem posting Bugzilla 
-				report... HTML mid-air collision dialog<ul>
-					<li>Overwrite changes dialog (if yes - SYNCHRONIZED, if no - 
-					CONFLICT)</li>
-				</ul></li>
-				<li>Case synchronize: should get option to override local changes<ul>
-					<li>If overriding, overlay and changes go away</li>
-					<li>If no override, get conflict icon to show<br>&nbsp;</li>
-				</ul></li>
-			</ul></li>
-			<li>Copy report to a local category, repeat above tests ensuring 
-		decoration always </li>
-			<li>Copy report to root category, repeat tests ensuring decoration 
-		always matches</li>
-		</ul></li>
-		<li>Check that auto background synchronize works<ul>
-			<li>Ensure that new hits (i.e. reports created using web ui) appear in 
-		query after auto sync</li>
-			<li>Ensure that incoming on existing tasks appears after auto 
-		synchronization&nbsp;&nbsp;&nbsp; </li>
-		</ul></li>
-		<li>If editor open and task gets incoming, dialog 
-		should be presented asking if user wants to refresh and reopen.</li>
-		<li>Check that if changes are made to the notes field of the Planning 
-		editor that save still works (editor doesn't remain dirty).</li>
-		<li>Ensure that when offline reports file is deleted, tasks don't 
-		suddenly all have incoming status upon synchronizing</li>
-		<li>Reports &gt; Outline View<ul>
-			<li>Clicking on comments in outline view should cause editor to 
-		scroll to respective bug on page.</li>
-		</ul></li>
-		<li>DnD Attachments: Ensure all of the following launch the new attachment wizard with
-		the appropriate file specified.
-		<ul><li>Drag a file from the workspace to the attachments section or new comment box.</li>
-		<li>Drag a file from a different application (or desktop) onto the attachments section
-		or new comment box.</li>
-		<li>Drag a region of text from any application (eg. a web browser) onto the attachments
-		section or new comment box.</li>
-		</ul></li>
-	</ul>
-	<p><b>Task List</b></p>
-	<ul>
-		<li>File -&gt; Export -&gt; Mylar Task Data: ensure it works</li>
-		<li>File -&gt; Import -&gt; Mylar Task Data:<ul>
-		<li>Test importing with task in active state</li>
-	</ul>
-		</li>
-		<li>Make a task, make it active, move it to the 
-		archive (remove from root category) - file should remain visible in task list</li>
-		<li>Task List Auto-Archive</li>
-		<li>Addition and removal of files from change sets</li>
-		<li>Mylar context sensitive JUnit unit tests</li>
-		<li>Ensure internal browser tab can be disabled (via preferences)</li>
-		<li>Drag and Drop<ul>
-		<li>From category to category: move</li>
-		<li>From query to category: copies</li>
-		<li>Task to external text: copies details</li>
-		<li>Task to external explorer: copies context file (<font color="#FF6600"> 
-		July 31, 2006 [0.6.1] - if context doesn't exist need to disable drop?</font> 
-		)</li>
-	</ul>
-	
-		</li>
-	</ul>
-	
-	<p><b>SDK Integration</b></p>
-	<ul>
-		<li>Problems view</li>
-		<li>Debug view</li>
-		<li>Eclipse native tasks view</li>
-		<li>History view -> context menu -> Open Corresponding Task</li>
-	</ul>
-	
-	<p><b>Java</b></p>
-	<ul>
-		<li>Run JUnit context test without interesting tests: should get message</li>
-		<li>Run JUnit contexts test with interesting tests, should run</li>
-		<li>Do above for PDE JUnit tests</li>
-		<li>Ensure code folding works properly</li>
-	</ul>
-	<p>PDE</p>
-	<ul>
-		<li>...</li>
-	</ul>
-</body></html>
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/AbstractHyperlinkDetector.java b/org.eclipse.mylyn.ide.dev/developer/src-old/AbstractHyperlinkDetector.java
deleted file mode 100644
index c00e819..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/AbstractHyperlinkDetector.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2005 - 2006 University Of British Columbia and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     University Of British Columbia - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.mylyn.internal.bugs.java;
-
-import org.eclipse.jface.text.IRegion;
-import org.eclipse.jface.text.ITextViewer;
-import org.eclipse.jface.text.hyperlink.IHyperlink;
-import org.eclipse.jface.text.hyperlink.IHyperlinkDetector;
-import org.eclipse.ui.texteditor.ITextEditor;
-
-/**
- * @author Mik Kersten
- */
-public abstract class AbstractHyperlinkDetector implements IHyperlinkDetector {
-
-	private ITextEditor fEditor;
-
-	public abstract IHyperlink[] detectHyperlinks(ITextViewer textViewer, IRegion region,
-			boolean canShowMultipleHyperlinks);
-
-	public ITextEditor getEditor() {
-		return fEditor;
-	}
-
-	public void setEditor(ITextEditor editor) {
-		this.fEditor = editor;
-	}
-}
\ No newline at end of file
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/AbstractQueryHit.java b/org.eclipse.mylyn.ide.dev/developer/src-old/AbstractQueryHit.java
deleted file mode 100644
index 8208a99..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/AbstractQueryHit.java
+++ /dev/null
@@ -1,193 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004 - 2006 University Of British Columbia and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     University Of British Columbia - initial API and implementation
- *******************************************************************************/
-package org.eclipse.mylyn.tasks.core;
-
-import org.eclipse.core.runtime.PlatformObject;
-import org.eclipse.mylyn.internal.tasks.core.RepositoryTaskHandleUtil;
-import org.eclipse.mylyn.tasks.core.Task.PriorityLevel;
-
-/**
- * @author Mik Kersten
- */
-/*public*/ abstract class AbstractQueryHit extends PlatformObject implements ITaskListElement {
-
-	protected TaskList taskList;
-
-	protected AbstractTask task;
-
-	protected String repositoryUrl;
-
-	protected String summary;
-
-	protected String priority = PriorityLevel.getDefault().toString();
-
-	protected String taskId;
-
-	private boolean completed = false;
-
-	private boolean isNotified = false;
-
-	private AbstractRepositoryQuery parent;
-
-	protected AbstractQueryHit(TaskList taskList, String repositoryUrl, String description, String taskId) {
-		this.taskList = taskList;
-		this.repositoryUrl = repositoryUrl;
-		this.summary = description;
-		this.taskId = taskId;
-	}
-
-	public AbstractRepositoryQuery getParent() {
-		return parent;
-	}
-
-	public void setParent(AbstractRepositoryQuery parent) {
-		this.parent = parent;
-	}
-
-	public String getRepositoryUrl() {
-		return repositoryUrl;
-	}
-
-	public void setRepositoryUrl(String repositoryUrl) {
-		this.repositoryUrl = repositoryUrl;
-	}
-
-	public String getSummary() {
-		if (task != null) {
-			return task.getSummary();
-		} else {
-			return summary;
-		}
-	}
-
-	public AbstractTask getOrCreateCorrespondingTask() {
-		if (taskList == null) {
-			return null;
-		}
-
-		ITask existingTask = taskList.getTask(getHandleIdentifier());
-		if (existingTask instanceof AbstractTask) {
-			this.task = (AbstractTask) existingTask;
-		} else {			
-			task = createTask();			
-			task.setCompleted(completed);
-			taskList.addTask(task);
-		}
-		return task;
-	}
-
-	//@Deprecated
-	protected abstract AbstractTask createTask();
-
-	/**
-	 * @return null if there is no corresponding task
-	 */
-	public AbstractTask getCorrespondingTask() {
-		return task;
-	}
-
-	public void setCorrespondingTask(AbstractTask task) {
-		this.task = task;
-	}
-
-	public boolean isCompleted() {
-		if (task != null) {
-			return task.isCompleted();
-		} else {
-			return completed;
-		}
-	}
-
-	public void setCompleted(boolean completed) {
-		this.completed = completed;
-	}
-
-	public final String getHandleIdentifier() {
-		if (task != null) {
-			return task.getHandleIdentifier();
-		}
-		return RepositoryTaskHandleUtil.getHandle(repositoryUrl, taskId);
-	}
-
-	/**
-	 * @return Unique identifier for this task on the corresponding server, must
-	 *         be robust to changing attributes on the task.
-	 */
-	public String getTaskId() {
-		return taskId;
-	}
-
-	/**
-	 * @return An ID that can be presented to the user for identifying the task,
-	 *         override to return null if no such ID exists.
-	 */
-	public String getIdentifyingLabel() {
-		return getTaskId();
-	}
-
-	public boolean isNotified() {
-		return isNotified;
-	}
-
-	public void setNotified(boolean notified) {
-		isNotified = notified;
-	}
-
-	@Override
-	public boolean equals(Object obj) {
-		if (!(obj instanceof AbstractQueryHit)) {
-			return false;
-		}
-		AbstractQueryHit hit = (AbstractQueryHit) obj;
-		return hit.getHandleIdentifier().equals(this.getHandleIdentifier());
-	}
-
-	@Override
-	public int hashCode() {
-		return this.getHandleIdentifier().hashCode();
-	}
-
-	/**
-	 * @return the url of the hit without any additional login information etc.
-	 */
-	public String getUrl() {
-		return "";
-	}
-
-	public String getPriority() {
-		if (task != null) {
-			return task.getPriority();
-		} else {
-			return priority;
-		}
-	}
-
-	public void setPriority(String priority) {
-		this.priority = priority;
-	}
-
-	public void setSummary(String description) {
-		this.summary = description;
-	}
-
-	public void setHandleIdentifier(String id) {
-		// ignore
-	}
-
-	public int compareTo(ITaskListElement taskListElement) {
-		return this.taskId.compareTo(((AbstractQueryHit) taskListElement).taskId);
-	}
-
-	@Deprecated
-	public void setTaskId(String taskId) {
-		this.taskId = taskId;
-	}
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/AwtExample.java b/org.eclipse.mylyn.ide.dev/developer/src-old/AwtExample.java
deleted file mode 100644
index 25bf549..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/AwtExample.java
+++ /dev/null
@@ -1,229 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004 - 2005 University Of British Columbia and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     University Of British Columbia - initial API and implementation
- *******************************************************************************/
-import java.awt.EventQueue;
-import java.io.File;
-
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.awt.SWT_AWT;
-import org.eclipse.swt.graphics.RGB;
-import org.eclipse.swt.graphics.Rectangle;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.*;
-
-public class AwtExample {
-
-    public static void main(String[] args) {
-        final Display display = new Display();
-        final Shell shell = new Shell(display);
-        shell.setText("SWT and Swing/AWT Example");
-
-        Listener exitListener = new Listener() {
-            public void handleEvent(Event e) {
-                MessageBox dialog = new MessageBox(shell, SWT.OK | SWT.CANCEL | SWT.ICON_QUESTION);
-                dialog.setText("Question");
-                dialog.setMessage("Exit?");
-                if (e.type == SWT.Close) e.doit = false;
-                if (dialog.open() != SWT.OK) return;
-                shell.dispose();
-            }
-        };  
-        Listener aboutListener = new Listener() {
-            public void handleEvent(Event e) {
-                final Shell s = new Shell(shell, SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL);
-                s.setText("About");
-                GridLayout layout = new GridLayout(1, false);
-                layout.verticalSpacing = 20;
-                layout.marginHeight = layout.marginWidth = 10;
-                s.setLayout(layout);
-                Label label = new Label(s, SWT.NONE);
-                label.setText("SWT and AWT Example.");
-                Button button = new Button(s, SWT.PUSH);
-                button.setText("OK");
-                GridData data = new GridData();
-                data.horizontalAlignment = GridData.CENTER;
-                button.setLayoutData(data);
-                button.addListener(SWT.Selection, new Listener() {
-                    public void handleEvent(Event e) {
-                        s.dispose();
-                    }
-                });
-                s.pack();
-                Rectangle parentBounds = shell.getBounds();
-                Rectangle bounds = s.getBounds();
-                int x = parentBounds.x + (parentBounds.width - bounds.width) / 2;
-                int y = parentBounds.y + (parentBounds.height - bounds.height) / 2;
-                s.setLocation(x, y);
-                s.open();
-                while (!s.isDisposed()) {
-                    if (!display.readAndDispatch()) display.sleep();
-                }
-            }
-        };
-        shell.addListener(SWT.Close, exitListener);
-        Menu mb = new Menu(shell, SWT.BAR);
-        MenuItem fileItem = new MenuItem(mb, SWT.CASCADE);
-        fileItem.setText("&File");
-        Menu fileMenu = new Menu(shell, SWT.DROP_DOWN);
-        fileItem.setMenu(fileMenu);
-        MenuItem exitItem = new MenuItem(fileMenu, SWT.PUSH);
-        exitItem.setText("&Exit\tCtrl+X");
-        exitItem.setAccelerator(SWT.CONTROL + 'X');
-        exitItem.addListener(SWT.Selection, exitListener);
-        MenuItem aboutItem = new MenuItem(fileMenu, SWT.PUSH);
-        aboutItem.setText("&About\tCtrl+A");
-        aboutItem.setAccelerator(SWT.CONTROL + 'A');
-        aboutItem.addListener(SWT.Selection, aboutListener);
-        shell.setMenuBar(mb);
-
-        RGB color = shell.getBackground().getRGB();
-        Label separator1 = new Label(shell, SWT.SEPARATOR | SWT.HORIZONTAL);
-        Label locationLb = new Label(shell, SWT.NONE);
-        locationLb.setText("Location:");
-        Composite locationComp = new Composite(shell, SWT.EMBEDDED);
-        ToolBar toolBar = new ToolBar(shell, SWT.FLAT);
-        ToolItem exitToolItem = new ToolItem(toolBar, SWT.PUSH);
-        exitToolItem.setText("&Exit");
-        exitToolItem.addListener(SWT.Selection, exitListener);
-        ToolItem aboutToolItem = new ToolItem(toolBar, SWT.PUSH);
-        aboutToolItem.setText("&About");
-        aboutToolItem.addListener(SWT.Selection, aboutListener);
-        Label separator2 = new Label(shell, SWT.SEPARATOR | SWT.HORIZONTAL);
-        final Composite comp = new Composite(shell, SWT.NONE);
-        final Tree fileTree = new Tree(comp, SWT.SINGLE | SWT.BORDER);
-        Sash sash = new Sash(comp, SWT.VERTICAL);
-        Composite tableComp = new Composite(comp, SWT.EMBEDDED);
-        Label separator3 = new Label(shell, SWT.SEPARATOR | SWT.HORIZONTAL);
-        Composite statusComp = new Composite(shell, SWT.EMBEDDED);
-
-        java.awt.Frame locationFrame = SWT_AWT.new_Frame(locationComp);
-        final java.awt.TextField locationText = new java.awt.TextField();
-        locationFrame.add(locationText);
-
-        java.awt.Frame fileTableFrame = SWT_AWT.new_Frame(tableComp);
-        java.awt.Panel panel = new java.awt.Panel(new java.awt.BorderLayout());
-        fileTableFrame.add(panel);
-
-        java.awt.Frame statusFrame = SWT_AWT.new_Frame(statusComp);
-        statusFrame.setBackground(new java.awt.Color(color.red, color.green, color.blue));
-        final java.awt.Label statusLabel = new java.awt.Label();
-        statusFrame.add(statusLabel);
-        statusLabel.setText("Select a file");
-
-        sash.addListener(SWT.Selection, new Listener() {
-            public void handleEvent(Event e) {
-                if (e.detail == SWT.DRAG) return;
-                GridData data = (GridData)fileTree.getLayoutData();
-                Rectangle trim = fileTree.computeTrim(0, 0, 0, 0);
-                data.widthHint = e.x - trim.width;
-                comp.layout();
-            }
-        });
-
-        File[] roots = File.listRoots();
-        for (int i = 0; i < roots.length; i++) {
-            File file = roots[i];
-            TreeItem treeItem = new TreeItem(fileTree, SWT.NONE);
-            treeItem.setText(file.getAbsolutePath());
-            treeItem.setData(file);
-            TreeItem dumyItem = new TreeItem(treeItem, SWT.NONE);
-        }
-        fileTree.addListener(SWT.Expand, new Listener() {
-            public void handleEvent(Event e) {
-                TreeItem item = (TreeItem)e.item;
-                if (item == null) return;
-                if (item.getItemCount() == 1) {
-                    TreeItem firstItem = item.getItems()[0];
-                    if (firstItem.getData() != null) return;
-                    firstItem.dispose();
-                } else {
-                    return;
-                }
-                File root = (File)item.getData();
-                File[] files = root.listFiles();
-                if (files == null) return;
-                for (int i = 0; i < files.length; i++) {
-                    File file = files[i];
-                    if (file.isDirectory()) {
-                        TreeItem treeItem = new TreeItem(item, SWT.NONE);
-                        treeItem.setText(file.getName());
-                        treeItem.setData(file);
-                        TreeItem dumyItem = new TreeItem(treeItem, SWT.NONE);
-                    }
-                }
-            }
-        });
-        fileTree.addListener(SWT.Selection, new Listener() {
-            public void handleEvent(Event e) {
-                TreeItem item = (TreeItem)e.item;
-                if (item == null) return;
-                final File root = (File)item.getData();
-                EventQueue.invokeLater(new Runnable() {
-                    public void run() {
-                        statusLabel.setText(root.getAbsolutePath());
-                        locationText.setText(root.getAbsolutePath());
-                    }
-                });
-            }
-        });
-        
-        GridLayout layout = new GridLayout(4, false);
-        layout.marginWidth = layout.marginHeight = 0;
-        layout.horizontalSpacing = layout.verticalSpacing = 1;
-        shell.setLayout(layout);
-        GridData data;      
-        data = new GridData(GridData.FILL_HORIZONTAL);
-        data.horizontalSpan = 4;
-        separator1.setLayoutData(data);
-        data = new GridData();
-        data.horizontalSpan = 1;
-        data.horizontalIndent = 10;
-        locationLb.setLayoutData(data);
-        data = new GridData(GridData.FILL_HORIZONTAL);
-        data.horizontalSpan = 2;
-        data.heightHint = locationText.getPreferredSize().height;
-        locationComp.setLayoutData(data);
-        data = new GridData(GridData.FILL_HORIZONTAL);
-        data.horizontalSpan = 1;
-        toolBar.setLayoutData(data);
-        data = new GridData(GridData.FILL_HORIZONTAL);
-        data.horizontalSpan = 4;
-        separator2.setLayoutData(data);
-        data = new GridData(GridData.FILL_BOTH);
-        data.horizontalSpan = 4;
-        comp.setLayoutData(data);
-        data = new GridData(GridData.FILL_HORIZONTAL);
-        data.horizontalSpan = 4;
-        separator3.setLayoutData(data);
-        data = new GridData(GridData.FILL_HORIZONTAL);
-        data.horizontalSpan = 4;
-        data.heightHint = statusLabel.getPreferredSize().height;
-        statusComp.setLayoutData(data);
-        
-        layout = new GridLayout(3, false);
-        layout.marginWidth = layout.marginHeight = 0;
-        layout.horizontalSpacing = layout.verticalSpacing = 1;
-        comp.setLayout(layout);         
-        data = new GridData(GridData.FILL_VERTICAL);
-        data.widthHint = 200;
-        fileTree.setLayoutData(data);       
-        data = new GridData(GridData.FILL_VERTICAL);
-        sash.setLayoutData(data);       
-        data = new GridData(GridData.FILL_BOTH);
-        tableComp.setLayoutData(data);
-
-        shell.open();
-        while(!shell.isDisposed()) {
-            if (!display.readAndDispatch()) display.sleep();
-        }
-        display.dispose();
-    }
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/BugzillaHyperLinkDetector.java b/org.eclipse.mylyn.ide.dev/developer/src-old/BugzillaHyperLinkDetector.java
deleted file mode 100644
index 423c1cf..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/BugzillaHyperLinkDetector.java
+++ /dev/null
@@ -1,202 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004 - 2006 University Of British Columbia and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     University Of British Columbia - initial API and implementation
- *******************************************************************************/
-package org.eclipse.mylyn.internal.bugs.java;
-
-import java.util.List;
-
-import org.eclipse.jdt.core.IJavaElement;
-import org.eclipse.jdt.core.dom.ASTNode;
-import org.eclipse.jdt.core.dom.Block;
-import org.eclipse.jdt.core.dom.Comment;
-import org.eclipse.jdt.core.dom.CompilationUnit;
-import org.eclipse.jdt.core.dom.TextElement;
-import org.eclipse.jdt.internal.corext.dom.NodeFinder;
-import org.eclipse.jdt.internal.ui.JavaPlugin;
-import org.eclipse.jdt.internal.ui.javaeditor.ASTProvider;
-import org.eclipse.jdt.internal.ui.javaeditor.JavaEditor;
-import org.eclipse.jface.text.BadLocationException;
-import org.eclipse.jface.text.IDocument;
-import org.eclipse.jface.text.IRegion;
-import org.eclipse.jface.text.ITextViewer;
-import org.eclipse.jface.text.hyperlink.IHyperlink;
-import org.eclipse.mylyn.internal.bugzilla.ui.BugzillaHyperlinkUtil;
-import org.eclipse.mylyn.internal.core.util.MylarStatusHandler;
-import org.eclipse.mylyn.provisional.tasklist.TaskRepository;
-import org.eclipse.ui.IEditorSite;
-import org.eclipse.ui.texteditor.ITextEditor;
-
-/**
- * @author Shawn Minto
- * Detects bugzilla hyperlinks within source code
- */
-public class BugzillaHyperLinkDetector extends AbstractHyperlinkDetector {
-
-	private TaskRepository repository;
-	
-	public BugzillaHyperLinkDetector(TaskRepository repository) {
-		this.repository = repository;
-	}
-	
-	@SuppressWarnings("unchecked")
-	public IHyperlink[] detectHyperlinks(ITextViewer textViewer, IRegion region, boolean canShowMultipleHyperlinks) {
-		
-		ITextEditor textEditor = getEditor();
-		if (region == null || textEditor == null || canShowMultipleHyperlinks || !(textEditor instanceof JavaEditor))
-			return null;
-
-		IEditorSite site = textEditor.getEditorSite();
-		if (site == null)
-			return null;
-
-		IJavaElement javaElement;
-		Object adapter = textEditor.getEditorInput().getAdapter(IJavaElement.class);
-		if (adapter instanceof IJavaElement) {
-			javaElement = (IJavaElement)adapter;
-		} else {
-			return null;
-		}
-		
-		if (javaElement == null)
-			return null;
-
-		CompilationUnit ast = JavaPlugin.getDefault().getASTProvider().getAST(javaElement, ASTProvider.WAIT_NO, null);
-		if (ast == null)
-			return null;
-
-		ASTNode node = NodeFinder.perform(ast, region.getOffset(), 1);
-
-		if (node == null || !(node instanceof TextElement || node instanceof Block))
-			return null;
-
-		String comment = null;
-		int commentStart = -1;
-
-		if (node instanceof TextElement) {
-			TextElement element = (TextElement) node;
-			comment = element.getText();
-			commentStart = element.getStartPosition();
-		} else if (node instanceof Block) {
-			Comment c = findComment(ast.getCommentList(), region.getOffset(), 1);
-			if (c != null) {
-				try {
-					IDocument document = textEditor.getDocumentProvider().getDocument(textEditor.getEditorInput());
-					String commentString = document.get(c.getStartPosition(), c.getLength());
-					comment = getStringFromComment(c, region.getOffset(), commentString);
-					commentStart = getLocationFromComment(c, comment, commentString) + c.getStartPosition();
-				} catch (BadLocationException e) {
-					MylarStatusHandler.log(e, "Failed to get text for comment");
-				}
-			}
-		}
-
-		if (comment == null)
-			return null;
-
-		int startOffset = region.getOffset();
-		int endOffset = startOffset + region.getLength();
-		
-		return BugzillaHyperlinkUtil.findBugHyperlinks(repository.getUrl(), startOffset, endOffset, comment, commentStart);
-	}
-
-//	private IHyperlink[] findBugHyperlinks(int startOffset, int endOffset, String comment, int commentStart) {
-//
-//		Pattern p = Pattern.compile("^.*bug\\s+\\d+.*");
-//		Matcher m = p.matcher(comment.toLowerCase().trim());
-//		boolean b = m.matches();
-//
-//		p = Pattern.compile("^.*bug#\\s+\\d+.*");
-//		m = p.matcher(comment.toLowerCase().trim());
-//		boolean b2 = m.matches();
-//
-//		p = Pattern.compile("^.*bug\\s#\\d+.*");
-//		m = p.matcher(comment.toLowerCase().trim());
-//		boolean b3 = m.matches();
-//
-//		p = Pattern.compile("^.*bug#\\d+.*");
-//		m = p.matcher(comment.toLowerCase().trim());
-//		boolean b4 = m.matches();
-//
-//		// XXX walk forward from where we are
-//		if (b || b2 || b3 || b4) {
-//
-//			int start = comment.toLowerCase().indexOf("bug");
-//			int ahead = 4;
-//			if (b2 || b3 || b4) {
-//				int pound = comment.toLowerCase().indexOf("#", start);
-//				ahead = pound - start + 1;
-//			}
-//			String endComment = comment.substring(start + ahead, comment.length());
-//			endComment = endComment.trim();
-//			int endCommentStart = comment.indexOf(endComment);
-//
-//			int end = comment.indexOf(" ", endCommentStart);
-//			int end2 = comment.indexOf(":", endCommentStart);
-//
-//			if ((end2 < end && end2 != -1) || (end == -1 && end2 != -1)) {
-//				end = end2;
-//			}
-//
-//			if (end == -1)
-//				end = comment.length();
-//
-//			try {
-//				int bugId = Integer.parseInt(comment.substring(endCommentStart, end).trim());
-//
-//				start += commentStart;
-//				end += commentStart;
-//
-//				if (startOffset >= start && endOffset <= end) {
-//					IRegion sregion = new Region(start, end - start);
-//					return new IHyperlink[] { new BugzillaHyperLink(sregion, bugId) };
-//				}
-//			} catch (NumberFormatException e) {
-//				return null;
-//			}
-//		}
-//		return null;
-//	}
-
-	private int getLocationFromComment(Comment c, String commentLine, String commentString) {
-		if (commentLine == null) {
-			return -1;
-		} else {
-			return commentString.indexOf(commentLine);
-		}
-	}
-
-	private String getStringFromComment(Comment comment, int desiredOffset, String commentString) {
-		String[] parts = commentString.split("\n");
-		if (parts.length > 1) {
-			int offset = comment.getStartPosition();
-			for (String part : parts) {
-				int newOffset = offset + part.length() + 1;
-				if (desiredOffset >= offset && desiredOffset <= newOffset) {
-					return part;
-				}
-
-			}
-		} else {
-			return commentString;
-		}
-
-		return null;
-	}
-
-	private Comment findComment(List<Comment> commentList, int offset, int i) {
-		for (Comment comment : commentList) {
-			if (comment.getStartPosition() <= offset
-					&& (comment.getStartPosition() + comment.getLength() >= offset + i)) {
-				return comment;
-			}
-		}
-		return null;
-	}
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/BugzillaReportElement.java b/org.eclipse.mylyn.ide.dev/developer/src-old/BugzillaReportElement.java
deleted file mode 100644
index 0547e7a..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/BugzillaReportElement.java
+++ /dev/null
@@ -1,118 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004 - 2006 University Of British Columbia and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     University Of British Columbia - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.mylyn.internal.tasklist;
-
-/**
- * Bugzilla XML element enum. Each enum has the attribute name
- * and associated xml element tag name.
- * 
- * @author Rob Elves
- */
-public class BugzillaReportElement {
-	// Format: ENUM ( "pretty name", "xml key", <hidden: true/false>, <readonly: true/false>)
-	// Hidden elements are not automatically displayed in ui	
-	public static final BugzillaReportElement ASSIGNED_TO = new BugzillaReportElement("Assigned to:", "assigned_to", false, true);
-	public static final BugzillaReportElement ATTACHID = new BugzillaReportElement("attachid", "attachid");
-	public static final BugzillaReportElement ATTACHMENT = new BugzillaReportElement("attachment", "attachment");
-	public static final BugzillaReportElement BLOCKED = new BugzillaReportElement("Bug blocks:", "blocked");
-	public static final BugzillaReportElement BUG = new BugzillaReportElement("bug","bug", true);
-	public static final BugzillaReportElement BUG_FILE_LOC = new BugzillaReportElement("URL:", "bug_file_loc", true);
-	public static final BugzillaReportElement BUG_ID = new BugzillaReportElement("Bug:", "bug_id", true);
-	public static final BugzillaReportElement BUG_SEVERITY = new BugzillaReportElement("Severity:", "bug_severity", false);
-	public static final BugzillaReportElement BUG_STATUS = new BugzillaReportElement("Status:", "bug_status", false, true);
-	public static final BugzillaReportElement BUG_WHEN = new BugzillaReportElement("bug_when", "bug_when", true, true);
-	public static final BugzillaReportElement BUGZILLA = new BugzillaReportElement("bugzilla", "bugzilla", true);
-	public static final BugzillaReportElement CC = new BugzillaReportElement("CC:", "cc", true, true);
-	public static final BugzillaReportElement CCLIST_ACCESSIBLE = new BugzillaReportElement("cclist_accessible", "cclist_accessible", true);
-	public static final BugzillaReportElement CLASSIFICATION = new BugzillaReportElement("Classification:", "classification", true);
-	public static final BugzillaReportElement CLASSIFICATION_ID = new BugzillaReportElement("Classification ID:", "classification_id", true);
-	public static final BugzillaReportElement COMPONENT = new BugzillaReportElement("Component:", "component", false);
-	public static final BugzillaReportElement CREATION_TS = new BugzillaReportElement("Creation date:", "creation_ts", true);
-	public static final BugzillaReportElement CTYPE = new BugzillaReportElement("Content Type", "ctype");
-	public static final BugzillaReportElement DATA = new BugzillaReportElement("data", "data"); 
-	public static final BugzillaReportElement DATE = new BugzillaReportElement("Date", "date"); 
-	public static final BugzillaReportElement DELTA_TS = new BugzillaReportElement("Last Modification", "delta_ts", true); 
-	public static final BugzillaReportElement DEPENDSON = new BugzillaReportElement("Bug depends on:", "dependson"); 
-	public static final BugzillaReportElement DESC = new BugzillaReportElement("desc", "desc"); 
-	public static final BugzillaReportElement EVERCONFIRMED = new BugzillaReportElement("everconfirmed", "everconfirmed", true);
-	public static final BugzillaReportElement FILENAME = new BugzillaReportElement("filename", "filename");
-	public static final BugzillaReportElement IS_OBSOLETE = new BugzillaReportElement("Obsolete", "isobsolete", true); 
-	public static final BugzillaReportElement KEYWORDS = new BugzillaReportElement("Keywords:", "keywords", true);
-	public static final BugzillaReportElement LONG_DESC = new BugzillaReportElement("Description:", "long_desc"); 
-	public static final BugzillaReportElement LONGDESCLENGTH = new BugzillaReportElement("Number of comments", "longdesclength", true); 
-	public static final BugzillaReportElement NEWCC = new BugzillaReportElement("Add CC:", "newcc", true); 
-	public static final BugzillaReportElement OP_SYS = new BugzillaReportElement("OS:", "op_sys", false); 
-	public static final BugzillaReportElement PRIORITY = new BugzillaReportElement("Priority:", "priority", false); 
-	public static final BugzillaReportElement PRODUCT = new BugzillaReportElement("Product:", "product", false); 
-	public static final BugzillaReportElement REP_PLATFORM = new BugzillaReportElement("Platform:", "rep_platform", false);
-	public static final BugzillaReportElement REPORTER = new BugzillaReportElement("Reporter:", "reporter", false, true);
-	public static final BugzillaReportElement REPORTER_ACCESSIBLE = new BugzillaReportElement("reporter_accessible", "reporter_accessible", true);
-	public static final BugzillaReportElement RESOLUTION = new BugzillaReportElement("Resolution:", "resolution", false, true); // Exiting bug field, new cc
-	public static final BugzillaReportElement SHORT_DESC = new BugzillaReportElement("Summary:", "short_desc", true);
-	public static final BugzillaReportElement TARGET_MILESTONE = new BugzillaReportElement("Target milestone:", "target_milestone", false);
-	public static final BugzillaReportElement THETEXT = new BugzillaReportElement("thetext", "thetext");
-	public static final BugzillaReportElement TYPE = new BugzillaReportElement("type", "type");
-	public static final BugzillaReportElement UNKNOWN = new BugzillaReportElement("UNKNOWN", "UNKNOWN");
-	public static final BugzillaReportElement VERSION = new BugzillaReportElement("Version:", "version", false);
-	public static final BugzillaReportElement VOTES = new BugzillaReportElement("Votes:", "votes", false, true);
-	public static final BugzillaReportElement WHO = new BugzillaReportElement("who", "who");
-	public static final BugzillaReportElement QA_CONTACT= new BugzillaReportElement("QA Contact", "qa_contact", false, false);
-	public static final BugzillaReportElement ADDSELFCC = new BugzillaReportElement("Add self to CC", "addselfcc", true, false);
-	// Used by search engine
-	public static final BugzillaReportElement LI = new BugzillaReportElement("used by search engine", "li", true);
-	public static final BugzillaReportElement ID = new BugzillaReportElement("used by search engine", "id", true);
-	public static final BugzillaReportElement SHORT_SHORT_DESC = new BugzillaReportElement("used by search engine", "short_short_desc", false);
-	public static final BugzillaReportElement SEQ = new BugzillaReportElement("used by search engine", "seq", false);	
-	public static final BugzillaReportElement RESULT = new BugzillaReportElement("used by search engine", "result", false);
-	public static final BugzillaReportElement RDF = new BugzillaReportElement("used by search engine", "rdf", false);
-	public static final BugzillaReportElement INSTALLATION = new BugzillaReportElement("used by search engine", "installation", false);
-	public static final BugzillaReportElement BUGS = new BugzillaReportElement("used by search engine", "bugs", false);
-	
-	private final boolean isHidden;
-	
-	private final boolean isReadOnly;
-	
-	private final String keyString;
-	
-	private final String prettyName;
-
-	BugzillaReportElement(String prettyName, String fieldName) {		
-		this(prettyName, fieldName, false, false);
-	}
-	
-	BugzillaReportElement(String prettyName, String fieldName, boolean hidden) {		
-		this(prettyName, fieldName, hidden, false);
-	}
-	
-	BugzillaReportElement(String prettyName, String fieldName, boolean hidden, boolean readonly) {		
-		this.prettyName = prettyName;
-		this.keyString = fieldName;
-		this.isHidden = hidden;
-		this.isReadOnly = readonly;
-	}
-
-	public String getKeyString() {
-		return keyString;
-	}
-
-	public boolean isHidden() {
-		return isHidden;
-	}	
-	
-	public boolean isReadOnly() {
-		return isReadOnly;
-	}
-	
-	public String toString() {
-		return prettyName;
-	}
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/BugzillaTaskHandler.java b/org.eclipse.mylyn.ide.dev/developer/src-old/BugzillaTaskHandler.java
deleted file mode 100644
index 0f12706..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/BugzillaTaskHandler.java
+++ /dev/null
@@ -1,272 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004 - 2006 University Of British Columbia and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     University Of British Columbia - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.mylyn.internal.bugzilla.ui.tasklist;
-
-import org.eclipse.jface.action.Action;
-import org.eclipse.mylyn.internal.tasklist.ITaskHandler;
-import org.eclipse.mylyn.internal.tasklist.ui.ITaskListElement;
-import org.eclipse.mylyn.internal.tasklist.ui.actions.CopyDescriptionAction;
-import org.eclipse.mylyn.internal.tasklist.ui.actions.DeleteAction;
-import org.eclipse.mylyn.internal.tasklist.ui.actions.GoIntoAction;
-import org.eclipse.mylyn.internal.tasklist.ui.actions.OpenTaskInExternalBrowserAction;
-import org.eclipse.mylyn.internal.tasklist.ui.actions.OpenTaskListElementAction;
-import org.eclipse.mylyn.internal.tasklist.ui.actions.RemoveFromCategoryAction;
-import org.eclipse.mylyn.internal.tasklist.ui.actions.RenameAction;
-import org.eclipse.mylyn.tasklist.ITask;
-
-/**
- * @author Mik Kersten and Ken Sueda
- * 
- * TODO: refactor
- */
-public class BugzillaTaskHandler implements ITaskHandler {
-
-	public boolean acceptsItem(ITaskListElement element) {
-		return element instanceof BugzillaTask || element instanceof BugzillaQueryHit
-				|| element instanceof BugzillaQueryCategory;
-	}
-
-//	public void taskClosed(ITask element, IWorkbenchPage page) {
-//		try {
-//			IEditorInput input = null;
-//			if (element instanceof BugzillaTask) {
-//				input = new BugzillaTaskEditorInput((BugzillaTask) element, true);
-//			}
-//			IEditorPart editor = page.findEditor(input);
-//
-//			if (editor != null) {
-//				page.closeEditor(editor, false);
-//			}
-//		} catch (Exception e) {
-//			MylarStatusHandler.log(e, "Error while trying to close a bugzilla task");
-//		}
-//	}
-
-	public boolean enableAction(Action action, ITaskListElement element) {
-
-		if (element instanceof BugzillaQueryHit) {
-			BugzillaQueryHit hit = (BugzillaQueryHit) element;
-			if (hit.getCorrespondingTask() != null && hit.getCorrespondingTask().hasValidUrl()) {
-				return true;
-			}
-			return false;
-		} else if (element instanceof BugzillaTask) {
-			if (action instanceof OpenTaskInExternalBrowserAction) {
-				if (((ITask) element).hasValidUrl()) {
-					return true;
-				} else {
-					return false;
-				}
-			} else if (action instanceof DeleteAction || action instanceof CopyDescriptionAction
-					|| action instanceof OpenTaskListElementAction || action instanceof RemoveFromCategoryAction) {
-				return true;
-			} else {
-				return false;
-			}
-		} else if (element instanceof BugzillaQueryCategory) {
-			if (action instanceof DeleteAction || action instanceof CopyDescriptionAction
-					|| action instanceof OpenTaskListElementAction || action instanceof RenameAction) {
-				return true;
-			} else if (action instanceof GoIntoAction) {
-				BugzillaQueryCategory cat = (BugzillaQueryCategory) element;
-				if (cat.getHits().size() > 0) {
-					return true;
-				}
-			} else {
-				return false;
-			}
-		}
-		return false;
-	}
-}
-
-//public void itemOpened(ITaskListElement element) {
-//
-//		boolean offline = MylarTaskListPlugin.getPrefs().getBoolean(TaskListPreferenceConstants.WORK_OFFLINE);
-//
-//		if (element instanceof BugzillaTask) {
-//			BugzillaTask bugzillaTask = (BugzillaTask) element;
-//			TaskListUiUtil.openEditor(bugzillaTask);
-//			MylarTaskListPlugin.ReportOpenMode mode = MylarTaskListPlugin.getDefault().getReportMode();
-//			if (mode == MylarTaskListPlugin.ReportOpenMode.EDITOR) {
-//				bugzillaTask.openTaskInEditor(offline);
-//			} else if (mode == MylarTaskListPlugin.ReportOpenMode.INTERNAL_BROWSER) {
-//				if (offline) {
-//					MessageDialog.openInformation(null, "Unable to open bug",
-//							"Unable to open the selected bugzilla task since you are currently offline");
-//					return;
-//				}
-//				String title = "Bug #" + TaskRepositoryManager.getTaskIdAsInt(bugzillaTask.getHandleIdentifier());
-//				TaskListUiUtil.openUrl(title, title, bugzillaTask.getUrl());
-//			} else {
-//				// not supported
-//			}
-//		} else if (element instanceof BugzillaCustomQueryCategory) {
-//			BugzillaCustomQueryCategory queryCategory = (BugzillaCustomQueryCategory) element;
-//			BugzillaCustomQueryDialog sqd = new BugzillaCustomQueryDialog(Display.getCurrent().getActiveShell(),
-//					queryCategory.getQueryUrl(), queryCategory.getDescription(), queryCategory.getMaxHits() + "");
-//			if (sqd.open() == Dialog.OK) {
-//				queryCategory.setDescription(sqd.getName());
-//				queryCategory.setQueryUrl(sqd.getUrl());
-//				int maxHits = -1;
-//				try {
-//					maxHits = Integer.parseInt(sqd.getMaxHits());
-//				} catch (Exception e) {
-//				}
-//				queryCategory.setMaxHits(maxHits);
-//
-//				new SynchronizeReportsAction(queryCategory).run();
-//			}
-//		} else if (element instanceof BugzillaQueryCategory) {
-//			BugzillaQueryCategory queryCategory = (BugzillaQueryCategory) element;
-//			BugzillaQueryDialog queryDialog = new BugzillaQueryDialog(Display.getCurrent().getActiveShell(),
-//					queryCategory.getRepositoryUrl(), queryCategory.getQueryUrl(), queryCategory.getDescription(),
-//					queryCategory.getMaxHits() + "");
-//			if (queryDialog.open() == Dialog.OK) {
-//				queryCategory.setDescription(queryDialog.getName());
-//				queryCategory.setQueryUrl(queryDialog.getUrl());
-//				queryCategory.setRepositoryUrl(queryDialog.getRepository().getUrl().toExternalForm());
-//				int maxHits = -1;
-//				try {
-//					maxHits = Integer.parseInt(queryDialog.getMaxHits());
-//				} catch (Exception e) {
-//				}
-//				queryCategory.setMaxHits(maxHits);
-//
-//				new SynchronizeReportsAction(queryCategory).run();
-//			}
-//		} else if (element instanceof BugzillaQueryHit) {
-//			BugzillaQueryHit hit = (BugzillaQueryHit) element;
-//			MylarTaskListPlugin.ReportOpenMode mode = MylarTaskListPlugin.getDefault().getReportMode();
-//			if (mode == MylarTaskListPlugin.ReportOpenMode.EDITOR) {
-//				if (hit.getCorrespondingTask() != null) {
-//					hit.getCorrespondingTask().openTaskInEditor(offline);
-//				} else {
-//					if (offline) {
-//						MessageDialog.openInformation(null, "Unable to open bug",
-//								"Unable to open the selected bugzilla report since you are currently offline");
-//						return;
-//					}
-//					BugzillaOpenStructure open = new BugzillaOpenStructure(((BugzillaQueryHit) element)
-//							.getRepositoryUrl(), ((BugzillaQueryHit) element).getId(), -1);
-//					List<BugzillaOpenStructure> selectedBugs = new ArrayList<BugzillaOpenStructure>();
-//					selectedBugs.add(open);
-//					ViewBugzillaAction viewBugs = new ViewBugzillaAction("Display bugs in editor", selectedBugs);
-//					viewBugs.schedule();
-//				}
-//			}
-//			else if (mode == MylarTaskListPlugin.ReportOpenMode.INTERNAL_BROWSER) {
-//				if (offline) {
-//					MessageDialog.openInformation(null, "Unable to open bug",
-//							"Unable to open the selected bugzilla report since you are currently offline");
-//					return;
-//				}
-//				String title = "Bug #" + TaskRepositoryManager.getTaskIdAsInt(hit.getHandleIdentifier());
-//				TaskListUiUtil.openUrl(title, title, hit.getBugUrl());
-//			} else {
-//				// not supported
-//			}
-//		}
-//	}
-
-// public ITask getCorrespondingTask(IQueryHit queryHit) {
-// if (queryHit instanceof BugzillaQueryHit) {
-// BugzillaQueryHit hit = (BugzillaQueryHit) queryHit;
-// return hit.getOrCreateCorrespondingTask();
-// } else {
-// return null;
-// }
-// }
-
-// public void itemRemoved(ITaskListElement element, ITaskCategory category) {
-// if (element instanceof BugzillaTask) {
-// BugzillaTask task = (BugzillaTask) element;
-// if (category instanceof TaskCategory) {
-// MylarTaskListPlugin.getTaskListManager().removeFromCategoryAndRoot((TaskCategory)
-// category, task);
-// // category.removeTask(task);
-// } else {
-// String message = MESSAGE_CONFIRM_DELETE;
-// boolean deleteConfirmed =
-// MessageDialog.openQuestion(PlatformUI.getWorkbench().getActiveWorkbenchWindow()
-// .getShell(), "Confirm delete", message);
-// if (!deleteConfirmed)
-// return;
-// MylarTaskListPlugin.getTaskListManager().deleteTask(task);
-// }
-// }
-// }
-
-// private static final String MESSAGE_CONFIRM_DELETE = "Remove this report from
-// the task list, and discard any task context or local notes?";
-
-// public boolean deleteElement(ITaskListElement element) {
-// if (element instanceof BugzillaQueryCategory) {
-// boolean deleteConfirmed =
-// MessageDialog.openQuestion(PlatformUI.getWorkbench().getActiveWorkbenchWindow()
-// .getShell(), "Confirm delete", "Delete the selected query and all contained
-// tasks?");
-// if (!deleteConfirmed)
-// return false;
-// BugzillaQueryCategory query = (BugzillaQueryCategory) element;
-// MylarTaskListPlugin.getTaskListManager().deleteQuery(query);
-// } else if (element instanceof BugzillaTask) {
-// BugzillaTask task = (BugzillaTask) element;
-// if (task.isActive()) {
-// MessageDialog.openError(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(),
-// "Delete failed",
-// "Task must be deactivated in order to delete.");
-// return false;
-// }
-//
-// // String message = task.getDeleteConfirmationMessage();
-// boolean deleteConfirmed =
-// MessageDialog.openQuestion(PlatformUI.getWorkbench().getActiveWorkbenchWindow()
-// .getShell(), "Confirm delete", MESSAGE_CONFIRM_DELETE);
-// if (!deleteConfirmed)
-// return false;
-//
-// // task.removeReport();
-// MylarTaskListPlugin.getTaskListManager().deleteTask(task);
-// ContextCorePlugin.getContextManager().contextDeleted(task.getHandleIdentifier());
-// IWorkbenchPage page =
-// MylarTaskListPlugin.getDefault().getWorkbench().getActiveWorkbenchWindow()
-// .getActivePage();
-//
-// // if we couldn't get the page, get out of here
-// if (page == null)
-// return true;
-// try {
-// TaskListView.getDefault().closeTaskEditors(task, page);
-// } catch (Exception e) {
-// MylarStatusHandler.log(e, " deletion failed");
-// }
-// }
-// TaskListView.getDefault().getViewer().refresh();
-// return true;
-// }
-
-// public void dropItem(ITaskListElement element, TaskCategory cat) {
-// if (element instanceof BugzillaQueryHit) {
-// BugzillaQueryHit bugzillaHit = (BugzillaQueryHit) element;
-// if (bugzillaHit.getAssociatedTask() != null) {
-// MylarTaskListPlugin.getTaskListManager().moveToCategory(cat,
-// bugzillaHit.getAssociatedTask());
-// } else {
-// BugzillaTask bugzillaTask = new BugzillaTask(bugzillaHit, true);
-// bugzillaHit.setAssociatedTask(bugzillaTask);
-// MylarTaskListPlugin.getTaskListManager().moveToCategory(cat,
-// bugzillaTask);
-// BugzillaUiPlugin.getDefault().getBugzillaTaskListManager().addToBugzillaTaskRegistry(bugzillaTask);
-// }
-// }
-// }
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/BugzillaTaskListManager.java b/org.eclipse.mylyn.ide.dev/developer/src-old/BugzillaTaskListManager.java
deleted file mode 100644
index c47474f..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/BugzillaTaskListManager.java
+++ /dev/null
@@ -1,84 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004 - 2006 University Of British Columbia and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     University Of British Columbia - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.mylyn.internal.bugzilla.ui.tasklist;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import org.eclipse.mylyn.bugzilla.core.IBugzillaBug;
-import org.eclipse.mylyn.internal.bugzilla.core.IOfflineBugListener;
-import org.eclipse.mylyn.internal.bugzilla.ui.tasklist.BugzillaTask.BugReportSyncState;
-import org.eclipse.mylyn.internal.tasklist.TaskCategory;
-import org.eclipse.mylyn.internal.tasklist.TaskRepositoryManager;
-import org.eclipse.mylyn.internal.tasklist.ui.views.TaskListView;
-import org.eclipse.mylyn.tasklist.ITask;
-import org.eclipse.mylyn.tasklist.MylarTaskListPlugin;
-
-/**
- * @author Mik Kersten and Ken Sueda
- */
-public class BugzillaTaskListManager { //implements IOfflineBugListener {
-
-//	private Map<String, BugzillaTask> bugzillaTaskArchive = new HashMap<String, BugzillaTask>();
-//
-//	private TaskCategory cat = null;
-//
-//	public void addToBugzillaTaskArchive(BugzillaTask task) {
-//		if (bugzillaTaskArchive.get(task.getHandleIdentifier()) == null) {
-//			bugzillaTaskArchive.put(task.getHandleIdentifier(), task);
-//			if (cat != null) {
-//				cat.internalAddTask(task);
-//			}
-//		}
-//	}
-//
-//	public BugzillaTask getFromBugzillaTaskRegistry(String handle) {
-//		return bugzillaTaskArchive.get(handle);
-//	}
-//
-//	public Map<String, BugzillaTask> getBugzillaTaskRegistry() {
-//		return bugzillaTaskArchive;
-//	}
-//
-//	public void setTaskRegistyCategory(TaskCategory cat) {
-//		this.cat = cat;
-//	}
-//
-//	public void offlineStatusChange(IBugzillaBug bug, BugzillaOfflineStaus status) {
-//		BugReportSyncState state = null;
-//		if (status == BugzillaOfflineStaus.SAVED_WITH_OUTGOING_CHANGES) {
-//			state = BugReportSyncState.OUTGOING;
-//		} else if (status == BugzillaOfflineStaus.SAVED) {
-//			state = BugReportSyncState.OK;
-//		} else if (status == BugzillaOfflineStaus.SAVED_WITH_INCOMMING_CHANGES) {
-//			state = BugReportSyncState.INCOMMING;
-//		} else if (status == BugzillaOfflineStaus.CONFLICT) {
-//			state = BugReportSyncState.CONFLICT;
-//		}
-//		if (state == null) {
-//			// this means that we got a status that we didn't understand
-//			return;
-//		}
-//
-//		String handle = TaskRepositoryManager.getHandle(bug.getRepository(), bug.getId());
-//		ITask task = MylarTaskListPlugin.getTaskListManager().getTaskForHandle(handle, true);
-//		if (task != null && task instanceof BugzillaTask) {
-//			BugzillaTask bugTask = (BugzillaTask) task;
-//			bugTask.setSyncState(state);
-//			if (TaskListView.getDefault() != null && TaskListView.getDefault().getViewer() != null
-//					&& !TaskListView.getDefault().getViewer().getControl().isDisposed()) {
-//				TaskListView.getDefault().getViewer().refresh();
-//			}
-//		}
-//	}
-
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/ChartTest.java b/org.eclipse.mylyn.ide.dev/developer/src-old/ChartTest.java
deleted file mode 100644
index 3a09dd2..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/ChartTest.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004 - 2005 University Of British Columbia and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     University Of British Columbia - initial API and implementation
- *******************************************************************************/
-/*
- * Created on Jul 12, 2004
-  */
-package org.eclipse.mylyn.tests.chart;
-
-import javax.swing.JFrame;
-
-import org.jfree.chart.*;
-import org.jfree.chart.plot.PlotOrientation;
-import org.jfree.data.CategoryDataset;
-import org.jfree.data.DatasetUtilities;
-
-public class ChartTest extends JFrame {
-
-    private static final long serialVersionUID = 3256720663090640433L;
-
-    public static void main(final String[] args) {
-        final ChartTest demo = new ChartTest("Mylar Test");
-        demo.pack();
-        demo.setTitle("chart test");
-        demo.setVisible(true);
-    }
-    
-    public ChartTest(final String title) {
-        final CategoryDataset dataset =  createCategoryDataset();
-        final JFreeChart chart = createChart(dataset);
-        final ChartPanel chartPanel = new ChartPanel(chart);
-        chartPanel.setPreferredSize(new java.awt.Dimension(500, 270));
-        super.setContentPane(chartPanel);
-    }
-
-    private JFreeChart createChart(final CategoryDataset dataset) {
- 
-        final JFreeChart chart = ChartFactory.createStackedBarChart(
-            "",  // chart title
-            "Eclipse Usage",                  // domain axis label
-            "Time (minutes)",                     // range axis label
-            dataset,                     // data
-            PlotOrientation.VERTICAL,    // the plot orientation
-            true,                        // legend
-            true,                        // tooltips
-            false                        // urls
-        );
-        return chart;
-    }
-    
-    public static CategoryDataset createCategoryDataset() {
-
-        final double[][] data = new double[][]
-            {{10.0, 4.0, 15.0, 14.0, 0, 0, 0},
-             {5.0, 7.0, 14.0, 3.0, 0, 0, 0},
-             {6.0, 17.0, 12.0, 7.0, 0, 0, 0}};
-
-        String[] measurements = { "navigating", "editing", "other" };
-        String[] days = { "mon", "tue", "wed", "thu", "fri", "sat", "sun" };
-        
-        return DatasetUtilities.createCategoryDataset(measurements, days, data);
-    }
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/CommitContextAction.java b/org.eclipse.mylyn.ide.dev/developer/src-old/CommitContextAction.java
deleted file mode 100644
index 9713ea4..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/CommitContextAction.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004 - 2006 University Of British Columbia and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     University Of British Columbia - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.mylyn.internal.team.ui.actions;
-
-import java.util.List;
-
-import org.eclipse.core.resources.IResource;
-import org.eclipse.jface.action.IAction;
-import org.eclipse.jface.dialogs.MessageDialog;
-import org.eclipse.jface.viewers.ISelection;
-import org.eclipse.mylyn.context.core.MylarStatusHandler;
-import org.eclipse.mylyn.internal.tasks.ui.views.TaskListView;
-import org.eclipse.mylyn.internal.team.TeamRespositoriesManager;
-import org.eclipse.mylyn.tasks.core.ITask;
-import org.eclipse.mylyn.team.MylarTeamPlugin;
-import org.eclipse.mylyn.team.AbstractTeamRepositoryProvider;
-import org.eclipse.ui.IViewActionDelegate;
-import org.eclipse.ui.IViewPart;
-
-/**
- * @author Mik Kersten
- */
-public class CommitContextAction implements IViewActionDelegate {
-
-	public void init(IViewPart view) {
-		// TODO Auto-generated method stub
-	}
-
-	public void run(IAction action) {
-		ITask task = TaskListView.getFromActivePerspective().getSelectedTask();
-		IResource[] resources = MylarTeamPlugin.getDefault().getChangeSetManager().getResources(task);
-		if (resources == null || resources.length == 0) {
-			MessageDialog.openInformation(null, "Mylar Information",
-					"There are no interesting resources in the corresponding change set.\nRefer to Synchronize view.");
-			return;
-		}
-
-		List<AbstractTeamRepositoryProvider> providers = TeamRespositoriesManager.getInstance().getProviders();
-		for (Object element : providers) {
-			try {
-				AbstractTeamRepositoryProvider provider = (AbstractTeamRepositoryProvider) element;
-				if (provider.hasOutgoingChanges(resources)) {
-					provider.commit(resources);
-				}
-			} catch (Exception e) {
-				MylarStatusHandler.fail(e, "Could not commit context.", false);
-			}
-		}
-
-	}
-
-	public void selectionChanged(IAction action, ISelection selection) {
-		// ignore
-	}
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/DoiDecoratingTableLabelProvider.java b/org.eclipse.mylyn.ide.dev/developer/src-old/DoiDecoratingTableLabelProvider.java
deleted file mode 100644
index fcd88eb..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/DoiDecoratingTableLabelProvider.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004 - 2005 University Of British Columbia and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     University Of British Columbia - initial API and implementation
- *******************************************************************************/
-/*
- * Created on Jul 26, 2004
-  */
-package org.eclipse.mylyn.ui.views.support;
-
-import org.eclipse.jdt.core.IJavaElement;
-import org.eclipse.jdt.core.JavaCore;
-import org.eclipse.jdt.internal.ui.viewsupport.JavaUILabelProvider;
-import org.eclipse.jface.viewers.IFontProvider;
-import org.eclipse.jface.viewers.ITableLabelProvider;
-import org.eclipse.swt.graphics.*;
-
-import org.eclipse.mylyn.model.*;
-import org.eclipse.mylyn.ui.UiUtil;
-
-/**
- * @author Mik Kersten
- * @deprecated
- */
-public class DoiDecoratingTableLabelProvider extends JavaUILabelProvider 
-	implements ITableLabelProvider, IFontProvider {
-    
-	public String getColumnText(Object object, int index) {
-        if (object instanceof TaskscapeNode) {
-                TaskscapeNode node = (TaskscapeNode)object;
-                if (node.getKind().equals(ITaskscapeNode.Kind.Java)) {
-                    IJavaElement element = JavaCore.create(node.getElementHandle());
-                    if (element != null) {
-        		        String label = element.getElementName();
-        		        return label + " (" + node.getDegreeOfInterest().getDegreeOfInterest().getDoiValue() + ")";     
-                    } else {
-                        return "<missing element>";
-                    }
-                } else {
-                    return node.getElementHandle();
-                }
-	    } else if (object instanceof TaskscapeEdge){
-            TaskscapeEdge edge = (TaskscapeEdge)object;
-            return edge.toString();
-        } 
-        return "? " + object;
-	} 
-
-	public Image getColumnImage(Object object, int index) {
-        if (object instanceof TaskscapeNode) {
-            TaskscapeNode node = (TaskscapeNode)object;
-            if (node.getKind().equals(ITaskscapeNode.Kind.Java)) {
-                IJavaElement javaElement = JavaCore.create(node.getElementHandle());
-                return getImage(javaElement);
-            }
-        } 
-        return null;
-	}  
- 
-    public Color getBackground(Object element) {
-//        if (element instanceof IJavaElement) {
-//            return UiUtil.getBackgroundForElement((IJavaElement)element);
-//        } else {
-            return null;
-//        }
-    }
-
-    public Color getForeground(Object element) {
-//        if (element instanceof IJavaElement) {
-//            return UiUtil.getForegroundForElement((IJavaElement)element);
-//        } else {
-            return null;
-//        }
-    }
-    
-    public Font getFont(Object object) {
-        if (object instanceof IJavaElement) {
-            return UiUtil.getFontForElement((IJavaElement)object);
-        } else {
-            return null;
-        }
-    }
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/EditorListener.java b/org.eclipse.mylyn.ide.dev/developer/src-old/EditorListener.java
deleted file mode 100644
index 10eab69..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/EditorListener.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004 - 2005 University Of British Columbia and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     University Of British Columbia - initial API and implementation
- *******************************************************************************/
-/*
- * Created on Jun 24, 2004
- *
- * TODO To change the template for this generated file go to
- * Window - Preferences - Java - Code Style - Code Templates
- */
-package org.eclipse.mylyn.monitor;
-
-import org.eclipse.ui.IPartListener;
-import org.eclipse.ui.IWorkbenchPart;
-
-/**
- * @author beatmik
- *
- * TODO To change the template for this generated type comment go to
- * Window - Preferences - Java - Code Style - Code Templates
- */
-public class EditorListener implements IPartListener {
-		
-	public void partOpened(IWorkbenchPart part) {
-
-	}
-	
-	public void partDeactivated(IWorkbenchPart part) {
-	}
-	
-	public void partClosed(IWorkbenchPart part) {
-
-	}
-	
-	public void partActivated(IWorkbenchPart part) {
-
-	}
-	
-	public void partBroughtToTop(IWorkbenchPart part) {
-
-	}	
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/EditorPageListener.java b/org.eclipse.mylyn.ide.dev/developer/src-old/EditorPageListener.java
deleted file mode 100644
index 49e8679..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/EditorPageListener.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004 - 2005 University Of British Columbia and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     University Of British Columbia - initial API and implementation
- *******************************************************************************/
-/*
- * Created on Jun 24, 2004
- *
- * TODO To change the template for this generated file go to
- * Window - Preferences - Java - Code Style - Code Templates
- */
-package org.eclipse.mylyn.monitor;
-
-import org.eclipse.ui.IPageListener;
-import org.eclipse.ui.IWorkbenchPage;
-
-/**
- * @author Mik Kersten
- */
-public class EditorPageListener implements IPageListener {
-
-	public EditorPageListener() {
-		super();
-	}
-
-	public void pageActivated(IWorkbenchPage page) {
-
-	}
-
-	public void pageClosed(IWorkbenchPage page) {
-
-	}
-
-	public void pageOpened(IWorkbenchPage page) {
-
-	}
-
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/ExplorerFilteredTree.java b/org.eclipse.mylyn.ide.dev/developer/src-old/ExplorerFilteredTree.java
deleted file mode 100644
index e8a200e..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/ExplorerFilteredTree.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004 - 2006 University Of British Columbia and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     University Of British Columbia - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.mylyn.internal.browser.views;
-
-import org.eclipse.core.runtime.jobs.Job;
-import org.eclipse.mylyn.context.ui.InterestFilter;
-import org.eclipse.mylyn.internal.tasks.ui.views.AbstractMylarFilteredTree;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.DisposeEvent;
-import org.eclipse.swt.events.DisposeListener;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.ui.dialogs.PatternFilter;
-
-/**
- * @author Mik Kersten
- */
-public class ExplorerFilteredTree extends AbstractMylarFilteredTree {
-
-	private InterestFilter suppressedFilter = null;
-    
-    public ExplorerFilteredTree(String viewId, Composite parent, int treeStyle, PatternFilter filter) {
-		super(parent, treeStyle, filter);
-//		this.viewId = viewId;
-	}
-	
-    /**
-     * Create the tree.  Subclasses may override.
-     * 
-     * @param parent parent <code>Composite</code>
-     * @param style SWT style bits used to create the tree
-     * @return the tree
-     */
-    protected Control createTreeControl(Composite parent, int style) {
-//        treeViewer = new ResourceTreeViewer(viewId, parent, style);
-        GridData data = new GridData(SWT.FILL, SWT.FILL, true, true);
-        treeViewer.getControl().setLayoutData(data);
-        treeViewer.getControl().addDisposeListener(new DisposeListener(){
-        	/* (non-Javadoc)
-        	 * @see org.eclipse.swt.events.DisposeListener#widgetDisposed(org.eclipse.swt.events.DisposeEvent)
-        	 */
-        	public void widgetDisposed(DisposeEvent e) {
-        		Job refreshJob = getRefreshJob();
-        		if (refreshJob != null) {
-        			getRefreshJob().cancel();
-        		}
-        	}
-        });
-
-        treeViewer.addFilter(getPatternFilter());  
-        return treeViewer.getControl();
-    }
-
-	@Override
-	protected Composite createStatusComposite(Composite container) {
-		return null;
-	}
-}
\ No newline at end of file
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/FilteringNavigatorView.java b/org.eclipse.mylyn.ide.dev/developer/src-old/FilteringNavigatorView.java
deleted file mode 100644
index dbfbff7..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/FilteringNavigatorView.java
+++ /dev/null
@@ -1,44 +0,0 @@
-package org.eclipse.mylyn.internal.browser.views;
-///*******************************************************************************
-// * Copyright (c) 2004 - 2006 University Of British Columbia and others.
-// * All rights reserved. This program and the accompanying materials
-// * are made available under the terms of the Eclipse Public License v1.0
-// * which accompanies this distribution, and is available at
-// * http://www.eclipse.org/legal/epl-v10.html
-// *
-// * Contributors:
-// *     University Of British Columbia - initial API and implementation
-// *******************************************************************************/
-//
-//package org.eclipse.mylyn.internal.browser.views;
-//
-//import org.eclipse.jface.viewers.TreeViewer;
-//import org.eclipse.mylyn.internal.tasks.ui.TaskListPatternFilter;
-//import org.eclipse.swt.SWT;
-//import org.eclipse.swt.widgets.Composite;
-//import org.eclipse.ui.dialogs.FilteredTree;
-//import org.eclipse.ui.views.navigator.ResourceNavigator;
-//
-///**
-// * @author Mik Kersten
-// */
-//public class ExplorerView extends ResourceNavigator {
-//
-//	public static final String ID = "org.eclipse.mylyn.explorer.ui.explorer";
-//	
-//	protected TreeViewer createViewer(Composite parent) {
-//		FilteredTree filteredTree = new ExplorerFilteredTree(ID, parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL,
-//				new TaskListPatternFilter());
-//
-//		TreeViewer viewer = filteredTree.getViewer();
-//
-//		// NOTE: below from super
-//		viewer.setUseHashlookup(true);
-//		initContentProvider(viewer);
-//		initLabelProvider(viewer);
-//		initFilters(viewer);
-//		initListeners(viewer);
-//
-//		return viewer;
-//	}
-//}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/FluidPrototyping.java b/org.eclipse.mylyn.ide.dev/developer/src-old/FluidPrototyping.java
deleted file mode 100644
index 920b7cc..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/FluidPrototyping.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004 - 2005 University Of British Columbia and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     University Of British Columbia - initial API and implementation
- *******************************************************************************/
-/*
- * Created on Jan 31, 2005
- */
-
-/**
- * @author Mik Kersten
- */
-public class Foo {
-    
-    int y = 0;
-    
-    public void setY(int y) {
-        this.y = y;
-        Display.update();
-    }
-    
-    public void setX(int x) { }
-    
-    public void setP1(<field> p) { }
-    
-    public void setP2(<field> p) { } 
-
-}
-
-class <field> { } 
-
-class Display { static void update() {}  }
-
-class Point { } 
-
-class Line { } 
\ No newline at end of file
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/IMapListener.java b/org.eclipse.mylyn.ide.dev/developer/src-old/IMapListener.java
deleted file mode 100644
index b742277..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/IMapListener.java
+++ /dev/null
@@ -1,23 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004 - 2005 University Of British Columbia and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     University Of British Columbia - initial API and implementation
- *******************************************************************************/
-/*
- * Created on Jul 8, 2004
-  */
-package org.eclipse.mylyn.monitor;
-
-/**
- * @author Mik Kersten
- */
-public interface IMapListener {
-
-    public void mapUpdated();
-    
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/Interest.java b/org.eclipse.mylyn.ide.dev/developer/src-old/Interest.java
deleted file mode 100644
index 4c165bf..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/Interest.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004 - 2005 University Of British Columbia and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     University Of British Columbia - initial API and implementation
- *******************************************************************************/
-/*
- * Created on Jun 23, 2004
- */
-package org.eclipse.mylyn.model;
-
-import java.io.Serializable;
-
-/**
- * @author Mik Kersten
- */
-public class Interest implements Serializable {
-
-	private float value = 10;
-	
-	public float getValue() {
-		return value;
-	}
-	
-	public void setValue(float value) {
-		this.value = value;
-	}
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/JavaStackTraceHyperlinkAdapter.java b/org.eclipse.mylyn.ide.dev/developer/src-old/JavaStackTraceHyperlinkAdapter.java
deleted file mode 100644
index 0a1b068..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/JavaStackTraceHyperlinkAdapter.java
+++ /dev/null
@@ -1,144 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004 - 2006 University Of British Columbia and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     University Of British Columbia - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.mylyn.internal.java.ui;
-
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.debug.ui.IDebugModelPresentation;
-import org.eclipse.jdt.internal.debug.ui.JDIDebugUIPlugin;
-import org.eclipse.jdt.internal.debug.ui.actions.OpenTypeAction;
-import org.eclipse.jface.dialogs.MessageDialog;
-import org.eclipse.jface.text.BadLocationException;
-import org.eclipse.jface.text.IDocument;
-import org.eclipse.jface.text.IRegion;
-import org.eclipse.ui.IEditorInput;
-import org.eclipse.ui.IEditorPart;
-import org.eclipse.ui.PlatformUI;
-import org.eclipse.ui.forms.events.HyperlinkAdapter;
-import org.eclipse.ui.texteditor.IDocumentProvider;
-import org.eclipse.ui.texteditor.ITextEditor;
-
-/**
- * @author Robert Elves
- */
-public final class JavaStackTraceHyperlinkAdapter extends HyperlinkAdapter {
-	public void linkActivated(org.eclipse.ui.forms.events.HyperlinkEvent e) {
-		String typeName;
-		int lineNumber;
-		try {
-			String linkText = (String) e.getHref();
-			typeName = getTypeName(linkText);
-			lineNumber = getLineNumber(linkText);
-	
-			// documents start at 0
-			if (lineNumber > 0) {
-				lineNumber--;
-			}
-			Object sourceElement = getSourceElement(typeName);
-			if (sourceElement != null) {
-				IDebugModelPresentation presentation = JDIDebugUIPlugin.getDefault()
-						.getModelPresentation();
-				IEditorInput editorInput = presentation.getEditorInput(sourceElement);
-				if (editorInput != null) {
-					String editorId = presentation.getEditorId(editorInput, sourceElement);
-					if (editorId != null) {
-						IEditorPart editorPart = JDIDebugUIPlugin.getActivePage().openEditor(
-								editorInput, editorId);
-						if (editorPart instanceof ITextEditor && lineNumber >= 0) {
-							ITextEditor textEditor = (ITextEditor) editorPart;
-							IDocumentProvider provider = textEditor.getDocumentProvider();
-							provider.connect(editorInput);
-							IDocument document = provider.getDocument(editorInput);
-							try {
-								IRegion line = document.getLineInformation(lineNumber);
-								textEditor.selectAndReveal(line.getOffset(), line.getLength());
-							} catch (BadLocationException e1) {
-								MessageDialog.openInformation(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(), "Open Type", "Failed to open type.");
-							}
-							provider.disconnect(editorInput);
-						}
-						return;
-					}
-				}
-			}
-			// did not find source
-			MessageDialog.openInformation(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(), "Open Type",
-					"Type could not be located.");
-		} catch (CoreException e1) {
-			MessageDialog.openInformation(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(), "Open Type",
-					"Failed to open type.");
-			return;
-		}
-	}
-	
-	// adapted from JavaStackTraceHyperlink
-	private Object getSourceElement(String typeName) throws CoreException {
-		Object result = null;
-		result = OpenTypeAction.findTypeInWorkspace(typeName);
-		// }
-		return result;
-	}
-
-	// adapted from JavaStackTraceHyperlink
-	private String getTypeName(String linkText) {
-		int start = linkText.indexOf('(');
-		int end = linkText.indexOf(':');
-		if (start >= 0 && end > start) {
-
-			// get File name (w/o .java)
-			String typeName = linkText.substring(start + 1, end);
-			typeName.indexOf(".");
-			typeName = typeName.substring(0, typeName.indexOf("."));
-
-			String qualifier = linkText.substring(0, start);
-			// remove the method name
-			start = qualifier.lastIndexOf('.');
-
-			if (start >= 0) {
-				// remove the class name
-				start = new String((String) qualifier.subSequence(0, start)).lastIndexOf('.');
-				if (start == -1) {
-					start = 0; // default package
-				}
-			}
-
-			if (start >= 0) {
-				qualifier = qualifier.substring(0, start);
-			}
-
-			if (qualifier.length() > 0) {
-				typeName = qualifier + "." + typeName; //$NON-NLS-1$
-			}
-			return typeName;
-		}
-
-		return "error"; // TODO: Complain
-	}
-
-	// adapted from JavaStackTraceHyperlink
-	private int getLineNumber(String linkText) throws CoreException {
-		int index = linkText.lastIndexOf(':');
-		if (index >= 0) {
-			String numText = linkText.substring(index + 1);
-			index = numText.indexOf(')');
-			if (index >= 0) {
-				numText = numText.substring(0, index);
-			}
-			try {
-				return Integer.parseInt(numText);
-			} catch (NumberFormatException e) {
-				throw new CoreException(null);
-			}
-		}
-
-		throw new CoreException(null);
-	}
-}
\ No newline at end of file
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/MylarJavaElementDescriptor.java b/org.eclipse.mylyn.ide.dev/developer/src-old/MylarJavaElementDescriptor.java
deleted file mode 100644
index 8965565..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/MylarJavaElementDescriptor.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004 - 2006 University Of British Columbia and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     University Of British Columbia - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.mylyn.internal.java.ui.editor;
-
-import org.eclipse.jdt.internal.ui.JavaPlugin;
-import org.eclipse.jface.resource.CompositeImageDescriptor;
-import org.eclipse.jface.resource.ImageDescriptor;
-import org.eclipse.jface.util.Assert;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.graphics.ImageData;
-import org.eclipse.swt.graphics.Point;
-
-/**
- * @author Shawn Minto
- */
-public class MylarJavaElementDescriptor extends CompositeImageDescriptor {
-
-	private Image baseImage;
-
-	private ImageDescriptor overlay;
-
-	private Point fSize;
-
-	public MylarJavaElementDescriptor(Image baseImage, ImageDescriptor overlay, Point size) {
-		this.baseImage = baseImage;
-		this.overlay = overlay;
-		setImageSize(size);
-	}
-
-	@Override
-	protected void drawCompositeImage(int width, int height) {
-		if (baseImage == null)
-			return;
-		ImageData bg = baseImage.getImageData();
-
-		drawImage(bg, 0, 0);
-
-		// Point size= getSize();
-		ImageData data = getImageData(overlay);
-		drawImage(data, data.width, bg.height - data.height);
-	}
-
-	private ImageData getImageData(ImageDescriptor descriptor) {
-		ImageData data = descriptor.getImageData(); // see bug 51965:
-													// getImageData can return
-													// null
-		if (data == null) {
-			data = DEFAULT_IMAGE_DATA;
-			JavaPlugin.logErrorMessage("Image data not available: " + descriptor.toString()); //$NON-NLS-1$
-		}
-		return data;
-	}
-
-	/**
-	 * Sets the size of the image created by calling <code>createImage()</code>.
-	 * 
-	 * @param size
-	 *            the size of the image returned from calling
-	 *            <code>createImage()</code>
-	 * @see ImageDescriptor#createImage()
-	 */
-	public void setImageSize(Point size) {
-		Assert.isNotNull(size);
-		Assert.isTrue(size.x >= 0 && size.y >= 0);
-		fSize = size;
-	}
-
-	@Override
-	protected Point getSize() {
-		return new Point(fSize.x, fSize.y);
-	}
-
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/NewLocalTaskAction.java b/org.eclipse.mylyn.ide.dev/developer/src-old/NewLocalTaskAction.java
deleted file mode 100644
index de71565..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/NewLocalTaskAction.java
+++ /dev/null
@@ -1,109 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004 - 2006 University Of British Columbia and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     University Of British Columbia - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.mylyn.internal.tasks.ui.actions;
-
-
-import org.eclipse.jface.action.Action;
-import org.eclipse.jface.action.IAction;
-import org.eclipse.jface.dialogs.MessageDialog;
-import org.eclipse.jface.viewers.ISelection;
-import org.eclipse.jface.viewers.IStructuredSelection;
-import org.eclipse.mylyn.internal.tasks.core.LocalRepositoryConnector;
-import org.eclipse.mylyn.internal.tasks.ui.ITasksUiConstants;
-import org.eclipse.mylyn.internal.tasks.ui.TasksUiImages;
-import org.eclipse.mylyn.internal.tasks.ui.views.TaskInputDialog;
-import org.eclipse.mylyn.internal.tasks.ui.views.TaskListView;
-import org.eclipse.mylyn.tasks.core.ITask;
-import org.eclipse.mylyn.tasks.core.Task;
-import org.eclipse.mylyn.tasks.core.TaskCategory;
-import org.eclipse.mylyn.tasks.ui.TaskListManager;
-import org.eclipse.mylyn.tasks.ui.TasksUiPlugin;
-import org.eclipse.mylyn.tasks.ui.TasksUiUtil;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.ui.IViewActionDelegate;
-import org.eclipse.ui.IViewPart;
-
-/**
- * @author Mik Kersten
- */
-@Deprecated
-public class NewLocalTaskAction extends Action implements IViewActionDelegate {
-
-	public static final String ID = "org.eclipse.mylyn.tasks.ui.actions.create.task";
-
-	public NewLocalTaskAction() {
-		this(null);
-	}
-
-	public NewLocalTaskAction(TaskListView view) {
-		setText(TaskInputDialog.LABEL_SHELL);
-		setToolTipText(TaskInputDialog.LABEL_SHELL);
-		setId(ID);
-		setImageDescriptor(TasksUiImages.TASK_NEW);
-	}
-
-	public void init(IViewPart view) {
-	}
-
-	public void run(IAction action) {
-		run();
-	}
-
-	@Override
-	public void run() {
-		Task newTask = new Task(TasksUiPlugin.getTaskListManager().genUniqueTaskHandle(), LocalRepositoryConnector.DEFAULT_SUMMARY);
-		TaskListManager.scheduleNewTask(newTask);
-
-		Object selectedObject = null;
-		TaskListView view = TaskListView.getFromActivePerspective();
-		if (view != null) {
-			selectedObject = ((IStructuredSelection) view.getViewer().getSelection()).getFirstElement();
-		}
-		if (selectedObject instanceof TaskCategory) {
-			TasksUiPlugin.getTaskList().addTask(newTask, (TaskCategory) selectedObject);
-		} else if (selectedObject instanceof ITask) {
-			ITask task = (ITask) selectedObject;
-			if (task.getContainer() instanceof TaskCategory) {
-				TasksUiPlugin.getTaskList().addTask(newTask, task.getContainer());
-			} else if (view != null && view.getDrilledIntoCategory() instanceof TaskCategory) {
-				TasksUiPlugin.getTaskList().addTask(newTask,
-						view.getDrilledIntoCategory());
-			} else {
-				TasksUiPlugin.getTaskList().addTask(newTask,
-						TasksUiPlugin.getTaskList().getUncategorizedCategory());
-			}
-		} else if (view != null && view.getDrilledIntoCategory() instanceof TaskCategory) {
-			TasksUiPlugin.getTaskList().addTask(newTask,
-					view.getDrilledIntoCategory());
-		} else {
-			if (view != null && view.getDrilledIntoCategory() != null) {
-				MessageDialog
-						.openInformation(Display.getCurrent().getActiveShell(), ITasksUiConstants.TITLE_DIALOG,
-								"The new task has been added to the root of the list, since tasks can not be added to a query.");
-			}
-			TasksUiPlugin.getTaskList().addTask(newTask,
-					TasksUiPlugin.getTaskList().getUncategorizedCategory());
-		}
-
-		TasksUiUtil.openEditor(newTask, true);
-		
-		// if (view != null) {
-		// view.getViewer().refresh();
-		// view.setInRenameAction(true);
-		// view.getViewer().editElement(newTask, 4);
-		// view.setInRenameAction(false);
-		// }
-	}
-
-	public void selectionChanged(IAction action, ISelection selection) {
-	}
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/PackageExplorerManager.java b/org.eclipse.mylyn.ide.dev/developer/src-old/PackageExplorerManager.java
deleted file mode 100644
index 90caa1d..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/PackageExplorerManager.java
+++ /dev/null
@@ -1,164 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004 - 2006 University Of British Columbia and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     University Of British Columbia - initial API and implementation
- *******************************************************************************/
-package org.eclipse.mylyn.internal.java;
-
-import java.util.Arrays;
-import java.util.List;
-
-import org.eclipse.jdt.core.ICompilationUnit;
-import org.eclipse.jdt.core.IJavaElement;
-import org.eclipse.jdt.core.IMember;
-import org.eclipse.jdt.internal.ui.actions.SelectionConverter;
-import org.eclipse.jdt.internal.ui.javaeditor.JavaEditor;
-import org.eclipse.jdt.internal.ui.packageview.PackageExplorerPart;
-import org.eclipse.jface.text.TextSelection;
-import org.eclipse.jface.viewers.ISelection;
-import org.eclipse.jface.viewers.StructuredSelection;
-import org.eclipse.jface.viewers.TreeViewer;
-import org.eclipse.jface.viewers.ViewerFilter;
-import org.eclipse.mylyn.context.core.ContextCorePlugin;
-import org.eclipse.mylyn.context.core.IMylarContext;
-import org.eclipse.mylyn.context.core.IMylarContextListener;
-import org.eclipse.mylyn.context.core.IMylarElement;
-import org.eclipse.mylyn.context.core.MylarStatusHandler;
-import org.eclipse.mylyn.internal.context.ui.actions.AbstractFocusViewAction;
-import org.eclipse.mylyn.internal.java.ui.JavaDeclarationsFilter;
-import org.eclipse.ui.ISelectionListener;
-import org.eclipse.ui.IWorkbenchPart;
-
-/**
- * Sets member selections on the Package Explorer when appropriate, and manages
- * tree expansion state.
- * 
- * @author Mik Kersten
- */
-public class PackageExplorerManager implements IMylarContextListener, ISelectionListener {
-
-	public void selectionChanged(IWorkbenchPart part, ISelection changedSelection) {
-		if (!(part instanceof PackageExplorerPart)) {
-			return;
-		}		
-		AbstractFocusViewAction applyAction = AbstractFocusViewAction.getActionForPart((PackageExplorerPart)part);		
-		if (!ContextCorePlugin.getContextManager().isContextActive()
-			|| (applyAction != null && !applyAction.isChecked())) {
-			return;
-		}
-		try {
-			Object elementToSelect = null;
-			if (changedSelection instanceof TextSelection && part instanceof JavaEditor) {
-				TextSelection textSelection = (TextSelection) changedSelection;
-				IJavaElement javaElement = SelectionConverter.resolveEnclosingElement((JavaEditor) part, textSelection);
-				if (javaElement != null)
-					elementToSelect = javaElement;
-			} else if (changedSelection instanceof TextSelection) {
-//				if (part instanceof EditorPart) {
-//					elementToSelect = ((EditorPart) part).getEditorInput().getAdapter(IResource.class);
-//				}
-			} else {
-				return;
-			}
-
-			if (elementToSelect != null) {
-				PackageExplorerPart packageExplorer = PackageExplorerPart.getFromActivePerspective();
-				if (packageExplorer != null) {
-					TreeViewer viewer = packageExplorer.getTreeViewer();
-					StructuredSelection currentSelection = (StructuredSelection)viewer.getSelection();
-					if (currentSelection.size() <= 1) {
-						boolean membersFilteredMode = false;
-						for (ViewerFilter filter : Arrays.asList(viewer.getFilters())) {
-							if (filter instanceof JavaDeclarationsFilter)
-								membersFilteredMode = true;
-						}
-						if (membersFilteredMode) {
-							if (elementToSelect instanceof IMember) {
-								ICompilationUnit toSelect = ((IMember) elementToSelect).getCompilationUnit();
-								if (toSelect != null) {
-									viewer.setSelection(new StructuredSelection(toSelect), true);
-								}
-							}
-						} else if (elementToSelect != null) {
-							if (!elementToSelect.equals(currentSelection.getFirstElement())) {
-								viewer.setSelection(new StructuredSelection(elementToSelect), true);
-							}
-						}
-					}
-//						if (elementToSelect != null
-//								&& MylarJavaPlugin.getDefault().getPluginPreferences().getBoolean(
-//										MylarJavaPrefConstants.PACKAGE_EXPLORER_AUTO_EXPAND)) {
-//							viewer.expandAll();
-//						}
-				}
-			}
-		} catch (Throwable t) {
-			MylarStatusHandler.log(t, "Could not update package explorer");
-		}
-	}
-
-	public void contextActivated(IMylarContext taskscape) {
-//		try {
-//			if (ContextCorePlugin.getContextManager().isContextActive()
-//					&& FocusPackageExplorerAction.getDefault() != null
-//					&& FocusPackageExplorerAction.getDefault().isChecked()) {
-//
-//				PackageExplorerPart packageExplorer = PackageExplorerPart.getFromActivePerspective();
-//				if (packageExplorer != null) { 
-//					packageExplorer.setLinkingEnabled(false);
-//					packageExplorer.getTreeViewer().expandAll();
-//				}
-//			}
-//		} catch (Throwable t) {
-//			MylarStatusHandler.log(t, "Could not update package explorer");
-//		}
-	}
-
-	public void contextDeactivated(IMylarContext taskscape) {
-		PackageExplorerPart packageExplorer = PackageExplorerPart.getFromActivePerspective();
-		if (packageExplorer != null) {
-			packageExplorer.getTreeViewer().collapseAll();
-		}
-	}
-
-//	private boolean isInLinkToEditorMode(PackageExplorerPart packageExplorer) {
-//		return JavaPlugin.getDefault().getPreferenceStore().getBoolean(PreferenceConstants.LINK_PACKAGES_TO_EDITOR);
-//	}
-	
-	public void interestChanged(List<IMylarElement> nodes) {
-		// ignore
-	}
-
-	public void revealInteresting() {
-		// ignore
-	}
-
-	public void presentationSettingsChanging(UpdateKind kind) {
-		// ignore
-	}
-
-	public void presentationSettingsChanged(UpdateKind kind) {
-		// ignore
-	}
-
-	public void landmarkAdded(IMylarElement node) {
-		// ignore
-	}
-
-	public void landmarkRemoved(IMylarElement node) {
-		// ignore
-	}
-
-	public void nodeDeleted(IMylarElement node) {
-		// ignore
-	}
-
-	public void edgesChanged(IMylarElement node) {
-		// ignore
-	}
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/ProblemsListInterestSorter.java b/org.eclipse.mylyn.ide.dev/developer/src-old/ProblemsListInterestSorter.java
deleted file mode 100644
index d3dd6f0..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/ProblemsListInterestSorter.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004 - 2006 University Of British Columbia and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     University Of British Columbia - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.mylyn.internal.ide.ui;
-
-import org.eclipse.core.resources.IMarker;
-import org.eclipse.jface.viewers.Viewer;
-import org.eclipse.mylyn.context.core.IMylarElement;
-import org.eclipse.mylyn.context.core.IMylarStructureBridge;
-import org.eclipse.mylyn.context.core.InterestComparator;
-import org.eclipse.mylyn.context.core.ContextCorePlugin;
-import org.eclipse.ui.views.markers.internal.FieldFolder;
-import org.eclipse.ui.views.markers.internal.FieldLineNumber;
-import org.eclipse.ui.views.markers.internal.FieldResource;
-import org.eclipse.ui.views.markers.internal.FieldSeverityAndMessage;
-import org.eclipse.ui.views.markers.internal.IField;
-import org.eclipse.ui.views.markers.internal.ProblemMarker;
-import org.eclipse.ui.views.markers.internal.TableSorter;
-
-/**
- * @author Mik Kersten
- */
-public class ProblemsListInterestSorter extends TableSorter {
-
-	// COPIED: from ProblemView
-	private final static int ASCENDING = TableSorter.ASCENDING;
-
-	private final static int DESCENDING = TableSorter.DESCENDING;
-
-	private final static int SEVERITY = 0;
-
-	private final static int DOI = 1;
-
-	private final static int DESCRIPTION = 2;
-
-	private final static int RESOURCE = 3;
-
-	private final static int[] DEFAULT_PRIORITIES = { SEVERITY, DOI, DESCRIPTION, RESOURCE };
-
-	private final static int[] DEFAULT_DIRECTIONS = { DESCENDING, // severity
-			ASCENDING, // folder
-			ASCENDING, // resource
-			ASCENDING }; // location
-
-	private final static IField[] VISIBLE_FIELDS = { new FieldSeverityAndMessage(), new FieldFolder(), new FieldResource(),
-			new FieldLineNumber() };
-
-	// END COPY
-
-	public ProblemsListInterestSorter() {
-		super(VISIBLE_FIELDS, DEFAULT_PRIORITIES, DEFAULT_DIRECTIONS);
-	}
-
-	protected InterestComparator<IMylarElement> interestComparator = new InterestComparator<IMylarElement>();
-
-	@Override
-	public int compare(Viewer viewer, Object obj1, Object obj2) {
-		if (obj1 instanceof ProblemMarker && obj1 instanceof ProblemMarker) {
-			ProblemMarker marker1 = (ProblemMarker) obj1;
-			ProblemMarker marker2 = (ProblemMarker) obj2;
-			if (marker1.getSeverity() == IMarker.SEVERITY_ERROR && marker2.getSeverity() < IMarker.SEVERITY_ERROR) {
-				return -1;
-			} else if (marker2.getSeverity() == IMarker.SEVERITY_ERROR
-					&& marker1.getSeverity() < IMarker.SEVERITY_ERROR) {
-				return 1;
-			} else {
-				if (ContextCorePlugin.getContextManager().isContextActive()) {
-					IMylarStructureBridge bridge = ContextCore.getStructureBridge(
-							marker1.getResource().getFileExtension());
-					IMylarElement node1 = ContextCorePlugin.getContextManager().getElement(
-							bridge.getHandleForOffsetInObject(marker1, 0));
-					IMylarElement node2 = ContextCorePlugin.getContextManager().getElement(
-							bridge.getHandleForOffsetInObject(marker2, 0));
-					return interestComparator.compare(node1, node2);
-				}
-			}
-		}
-		return super.compare(viewer, obj1, obj2);
-	}
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/RelativePathUtil.java b/org.eclipse.mylyn.ide.dev/developer/src-old/RelativePathUtil.java
deleted file mode 100644
index 408917e..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/RelativePathUtil.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004 - 2006 University Of British Columbia and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     University Of British Columbia - initial API and implementation
- *******************************************************************************/
-package org.eclipse.mylyn.internal.tasklist;
-
-public class RelativePathUtil {
-	public static String findRelativePath(String baseDirectory, String filePath) {
-		if (filePath.startsWith(baseDirectory)) {
-			return filePath.substring(baseDirectory.length(), filePath.lastIndexOf('.'));
-		} else {
-			StringBuffer result = new StringBuffer(filePath.length());
-			String[] rootFolders = baseDirectory.split("/");
-			String[] pathFolders = filePath.split("/");
-			int diff = 0;
-			for (int i = 0; i < pathFolders.length; i++) {
-				if (!rootFolders[i].equals(pathFolders[i])) {
-					diff = i;
-					while (i < rootFolders.length) {
-						result.append('.');
-						result.append('.');
-						result.append('/');
-						i++;
-					}
-					while (diff < pathFolders.length - 1) {
-						result.append(pathFolders[diff]);
-						diff++;
-					}
-					result.append(pathFolders[diff].substring(0, pathFolders[diff].lastIndexOf('.')));
-				}
-			}
-			return result.toString();
-		}
-	}
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/RemoveFromContextAction.java b/org.eclipse.mylyn.ide.dev/developer/src-old/RemoveFromContextAction.java
deleted file mode 100644
index 5fe86fa..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/RemoveFromContextAction.java
+++ /dev/null
@@ -1,105 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004 - 2006 University Of British Columbia and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     University Of British Columbia - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.mylyn.internal.context.ui.actions;
-
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Set;
-
-import org.eclipse.core.resources.IResource;
-import org.eclipse.core.runtime.IAdaptable;
-import org.eclipse.mylyn.context.core.AbstractContextStructureBridge;
-import org.eclipse.mylyn.context.core.ContextCorePlugin;
-import org.eclipse.mylyn.context.core.IInteractionElement;
-import org.eclipse.mylyn.context.ui.InterestFilter;
-import org.eclipse.mylyn.internal.tasks.ui.TasksUiImages;
-import org.eclipse.ui.actions.BaseSelectionListenerAction;
-import org.eclipse.ui.internal.navigator.NavigatorContentServiceContentProvider;
-import org.eclipse.ui.navigator.CommonViewer;
-
-/**
- * 
- * @author Mik Kersten
- */
-public class RemoveFromContextAction extends BaseSelectionListenerAction {
-
-	public static final String ID = "org.eclipse.mylyn.context.ui.actions.delete";
-
-	private CommonViewer commonViewer;
-	
-	private InterestFilter interestFilter;
-	
-	public RemoveFromContextAction(CommonViewer commonViewer, InterestFilter interestFilter) {
-		super("Remove from Context");
-		setId(ID);
-		setImageDescriptor(TasksUiImages.REMOVE);
-		this.commonViewer = commonViewer;
-		this.interestFilter = interestFilter;
-	}
-
-	@Override
-	public void run() {
-		Set<IInteractionElement> toRemove = new HashSet<IInteractionElement>();
-		
-		for (Iterator<?> iterator = super.getStructuredSelection().iterator(); iterator.hasNext();) {
-			Object object = iterator.next();
-			collectChildren(toRemove, object);
-		}
-		
-		for (IInteractionElement element : toRemove) {
-			ContextCorePlugin.getContextManager().delete(element);
-		}
-		if (commonViewer != null) {
-			commonViewer.refresh();
-		}
- 	}
-
-	private void collectChildren(Set<IInteractionElement> toRemove, Object object) {
-		IInteractionElement element = resolveElement(object);
-		if (element != null) {
-			toRemove.add(element);
-		}
-
-		Object[] children = ((NavigatorContentServiceContentProvider)commonViewer.getContentProvider()).getChildren(object);
-		for (int i = 0; i < children.length; i++) {
-			Object child = children[i];
-			if (interestFilter.select(commonViewer, object, child)) {
-				collectChildren(toRemove, child);
-			}
-		}
-	}
-
-	private IInteractionElement resolveElement(Object object) {
-		IInteractionElement element = null;
-		if (object instanceof IInteractionElement) {
-			element = (IInteractionElement)object;
-		} else {
-			AbstractContextStructureBridge bridge = ContextCore.getStructureBridge(object);
-			if (bridge.getContentType() == null) {
-				// try to resolve the resource
-				if (object instanceof IAdaptable) {
-					Object adapted = ((IAdaptable) object).getAdapter(IResource.class);
-					if (adapted instanceof IResource) {
-						object = adapted;
-					}
-					bridge = ContextCore.getStructureBridge(object);
-				} 
-			}
-
-			if (!object.getClass().getName().equals(Object.class.getCanonicalName())) {
-				String handle = bridge.getHandleIdentifier(object);
-				element = ContextCorePlugin.getContextManager().getElement(handle);
-			} 
-		}
-		return element;
-	}
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/RepositoryAwareStatusHandler.java b/org.eclipse.mylyn.ide.dev/developer/src-old/RepositoryAwareStatusHandler.java
deleted file mode 100644
index 8310f6d..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/RepositoryAwareStatusHandler.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004, 2008 Tasktop Technologies and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     Tasktop Technologies - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.mylyn.internal.tasks.ui;
-
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.Platform;
-import org.eclipse.jface.dialogs.ErrorDialog;
-import org.eclipse.swt.widgets.Shell;
-import org.eclipse.ui.PlatformUI;
-
-/**
- * @deprecated Do not use. This class is pending for removal: see bug 237552.
- */
-@Deprecated
-public class RepositoryAwareStatusHandler {
-
-	protected static final String ERROR_MESSAGE = "Please report the following error at:\n"
-			+ "http://bugs.eclipse.org/bugs/enter_bug.cgi?product=Mylyn\n\n"
-			+ "Or via the popup menu in the Error Log view (see Window -> Show View)";
-
-	/**
-	 * Used to ensure that only one dialog is open.
-	 */
-	private static boolean errorDialogOpen = false;
-
-	private static RepositoryAwareStatusHandler instance;
-
-	public synchronized static RepositoryAwareStatusHandler getInstance() {
-		if (instance == null) {
-			new RepositoryAwareStatusHandler();
-		}
-		return instance;
-	}
-
-	public RepositoryAwareStatusHandler() {
-		instance = this;
-	}
-
-	@Deprecated
-	public void fail(final IStatus status, boolean informUser) {
-		if (informUser && Platform.isRunning()) {
-			try {
-				PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {
-					public void run() {
-						Shell shell = null;
-						if (PlatformUI.getWorkbench() != null
-								&& PlatformUI.getWorkbench().getActiveWorkbenchWindow() != null) {
-							shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell();
-						}
-
-						// ensure that only one dialog can be open at a time
-						synchronized (shell) {
-							try {
-								if (!errorDialogOpen) {
-									errorDialogOpen = true;
-									ErrorDialog.openError(shell, "Mylyn Error", ERROR_MESSAGE, status);
-								}
-							} finally {
-								errorDialogOpen = false;
-							}
-						}
-					}
-				});
-			} catch (Throwable t) {
-				status.getException().printStackTrace();
-			}
-		}
-	}
-
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/Scatch.jpage b/org.eclipse.mylyn.ide.dev/developer/src-old/Scatch.jpage
deleted file mode 100644
index 990639a..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/Scatch.jpage
+++ /dev/null
@@ -1,179 +0,0 @@
-package ca.ubc.mylar;
-
-import java.io.*;
-import java.util.MissingResourceException;
-import java.util.ResourceBundle;
-
-import org.eclipse.core.resources.ResourcesPlugin;
-import org.eclipse.core.runtime.IPath;
-import org.eclipse.core.runtime.Status;
-import org.eclipse.jdt.internal.ui.viewsupport.JavaElementImageProvider;
-import org.eclipse.jface.dialogs.ErrorDialog;
-import org.eclipse.jface.preference.IPreferenceStore;
-import org.eclipse.ui.internal.Workbench;
-import org.eclipse.ui.plugin.AbstractUIPlugin;
-
-import ca.ubc.mylar.model.DoiModelManager;
-import ca.ubc.mylar.monitor.UsageStatisticsManager;
- 
-/**
- * The main plugin class to be used in the desktop.
- */
-public class MylarPlugin extends AbstractUIPlugin {
-    
-    public static boolean DEBUG_MODE = false;
-    public static final String LOG_FILE_NAME = "mylar-log.txt";
-    
-    private static boolean enabled = true;
-  
-	private static MylarPlugin plugin;
-	private static UserSelectionListener userSelectionListneer = new UserSelectionListener(); 
-    private static DoiModelManager modelManager = new DoiModelManager();
-    private static UsageStatisticsManager statisticsManager = new UsageStatisticsManager();
-    
-    private static PrintStream logStream;
-    
-	//Resource bundle.
-	private ResourceBundle resourceBundle;
-	private JavaElementImageProvider javaImageProvider;
-	 
-    public static DoiModelManager getModelManager() {
-        return modelManager;
-    }
-  
-	static {
-        IPath rootPath = ResourcesPlugin.getWorkspace().getRoot().getLocation();
-        String path = rootPath.toString() + File.separator + LOG_FILE_NAME;
-        try {
-            logStream = new PrintStream(new FileOutputStream(new File(path), true));
-        } catch (FileNotFoundException e) {
-            e.printStackTrace();
-        }
-    }  
-    
-    /**
-	 * The constructor.
-	 */  
-	public MylarPlugin() {
-		super();
-		plugin = this;
-		try {
-		    resourceBundle = ResourceBundle.getBundle("ca.ubc.mylar.MylarPluginResources");
-		    javaImageProvider = new JavaElementImageProvider();
-		} catch (MissingResourceException x) {
-			resourceBundle = null;
-		} catch (Throwable t) {
-			System.err.println("> Mylar failed to start: " + t.getMessage());
-			t.printStackTrace();		
-		}
-	}
-    
-    /**
-	 * Returns the shared instance.
-	 */
-	public static MylarPlugin getDefault() {
-		return plugin;
-	}
-	
-	public static IPreferenceStore getPrefs() {
-		return getDefault().getPreferenceStore();
-	}
-	
-	public static void log(Object source, String message) {
-	    StringBuffer buffer = new StringBuffer();
-	    buffer.append("[");
-	    buffer.append(Util.getFormattedDate());
-	    buffer.append(", ");
-	    buffer.append(Util.getFormattedTime());
-	    buffer.append("] ");
-	    
-	    if (source != null) buffer.append(source.getClass().getName());
-	    buffer.append(": " + message);
-	    
-	    if (DEBUG_MODE) System.out.println(buffer.toString());
-        if (logStream != null) logStream.println(buffer.toString());
-	}
-
-	/**
-	 * @param throwable  can be null
-	 * @param message
-	 */
-	public static void fail(Throwable throwable, String message) {
-		StringWriter stringWriter= new StringWriter();
-		PrintWriter writer= new PrintWriter(stringWriter);
-		StringBuffer buffer = new StringBuffer();
-		if (throwable != null) {
-		    throwable.printStackTrace(writer);
-		    buffer = stringWriter.getBuffer();
-		}
-		log(MylarPlugin.getDefault(), "fail: " + message + "\n" + buffer.toString());
-		
-		final Status status= new Status(
-		        Status.ERROR,
-				"ca.ubc.mylar", 
-				Status.OK,
-				message,  //$NON-NLS-1$
-				throwable);
-		
-		Workbench.getInstance().getDisplay().syncExec(new Runnable() {
-			public void run() {
-			    ErrorDialog.openError(
-			            Workbench.getInstance().getActiveWorkbenchWindow().getShell(),
-			            "Mylar error",
-			            "Please report the following error",
-						status);
-			}
-		});
-	}  
-
-	/**
-	 * Returns the string from the plugin's resource bundle,
-	 * or 'key' if not found.
-	 */
-	public static String getResourceString(String key) {
-		ResourceBundle bundle = MylarPlugin.getDefault().getResourceBundle(); 
-		try {
-			return (bundle != null) ? bundle.getString(key) : key;
-		} catch (MissingResourceException e) {
-			return key;
-		}
-	}
-
-	/**
-	 * Returns the string from the plugin's resource bundle,
-	 * or 'key' if not found.
-	 */
-	public static String getMessage(String key) {
-		ResourceBundle bundle = getDefault().getResourceBundle();
-		try {
-			return (bundle != null) ? bundle.getString(key) : key;
-		} catch (MissingResourceException e) {
-			return key;
-		}
-	}
-	
-	/**
-	 * Returns the plugin's resource bundle,
-	 */
-	public ResourceBundle getResourceBundle() {
-		return resourceBundle;
-	}
-	
-    public static UsageStatisticsManager getStatisticsManager() {
-        return statisticsManager;
-    }
-    
-    /**
-     * For testing.
-     */
-    public static UserSelectionListener getUserSelectionListneer() {
-        return userSelectionListneer;
-    }
-
-    public static boolean isEnabled() {
-        return enabled;
-    }
-    public static void setEnabled(boolean enabled) {
-        MylarPlugin.enabled = enabled;
-    }
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/SynchronizeChangedTasksJob.java b/org.eclipse.mylyn.ide.dev/developer/src-old/SynchronizeChangedTasksJob.java
deleted file mode 100644
index 3a27af1..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/SynchronizeChangedTasksJob.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004 - 2006 Mylar committers and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *******************************************************************************/
-
-package org.eclipse.mylyn.tasks.ui;
-
-import java.util.Iterator;
-import java.util.Set;
-
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.Status;
-import org.eclipse.core.runtime.SubProgressMonitor;
-import org.eclipse.core.runtime.jobs.Job;
-import org.eclipse.mylyn.internal.monitor.core.util.StatusManager;
-import org.eclipse.mylyn.tasks.core.AbstractRepositoryConnector;
-import org.eclipse.mylyn.tasks.core.AbstractTask;
-import org.eclipse.mylyn.tasks.core.TaskList;
-import org.eclipse.mylyn.tasks.core.TaskRepository;
-
-public class SynchronizeChangedTasksJob extends Job {
-
-	private final AbstractRepositoryConnector connector;
-
-	private final TaskRepository repository;
-
-	private boolean forced;
-
-	public SynchronizeChangedTasksJob(AbstractRepositoryConnector connector, TaskRepository repository) {
-		super("Get Changed Tasks");
-		
-		this.connector = connector;
-		this.repository = repository;
-	}
-
-	/**
-	 * Returns true, if synchronization was triggered manually and not by an automatic background job.
-	 */
-	public boolean isForced() {
-		return forced;
-	}
-
-	/**
-	 * Indicates a manual synchronization (User initiated). If set to true, a dialog will be displayed in case of
-	 * errors. Any tasks with missing data will be retrieved.
-	 */
-	public void setForced(boolean forced) {
-		this.forced = forced;
-	}
-
-	@Override
-	public IStatus run(IProgressMonitor monitor) {
-		try {
-			monitor.beginTask("Synchronizing changed tasks", IProgressMonitor.UNKNOWN);
-			
-			TaskList taskList = TasksUiPlugin.getTaskList();
-			Set<AbstractTask> tasks = taskList.getRepositoryTasks(repository.getUrl());
-
-			boolean changed = connector.markStaleTasks(repository, tasks, new SubProgressMonitor(monitor, 1));
-			if (!changed) {
-				return Status.OK_STATUS;
-			}
-			
-			for (Iterator<AbstractTask> it = tasks.iterator(); it.hasNext();) {
-				if (!it.next().isStale()) {
-					it.remove();
-				}
-			}
-
-			if (tasks.isEmpty()) {
-				return Status.OK_STATUS;
-			}
-
-			TasksUiPlugin.getSynchronizationManager().synchronize(connector, tasks, forced, null);
-		} catch (final CoreException e) {
-			StatusManager.log(e.getStatus());
-		} finally {
-			monitor.done();
-		}
-		
-		return Status.OK_STATUS;
-	};
-	
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/TaskActivityTimer.java b/org.eclipse.mylyn.ide.dev/developer/src-old/TaskActivityTimer.java
deleted file mode 100644
index fe5b191..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/TaskActivityTimer.java
+++ /dev/null
@@ -1,129 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004 - 2006 University Of British Columbia and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     University Of British Columbia - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.mylyn.internal.tasks.ui.util;
-
-import java.util.Calendar;
-
-import org.eclipse.mylyn.context.core.IInteractionEventListener;
-import org.eclipse.mylyn.context.core.InteractionEvent;
-import org.eclipse.mylyn.internal.context.core.util.ITimerThreadListener;
-import org.eclipse.mylyn.internal.context.core.util.TimerThread;
-import org.eclipse.mylyn.monitor.MylarMonitorPlugin;
-import org.eclipse.mylyn.tasks.core.ITask;
-import org.eclipse.ui.IWindowListener;
-import org.eclipse.ui.IWorkbenchWindow;
-import org.eclipse.ui.PlatformUI;
-
-/**
- * @author Mik Kersten
- */
-public class TaskActivityTimer implements ITimerThreadListener, IInteractionEventListener, IWindowListener {
-
-	private TimerThread timer;
-
-	private ITask task;
-
-	private long lastActivity;
-
-	private boolean started;
-
-	public TaskActivityTimer(ITask task, int timeout, int sleepInterval) {
-		this.task = task;
-		timer = new TimerThread(timeout, sleepInterval);
-		PlatformUI.getWorkbench().addWindowListener(this);
-		MylarMonitorPlugin.getDefault().addInteractionListener(this);
-		timer.addListener(this);
-	}
-
-	public void startTimer() {
-		lastActivity = Calendar.getInstance().getTimeInMillis();
-		timer.start();
-		started = true;
-	}
-
-	public void stopTimer() {
-		if (!timer.isSuspended()) {
-			addElapsedToActivityTime();
-		}
-		timer.kill();
-		timer.removeListener(this);
-		MylarMonitorPlugin.getDefault().removeInteractionListener(this);
-		PlatformUI.getWorkbench().removeWindowListener(this);
-		started = false;
-	}
-
-	public void fireTimedOut() {
-		suspendTiming();
-	}
-
-	public void interactionObserved(InteractionEvent event) {
-		// lastActivity = Calendar.getInstance().getTimeInMillis();
-		timer.resetTimer();
-	}
-
-	private void suspendTiming() {
-		addElapsedToActivityTime();
-		timer.setSuspended(true);
-	}
-
-	private void addElapsedToActivityTime() {
-//		long elapsed = Calendar.getInstance().getTimeInMillis() - lastActivity;
-//		task.setElapsedTime(task.getElapsedTime() + elapsed);
-//		lastActivity = Calendar.getInstance().getTimeInMillis();
-	}
-
-	public void startMonitoring() {
-
-	}
-
-	public void stopMonitoring() {
-
-	}
-
-	/**
-	 * Public for testing
-	 */
-	public boolean isStarted() {
-		return started;
-	}
-
-	public String toString() {
-		return "timer for task: " + task.toString();
-	}
-
-	public boolean isSuspended() {
-		return timer.isSuspended();
-	}
-
-	public void intervalElapsed() {
-		addElapsedToActivityTime();
-	}
-
-	public void windowActivated(IWorkbenchWindow window) {
-		timer.resetTimer();
-		lastActivity = Calendar.getInstance().getTimeInMillis();
-	}
-
-	public void windowDeactivated(IWorkbenchWindow window) {
-		suspendTiming();
-	}
-
-	public void windowClosed(IWorkbenchWindow window) {
-		if (PlatformUI.getWorkbench().getWorkbenchWindowCount() == 0) {
-			timer.kill();
-		}
-	}
-
-	public void windowOpened(IWorkbenchWindow window) {
-		// ignore
-	}
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/TaskActivityTimingTest.java b/org.eclipse.mylyn.ide.dev/developer/src-old/TaskActivityTimingTest.java
deleted file mode 100644
index dbc6300..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/TaskActivityTimingTest.java
+++ /dev/null
@@ -1,176 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004 - 2006 University Of British Columbia and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     University Of British Columbia - initial API and implementation
- *******************************************************************************/
-package org.eclipse.mylyn.tasks.tests;
-
-import junit.framework.TestCase;
-
-import org.eclipse.mylyn.context.core.InteractionEvent;
-import org.eclipse.mylyn.internal.context.core.util.TimerThread;
-import org.eclipse.mylyn.internal.tasks.ui.util.TaskActivityTimer;
-import org.eclipse.mylyn.monitor.MylarMonitorPlugin;
-import org.eclipse.mylyn.tasks.core.ITask;
-import org.eclipse.mylyn.tasks.core.Task;
-import org.eclipse.mylyn.tasks.ui.TaskListManager;
-import org.eclipse.mylyn.tasks.ui.TasksUiPlugin;
-
-/**
- * @author Mik Kersten
- */
-public class TaskActivityTimingTest extends TestCase {
-
-	// 5 seconds (minimum value since TimerThread sleeps
-	// for 5 seconds anyway before checking
-
-	private static final int SLOP = 100;
-
-	private static final int SLEEP_INTERVAL = SLOP * 3;
-
-	private static final int TIMEOUT = SLEEP_INTERVAL * 2;
-
-	private static final int SLEEP_NOTIMEOUT = TIMEOUT - SLOP; // 1 second
-
-	// Introdueced long sleep for testing inactivity where TimerThread
-	// sleeps for 5 seconds so we must sleep at least that long before
-	// it will have woken up and suspended.
-	private static final int SLEEP_TIMEOUT = TIMEOUT + SLOP; // 5.5 seconds
-
-	protected TaskListManager manager = TasksUiPlugin.getTaskListManager();
-
-	protected Task task1 = null;
-
-	protected int originalActivityTimeout = -1;
-
-	protected void setUp() throws Exception {
-		super.setUp();
-		task1 = new Task("t1", "t1", true);
-		originalActivityTimeout = MylarMonitorPlugin.getDefault().getInactivityTimeout();
-		MylarMonitorPlugin.getDefault().setInactivityTimeout(TIMEOUT);
-		manager.setTimerSleepInterval(SLEEP_INTERVAL);
-	}
-
-	public void tearDown() {
-		TasksUiPlugin.getTaskListManager().deactivateTask(task1);
-		ITask remaining = TasksUiPlugin.getTaskList().getActiveTask();
-		if (remaining != null) {
-			TasksUiPlugin.getTaskListManager().deactivateTask(remaining);
-		}
-		MylarMonitorPlugin.getDefault().setInactivityTimeout(originalActivityTimeout);
-		manager.setTimerSleepInterval(TimerThread.DEFAULT_SLEEP_INTERVAL);
-	}
-
-	public void testDeactivation() throws InterruptedException {
-		assertEquals(0, task1.getElapsedTime());
-		TasksUiPlugin.getTaskListManager().deactivateTask(task1);
-		assertEquals(0, task1.getElapsedTime());
-
-		TasksUiPlugin.getTaskListManager().activateTask(task1);
-		Thread.sleep(SLEEP_NOTIMEOUT);
-		TasksUiPlugin.getTaskListManager().deactivateTask(task1);
-		assertTrue("elapsed: " + task1.getElapsedTime(), task1.getElapsedTime() >= SLEEP_NOTIMEOUT - 2*SLOP);
-	}
-
-	public void testTimerMap() throws InterruptedException {
-		Task task0 = new Task("t0", "t0", true);
-		manager.activateTask(task0);
-		assertEquals(1, manager.getTimerMap().values().size());
-		TaskActivityTimer timer0 = manager.getTimerMap().get(task0);
-		assertTrue(timer0.isStarted());
-
-		long elapsed = task1.getElapsedTime();
-		assertEquals(0, elapsed);
-		TasksUiPlugin.getTaskListManager().activateTask(task1);
-		TaskActivityTimer timer1 = manager.getTimerMap().get(task1);
-		// previous task was deactivated
-		assertEquals(1, manager.getTimerMap().values().size());
-		assertTrue(timer1.isStarted());
-		Thread.sleep(SLEEP_TIMEOUT);
-
-		manager.deactivateTask(task1);
-		elapsed = task1.getElapsedTime();
-		assertTrue("should be around TIMEOUT", (elapsed > (TIMEOUT - 500)) && (elapsed < (TIMEOUT + 500)));
-		assertFalse(timer1.isStarted());
-		assertEquals(0, manager.getTimerMap().values().size());
-
-		Thread.sleep(SLEEP_TIMEOUT);
-		long elapsedAfterInactivity = task1.getElapsedTime();
-		assertEquals("no accumulation if task deactivated", elapsed, elapsedAfterInactivity);
-
-		assertFalse(timer0.isStarted());
-		assertEquals(0, manager.getTimerMap().values().size());
-	}
-
-	public void testElapsedTimeCapture() throws InterruptedException {
-		long elapsed = task1.getElapsedTime();
-		assertEquals(0, elapsed);
-		TasksUiPlugin.getTaskListManager().activateTask(task1);
-		Thread.sleep(SLEEP_TIMEOUT);
-
-		elapsed = task1.getElapsedTime();
-		assertTrue("should be bigger than timeout: " + elapsed + " > " + TIMEOUT, elapsed + SLOP >= TIMEOUT);
-
-		// Task should be inactive so no time accumulated
-		Thread.sleep(SLEEP_TIMEOUT);
-		TasksUiPlugin.getTaskListManager().deactivateTask(task1);
-
-		long elapsedAfterDeactivation = task1.getElapsedTime();
-		assertEquals(elapsed, elapsedAfterDeactivation);
-
-		Thread.sleep(SLEEP_TIMEOUT);
-		long elapsedAfterInactivity = task1.getElapsedTime();
-		assertEquals("no accumulation if task inactive", elapsedAfterDeactivation, elapsedAfterInactivity);
-
-		MylarMonitorPlugin.getDefault().setInactivityTimeout(SLEEP_TIMEOUT * 2);
-		TasksUiPlugin.getTaskListManager().activateTask(task1);
-		Thread.sleep(SLEEP_TIMEOUT);
-		// Should not have timed out
-		TasksUiPlugin.getTaskListManager().deactivateTask(task1);
-		long elpasedAfterReactivation = task1.getElapsedTime();
-
-		// adds some slop
-		assertTrue("time: " + (elpasedAfterReactivation - elapsedAfterInactivity), elpasedAfterReactivation
-				- elapsedAfterInactivity + 50 >= SLEEP_TIMEOUT);
-	}
-
-	public void testTimeout() throws InterruptedException {
-
-		Task task0 = new Task("t0", "t0", true);
-		assertEquals(task0.getElapsedTime(), 0);
-		manager.activateTask(task0);
-		assertEquals(1, manager.getTimerMap().values().size());
-		TaskActivityTimer timer0 = manager.getTimerMap().get(task0);
-		assertTrue(timer0.isStarted());
-
-		Thread.sleep(SLEEP_TIMEOUT);
-
-		// timeout should have occurred before SLEEP time
-		long timeAfterSleep = task0.getElapsedTime();
-
-		assertTrue(timeAfterSleep < SLEEP_TIMEOUT);
-		timer0 = manager.getTimerMap().get(task0);
-		assertNotNull(timer0);
-		assertTrue(timer0.isSuspended());
-
-		// Interaction should cause task timer to startup.
-		mockInteraction();
-		assertFalse(timer0.isSuspended());
-		Thread.sleep(SLEEP_NOTIMEOUT);
-		manager.deactivateTask(task0);
-
-		assertTrue(task0.getElapsedTime() > timeAfterSleep);
-		TasksUiPlugin.getTaskListManager().deactivateTask(task0);
-
-	}
-
-	protected void mockInteraction() {
-		MylarMonitorPlugin.getDefault().notifyInteractionObserved(
-				new InteractionEvent(InteractionEvent.Kind.EDIT, "java", "A.java", "mock-id"));
-	}
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/TaskListBackupManager.java b/org.eclipse.mylyn.ide.dev/developer/src-old/TaskListBackupManager.java
deleted file mode 100644
index aa696b0..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/TaskListBackupManager.java
+++ /dev/null
@@ -1,350 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004, 2007 Mylyn project committers and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *******************************************************************************/
-
-package org.eclipse.mylyn.internal.tasks.ui;
-
-import java.io.File;
-import java.lang.reflect.InvocationTargetException;
-import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Calendar;
-import java.util.Comparator;
-import java.util.Date;
-import java.util.HashSet;
-import java.util.Locale;
-import java.util.SortedMap;
-import java.util.Timer;
-import java.util.TimerTask;
-import java.util.TreeMap;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.Platform;
-import org.eclipse.core.runtime.Status;
-import org.eclipse.core.runtime.jobs.Job;
-import org.eclipse.jface.dialogs.MessageDialog;
-import org.eclipse.jface.util.IPropertyChangeListener;
-import org.eclipse.jface.util.PropertyChangeEvent;
-import org.eclipse.mylyn.internal.tasks.core.ITasksCoreConstants;
-import org.eclipse.mylyn.internal.tasks.core.TaskActivityUtil;
-import org.eclipse.mylyn.internal.tasks.ui.util.TaskDataExportJob;
-import org.eclipse.mylyn.internal.tasks.ui.wizards.TaskDataExportWizard;
-import org.eclipse.mylyn.tasks.core.AbstractTask;
-import org.eclipse.ui.PlatformUI;
-import org.eclipse.ui.progress.IProgressService;
-
-/**
- * @author Rob Elves
- */
-public class TaskListBackupManager implements IPropertyChangeListener {
-
-	public static final String TIMESTAMP_FORMAT = "yyyy-MM-dd-HHmmss";
-
-	private static final String TITLE_TASKLIST_BACKUP = "Tasklist Backup";
-
-	private static final String BACKUP_JOB_NAME = "Scheduled task data backup";
-
-	public static final String BACKUP_FAILURE_MESSAGE = "Could not backup task data. Check backup preferences.\n";
-
-	private static final long SECOND = 1000;
-
-	private static final long MINUTE = 60 * SECOND;
-
-	private static final long HOUR = 60 * MINUTE;
-
-	private static final long DAY = 24 * HOUR;
-
-	private Timer timer;
-
-	//private static final Pattern zipPattern = Pattern.compile("^" + TaskDataExportWizard.ZIP_FILE_PREFIX + ".*");
-
-	public TaskListBackupManager() {
-		int days = TasksUiPlugin.getDefault().getPreferenceStore().getInt(TasksUiPreferenceConstants.BACKUP_SCHEDULE);
-		if (days > 0) {
-			start(HOUR);///2 * MINUTE
-		}
-	}
-
-	public void start(long delay) {
-		timer = new Timer();
-		timer.schedule(new CheckBackupRequired(), delay, HOUR);
-	}
-
-	public void stop() {
-		timer.cancel();
-	}
-
-	public void propertyChange(PropertyChangeEvent event) {
-//		if (event.getProperty().equals(TaskListPreferenceConstants.BACKUP_AUTOMATICALLY)) {
-//			if ((Boolean) event.getNewValue() == true) {
-//				start(MINUTE);
-//			} else {
-//				stop();
-//			}
-//		}
-	}
-
-	public void backupNow(boolean synchronous) {
-		String destination = TasksUiPlugin.getDefault().getBackupFolderPath();
-
-		File backupFolder = new File(destination);
-		if (!backupFolder.exists()) {
-			backupFolder.mkdir();
-		}
-
-		removeOldBackups(backupFolder);
-
-		String fileName = TaskDataExportWizard.getZipFileName();
-
-		if (!synchronous) {
-
-			ExportJob export = new ExportJob(destination, fileName);
-			export.schedule();
-
-		} else {
-
-			final TaskDataExportJob backupJob = new TaskDataExportJob(destination, true, true, false, false, fileName,
-					new HashSet<AbstractTask>());
-
-			IProgressService service = PlatformUI.getWorkbench().getProgressService();
-			try {
-				service.run(true, false, backupJob);
-				TasksUiPlugin.getDefault().getPreferenceStore().setValue(TasksUiPreferenceConstants.BACKUP_LAST,
-						new Date().getTime());
-			} catch (InterruptedException e) {
-				// ignore
-			} catch (InvocationTargetException e) {
-				MessageDialog.openError(null, TITLE_TASKLIST_BACKUP, BACKUP_FAILURE_MESSAGE);
-			}
-
-		}
-	}
-
-	/** public for testing purposes */
-	public void removeOldBackups(File folder) {
-
-		int maxBackups = TasksUiPlugin.getDefault().getPreferenceStore().getInt(
-				TasksUiPreferenceConstants.BACKUP_MAXFILES);
-
-		File[] files = folder.listFiles();
-		ArrayList<File> backupFiles = new ArrayList<File>();
-		for (File file : files) {
-			if (file.getName().startsWith(TaskDataExportWizard.ZIP_FILE_PREFIX)) {
-				backupFiles.add(file);
-			}
-		}
-
-		File[] backupFileArray = backupFiles.toArray(new File[backupFiles.size()]);
-
-		if (backupFileArray != null && backupFileArray.length > 0) {
-			Arrays.sort(backupFileArray, new Comparator<File>() {
-				public int compare(File file1, File file2) {
-					return new Long((file1).lastModified()).compareTo(new Long((file2).lastModified()));
-				}
-
-			});
-
-			int toomany = backupFileArray.length - maxBackups;
-			if (toomany > 0) {
-				for (int x = 0; x < toomany; x++) {
-					if (backupFileArray[x] != null) {
-						backupFileArray[x].delete();
-					}
-				}
-			}
-		}
-	}
-
-	/** public for testing purposes */
-	public synchronized static void removeOldBackups(File folder, Pattern pattern, int maxBackups) {
-
-		if (maxBackups <= 0) {
-			maxBackups = 1;
-		}
-
-		File[] files = folder.listFiles();
-		ArrayList<File> backupFiles = new ArrayList<File>();
-		for (File file : files) {
-			Matcher matcher = pattern.matcher(file.getName());
-			if (matcher.find()) {
-				backupFiles.add(file);
-			}
-		}
-
-		File[] backupFileArray = backupFiles.toArray(new File[backupFiles.size()]);
-
-		if (backupFileArray != null && backupFileArray.length > 0) {
-			Arrays.sort(backupFileArray, new Comparator<File>() {
-				public int compare(File file1, File file2) {
-					return new Long((file1).lastModified()).compareTo(new Long((file2).lastModified()));
-				}
-			});
-
-			SortedMap<Long, File> filesMap = new TreeMap<Long, File>();
-			for (File file2 : backupFileArray) {
-				String name = file2.getName();
-				if (name.startsWith(ITasksCoreConstants.PREFIX_TASKLIST)) {
-					try {
-						String dateString = name.substring(ITasksCoreConstants.PREFIX_TASKLIST.length() + 1,
-								ITasksCoreConstants.PREFIX_TASKLIST.length() + TIMESTAMP_FORMAT.length() + 1);
-						SimpleDateFormat format = new SimpleDateFormat(TIMESTAMP_FORMAT, Locale.ENGLISH);
-						Date date = format.parse(dateString);
-						filesMap.put(new Long(date.getTime()), file2);
-					} catch (Exception e) {
-						continue;
-					}
-				}
-			}
-
-			if (filesMap.size() > 0) {
-
-				Calendar rangeStart = TaskActivityUtil.getCalendar();
-				rangeStart.setTimeInMillis(filesMap.lastKey());
-				TaskActivityUtil.snapStartOfHour(rangeStart);
-				int startHour = rangeStart.get(Calendar.HOUR_OF_DAY);
-				Calendar rangeEnd = TaskActivityUtil.getCalendar();
-				rangeEnd.setTimeInMillis(rangeStart.getTimeInMillis());
-				rangeEnd.add(Calendar.HOUR_OF_DAY, 1);
-				// Keep one backup for last 8 hours of today
-				for (int x = 1; x <= startHour && x < 9; x++) {
-					SortedMap<Long, File> subMap = filesMap.subMap(rangeStart.getTimeInMillis(),
-							rangeEnd.getTimeInMillis());
-					if (subMap.size() > 1) {
-						while (subMap.size() > 1) {
-							File toDelete = subMap.remove(subMap.firstKey());
-							toDelete.delete();
-						}
-					}
-					rangeStart.add(Calendar.HOUR_OF_DAY, -1);
-					rangeEnd.add(Calendar.HOUR_OF_DAY, -1);
-				}
-
-				// Keep one backup a day for the past 12 days
-				TaskActivityUtil.snapStartOfDay(rangeEnd);
-				rangeStart.add(Calendar.DAY_OF_YEAR, -1);
-				for (int x = 1; x <= 12; x++) {
-					SortedMap<Long, File> subMap = filesMap.subMap(rangeStart.getTimeInMillis(),
-							rangeEnd.getTimeInMillis());
-					if (subMap.size() > 1) {
-						while (subMap.size() > 1) {
-							File toDelete = subMap.remove(subMap.firstKey());
-							toDelete.delete();
-						}
-					}
-					rangeStart.add(Calendar.DAY_OF_YEAR, -1);
-					rangeEnd.add(Calendar.DAY_OF_YEAR, -1);
-				}
-
-				// Remove all older backups
-				SortedMap<Long, File> subMap = filesMap.subMap(0l, rangeStart.getTimeInMillis());
-				if (subMap.size() > 0) {
-					while (subMap.size() > 0) {
-						File toDelete = subMap.remove(subMap.firstKey());
-						toDelete.delete();
-					}
-				}
-			}
-		}
-	}
-
-//	public File getMostRecentBackup() {
-//		String destination = TasksUiPlugin.getDefault().getBackupFolderPath();
-//
-//		File backupFolder = new File(destination);
-//		ArrayList<File> backupFiles = new ArrayList<File>();
-//		if (backupFolder.exists()) {
-//			File[] files = backupFolder.listFiles();
-//			for (File file : files) {
-//				if (file.getName().startsWith(TaskDataExportWizard.ZIP_FILE_PREFIX)) {
-//					backupFiles.add(file);
-//				}
-//			}
-//		} 
-//
-//		File[] backupFileArray = backupFiles.toArray(new File[backupFiles.size()]);
-//   
-//		if (backupFileArray != null && backupFileArray.length > 0) {
-//			Arrays.sort(backupFileArray, new Comparator<File>() {
-//				public int compare(File file1, File file2) {
-//					return (new Long((file1).lastModified()).compareTo(new Long((file2).lastModified()))) * -1;
-//				}
-//
-//			});
-//		}
-//		if (backupFileArray != null && backupFileArray.length > 0) {
-//			return backupFileArray[0];
-//		}
-//		
-//		return null;
-//	}
-
-	class CheckBackupRequired extends TimerTask {
-
-		@Override
-		public void run() {
-			PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {
-				public void run() {
-					backupNow(false);
-				}
-			});
-//			if (!Platform.isRunning() || TasksUiPlugin.getDefault() == null) {
-//				return;
-//			} else {
-//				long lastBackup = TasksUiPlugin.getDefault().getPreferenceStore().getLong(
-//						TasksUiPreferenceConstants.BACKUP_LAST);
-//				int days = TasksUiPlugin.getDefault().getPreferenceStore().getInt(
-//						TasksUiPreferenceConstants.BACKUP_SCHEDULE);
-//				long waitPeriod = days * DAY;
-//				final long now = new Date().getTime();
-//
-//				if ((now - lastBackup) > waitPeriod) {
-//					if (Platform.isRunning() && !PlatformUI.getWorkbench().isClosing()
-//							&& PlatformUI.getWorkbench().getDisplay() != null
-//							&& !PlatformUI.getWorkbench().getDisplay().isDisposed()) {
-//						PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {
-//							public void run() {
-//								backupNow(false);
-//							}
-//						});
-//					}
-//				}
-//			}
-		}
-	}
-
-	static class ExportJob extends Job {
-
-		final TaskDataExportJob backupJob;
-
-		public ExportJob(String destination, String filename) {
-			super(BACKUP_JOB_NAME);
-			backupJob = new TaskDataExportJob(destination, true, filename);
-		}
-
-		@Override
-		protected IStatus run(IProgressMonitor monitor) {
-			try {
-				if (Platform.isRunning()) {
-					backupJob.run(monitor);
-					TasksUiPlugin.getDefault().getPreferenceStore().setValue(TasksUiPreferenceConstants.BACKUP_LAST,
-							new Date().getTime());
-				}
-			} catch (InvocationTargetException e) {
-				MessageDialog.openError(null, BACKUP_JOB_NAME,
-						"Error occured during scheduled tasklist backup.\nCheck settings on Tasklist preferences page.");
-			} catch (InterruptedException e) {
-				return Status.CANCEL_STATUS;
-			}
-			return Status.OK_STATUS;
-		}
-
-	}
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/TaskListDataMigration.java b/org.eclipse.mylyn.ide.dev/developer/src-old/TaskListDataMigration.java
deleted file mode 100644
index 5b8bdc2..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/TaskListDataMigration.java
+++ /dev/null
@@ -1,261 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004 - 2006 Mylar committers and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *******************************************************************************/
-
-package org.eclipse.mylyn.tasks.ui;
-
-import java.io.File;
-import java.lang.reflect.InvocationTargetException;
-import java.util.ArrayList;
-
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.SubProgressMonitor;
-import org.eclipse.jface.operation.IRunnableWithProgress;
-import org.eclipse.mylyn.context.core.MylarStatusHandler;
-import org.eclipse.mylyn.internal.context.core.MylarContextManager;
-import org.eclipse.mylyn.internal.context.core.util.ZipFileUtil;
-import org.eclipse.mylyn.internal.tasks.ui.ITasksUiConstants;
-import org.eclipse.mylyn.tasks.core.TaskRepositoryManager;
-
-/**
- * Migrate 0.6 -> 0.7 mylar data format
- * 
- * @author Rob Elves
- */
-public class TaskListDataMigration implements IRunnableWithProgress {
-
-	private File dataDirectory = null;
-
-	public TaskListDataMigration(File sourceFolder) {
-		this.dataDirectory = sourceFolder;
-	}
-
-	public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
-		try {
-			monitor.beginTask("Task Data Migration", IProgressMonitor.UNKNOWN);
-			doMigration(monitor);
-		} finally {
-
-		}
-	}
-
-	public void doMigration(IProgressMonitor monitor) {
-		try {
-			if(dataDirectory == null || !dataDirectory.exists()) return;
-			monitor.beginTask("Mylar Data Migration", 4);
-			migrateTaskList(new SubProgressMonitor(monitor, IProgressMonitor.UNKNOWN));
-			monitor.worked(1);
-			migrateRepositoriesData(new SubProgressMonitor(monitor, IProgressMonitor.UNKNOWN));
-			monitor.worked(1);
-			migrateTaskContextData(new SubProgressMonitor(monitor, IProgressMonitor.UNKNOWN));
-			monitor.worked(1);
-			migrateActivityData(new SubProgressMonitor(monitor, IProgressMonitor.UNKNOWN));
-			monitor.worked(1);
-		} finally {
-			monitor.done();
-		}
-	}
-
-	public boolean migrateTaskList(IProgressMonitor monitor) {
-		File oldTasklistFile = new File(dataDirectory, ITasksUiConstants.OLD_TASK_LIST_FILE);
-		File newTasklistFile = new File(dataDirectory, ITasksUiConstants.DEFAULT_TASK_LIST_FILE);
-		if (!oldTasklistFile.exists())
-			return false;
-		if (newTasklistFile.exists()) {
-			if (!newTasklistFile.delete()) {
-				MylarStatusHandler.fail(null, "Could not overwrite tasklist", false);
-				return false;
-			}
-		}
-		ArrayList<File> filesToZip = new ArrayList<File>();
-		filesToZip.add(oldTasklistFile);
-		try {
-			monitor.beginTask("Migrate Tasklist Data", 1);
-			ZipFileUtil.createZipFile(newTasklistFile, filesToZip, new SubProgressMonitor(monitor, 1));
-			if (!oldTasklistFile.delete()) {
-				MylarStatusHandler.fail(null, "Could not remove old tasklist.", false);
-				return false;
-			}
-			monitor.worked(1);
-		} catch (Exception e) {
-			MylarStatusHandler.fail(e, "Error occurred while migrating old tasklist: " + e.getMessage(), true);
-			return false;
-		} finally {
-			monitor.done();
-		}
-		return true;
-	}
-
-	public boolean migrateRepositoriesData(IProgressMonitor monitor) {
-		File oldRepositoriesFile = new File(dataDirectory, TaskRepositoryManager.OLD_REPOSITORIES_FILE);
-		File newRepositoriesFile = new File(dataDirectory, TaskRepositoryManager.DEFAULT_REPOSITORIES_FILE);
-		if (!oldRepositoriesFile.exists())
-			return false;
-		if (newRepositoriesFile.exists()) {
-			if (!newRepositoriesFile.delete()) {
-				MylarStatusHandler.fail(null,
-						"Could not overwrite repositories file. Check read/write permission on data directory.", false);
-				return false;
-			}
-		}
-		ArrayList<File> filesToZip = new ArrayList<File>();
-		filesToZip.add(oldRepositoriesFile);
-		try {
-			monitor.beginTask("Migrate Repository Data", 1);
-			ZipFileUtil.createZipFile(newRepositoriesFile, filesToZip, new SubProgressMonitor(monitor, 1));
-			if (!oldRepositoriesFile.delete()) {
-				MylarStatusHandler
-						.fail(
-								null,
-								"Could not remove old repositories file. Check read/write permission on data directory.",
-								false);
-				return false;
-			}
-			monitor.worked(1);
-		} catch (Exception e) {
-			MylarStatusHandler.fail(e, "Error occurred while migrating old repositories data: " + e.getMessage(), true);
-			return false;
-		} finally {
-			monitor.done();
-		}
-		return true;
-	}
-
-	public boolean migrateTaskContextData(IProgressMonitor monitor) {
-		ArrayList<File> contextFiles = new ArrayList<File>();
-		for (File file : dataDirectory.listFiles()) {
-			if (file.getName().startsWith("http") || file.getName().startsWith("local") || file.getName().startsWith("task")) {
-				if (!file.getName().endsWith(".zip")) {
-					contextFiles.add(file);
-				}
-			}
-		}
-
-		try {
-			monitor.beginTask("Task Context Migration", contextFiles.size());
-
-			File contextsFolder = new File(dataDirectory, MylarContextManager.CONTEXTS_DIRECTORY);
-			if (!contextsFolder.exists()) {
-				if (!contextsFolder.mkdir()) {
-					MylarStatusHandler.fail(null,
-							"Could not create contexts folder. Check read/write permission on data directory.", false);
-					return false;
-				}
-			}
-			for (File file : contextFiles) {
-				ArrayList<File> filesToZip = new ArrayList<File>();
-				filesToZip.add(file);
-				File newContextFile = new File(contextsFolder, file.getName()+".zip");
-				if (newContextFile.exists()) {
-					if (!newContextFile.delete()) {
-						MylarStatusHandler.fail(null,
-								"Could not overwrite context file. Check read/write permission on data directory.",
-								false);
-						return false;
-					}
-				}
-				ZipFileUtil.createZipFile(newContextFile, filesToZip, new SubProgressMonitor(monitor, 1));
-				if (!file.delete()) {
-					MylarStatusHandler.fail(null,
-							"Could not remove old context file. Check read/write permission on data directory.", false);
-					return false;
-				}
-				monitor.worked(1);
-			}
-		} catch (Exception e) {
-			MylarStatusHandler.fail(e, "Error occurred while migrating old repositories data: " + e.getMessage(), true);
-			return false;
-		} finally {
-			monitor.done();
-		}
-		return true;
-	}
-		
-	public boolean migrateActivityData(IProgressMonitor monitor) {
-		File oldActivityFile = new File(dataDirectory, MylarContextManager.OLD_CONTEXT_HISTORY_FILE_NAME+MylarContextManager.CONTEXT_FILE_EXTENSION_OLD);
-		if (!oldActivityFile.exists())
-			return false;
-		
-		File contextsFolder = new File(dataDirectory, MylarContextManager.CONTEXTS_DIRECTORY);
-		if (!contextsFolder.exists()) {
-			if (!contextsFolder.mkdir()) {
-				MylarStatusHandler.fail(null,
-						"Could not create contexts folder. Check read/write permission on data directory.", false);
-				return false;
-			}
-		}
-		
-		File newActivityFile = new File(contextsFolder, MylarContextManager.CONTEXT_HISTORY_FILE_NAME+MylarContextManager.CONTEXT_FILE_EXTENSION);
-		
-		if (newActivityFile.exists()) {
-			if (!newActivityFile.delete()) {
-				MylarStatusHandler.fail(null,
-						"Could not overwrite activity file. Check read/write permission on data directory.", false);
-				return false;
-			}
-		}
-		ArrayList<File> filesToZip = new ArrayList<File>();
-		filesToZip.add(oldActivityFile);
-		try {
-			monitor.beginTask("Migrate Activity Data", 1);
-			ZipFileUtil.createZipFile(newActivityFile, filesToZip, new SubProgressMonitor(monitor, 1));
-			if (!oldActivityFile.delete()) {
-				MylarStatusHandler
-						.fail(
-								null,
-								"Could not remove old activity file. Check read/write permission on data directory.",
-								false);
-				return false;
-			}
-			monitor.worked(1);
-		} catch (Exception e) {
-			MylarStatusHandler.fail(e, "Error occurred while migrating old activity data: " + e.getMessage(), true);
-			return false;
-		} finally {
-			monitor.done();
-		}
-		return true;
-	}
-
-}
-
-//public boolean migrateActivityData(IProgressMonitor monitor) {
-//File oldActivityFile = new File(dataDirectory, MylarContextManager.OLD_CONTEXT_HISTORY_FILE_NAME+MylarContextManager.CONTEXT_FILE_EXTENSION_OLD);
-//if (!oldActivityFile.exists())
-//	return false;
-//		
-//File newActivityFile = new File(dataDirectory, MylarContextManager.CONTEXT_HISTORY_FILE_NAME+MylarContextManager.CONTEXT_FILE_EXTENSION);
-//
-//if (newActivityFile.exists()) {
-//	if (!newActivityFile.delete()) {
-//		MylarStatusHandler.fail(null,
-//				"Could not overwrite activity file. Check read/write permission on data directory.", false);
-//		return false;
-//	}
-//}
-//ArrayList<File> filesToZip = new ArrayList<File>();
-//filesToZip.add(oldActivityFile);
-//try {
-//	monitor.beginTask("Migrate Activity Data", 1);
-//	ZipFileUtil.createZipFile(newActivityFile, filesToZip, new SubProgressMonitor(monitor, 1));
-//	if (!oldActivityFile.delete()) {
-//		MylarStatusHandler
-//				.fail(
-//						null,
-//						"Could not remove old activity file. Check read/write permission on data directory.",
-//						false);
-//		return false;
-//	}
-//	monitor.worked(1);
-//} catch (Exception e) {
-//	MylarStatusHandler.fail(e, "Error occurred while migrating old activity data: " + e.getMessage(), true);
-//	return false;
-//} finally {
-//	monitor.done();
-//}
-//return true;
-//}
\ No newline at end of file
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/TaskListSaveManager.java b/org.eclipse.mylyn.ide.dev/developer/src-old/TaskListSaveManager.java
deleted file mode 100644
index d0f40ea..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/TaskListSaveManager.java
+++ /dev/null
@@ -1,352 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004, 2007 Mylyn project committers and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *******************************************************************************/
-
-package org.eclipse.mylyn.internal.tasks.ui.util;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Locale;
-import java.util.Queue;
-import java.util.Set;
-import java.util.regex.Pattern;
-
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.Platform;
-import org.eclipse.core.runtime.Status;
-import org.eclipse.core.runtime.jobs.Job;
-import org.eclipse.mylyn.commons.core.StatusHandler;
-import org.eclipse.mylyn.context.core.ContextCore;
-import org.eclipse.mylyn.context.core.IInteractionContextManager;
-import org.eclipse.mylyn.internal.tasks.core.ITasksCoreConstants;
-import org.eclipse.mylyn.internal.tasks.ui.TaskListManager;
-import org.eclipse.mylyn.internal.tasks.ui.TasksUiPlugin;
-import org.eclipse.mylyn.tasks.core.AbstractTask;
-import org.eclipse.mylyn.tasks.core.ITaskListChangeListener;
-import org.eclipse.mylyn.tasks.core.TaskContainerDelta;
-
-//import org.eclipse.ui.PlatformUI;
-
-/**
- * @author Mik Kersten
- * @author Eugene Kuleshov
- * @author Rob Elves
- */
-public class TaskListSaveManager implements ITaskListChangeListener, IBackgroundSaveListener {
-
-	private final static int DEFAULT_SAVE_INTERVAL = 1 * 60 * 1000;
-
-	private final BackgroundSaveTimer saveTimer;
-
-	private final TaskListSaverJob taskListSaverJob;
-
-	private final boolean initializationWarningDialogShow = false;
-
-	private static final int MAX_TASKLIST_SNAPSHOTS = 8;
-
-	public static final Pattern SNAPSHOT_REGEXP = Pattern.compile("^tasklist-.*");
-
-	public TaskListSaveManager() {
-		saveTimer = new BackgroundSaveTimer(this);
-		saveTimer.setSaveIntervalMillis(DEFAULT_SAVE_INTERVAL);
-		saveTimer.start();
-
-		taskListSaverJob = new TaskListSaverJob();
-		//taskListSaverJob.setRule(TasksUiPlugin.getTaskList());
-		taskListSaverJob.schedule();
-	}
-
-	/**
-	 * Called periodically by the save timer
-	 */
-	public void saveRequested() {
-		if (TasksUiPlugin.getDefault() != null && Platform.isRunning()) {// &&
-			// TasksUiPlugin.getDefault().isShellActive()
-			try {
-				taskListSaverJob.runRequested();
-			} catch (Exception e) {
-				StatusHandler.log(new Status(IStatus.ERROR, TasksUiPlugin.ID_PLUGIN, "Could not auto save task list", e));
-			}
-		}
-	}
-
-	/**
-	 * Should only be used by TaskListManager and unit tests
-	 * 
-	 * @param saveContext
-	 * @param async
-	 */
-	public void saveTaskList(boolean saveContext, boolean async) {
-		if (TasksUiPlugin.getDefault() != null && TasksUiPlugin.getDefault().isInitialized()) {
-			TaskListManager taskListManager = TasksUiPlugin.getTaskListManager();
-			if (async) {
-				if (saveContext) {
-					AbstractTask task = taskListManager.getActiveTask();
-					if (task != null) {
-						taskListSaverJob.addTaskContext(task);
-					}
-				}
-				taskListSaverJob.requestSave();
-			} else {
-				taskListSaverJob.waitSaveCompleted();
-				IInteractionContextManager contextManager = ContextCore.getContextManager();
-				if (saveContext) {
-					AbstractTask task = taskListManager.getActiveTask();
-					if (task != null) {
-						contextManager.saveContext(task.getHandleIdentifier());
-					}
-				}
-				internalSaveTaskList();
-			}
-		} /*else if (PlatformUI.getWorkbench() != null && !PlatformUI.getWorkbench().isClosing()) {
-									StatusHandler.fail(new Status(IStatus.WARNING, TasksUiPlugin.ID_PLUGIN,
-											"Possible task list initialization failure, not saving list"));
-									if (!initializationWarningDialogShow) {
-										initializationWarningDialogShow = true;
-										PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {
-											public void run() {
-												if (PlatformUI.getWorkbench() != null && PlatformUI.getWorkbench().getDisplay() != null) {
-													MessageDialog.openInformation(
-															PlatformUI.getWorkbench().getDisplay().getActiveShell(),
-															ITasksUiConstants.TITLE_DIALOG,
-															"If task list is blank, Mylyn Task List may have failed to initialize.\n\n"
-																	+ "First, try restarting to see if that corrects the problem.\n\n"
-																	+ "Then, check the Error Log view for messages, and the FAQ for solutions.\n\n"
-																	+ ITasksUiConstants.URL_HOMEPAGE);
-												}
-											}
-										});
-									}*/
-		//}
-	}
-
-	private synchronized void internalSaveTaskList() {
-		TaskListManager taskListManager = TasksUiPlugin.getTaskListManager();
-		File current = taskListManager.getTaskListFile();
-		SimpleDateFormat format = new SimpleDateFormat(ITasksCoreConstants.TIMESTAMP_FORMAT, Locale.ENGLISH);
-		String date = format.format(new Date());
-		String backupFileName = ITasksCoreConstants.PREFIX_TASKLIST + "-" + date + ITasksCoreConstants.FILE_EXTENSION;
-
-		String destination = TasksUiPlugin.getDefault().getBackupFolderPath();
-
-		File backupFolder = new File(destination);
-		if (!backupFolder.exists()) {
-			backupFolder.mkdir();
-		}
-
-		File backup = new File(backupFolder, backupFileName);
-		if (current.renameTo(backup)) {
-			TasksUiPlugin.getBackupManager().removeOldBackups();
-
-			String newTasklistPath = TasksUiPlugin.getDefault().getDataDirectory() + File.separator
-					+ ITasksCoreConstants.DEFAULT_TASK_LIST_FILE;
-			File newTaskListFile = new File(newTasklistPath);
-			taskListManager.setTaskListFile(newTaskListFile);
-		} else {
-			StatusHandler.log(new Status(IStatus.WARNING, TasksUiPlugin.ID_PLUGIN,
-					"Unable to create task list snapshot " + backup.getAbsolutePath()));
-		}
-
-		taskListManager.getTaskListWriter().writeTaskList(taskListManager.getTaskList(),
-				taskListManager.getTaskListFile());
-	}
-
-	/**
-	 * Copies all files in the current data directory to the specified folder. Will overwrite.
-	 */
-	public void copyDataDirContentsTo(String targetFolderPath) {
-		saveTaskList(true, false);
-
-		File mainDataDir = new File(TasksUiPlugin.getDefault().getDataDirectory());
-
-		for (File currFile : mainDataDir.listFiles()) {
-			if (currFile.isFile()) {
-				File destFile = new File(targetFolderPath + File.separator + currFile.getName());
-				copy(currFile, destFile);
-			} else if (currFile.isDirectory()) {
-				File destDir = new File(targetFolderPath + File.separator + currFile.getName());
-				if (!destDir.exists()) {
-					if (!destDir.mkdir()) {
-						StatusHandler.log(new Status(IStatus.WARNING, TasksUiPlugin.ID_PLUGIN,
-								"Unable to create destination context folder: " + destDir.getAbsolutePath()));
-						continue;
-					}
-				}
-				for (File file : currFile.listFiles()) {
-					File destFile = new File(destDir, file.getName());
-					if (destFile.exists()) {
-						destFile.delete();
-					}
-					copy(file, destFile);
-				}
-			}
-		}
-	}
-
-	// public void createTaskListBackupFile() {
-	// String path = TasksUiPlugin.getDefault().getDataDirectory() +
-	// File.separator
-	// + TasksUiPlugin.DEFAULT_TASK_LIST_FILE;
-	// File taskListFile = new File(path);
-	// String backup = path.substring(0, path.indexOf('.')) +
-	// FILE_SUFFIX_BACKUP;
-	// copy(taskListFile, new File(backup));
-	// }
-	//
-	// public String getBackupFilePath() {
-	// String path = TasksUiPlugin.getDefault().getDataDirectory() +
-	// File.separator
-	// + TasksUiPlugin.DEFAULT_TASK_LIST_FILE;
-	// return path.substring(0, path.indexOf('.')) + FILE_SUFFIX_BACKUP;
-	// }
-	//
-	// public void reverseBackup() {
-	// String path = TasksUiPlugin.getDefault().getBackupFolderPath() +
-	// File.separator
-	// + TasksUiPlugin.DEFAULT_TASK_LIST_FILE;
-	// File taskListFile = new File(path);
-	// String backup = path.substring(0, path.indexOf('.')) +
-	// FILE_SUFFIX_BACKUP;
-	// copy(new File(backup), taskListFile);
-	// }
-
-	private boolean copy(File src, File dst) {
-		try {
-			InputStream in = new FileInputStream(src);
-			OutputStream out = new FileOutputStream(dst);
-
-			// Transfer bytes from in to out
-			byte[] buf = new byte[1024];
-			int len;
-			while ((len = in.read(buf)) > 0) {
-				out.write(buf, 0, len);
-			}
-			in.close();
-			out.close();
-			return true;
-		} catch (IOException ioe) {
-			return false;
-		}
-	}
-
-	public void taskActivated(AbstractTask task) {
-		// ignore
-	}
-
-	public void tasksActivated(List<AbstractTask> tasks) {
-		// ignore
-	}
-
-	public void taskDeactivated(AbstractTask task) {
-		saveTaskList(true, true);
-	}
-
-	public void localInfoChanged(AbstractTask task) {
-		saveTaskList(false, true);
-	}
-
-	public void repositoryInfoChanged(AbstractTask task) {
-		// ignore
-	}
-
-	/** For testing only * */
-	public BackgroundSaveTimer getSaveTimer() {
-		return saveTimer;
-	}
-
-	public void containersChanged(Set<TaskContainerDelta> containers) {
-		saveTaskList(false, true);
-	}
-
-	public void synchronizationCompleted() {
-		// ignore
-	}
-
-	private class TaskListSaverJob extends Job {
-
-		private final Queue<AbstractTask> taskQueue = new LinkedList<AbstractTask>();
-
-		private volatile boolean saveRequested = false;
-
-		private volatile boolean saveCompleted = true;
-
-		TaskListSaverJob() {
-			super("Task List Saver");
-			setPriority(Job.LONG);
-			setSystem(true);
-		}
-
-		@Override
-		protected IStatus run(IProgressMonitor monitor) {
-			while (true) {
-				if (saveRequested) {
-					saveRequested = false;
-					saveCompleted = false;
-					IInteractionContextManager contextManager = ContextCore.getContextManager();
-					while (!taskQueue.isEmpty()) {
-						AbstractTask task = taskQueue.poll();
-						if (task != null) {
-							contextManager.saveContext(task.getHandleIdentifier());
-						}
-					}
-					internalSaveTaskList();
-				}
-
-				if (!saveRequested) {
-					synchronized (this) {
-						saveCompleted = true;
-						notifyAll();
-						try {
-							wait();
-						} catch (InterruptedException ex) {
-							// ignore
-						}
-					}
-				}
-			}
-		}
-
-		void addTaskContext(AbstractTask task) {
-			taskQueue.add(task);
-		}
-
-		void requestSave() {
-			saveRequested = true;
-		}
-
-		void runRequested() {
-			synchronized (this) {
-				notifyAll();
-			}
-		}
-
-		void waitSaveCompleted() {
-			while (!saveCompleted) {
-				synchronized (this) {
-					try {
-						wait();
-					} catch (InterruptedException ex) {
-						// ignore
-					}
-				}
-			}
-		}
-	}
-
-	public void taskListRead() {
-	}
-
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/TaskRepositoriesTableLabelProvider.java b/org.eclipse.mylyn.ide.dev/developer/src-old/TaskRepositoriesTableLabelProvider.java
deleted file mode 100644
index eb4f958..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/TaskRepositoriesTableLabelProvider.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004 - 2006 University Of British Columbia and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     University Of British Columbia - initial API and implementation
- *******************************************************************************/
-/*
- * Created on Feb 18, 2005
- */
-package org.eclipse.mylyn.internal.tasks.ui.views;
-
-import org.eclipse.jface.viewers.DecoratingLabelProvider;
-import org.eclipse.jface.viewers.ILabelDecorator;
-import org.eclipse.jface.viewers.ILabelProvider;
-import org.eclipse.jface.viewers.ITableLabelProvider;
-import org.eclipse.mylyn.tasks.core.AbstractRepositoryConnector;
-import org.eclipse.mylyn.tasks.core.TaskRepository;
-import org.eclipse.swt.graphics.Image;
-
-/**
- * @author Mik Kersten
- */
-public class TaskRepositoriesTableLabelProvider extends DecoratingLabelProvider implements ITableLabelProvider {
-
-	public TaskRepositoriesTableLabelProvider(ILabelProvider provider, ILabelDecorator decorator) {
-		super(provider, decorator);
-	}
-
-	public String getColumnText(Object object, int index) {
-		switch (index) {
-		case 0:
-			return null;
-		case 1:
-			if (object instanceof TaskRepository) {
-				TaskRepository repository = (TaskRepository) object;
-				if (repository.getRepositoryLabel() != null && repository.getRepositoryLabel().length() > 0) {
-					return repository.getRepositoryLabel();
-				} else {
-					return null;
-				}
-//				else {
-//					return repository.getUrl();
-//				}
-			} else if (object instanceof AbstractRepositoryConnector) {
-				return ((AbstractRepositoryConnector) object).getLabel();
-			} else {
-				return getText(object);
-			}
-		case 2:
-			if (object instanceof TaskRepository) {
-				TaskRepository repository = (TaskRepository) object;
-				return repository.getUrl();
-			} else if (object instanceof AbstractRepositoryConnector) {
-				return ((AbstractRepositoryConnector) object).getLabel();
-			} else {
-				return getText(object);
-			}
-		}
-		return null;
-	}
-
-	public Image getColumnImage(Object element, int columnIndex) {
-		if (columnIndex == 0) {
-			return super.getImage(element);
-		} else {
-			return null;
-		}
-	}
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/TaskTest.java b/org.eclipse.mylyn.ide.dev/developer/src-old/TaskTest.java
deleted file mode 100644
index e8911df..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/TaskTest.java
+++ /dev/null
@@ -1,139 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004 - 2005 University Of British Columbia and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     University Of British Columbia - initial API and implementation
- *******************************************************************************/
-/*
- * Created on Jan 24, 2005
- */
-package org.eclipse.mylyn.tasklist.tests;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * @author Shawn Minto
- * 
- * TODO: remove?
- */
-public class TaskTest {
-    private int id = -1;
-
-    private String name = "";
-
-    private List<String> categories = new ArrayList<String>();
-
-    private List<TaskTest> taskList = new ArrayList<TaskTest>();
-
-    @Override
-    public String toString() {
-        return "Task";
-    }
-
-    public boolean isEqual(TaskTest otherTask) {
-
-        boolean result = true;
-        result = result && (this.id == otherTask.id);
-        int compare = (this.name.compareTo(otherTask.name));
-        if (compare != 0)
-            result = false;
-
-        if (this.categories.size() == otherTask.categories.size()) {
-            for (int i = 0; i < this.categories.size(); i++) {
-                compare = this.categories.get(i).compareTo(
-                        otherTask.categories.get(i));
-                if (compare != 0) {
-                    result = false;
-                    break;
-                }
-            }
-        } else {
-            result = false;
-        }
-        if (this.taskList.size() == otherTask.taskList.size()) {
-            for (int i = 0; i < this.taskList.size(); i++) {
-                result = result
-                        && (this.taskList.get(i).isEqual(otherTask.taskList
-                                .get(i)));
-            }
-        } else {
-            result = false;
-        }
-        return result;
-    }
-
-    public static void printTask(TaskTest t, String tab) {
-        System.out.println(tab + "TaskID: " + t.id);
-        System.out.println(tab + "Name: " + t.name);
-        System.out.println(tab + "Categories: ");
-        for (int i = 0; i < t.categories.size(); i++) {
-            System.out.println(tab + "\t " + t.categories.get(i));
-        }
-        for (int i = 0; i < t.taskList.size(); i++) {
-            printTask(t.taskList.get(i), tab + "\t");
-        }
-    }
-
-    public String getName() {
-        return name;
-    }
-
-    public void setName(String name) {
-        this.name = name;
-    }
-
-    //    public List<String> getCategories() {
-    //        return categories;
-    //    }
-    //    public void setCategories(List<String> categories) {
-    //        this.categories = categories;
-    //    }
-    public int getId() {
-        return id;
-    }
-
-    public void setId(int id) {
-        this.id = id;
-    }
-
-    public void addCategory(String category) {
-        this.categories.add(category);
-    }
-
-    /**
-     * @return Returns the categories.
-     */
-    public List<String> getCategories() {
-        return categories;
-    }
-
-    /**
-     * @param categories The categories to set.
-     */
-    public void setCategories(List<String> categories) {
-        this.categories = categories;
-    }
-
-    /**
-     * @return Returns the taskList.
-     */
-    public List<TaskTest> getTaskList() {
-        return taskList;
-    }
-
-    /**
-     * @param taskList The taskList to set.
-     */
-    public void setTaskList(List<TaskTest> taskList) {
-        this.taskList = taskList;
-    }
-
-    public void addSubTask(TaskTest sub) {
-        this.taskList.add(sub);
-    }
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/TaskscapeVizView.java b/org.eclipse.mylyn.ide.dev/developer/src-old/TaskscapeVizView.java
deleted file mode 100644
index f5b13fa..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/TaskscapeVizView.java
+++ /dev/null
@@ -1,195 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004 - 2005 University Of British Columbia and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     University Of British Columbia - initial API and implementation
- *******************************************************************************/
-/*
- * Created on Feb 4, 2005
-  */
-package org.eclipse.mylyn.sandbox.springviz;
-
-import java.awt.*;
-import java.awt.event.*;
-
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.awt.SWT_AWT;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.ui.part.ViewPart;
-
-import edu.berkeley.guir.prefuse.*;
-import edu.berkeley.guir.prefuse.action.RepaintAction;
-import edu.berkeley.guir.prefuse.action.assignment.ColorFunction;
-import edu.berkeley.guir.prefuse.action.filter.GraphFilter;
-import edu.berkeley.guir.prefuse.activity.ActionList;
-import edu.berkeley.guir.prefuse.activity.Activity;
-import edu.berkeley.guir.prefuse.graph.Graph;
-import edu.berkeley.guir.prefuse.graph.GraphLib;
-import edu.berkeley.guir.prefuse.render.*;
-import edu.berkeley.guir.prefusex.controls.*;
-import edu.berkeley.guir.prefusex.force.*;
-import edu.berkeley.guir.prefusex.layout.ForceDirectedLayout;
-
-/**
- * @author Mik Kersten
- */
-public class TaskscapeVizView extends ViewPart {
-
-    public TaskscapeVizView() {
-        super();
-    }
-
-    public void createPartControl(Composite parent) {
-        try {
-            System.setProperty("sun.awt.noerasebackground", "true");
-        } catch (NoSuchMethodError error) { 
-        }
-        Composite stuff = new Composite(parent, SWT.EMBEDDED);
-        java.awt.Frame frame = SWT_AWT.new_Frame(stuff);
-//        final java.awt.Label statusLabel = new java.awt.Label();
-//        statusFrame.add(statusLabel);
-        
-//        String file = ("C:/Dev/mylar-workspace/prefuse/etc/friendster.xml");
-        Graph g = GraphLib.getGrid(5,5);
-        
-        System.out.println("Visualizing Graph: "
-            +g.getNodeCount()+" nodes, "+g.getEdgeCount()+" edges");
-        
-        ForceSimulator fsim = new ForceSimulator();
-        fsim.addForce(new NBodyForce(-0.4f, -1f, 0.9f));
-        fsim.addForce(new SpringForce(4E-5f, 75f));
-        fsim.addForce(new DragForce(-0.005f));
-        
-        ForceDemo fdemo = new ForceDemo(g, fsim);
-        fdemo.runDemo(frame);
-    }
-
-    public void setFocus() {
-    }
-
-}
-
-class ForceDemo extends Display {
-    private static final long serialVersionUID = 1L;
-
-    private ForcePanel fpanel;
-    
-    private ForceSimulator m_fsim;
-    private String         m_textField;
-    private ItemRegistry   m_registry;
-    private Activity       m_actionList;
-    
-    private Font frameCountFont = new Font("SansSerif", Font.PLAIN, 14);
-    
-    public ForceDemo(Graph g, ForceSimulator fsim) {
-        this(g, fsim, "label");
-    } //
-    
-    public ForceDemo(Graph g, ForceSimulator fsim, String textField) {
-        // set up component first
-        m_fsim = fsim;
-        m_textField = textField;
-        m_registry = new ItemRegistry(g);
-        this.setItemRegistry(m_registry);
-        initRenderers();
-        m_actionList = initActionList();
-        setSize(700,700);
-        pan(350,350);
-        this.addControlListener(new NeighborHighlightControl());
-        this.addControlListener(new DragControl(false, true));
-        this.addControlListener(new FocusControl(0));
-        this.addControlListener(new PanControl(false));
-        this.addControlListener(new ZoomControl(false));
-    } //
-    
-    public void runDemo(final java.awt.Frame frame) {
-        // now set up application window
-        fpanel = new ForcePanel(m_fsim) {        
-            private static final long serialVersionUID = 3617009741533296438L;
-
-            public void update(java.awt.Graphics g) {
-                /* Do not erase the background */
-                paint(g);
-            }
-        };
-        
-//        frame = new Frame("Force Simulator Demo");
-//        Container c = frame.getContentPane();
-        frame.setLayout(new BorderLayout());
-        frame.add(this, BorderLayout.CENTER);
-        frame.add(fpanel, BorderLayout.EAST);
-        frame.addWindowListener(new WindowAdapter() {
-            public void windowClosing(WindowEvent e) {
-                System.exit(0);
-            }
-        });
-        frame.addComponentListener(new ComponentAdapter() {
-            public void componentResized(ComponentEvent e) {
-                Dimension d = frame.getSize();
-                Dimension p = fpanel.getSize();
-                Insets in = frame.getInsets();
-                ForceDemo.this.setSize(d.width-in.left-in.right-p.width,
-                        d.height-in.top-in.bottom);
-            } //
-            
-        });
-        frame.pack();
-        frame.setVisible(true);
-        
-        // start force simulation
-        m_actionList.runNow();
-    } //
-    
-    private void initRenderers() {
-        TextItemRenderer    nodeRenderer = new TextItemRenderer();
-        nodeRenderer.setRenderType(TextItemRenderer.RENDER_TYPE_FILL);
-        nodeRenderer.setRoundedCorner(8,8);
-        nodeRenderer.setTextAttributeName(m_textField);
-        DefaultNodeRenderer nRenderer = new DefaultNodeRenderer();
-        DefaultEdgeRenderer edgeRenderer = new DefaultEdgeRenderer();    
-        m_registry.setRendererFactory(new DefaultRendererFactory(
-                nodeRenderer, edgeRenderer, null));
-    } //
-    
-    private ActionList initActionList() {
-        ActionList actionList = new ActionList(m_registry,-1,20);
-        actionList.add(new GraphFilter());
-        actionList.add(new ForceDirectedLayout(m_fsim, false, false));
-        actionList.add(new DemoColorFunction());
-        actionList.add(new RepaintAction());
-        return actionList;
-    } //
-
-    public class DemoColorFunction extends ColorFunction {
-        private Color pastelRed = new Color(255,125,125);
-        private Color pastelOrange = new Color(255,200,125);
-        private Color lightGray = new Color(220,220,255);
-        public Paint getColor(VisualItem item) {
-            if ( item instanceof EdgeItem ) {
-                if ( item.isHighlighted() )
-                    return pastelOrange;
-                else
-                    return Color.LIGHT_GRAY;
-            } else {
-                return Color.BLACK;
-            }
-        } //
-        public Paint getFillColor(VisualItem item) {
-            if ( item.isHighlighted() )
-                return pastelOrange;
-            else if ( item instanceof NodeItem ) {
-                if ( item.isFocus() )
-                    return pastelRed;
-                else
-                    return lightGray;
-            } else {
-                return Color.BLACK;
-            }
-        } //        
-    } //
-    
-} // end of class ForceDemo
\ No newline at end of file
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/TimingStuff.jpage b/org.eclipse.mylyn.ide.dev/developer/src-old/TimingStuff.jpage
deleted file mode 100644
index 3680237..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/TimingStuff.jpage
+++ /dev/null
@@ -1,16 +0,0 @@
-//MylarPlugin.log(this, "text changed: " + event);
-//if (javaEditingTimer == null) {
-//  javaEditingTimer = new PassiveTimer();
-//  javaEditingTimer.restart();
-//}            
-//if (keystrokeTimer != null) keystrokeTimer.stop();
-//keystrokeTimer = new ActiveTimer(
-//  KEYSTROKE_TIMOUT,
-//  new IActiveTimerListener() {
-//      public void fireTimedOut() {
-//          MylarPlugin.getUserManager().getCurrentSession().appendToTimeJavaEditing(
-//              javaEditingTimer.getElapsedInSeconds()
-//          );
-//          javaEditingTimer = null;
-//      }  
-//  }); 
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/UserSelectionMonitor.java b/org.eclipse.mylyn.ide.dev/developer/src-old/UserSelectionMonitor.java
deleted file mode 100644
index 2a415f8..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/UserSelectionMonitor.java
+++ /dev/null
@@ -1,94 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004 - 2005 University Of British Columbia and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     University Of British Columbia - initial API and implementation
- *******************************************************************************/
-/*
- * Created on Feb 8, 2005
-  */
-package org.eclipse.mylyn.monitor;
-
-import org.eclipse.core.internal.resources.File;
-import org.eclipse.jdt.core.IJavaElement;
-import org.eclipse.jdt.internal.ui.javaeditor.JavaEditor;
-import org.eclipse.jdt.internal.ui.javaeditor.JavaOutlinePage;
-import org.eclipse.jdt.internal.ui.packageview.PackageExplorerPart;
-import org.eclipse.jface.text.*;
-import org.eclipse.jface.viewers.ISelection;
-import org.eclipse.search2.internal.ui.SearchView;
-import org.eclipse.ui.IWorkbenchPart;
-import org.eclipse.ui.texteditor.AbstractTextEditor;
-import org.eclipse.ui.views.contentoutline.ContentOutline;
-import org.eclipse.ui.views.markers.internal.ProblemView;
-
-import org.eclipse.mylyn.core.AbstractSelectionMonitor;
-import org.eclipse.mylyn.monitor.stats.UsageSession;
-import org.eclipse.mylyn.monitor.views.UsageStatisticsView;
-
-/**
- * @author Mik Kersten
- */
-public class UserSelectionMonitor extends AbstractSelectionMonitor {
-
-    private final ITextListener TEXT_LISTENER = new ITextListener() {
-        public void textChanged(TextEvent event) {
-            MonitorPlugin.getStatisticsManager().getCurrentSession().getCardinalStatistic(
-                    UsageSession.NUM_KEYSTROKES_JAVA_EDITOR).increment();
-        }
-    };
-    
-    public UserSelectionMonitor() {
-        super();
-    }
-
-    public void handleElementSelection(IJavaElement selected) {
-    }
-
-    protected void handleUnknownSelection(Object selectedObject) {
-    }
-
-    public void handleReferenceNavigation(IJavaElement from, IJavaElement to) {
-    }
-    
-    protected void handleSelection(File file) {
-    } 
-
-    protected void handleWorkbenchPartSelection(IWorkbenchPart part, ISelection selection) {
-        UsageSession session = MonitorPlugin.getStatisticsManager().getCurrentSession();
-        if (part instanceof PackageExplorerPart) {
-            session.getCardinalStatistic(UsageSession.NUM_SELECTIONS_PKG_EXPLORER).increment();
-        } else if (part instanceof ContentOutline) {
-            ContentOutline outline = (ContentOutline)part;
-            if (outline.getCurrentPage() instanceof JavaOutlinePage) { 
-                session.getCardinalStatistic(UsageSession.NUM_SELECTIONS_JAVA_OUTLINE).increment();
-            }
-        } else if (part instanceof SearchView) {
-            session.getCardinalStatistic(UsageSession.NUM_SELECTIONS_SEARCH).increment();
-        } else if (part instanceof ProblemView) {
-            session.getCardinalStatistic(UsageSession.NUM_SELECTIONS_PROBLEMS).increment();
-        } else if (part instanceof AbstractTextEditor) {
-            session.getCardinalStatistic(UsageSession.NUM_SELECTIONS_JAVA_EDITOR).increment();
-        } else {
-            session.getCardinalStatistic(UsageSession.NUM_SELECTIONS_OTHER).increment();
-//            MonitorPlugin.log(this, "unknow selection from: " + part.getClass());
-        }
-        if (UsageStatisticsView.getDefault() != null) {     
-            UsageStatisticsView.getDefault().getViewer().refresh();
-        }
-        if (part instanceof AbstractTextEditor) {
-            if (selection instanceof TextSelection && part instanceof JavaEditor) {
-                JavaEditor currentEditor = (JavaEditor)part;
-                currentEditor.getViewer().removeTextListener(TEXT_LISTENER); // in case already added
-                currentEditor.getViewer().addTextListener(TEXT_LISTENER);
-            }
-        }
-    }
-
-    public void handleImplementorNavigation(IJavaElement from, IJavaElement to) {
-    }
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/bugs/BugzillaActiveSearchTest.java b/org.eclipse.mylyn.ide.dev/developer/src-old/bugs/BugzillaActiveSearchTest.java
deleted file mode 100644
index 33fd05b..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/bugs/BugzillaActiveSearchTest.java
+++ /dev/null
@@ -1,339 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004, 2008 Tasktop Technologies and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     Tasktop Technologies - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.mylyn.sandbox.tests;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import junit.framework.TestCase;
-
-import org.eclipse.jdt.core.IJavaProject;
-import org.eclipse.jdt.core.IType;
-import org.eclipse.mylyn.internal.bugzilla.core.BugzillaCorePlugin;
-import org.eclipse.mylyn.internal.bugzilla.core.IBugzillaConstants;
-import org.eclipse.mylyn.internal.context.core.IActiveSearchListener;
-import org.eclipse.mylyn.internal.sandbox.bridge.bugs.BugzillaMylynSearch;
-import org.eclipse.mylyn.internal.sandbox.bridge.bugs.BugzillaReportInfo;
-import org.eclipse.mylyn.internal.sandbox.bridge.bugs.MylynBugsManager;
-import org.eclipse.mylyn.internal.tasks.core.AbstractTask;
-import org.eclipse.mylyn.internal.tasks.core.TaskCategory;
-import org.eclipse.mylyn.internal.tasks.core.TaskTask;
-import org.eclipse.mylyn.internal.tasks.ui.TaskListManager;
-import org.eclipse.mylyn.internal.tasks.ui.TasksUiPlugin;
-import org.eclipse.mylyn.java.tests.search.SearchPluginTestHelper;
-import org.eclipse.mylyn.java.tests.search.WorkspaceSetupHelper;
-import org.eclipse.mylyn.tasks.core.TaskRepository;
-
-/*
- * TEST CASES TO HANDLE 1. what is here 2. different scopes ( local and remote )
- * 3. no bugs 4. offline bugs
- * 
- * DEGREE OF SEPARATIONS 1 Local bug, qualified reference 2 local bug,
- * unqualified reference 3 remote bug, qualified reference 4 remote bug,
- * unqualified reference 5 NONE
- */
-
-/**
- * Test the bugzilla search functionality of the bridge
- * 
- * @author Shawn Minto
- */
-public class BugzillaActiveSearchTest extends TestCase {
-
-	private TaskRepository repository;
-
-	// SHAWNTODO Add tests for the different types of searches (local qual,
-	// local unqual, fully qual, unqual) and mock up a bugs db for testing
-
-	/** The expected number of results when searching for astNode */
-	// SHAWNTODO add back in when we have a test server mocked up
-	// private static final int NUM_AST_RESULTS = 302;
-	//	
-	// private static final int NUM_AST_SETSOURCERANGE_RESULTS = 15;
-	/** list to add collectors to when notified */
-	private final List<List<?>> lists = new ArrayList<List<?>>();
-
-	private IType astNodeType;
-
-	@Override
-	protected void setUp() throws Exception {
-		WorkspaceSetupHelper.setupWorkspace();
-		repository = new TaskRepository(BugzillaCorePlugin.CONNECTOR_KIND, IBugzillaConstants.ECLIPSE_BUGZILLA_URL);
-		TasksUiPlugin.getRepositoryManager().addRepository(repository);
-
-		IJavaProject jp = WorkspaceSetupHelper.getJdtCoreDomProject();
-		astNodeType = WorkspaceSetupHelper.getType(jp, "org.eclipse.jdt.core.dom.ASTNode");
-	}
-
-	@Override
-	protected void tearDown() throws Exception {
-		WorkspaceSetupHelper.clearDoiModel();
-		TasksUiPlugin.getRepositoryManager().removeRepository(repository,
-				TasksUiPlugin.getDefault().getRepositoriesFilePath());
-	}
-
-	/**
-	 * Test adding and removing ISearchCompletedListeners
-	 */
-	public void testSearchCompletedListenerAddAndRemove() {
-		lists.clear();
-
-		// create 2 listeners
-		IActiveSearchListener l1 = new IActiveSearchListener() {
-			private boolean gathered = false;
-
-			public void searchCompleted(List<?> l) {
-				lists.add(l);
-				gathered = true;
-			}
-
-			public boolean resultsGathered() {
-				return gathered;
-			}
-		};
-		IActiveSearchListener l2 = new IActiveSearchListener() {
-			private boolean gathered = false;
-
-			public void searchCompleted(List<?> l) {
-				lists.add(l);
-				gathered = true;
-			}
-
-			public boolean resultsGathered() {
-				return gathered;
-			}
-		};
-
-		BugzillaMylynSearch s = new BugzillaMylynSearch(BugzillaMylynSearch.UNQUAL, astNodeType,
-				IBugzillaConstants.ECLIPSE_BUGZILLA_URL);
-
-		// add the first listener
-		s.addListener(l1);
-		// remove the first listener
-		s.removeListener(l1);
-
-		// perform the search
-		SearchPluginTestHelper.search(s, l2);
-
-		// make sure that only the second listener added has any results left
-		assertTrue("listener was not removed", lists.size() >= 1 && !l1.resultsGathered());
-		assertTrue("listener was not added", lists.size() == 1);
-
-		// display the time it took for the search
-		MylynBugsManager.getBridge().removeFromLandmarksHash(astNodeType);
-	}
-
-	/**
-	 * Tests that the bridge gets the right data for us This test is wierd because it waits on results.
-	 */
-	public void testBridge() {
-		lists.clear();
-		BugzillaMylynSearch s = new BugzillaMylynSearch(BugzillaMylynSearch.UNQUAL, astNodeType,
-				IBugzillaConstants.ECLIPSE_BUGZILLA_URL);
-
-		IActiveSearchListener l = new IActiveSearchListener() {
-			private boolean gathered = false;
-
-			public void searchCompleted(List<?> results) {
-				lists.add(results);
-				gathered = true;
-			}
-
-			public boolean resultsGathered() {
-				return gathered;
-			}
-		};
-
-		// perform the search
-		SearchPluginTestHelper.search(s, l);
-
-		// make sure we got the right number of bugs back
-		assertTrue("No collector returned", lists.size() != 0);
-		List<?> c = lists.get(0);
-		assertTrue("Results not the right size", c.size() > 0); // TODO should
-		// be
-		// assertEquals
-		// on expected
-		// size
-
-		// display the time it took for the search and the results returned
-		MylynBugsManager.getBridge().removeFromLandmarksHash(astNodeType);
-
-	}
-
-	/**
-	 * Tests that the bridge saves the results of a search so that it can be used later
-	 */
-	public void testSaveResults() {
-		lists.clear();
-		BugzillaMylynSearch s = new BugzillaMylynSearch(BugzillaMylynSearch.UNQUAL, astNodeType,
-				IBugzillaConstants.ECLIPSE_BUGZILLA_URL);
-
-		IActiveSearchListener l = new IActiveSearchListener() {
-			private boolean gathered = false;
-
-			public void searchCompleted(List<?> results) {
-				lists.add(results);
-				gathered = true;
-			}
-
-			public boolean resultsGathered() {
-				return gathered;
-			}
-		};
-
-		// perform the search
-		SearchPluginTestHelper.search(s, l);
-
-		// do an inital search
-		assertTrue("No collectors returned", lists.size() != 0);
-		List<?> c = lists.get(0);
-		assertTrue("Results not the right size", c.size() > 0);
-		// TODO should be assertEquals on expected size
-
-		// check that the search has been saved
-		List<BugzillaReportInfo> saved = MylynBugsManager.getBridge().getFromLandmarksHash(astNodeType,
-				BugzillaMylynSearch.UNQUAL);
-		assertTrue("Results not cached", saved != null);
-		if (saved == null) {
-			fail();
-		} else {
-			assertTrue("Results not the right size", saved.size() > 0);
-			// TODO should be assertEquals on expected size
-
-			assertTrue(c.containsAll(saved) && saved.containsAll(c));
-			MylynBugsManager.getBridge().removeFromLandmarksHash(astNodeType);
-		}
-	}
-
-	public void testLocalBugUnqual() throws InterruptedException {
-		lists.clear();
-
-		String bugPrefix = "<server>-";
-
-		TaskListManager manager = TasksUiPlugin.getTaskListManager();
-		TaskCategory cat = new TaskCategory("Testing Category");
-		manager.getTaskList().addCategory(cat);
-		AbstractTask bugTask1 = new TaskTask(bugPrefix, "" + 94185, "<bugzilla info>");
-
-		manager.getTaskList().addTask(bugTask1, cat);
-		// cat.addTask(bugTask1);
-		while (bugTask1.isSynchronizing()) {
-			Thread.sleep(500);
-		}
-		AbstractTask bugTask2 = new TaskTask(bugPrefix, "" + 3692, "<bugzilla info>");
-		manager.getTaskList().addTask(bugTask2, cat);
-		// cat.addTask(bugTask2);
-		while (bugTask2.isSynchronizing()) {
-			Thread.sleep(500);
-		}
-		AbstractTask bugTask3 = new TaskTask(bugPrefix, "" + 3693, "<bugzilla info>");
-		manager.getTaskList().addTask(bugTask3, cat);
-		// cat.addTask(bugTask3);
-		while (bugTask3.isSynchronizing()) {
-			Thread.sleep(500);
-		}
-
-		AbstractTask bugTask4 = new TaskTask(bugPrefix, "" + 9583, "<bugzilla info>");
-		manager.getTaskList().addTask(bugTask4, cat);
-		// cat.addTask(bugTask4);
-		while (bugTask4.isSynchronizing()) {
-			Thread.sleep(500);
-		}
-
-		BugzillaMylynSearch s = new BugzillaMylynSearch(BugzillaMylynSearch.LOCAL_UNQUAL, astNodeType,
-				IBugzillaConstants.ECLIPSE_BUGZILLA_URL);
-
-		IActiveSearchListener l = new IActiveSearchListener() {
-			private boolean gathered = false;
-
-			public void searchCompleted(List<?> results) {
-				lists.add(results);
-				gathered = true;
-			}
-
-			public boolean resultsGathered() {
-				return gathered;
-			}
-		};
-
-		// perform the search
-		SearchPluginTestHelper.search(s, l);
-
-		// do an inital search
-		assertTrue("No collectors returned", lists.size() != 0);
-		List<?> c = lists.get(0);
-		assertEquals("Results not the right size", 3, c.size());
-
-		MylynBugsManager.getBridge().removeFromLandmarksHash(astNodeType);
-		TasksUiPlugin.getTaskList().deleteCategory(cat);
-	}
-
-	// TODO need to test a bug that wraps...should fail since we can only search
-	// on a single line
-	public void testLocalBugFullyQual() throws InterruptedException {
-		lists.clear();
-
-		String bugPrefix = "Bugzilla-";
-
-		TaskListManager manager = TasksUiPlugin.getTaskListManager();
-		TaskCategory cat = new TaskCategory("Testing Category");
-		manager.getTaskList().addCategory(cat);
-		AbstractTask bugTask1 = new TaskTask(bugPrefix, "" + 94185, "<bugzilla info>");
-		manager.getTaskList().addTask(bugTask1, cat);
-		// cat.addTask(bugTask1);
-		while (bugTask1.isSynchronizing()) {
-			Thread.sleep(500);
-		}
-
-		AbstractTask bugTask2 = new TaskTask(bugPrefix, "" + 9583, "<bugzilla info>");
-		manager.getTaskList().addTask(bugTask2, cat);
-		// cat.addTask(bugTask2);
-		while (bugTask2.isSynchronizing()) {
-			Thread.sleep(500);
-		}
-		AbstractTask bugTask3 = new TaskTask(bugPrefix, "" + 3693, "<bugzilla info>");
-		manager.getTaskList().addTask(bugTask3, cat);
-		// cat.addTask(bugTask3);
-		while (bugTask3.isSynchronizing()) {
-			Thread.sleep(500);
-		}
-
-		BugzillaMylynSearch s = new BugzillaMylynSearch(BugzillaMylynSearch.LOCAL_QUAL, astNodeType,
-				IBugzillaConstants.ECLIPSE_BUGZILLA_URL);
-
-		IActiveSearchListener l = new IActiveSearchListener() {
-			private boolean gathered = false;
-
-			public void searchCompleted(List<?> results) {
-				lists.add(results);
-				gathered = true;
-			}
-
-			public boolean resultsGathered() {
-				return gathered;
-			}
-		};
-
-		// perform the search
-		SearchPluginTestHelper.search(s, l);
-
-		// do an inital search
-		assertTrue("No collectors returned", lists.size() != 0);
-		List<?> c = lists.get(0);
-		assertEquals("Results not the right size", 1, c.size());
-
-		MylynBugsManager.getBridge().removeFromLandmarksHash(astNodeType);
-		TasksUiPlugin.getTaskList().deleteCategory(cat);
-	}
-
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/bugs/BugzillaContextLabelProvider.java b/org.eclipse.mylyn.ide.dev/developer/src-old/bugs/BugzillaContextLabelProvider.java
deleted file mode 100644
index ae245e4..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/bugs/BugzillaContextLabelProvider.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004, 2008 Tasktop Technologies and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     Tasktop Technologies - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.mylyn.internal.sandbox.bridge.bugs;
-
-import org.eclipse.mylyn.context.core.AbstractContextStructureBridge;
-import org.eclipse.mylyn.context.core.ContextCore;
-import org.eclipse.mylyn.context.core.IInteractionElement;
-import org.eclipse.mylyn.context.core.IInteractionRelation;
-import org.eclipse.mylyn.internal.context.ui.AbstractContextLabelProvider;
-import org.eclipse.mylyn.internal.context.ui.ContextUiImages;
-import org.eclipse.mylyn.internal.provisional.commons.ui.CommonImages;
-import org.eclipse.mylyn.tasks.ui.TasksUiImages;
-import org.eclipse.swt.graphics.Image;
-
-/**
- * @author Mik Kersten
- */
-public class BugzillaContextLabelProvider extends AbstractContextLabelProvider {
-
-	@Override
-	protected Image getImage(IInteractionElement node) {
-		return CommonImages.getImage(TasksUiImages.TASK_REMOTE);
-	}
-
-	@Override
-	protected Image getImage(IInteractionRelation edge) {
-		return ContextUiImages.getImage(MylynBugsManager.EDGE_REF_BUGZILLA);
-	}
-
-	@Override
-	protected Image getImageForObject(Object object) {
-		return CommonImages.getImage(TasksUiImages.TASK_REMOTE);
-	}
-
-	@Override
-	protected String getTextForObject(Object node) {
-		return "" + node;
-	}
-
-	/**
-	 * TODO: slow?
-	 */
-	@Override
-	protected String getText(IInteractionElement node) {
-		// try to get from the cache before downloading
-		Object report;
-		BugzillaReportInfo reportNode = MylynBugsManager.getReferenceProvider().getCached(node.getHandleIdentifier());
-		AbstractContextStructureBridge bridge = ContextCore.getStructureBridge(BugzillaStructureBridge.CONTENT_TYPE);
-
-		if (reportNode != null) {
-			report = reportNode;
-		} else {
-			report = bridge.getObjectForHandle(node.getHandleIdentifier());
-		}
-		return bridge.getLabel(report);
-	}
-
-	@Override
-	protected String getText(IInteractionRelation edge) {
-		return BugzillaReferencesProvider.NAME;
-	}
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/bugs/BugzillaEditingMonitor.java b/org.eclipse.mylyn.ide.dev/developer/src-old/bugs/BugzillaEditingMonitor.java
deleted file mode 100644
index bbc9fb6..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/bugs/BugzillaEditingMonitor.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004, 2008 Tasktop Technologies and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     Tasktop Technologies - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.mylyn.internal.sandbox.bridge.bugs;
-
-import org.eclipse.jface.viewers.ISelection;
-import org.eclipse.jface.viewers.StructuredSelection;
-import org.eclipse.mylyn.internal.tasks.ui.deprecated.AbstractRepositoryTaskEditor;
-import org.eclipse.mylyn.internal.tasks.ui.editors.RepositoryTaskSelection;
-import org.eclipse.mylyn.monitor.ui.AbstractUserInteractionMonitor;
-import org.eclipse.mylyn.tasks.ui.editors.TaskEditor;
-import org.eclipse.ui.IWorkbenchPart;
-
-/**
- * @author Mik Kersten
- */
-public class BugzillaEditingMonitor extends AbstractUserInteractionMonitor {
-
-	public BugzillaEditingMonitor() {
-		super();
-	}
-
-	@Override
-	protected void handleWorkbenchPartSelection(IWorkbenchPart part, ISelection selection, boolean contributeToContext) {
-		if (!(part instanceof AbstractRepositoryTaskEditor) && !(part instanceof TaskEditor)) {
-			return;
-		}
-
-		if (selection instanceof StructuredSelection) {
-			StructuredSelection ss = (StructuredSelection) selection;
-			Object object = ss.getFirstElement();
-			if (object instanceof RepositoryTaskSelection) {
-				super.handleElementSelection(part, object, contributeToContext);
-			}
-		}
-	}
-
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/bugs/BugzillaMylynSearch.java b/org.eclipse.mylyn.ide.dev/developer/src-old/bugs/BugzillaMylynSearch.java
deleted file mode 100644
index 3c32e94..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/bugs/BugzillaMylynSearch.java
+++ /dev/null
@@ -1,188 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004, 2008 Tasktop Technologies and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     Tasktop Technologies - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.mylyn.internal.sandbox.bridge.bugs;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.Status;
-import org.eclipse.core.runtime.jobs.Job;
-import org.eclipse.jdt.core.IJavaElement;
-import org.eclipse.jdt.core.IMember;
-import org.eclipse.mylyn.context.core.InterestComparator;
-import org.eclipse.mylyn.internal.context.core.IActiveSearchListener;
-import org.eclipse.mylyn.internal.context.core.IActiveSearchOperation;
-
-/**
- * Used to facilitate bugzilla searches based on IJavaElements
- * 
- * @author Shawn Minto
- */
-public class BugzillaMylynSearch implements IActiveSearchOperation {
-
-	// scope identifiers
-	public static final int LOCAL_QUAL = 1; // local implies a bugzilla task,
-
-	// not just an offline report
-
-	public static final int LOCAL_UNQUAL = 2;
-
-	public static final int FULLY_QUAL = 3;
-
-	public static final int UNQUAL = 4;
-
-	private final int scope;
-
-	private final IJavaElement element;
-
-	private String handle = "";
-
-	private String serverUrl = "";
-
-	/**
-	 * Constructor
-	 * 
-	 * @param scope
-	 *            The scope of this search
-	 */
-	public BugzillaMylynSearch(int scope, IJavaElement element, String serverUrl) {
-		this.scope = scope;
-		this.element = element;
-		this.serverUrl = serverUrl;
-	}
-
-	public IStatus run(IProgressMonitor monitor) {
-		return run(monitor, Job.DECORATE);
-	}
-
-	public IStatus run(IProgressMonitor monitor, int priority) {
-		handle = element.getHandleIdentifier() + " " + scope;
-		List<IJavaElement> landmarks = new ArrayList<IJavaElement>();
-		landmarks.add(element);
-
-		if (!BugzillaSearchManager.doesJobExist(handle)) {
-
-			// perform the bugzilla search
-			// get only the useful landmarks (IMember)
-			List<IMember> members = getMemberLandmarks(landmarks);
-
-			// go through all of the landmarks that we are given and perform a
-			// search on them
-			for (IMember m : members) {
-
-				// FIXME: decide whether to do leave the caching of searches in
-				// for now or not
-				// check if we have the info cached
-				// List<BugzillaReportNode> landmarkDoi =
-				// MylarTaskListPlugin.getBridge()
-				// .getFromLandmarksHash(m, scope);
-
-				// if (landmarkDoi != null) {
-				// //TODO decide when to queue up and do a refresh search
-				// notifySearchCompleted(landmarkDoi);
-				// continue;
-				// }
-
-				// create a search operation so that we can search
-				BugzillaMylynSearchOperation op = new BugzillaMylynSearchOperation(this, m, scope);
-
-				// create a new search job so that it can be scheduled and
-				// run as a background thread
-				Job searchJob = new BugzillaMylynSearchJob("Querying Bugzilla Server - Mylar - "
-						+ op.getSearchMemberName(), op);
-
-				// schedule the new search job
-				searchJob.setPriority(priority);
-				searchJob.schedule();
-
-				// save this searchJobs handle so that we can cancel it if need
-				// be
-				BugzillaSearchManager.addJob(handle, searchJob);
-			}
-		}
-		return Status.OK_STATUS;
-	}
-
-	/** List of listeners wanting to know about the searches */
-	private final List<IActiveSearchListener> listeners = new ArrayList<IActiveSearchListener>();
-
-	/**
-	 * Add a listener for when the bugzilla search is completed
-	 * 
-	 * @param l
-	 *            The listener to add
-	 */
-	public void addListener(IActiveSearchListener l) {
-		// add the listener to the list
-		listeners.add(l);
-	}
-
-	/**
-	 * Remove a listener for when the bugzilla search is completed
-	 * 
-	 * @param l
-	 *            The listener to remove
-	 */
-	public void removeListener(IActiveSearchListener l) {
-		// remove the listener from the list
-		listeners.remove(l);
-	}
-
-	/**
-	 * Notify all of the listeners that the bugzilla search is completed
-	 * 
-	 * @param doiList
-	 *            A list of BugzillaSearchHitDoiInfo
-	 * @param member
-	 *            The IMember that the search was performed on
-	 */
-	public void notifySearchCompleted(List<BugzillaReportInfo> doiList) {
-		// go through all of the listeners and call searchCompleted(colelctor,
-		// member)
-		BugzillaSearchManager.removeSearchJob(handle);
-		for (IActiveSearchListener listener : listeners) {
-			listener.searchCompleted(doiList);
-		}
-	}
-
-	/**
-	 * Get only the landmarks that are IMember and sort them according to their DOI value (highest to lowest)
-	 * 
-	 * @param landmarks
-	 *            The landmarks to check
-	 * @return List of IMember landmarks sorted by DOI value
-	 */
-	public static List<IMember> getMemberLandmarks(List<IJavaElement> landmarks) {
-		List<IMember> memberLandmarks = new ArrayList<IMember>();
-
-		for (IJavaElement je : landmarks) {
-
-			// keep only the IMember landmarks
-			if (je instanceof IMember) {
-				memberLandmarks.add((IMember) je);
-			}
-		}
-
-		// sort the landmarks
-		Collections.sort(memberLandmarks, new InterestComparator<IMember>());
-
-		return memberLandmarks;
-	}
-
-	public String getServerUrl() {
-		return serverUrl;
-	}
-
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/bugs/BugzillaMylynSearchJob.java b/org.eclipse.mylyn.ide.dev/developer/src-old/bugs/BugzillaMylynSearchJob.java
deleted file mode 100644
index d8a45db..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/bugs/BugzillaMylynSearchJob.java
+++ /dev/null
@@ -1,104 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004, 2008 Tasktop Technologies and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     Tasktop Technologies - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.mylyn.internal.sandbox.bridge.bugs;
-
-import javax.security.auth.login.LoginException;
-
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.Status;
-import org.eclipse.core.runtime.jobs.Job;
-import org.eclipse.jface.dialogs.ErrorDialog;
-import org.eclipse.jface.dialogs.MessageDialog;
-import org.eclipse.mylyn.internal.bugzilla.core.BugzillaCorePlugin;
-import org.eclipse.mylyn.internal.bugzilla.ui.BugzillaUiPlugin;
-import org.eclipse.ui.PlatformUI;
-
-/**
- * The bugzilla search job used to search a bugzilla site
- * 
- * @author Shawn Minto
- * @author Mik Kersten
- */
-public class BugzillaMylynSearchJob extends Job {
-
-	/** The search operation used to perform the query */
-	private final BugzillaMylynSearchOperation operation;
-
-	/**
-	 * Constructor
-	 * 
-	 * @param name
-	 *            Job name
-	 * @param operation
-	 *            The operation to perform the search query
-	 */
-	public BugzillaMylynSearchJob(String name, BugzillaMylynSearchOperation operation) {
-		super(name);
-		this.operation = operation;
-	}
-
-	@Override
-	protected IStatus run(IProgressMonitor monitor) {
-		final IStatus[] status = new IStatus[1];
-
-		try {
-			// execute the search operation
-			operation.execute(monitor);
-
-			// get the status of the search operation
-			status[0] = operation.getStatus();
-
-			// determine if there was an error, if it was cancelled, or if it is
-			// ok
-			if (status[0] == null) {
-
-			} else if (status[0].getCode() == IStatus.CANCEL) {
-				// it was cancelled, so just return
-				status[0] = Status.OK_STATUS;
-
-				// make sure that we know this job is not running anymore
-				BugzillaSearchManager.removeSearchJob(operation.getSearchMember().getHandleIdentifier() + " "
-						+ operation.getScope());// runningJobs.remove(operation.getSearchMember());
-				return status[0];
-			} else if (!status[0].isOK()) {
-				// there was an error, so display an error message
-				PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {
-					public void run() {
-						ErrorDialog.openError(null, "Bugzilla Search Error", null, status[0]);
-					}
-				});
-				status[0] = Status.OK_STATUS;
-
-				// make sure we know that this job is not running anymore
-				BugzillaSearchManager.removeSearchJob(operation.getSearchMember().getHandleIdentifier() + " "
-						+ operation.getScope());// runningJobs.remove(operation.getSearchMember());
-				return status[0];
-			}
-		} catch (LoginException e) {
-			// we had a problem while searching that seems like a login info
-			// problem
-			// thrown in BugzillaSearchOperation
-			MessageDialog.openError(
-					null,
-					"Login Error",
-					"Bugzilla could not log you in to get the information you requested since login name or password is incorrect.\nPlease check your settings in the bugzilla preferences. ");
-			BugzillaCorePlugin.log(new Status(IStatus.ERROR, BugzillaUiPlugin.ID_PLUGIN, IStatus.OK, "", e));
-		} finally {
-			// make sure that we know that this job is not running anymore
-			BugzillaSearchManager.removeSearchJob(operation.getSearchMember().getHandleIdentifier() + " "
-					+ operation.getScope());// .runningJobs.remove(operation.getSearchMember());
-		}
-
-		return status[0];
-	}
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/bugs/BugzillaMylynSearchOperation.java b/org.eclipse.mylyn.ide.dev/developer/src-old/bugs/BugzillaMylynSearchOperation.java
deleted file mode 100644
index 54f30e8..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/bugs/BugzillaMylynSearchOperation.java
+++ /dev/null
@@ -1,540 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004, 2008 Tasktop Technologies and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     Tasktop Technologies - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.mylyn.internal.sandbox.bridge.bugs;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Set;
-
-import javax.security.auth.login.LoginException;
-
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.MultiStatus;
-import org.eclipse.core.runtime.Status;
-import org.eclipse.jdt.core.IJavaElement;
-import org.eclipse.jdt.core.IMember;
-import org.eclipse.jdt.core.IType;
-import org.eclipse.jface.resource.ImageDescriptor;
-import org.eclipse.mylyn.commons.core.StatusHandler;
-import org.eclipse.mylyn.internal.bugzilla.core.BugzillaCorePlugin;
-import org.eclipse.mylyn.internal.sandbox.ui.SandboxUiPlugin;
-import org.eclipse.mylyn.internal.tasks.core.AbstractTask;
-import org.eclipse.mylyn.internal.tasks.core.AbstractTaskCategory;
-import org.eclipse.mylyn.internal.tasks.core.deprecated.RepositoryTaskData;
-import org.eclipse.mylyn.internal.tasks.core.deprecated.TaskComment;
-import org.eclipse.mylyn.internal.tasks.ui.TasksUiPlugin;
-import org.eclipse.mylyn.internal.tasks.ui.deprecated.TaskFactory;
-import org.eclipse.mylyn.internal.tasks.ui.search.AbstractRepositorySearchQuery;
-import org.eclipse.mylyn.internal.tasks.ui.util.TasksUiInternal;
-import org.eclipse.mylyn.tasks.core.ITask;
-import org.eclipse.mylyn.tasks.core.TaskRepository;
-import org.eclipse.mylyn.tasks.core.data.TaskData;
-import org.eclipse.mylyn.tasks.ui.TasksUi;
-import org.eclipse.ui.actions.WorkspaceModifyOperation;
-
-/**
- * Bugzilla search operation for Mylar
- * 
- * @author Shawn Minto
- * @author Mik Kersten
- */
-public class BugzillaMylynSearchOperation extends WorkspaceModifyOperation implements IBugzillaSearchOperation {
-
-	/** The IMember we are doing the search for */
-	private final IMember javaElement;
-
-	/** The bugzilla collector for the search */
-	private ProgressQueryHitCollector collector = null;//SearchHitCollector
-
-	/** The status of the search operation */
-	private IStatus status;
-
-	/** The LoginException that was thrown when trying to do the search */
-	private LoginException loginException = null;
-
-	/** The fully qualified name of the member we are searching for */
-	private final String name;
-
-	/** The bugzilla search query */
-	private AbstractRepositorySearchQuery query;
-
-	private final BugzillaMylynSearch search;
-
-	private final int scope;
-
-	public BugzillaMylynSearchOperation(BugzillaMylynSearch search, IMember m, int scope) {
-		this.javaElement = m;
-		this.search = search;
-		this.scope = scope;
-		name = getFullyQualifiedName(m);
-	}
-
-	/**
-	 * Get the fully qualified name of a IMember TODO: move to a more central location so that others can use this, but
-	 * don't want to add unecessary coupling
-	 * 
-	 * @return String representing the fully qualified name
-	 */
-	public static String getFullyQualifiedName(IJavaElement je) {
-		if (!(je instanceof IMember)) {
-			return null;
-		}
-
-		IMember m = (IMember) je;
-		if (m.getDeclaringType() == null) {
-			return ((IType) m).getFullyQualifiedName();
-		} else {
-			return m.getDeclaringType().getFullyQualifiedName() + "." + m.getElementName();
-		}
-	}
-
-	@Override
-	public void execute(IProgressMonitor monitor) {
-
-		ProgressQueryHitCollector searchCollector = null;
-
-		if (scope == BugzillaMylynSearch.FULLY_QUAL) {
-			searchCollector = searchQualified(search.getServerUrl(), monitor);
-		} else if (scope == BugzillaMylynSearch.UNQUAL) {
-			searchCollector = searchUnqualified(search.getServerUrl(), monitor);
-		} else if (scope == BugzillaMylynSearch.LOCAL_QUAL) {
-			searchCollector = searchLocalQual(monitor);
-		} else if (scope == BugzillaMylynSearch.LOCAL_UNQUAL) {
-			searchCollector = searchLocalUnQual(monitor);
-		} else {
-			status = Status.OK_STATUS;
-			return;
-		}
-
-		if (searchCollector == null) {
-			search.notifySearchCompleted(new ArrayList<BugzillaReportInfo>());
-			return;
-		}
-
-		Set<AbstractTask> l = searchCollector.getTasks();
-
-		// get the list of doi elements
-		List<BugzillaReportInfo> doiList = getDoiList(l);
-
-		// we completed the search, so notify all of the listeners
-		// that the search has been completed
-		MylynBugsManager.getBridge().addToLandmarksHash(doiList, javaElement, scope);
-		search.notifySearchCompleted(doiList);
-		// MIK: commmented out logging
-		// MonitorPlugin.log(this, "There were " + doiList.size() + " items
-		// found");
-	}
-
-	/**
-	 * Search the local bugs for the member using the qualified name
-	 * 
-	 * @param monitor
-	 *            The progress monitor to search with
-	 * @return The QueryHitCollector with the results of the search
-	 */
-	@SuppressWarnings("deprecation")
-	private ProgressQueryHitCollector searchLocalQual(IProgressMonitor monitor) {
-
-		// get the fully qualified name for searching
-		String elementName = getFullyQualifiedName(javaElement);
-
-		// setup the search result collector
-		collector = new ProgressQueryHitCollector(TasksUiInternal.getTaskList(), new TaskFactory(null));//SearchHitCollector(TasksUiPlugin.getTaskList());
-		//collector.setOperation(this);
-		collector.setProgressMonitor(monitor);
-
-		// get all of the root tasks and start the search
-		// FIXME
-//		Set<AbstractTask> tasks = TasksUiPlugin.getTaskList().getOrphanContainer(
-//				LocalRepositoryConnector.REPOSITORY_URL).getChildren();
-		Set<ITask> tasks = new HashSet<ITask>();
-		searchLocal(tasks, collector, elementName, monitor);
-		for (AbstractTaskCategory cat : TasksUiPlugin.getTaskList().getTaskCategories()) {
-			searchLocal(cat.getChildren(), collector, elementName, monitor);
-		}
-
-		// return the collector
-		return collector;
-	}
-
-	/**
-	 * Search the local bugs for the member using the unqualified name
-	 * 
-	 * @param monitor
-	 *            The progress monitor to search with
-	 * @return The QueryHitCollector with the results of the search
-	 */
-	@SuppressWarnings("deprecation")
-	private ProgressQueryHitCollector searchLocalUnQual(IProgressMonitor monitor) {
-
-		// get the element name for searching
-		String elementName = javaElement.getElementName();
-
-		// setup the search result collector
-		collector = new ProgressQueryHitCollector(TasksUiInternal.getTaskList(), new TaskFactory(null));//SearchHitCollector(TasksUiPlugin.getTaskList());
-		//collector.setOperation(this);
-		collector.setProgressMonitor(monitor);
-
-		// get all of the root tasks and start the search
-		// FIXME
-//		Set<AbstractTask> tasks = TasksUiPlugin.getTaskList().getOrphanContainer(
-//				LocalRepositoryConnector.REPOSITORY_URL).getChildren();
-		Set<ITask> tasks = new HashSet<ITask>();
-		searchLocal(tasks, collector, elementName, monitor);
-		for (AbstractTaskCategory cat : TasksUiPlugin.getTaskList().getTaskCategories()) {
-			searchLocal(cat.getChildren(), collector, elementName, monitor);
-		}
-		// return the collector
-		return collector;
-	}
-
-	/**
-	 * Search the local bugs for the member
-	 * 
-	 * @param tasks
-	 *            The tasks to search
-	 * @param searchCollector
-	 *            The collector to add the results to
-	 * @param elementName
-	 *            The name of the element that we are looking for
-	 * @param monitor
-	 *            The progress monitor
-	 */
-	private void searchLocal(Collection<ITask> tasks, ProgressQueryHitCollector searchCollector, String elementName,
-			IProgressMonitor monitor) {
-		if (tasks == null) {
-			return;
-		}
-
-		// go through all of the tasks
-		for (ITask task : tasks) {
-			monitor.worked(1);
-
-			// check what kind of task it is
-//			if (task instanceof BugzillaTask) {
-
-			// we have a bugzilla task, so get the bug report
-//				BugzillaTask bugTask = (BugzillaTask) task;
-			RepositoryTaskData bugTaskData = TasksUiPlugin.getTaskDataStorageManager().getNewTaskData(
-					task.getRepositoryUrl(), task.getTaskId());
-			//RepositoryTaskData bugTaskData = bugTask.getTaskData();
-
-			// parse the bug report for the element that we are searching
-			// for
-			boolean isHit = search(elementName, bugTaskData);
-
-			// determine if we have a hit or not
-			if (isHit) {
-//					// make a search hit from the bug and then add it to the collector
-//					BugzillaQueryHit hit = new BugzillaQueryHit(TasksUiPlugin.getTaskList(), bugTaskData.getDescription(), "", bugTaskData.getRepositoryUrl(), bugTaskData.getId(), null, "");
-//					BugzillaTask task = new BugzillaTask();
-				// FIXME
-				//					searchCollector.accept(bugTask);
-			}
-//			}
-		}
-		status = Status.OK_STATUS;
-	}
-
-	/**
-	 * Search the bug for the given element name
-	 * 
-	 * @param elementName
-	 *            The name of the element to search for
-	 * @param bug
-	 *            The bug to search in
-	 */
-	private boolean search(String elementName, RepositoryTaskData bug) {
-
-		if (bug == null) {
-			return false; // MIK: added null check here
-		}
-		String description = bug.getDescription();
-		String summary = bug.getSummary();
-		List<TaskComment> taskComments = bug.getComments();
-
-		// search the summary and the summary
-		if (Util.hasElementName(elementName, summary)) {
-			return true;
-		}
-
-		if (Util.hasElementName(elementName, description)) {
-			return true;
-		}
-
-		Iterator<TaskComment> comItr = taskComments.iterator();
-		while (comItr.hasNext()) {
-			TaskComment taskComment = comItr.next();
-			String commentText = taskComment.getText();
-			// search the text for a reference to the element
-			if (Util.hasElementName(elementName, commentText)) {
-				return true;
-			}
-		}
-		return false;
-	}
-
-	/**
-	 * Perform the actual search on the Bugzilla server
-	 * 
-	 * @param url
-	 *            The url to use for the search
-	 * @param searchCollector
-	 *            The collector to put the search results into
-	 * @param monitor
-	 *            The progress monitor to use for the search
-	 * @return The QueryHitCollector with the search results
-	 */
-	private ProgressQueryHitCollector search(String url, TaskRepository repository,
-			ProgressQueryHitCollector searchCollector, IProgressMonitor monitor) {
-
-		// set the initial number of matches to 0
-		int matches = 0;
-		// setup the progress monitor and start the search
-		searchCollector.setProgressMonitor(monitor);
-
-		BugzillaSearchEngine engine = new BugzillaSearchEngine(repository, url);
-		try {
-			// perform the search
-			status = engine.search(searchCollector, matches);
-
-			// check the status so that we don't keep searching if there
-			// is a problem
-			if (status.getCode() == IStatus.CANCEL) {
-				return null;
-			} else if (!status.isOK()) {
-				MultiStatus errorStatus = new MultiStatus(SandboxUiPlugin.ID_PLUGIN, 0, "Search error", null);
-				errorStatus.add(status);
-				StatusHandler.fail(errorStatus);
-				return null;
-			}
-			return searchCollector;
-		} catch (LoginException e) {
-			// save this exception to throw later
-			this.loginException = e;
-		}
-		return null;
-	}
-
-	/**
-	 * Perform a search for qualified instances of the member
-	 * 
-	 * @param monitor
-	 *            The progress monitor to use
-	 * @return The QueryHitCollector with the search results
-	 */
-	@SuppressWarnings("deprecation")
-	private ProgressQueryHitCollector searchQualified(String repositoryUrl, IProgressMonitor monitor) {
-		// create a new collector for the results
-		collector = new ProgressQueryHitCollector(TasksUiInternal.getTaskList(), new TaskFactory(null));//SearchHitCollector(TasksUiPlugin.getTaskList());
-		//collector.setOperation(this);
-		collector.setProgressMonitor(monitor);
-
-		// get the search url
-		String url = Util.getExactSearchURL(repositoryUrl, javaElement);
-		TaskRepository repository = TasksUi.getRepositoryManager().getRepository(BugzillaCorePlugin.CONNECTOR_KIND,
-				repositoryUrl);
-		return search(url, repository, collector, monitor);
-	}
-
-	/**
-	 * Perform a search for unqualified instances of the member
-	 * 
-	 * @param monitor
-	 *            The progress monitor to use
-	 * @return The QueryHitCollector with the search results
-	 */
-	@SuppressWarnings("deprecation")
-	private ProgressQueryHitCollector searchUnqualified(String repositoryUrl, IProgressMonitor monitor) {
-		// create a new collector for the results
-		collector = new ProgressQueryHitCollector(TasksUiInternal.getTaskList(), new TaskFactory(null));//SearchHitCollector(TasksUiPlugin.getTaskList());
-		//collector.setOperation(this);
-		collector.setProgressMonitor(monitor);
-
-		// get the search url
-		String url = Util.getInexactSearchURL(repositoryUrl, javaElement);
-		TaskRepository repository = TasksUi.getRepositoryManager().getRepository(BugzillaCorePlugin.CONNECTOR_KIND,
-				repositoryUrl);
-
-		return search(url, repository, collector, monitor);
-	}
-
-	/**
-	 * Perform a second pass parse to determine if there are any stack traces in the bug - currently only used for the
-	 * exact search results
-	 * 
-	 * @param doiList
-	 *            - the list of BugzillaSearchHitDOI elements to parse
-	 */
-	public static void secondPassBugzillaParser(List<BugzillaReportInfo> doiList) {
-
-		// go through each of the items in the doiList
-		for (BugzillaReportInfo info : doiList) {
-
-			// get the bug report so that we have all of the data
-			// - descriptions, comments, etc
-			TaskData b = null;
-			try {
-				b = info.getBug();
-			} catch (Exception e) {
-				// don't care since null will be caught
-			}
-
-			// if the report could not be downloaded, try the next one
-			if (b == null) {
-				continue;
-			}
-
-			// Add back:
-			// see if the summary has a stack trace in it
-//			StackTrace[] stackTrace = StackTrace.getStackTrace(b.getDescription(), b.getDescription());
-//			if (stackTrace != null) {
-//
-//				// add the stack trace to the doi info
-//				info.setExact(true);
-//				info.addStackTraces(stackTrace);
-//			}
-
-			// Add back:
-			// go through all of the comments for the bug
-//			Iterator<TaskComment> comItr = b.getComments().iterator();
-//			while (comItr.hasNext()) {
-//				TaskComment taskComment = comItr.next();
-//				String commentText = taskComment.getText();
-//
-//				// see if the comment has a stack trace in it
-//				stackTrace = StackTrace.getStackTrace(commentText, taskComment);
-//				if (stackTrace != null) {
-//
-//					// add the stack trace to the doi info
-//					info.setExact(true);
-//					info.addStackTraces(stackTrace);
-//				}
-//			}
-		}
-	}
-
-	/**
-	 * Add the results returned to the Hash of landmarks
-	 * 
-	 * @param results
-	 *            The list of results
-	 * @param isExact
-	 *            whether the search was exact or not
-	 */
-	private List<BugzillaReportInfo> getDoiList(Set<AbstractTask> results) {
-		List<BugzillaReportInfo> doiList = new ArrayList<BugzillaReportInfo>();
-
-		boolean isExact = (scope == BugzillaMylynSearch.FULLY_QUAL || scope == BugzillaMylynSearch.LOCAL_QUAL) ? true
-				: false;
-
-		BugzillaReportInfo info = null;
-		// go through all of the results and create a DoiInfo list
-		for (ITask hit : results) {
-
-			try {
-				float value = 0;
-				info = new BugzillaReportInfo(value, hit, isExact);
-
-				// only download the bug for the exact matches
-				// downloading bugs kills the time - can we do this elsewhere? -
-				// different thread? persistant?
-				// if(isExact){
-				// // get the bug report for the doi info item
-				// BugReport b = BugzillaRepositoryUtil.getInstance().getBug(
-				// hit.getId());
-				// // add the bug to the doi info for future use
-				// info.setBug(b);
-				// }
-
-			} catch (Exception e) {
-				StatusHandler.log(new Status(IStatus.INFO, SandboxUiPlugin.ID_PLUGIN, "Search failed", e));
-			} finally {
-				doiList.add(info);
-			}
-		}
-		return doiList;
-	}
-
-	/**
-	 * @see org.eclipse.mylyn.internal.bugs.core.search.IBugzillaSearchOperation#getStatus()
-	 */
-	public IStatus getStatus() throws LoginException {
-		// if a LoginException was thrown while trying to search, throw this
-		if (loginException == null) {
-			return status;
-		} else {
-			throw loginException;
-		}
-	}
-
-	/**
-	 * @see org.eclipse.mylyn.internal.bugs.core.search.IBugzillaSearchOperation#getImageDescriptor()
-	 */
-	public ImageDescriptor getImageDescriptor() {
-		return null;
-	}
-
-	/**
-	 * Get the member that we are performing the search for
-	 * 
-	 * @return The member this search is being performed for
-	 */
-	public IMember getSearchMember() {
-		return javaElement;
-	}
-
-	/**
-	 * Get the name of the member that we are searching for
-	 * 
-	 * @return The fully qualified name of the member
-	 */
-	public String getSearchMemberName() {
-		return name;
-	}
-
-	/**
-	 * @see org.eclipse.mylyn.internal.bugs.core.search.IBugzillaSearchOperation#getQuery()
-	 */
-	public AbstractRepositorySearchQuery getQuery() {
-		return query;
-	}
-
-	/**
-	 * @see org.eclipse.mylyn.internal.bugs.core.search.IBugzillaSearchOperation#setQuery(org.eclipse.mylyn.internal.bugs.core.search.AbstractRepositorySearchQuery)
-	 */
-	public void setQuery(AbstractRepositorySearchQuery newQuery) {
-		this.query = newQuery;
-	}
-
-	/**
-	 * Get the name of the element that we are searching for
-	 * 
-	 * @return The name of the element
-	 */
-	public String getName() {
-		return name;
-	}
-
-	/**
-	 * Get the scope of the search operation
-	 * 
-	 * @return The scope - defined in BugzillaMylarSearch
-	 */
-	public int getScope() {
-		return scope;
-	}
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/bugs/BugzillaReferencesProvider.java b/org.eclipse.mylyn.ide.dev/developer/src-old/bugs/BugzillaReferencesProvider.java
deleted file mode 100644
index fb3f4d3..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/bugs/BugzillaReferencesProvider.java
+++ /dev/null
@@ -1,199 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004, 2008 Tasktop Technologies and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     Tasktop Technologies - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.mylyn.internal.sandbox.bridge.bugs;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-import org.eclipse.core.runtime.NullProgressMonitor;
-import org.eclipse.core.runtime.jobs.Job;
-import org.eclipse.jdt.core.IJavaElement;
-import org.eclipse.jdt.core.IMember;
-import org.eclipse.jdt.core.IType;
-import org.eclipse.jdt.core.JavaCore;
-import org.eclipse.mylyn.context.core.IInteractionContext;
-import org.eclipse.mylyn.context.core.IInteractionElement;
-import org.eclipse.mylyn.internal.context.core.AbstractRelationProvider;
-import org.eclipse.mylyn.internal.context.core.DegreeOfSeparation;
-import org.eclipse.mylyn.internal.context.core.IActiveSearchListener;
-import org.eclipse.mylyn.internal.context.core.IActiveSearchOperation;
-import org.eclipse.mylyn.internal.context.core.IDegreeOfSeparation;
-import org.eclipse.mylyn.internal.tasks.ui.TasksUiPlugin;
-import org.eclipse.mylyn.tasks.core.ITask;
-import org.eclipse.mylyn.tasks.core.TaskRepository;
-import org.eclipse.ui.PlatformUI;
-
-/**
- * @author Shawn Minto
- */
-public class BugzillaReferencesProvider extends AbstractRelationProvider {
-
-	public static final String ID = "org.eclipse.mylyn.bugs.search.references";
-
-	public static final String NAME = "referenced by";
-
-	public static final int DEFAULT_DEGREE = 0;
-
-	public BugzillaReferencesProvider() {
-		super(BugzillaStructureBridge.CONTENT_TYPE, ID);
-	}
-
-	@Override
-	public List<IDegreeOfSeparation> getDegreesOfSeparation() {
-		List<IDegreeOfSeparation> separations = new ArrayList<IDegreeOfSeparation>();
-		separations.add(new DegreeOfSeparation("disabled", 0));
-		separations.add(new DegreeOfSeparation("local, fully qualified matches", 1));
-		separations.add(new DegreeOfSeparation("local, unqualified matches", 2));
-		separations.add(new DegreeOfSeparation("server, fully quaified matches", 3));
-		separations.add(new DegreeOfSeparation("server, unqualified matches", 4));
-
-		return separations;
-	}
-
-	protected boolean acceptElement(IJavaElement javaElement) {
-		return javaElement != null && (javaElement instanceof IMember || javaElement instanceof IType)
-				&& javaElement.exists();
-	}
-
-	/**
-	 * HACK: checking kind as string - don't want the dependancy to mylar.java
-	 */
-	@Override
-	protected void findRelated(final IInteractionElement node, int degreeOfSeparation) {
-		if (!node.getContentType().equals("java")) {
-			return;
-		}
-		IJavaElement javaElement = JavaCore.create(node.getHandleIdentifier());
-		if (!acceptElement(javaElement)) {
-			return;
-		}
-		runJob(node, degreeOfSeparation);
-	}
-
-	@Override
-	public IActiveSearchOperation getSearchOperation(IInteractionElement node, int limitTo, int degreeOfSepatation) {
-		IJavaElement javaElement = JavaCore.create(node.getHandleIdentifier());
-
-		ITask task = TasksUiPlugin.getTaskListManager().getActiveTask();
-		TaskRepository repository = TasksUiPlugin.getRepositoryManager().getRepository(task.getConnectorKind(),
-				task.getRepositoryUrl());
-		return new BugzillaMylynSearch(degreeOfSepatation, javaElement, repository.getRepositoryUrl());
-	}
-
-	private void runJob(final IInteractionElement node, final int degreeOfSeparation) {
-		BugzillaMylynSearch search = (BugzillaMylynSearch) getSearchOperation(node, 0, degreeOfSeparation);
-
-		search.addListener(new IActiveSearchListener() {
-
-			private boolean gathered = false;
-
-			public void searchCompleted(List<?> nodes) {
-				Iterator<?> itr = nodes.iterator();
-
-				if (MylynBugsManager.getDefault() == null) {
-					return;
-				}
-
-				while (itr.hasNext()) {
-					Object o = itr.next();
-					if (o instanceof BugzillaReportInfo) {
-						BugzillaReportInfo bugzillaNode = (BugzillaReportInfo) o;
-						final String handle = bugzillaNode.getElementHandle();
-//						if (MylarBugsPlugin.getDefault().getCache().getCached(handle) == null)
-//							cache(handle, bugzillaNode);
-
-						PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {
-							public void run() {
-								incrementInterest(node, BugzillaStructureBridge.CONTENT_TYPE, handle,
-										degreeOfSeparation);
-							}
-						});
-					}
-				}
-				gathered = true;
-				BugzillaReferencesProvider.this.searchCompleted(node);
-			}
-
-			public boolean resultsGathered() {
-				return gathered;
-			}
-
-		});
-		search.run(new NullProgressMonitor(), Job.DECORATE - 10);
-	}
-
-	@Override
-	public String getGenericId() {
-		return ID;
-	}
-
-	@Override
-	protected String getSourceId() {
-		return ID;
-	}
-
-	@Override
-	public String getName() {
-		return NAME;
-	}
-
-	/*
-	 * 
-	 * STUFF FOR TEMPORARILY CACHING A PROXY REPORT
-	 * 
-	 * TODO remove the proxys and update the BugzillaStructureBridge cache so
-	 * that on restart, we dont have to get all of the bugs
-	 * 
-	 */
-	private static final Map<String, BugzillaReportInfo> reports = new HashMap<String, BugzillaReportInfo>();
-
-	public BugzillaReportInfo getCached(String handle) {
-		return reports.get(handle);
-	}
-
-	protected void cache(String handle, BugzillaReportInfo bugzillaNode) {
-		reports.put(handle, bugzillaNode);
-	}
-
-	public void clearCachedReports() {
-		reports.clear();
-	}
-
-	public Collection<? extends String> getCachedHandles() {
-		return reports.keySet();
-	}
-
-	@Override
-	public void stopAllRunningJobs() {
-		BugzillaSearchManager.cancelAllRunningJobs();
-
-	}
-
-	@Override
-	protected int getDefaultDegreeOfSeparation() {
-		return DEFAULT_DEGREE;
-	}
-
-	@Override
-	public void contextPreActivated(IInteractionContext context) {
-		// ignore	
-	}
-
-	@Override
-	public void elementsDeleted(List<IInteractionElement> elements) {
-		// ignore
-	}
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/bugs/BugzillaReportInfo.java b/org.eclipse.mylyn.ide.dev/developer/src-old/bugs/BugzillaReportInfo.java
deleted file mode 100644
index bb69654..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/bugs/BugzillaReportInfo.java
+++ /dev/null
@@ -1,189 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004, 2008 Tasktop Technologies and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     Tasktop Technologies - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.mylyn.internal.sandbox.bridge.bugs;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.NullProgressMonitor;
-import org.eclipse.mylyn.internal.bugzilla.core.BugzillaCorePlugin;
-import org.eclipse.mylyn.internal.bugzilla.core.BugzillaRepositoryConnector;
-import org.eclipse.mylyn.internal.bugzilla.core.BugzillaTaskDataHandler;
-import org.eclipse.mylyn.internal.bugzilla.ui.tasklist.StackTrace;
-import org.eclipse.mylyn.tasks.core.ITask;
-import org.eclipse.mylyn.tasks.core.TaskRepository;
-import org.eclipse.mylyn.tasks.core.data.TaskData;
-import org.eclipse.mylyn.tasks.ui.TasksUi;
-
-/**
- * Class to store the DoiInfo of a BugzillaSearchHit
- * 
- * TODO: refactor
- * 
- * @author Shawn Minto
- */
-public class BugzillaReportInfo {
-
-	private static final int MAX_LABEL_LENGTH = 150;
-
-	private static final long serialVersionUID = 3257004367222419506L;
-
-	/** The BugzillaSearchHit associated with this DoiInfo */
-	private final ITask hit;
-
-	/** Whether this search hit was from an exact search like a stack trace */
-	private boolean isExact = false;
-
-	/** List of all of the StackTrace's in the given bug */
-	private final List<StackTrace> stackTraces;
-
-	/** The bug report associated with this DoiInfo */
-	private TaskData bug;
-
-	/**
-	 * Constructor
-	 * 
-	 * @param initialValue
-	 *            The initial Doi value
-	 * @param hit
-	 *            The BugzillaSearchHit associated with this DoiInfo
-	 * @param isExact
-	 *            Whether the search was exact or not
-	 */
-	public BugzillaReportInfo(float initialValue, ITask hit, boolean isExact) {
-		this.hit = hit;
-		this.isExact = isExact;
-		bug = null;
-		stackTraces = new ArrayList<StackTrace>();
-	}
-
-	/**
-	 * Get the bugzilla search hit relating to this DoiInfo
-	 * 
-	 * @return The BugzillaSearchHit related to this DoiInfo
-	 */
-	public ITask getHit() {
-		return hit;
-	}
-
-	@Override
-	public String toString() {
-		return hit.toString();
-	}
-
-	/**
-	 * Determine if the search hit this represents is exact or not
-	 * 
-	 * @return <code>true</code> if the search was exact otherwise <code>false</code>
-	 */
-	public boolean isExact() {
-		return isExact;
-	}
-
-	/**
-	 * Set whether this bug has any exact elements in it - the search used was fully qualified
-	 * 
-	 * @param isExact
-	 *            - Whether there are any exact element matches in it
-	 */
-	public void setExact(boolean isExact) {
-		this.isExact = isExact;
-	}
-
-	/**
-	 * Get the bug report associated with this DoiInfo<br>
-	 * The bug is downloaded if it was not previously
-	 * 
-	 * @return Returns the BugReport
-	 */
-	public TaskData getBug() throws CoreException {
-		if (bug == null) {
-			// get the bug report
-			TaskRepository repository = TasksUi.getRepositoryManager().getRepository(BugzillaCorePlugin.CONNECTOR_KIND,
-					hit.getRepositoryUrl());
-			BugzillaRepositoryConnector bugzillaConnector = (BugzillaRepositoryConnector) TasksUi.getRepositoryManager()
-					.getRepositoryConnector(BugzillaCorePlugin.CONNECTOR_KIND);
-			BugzillaTaskDataHandler handler = new BugzillaTaskDataHandler(bugzillaConnector);
-			bug = handler.getTaskData(repository, hit.getTaskId(), new NullProgressMonitor());
-		}
-		return bug;
-	}
-
-	/**
-	 * Set the bug report associated with this DoiInfo
-	 * 
-	 * @param bug
-	 *            - BugReport that this is associated with
-	 */
-	public void setBug(TaskData bug) {
-		this.bug = bug;
-	}
-
-	/**
-	 * Get all of the stack traces contained in the bug
-	 * 
-	 * @return Returns a list of StackTrace's
-	 */
-	public List<StackTrace> getStackTraces() {
-		return stackTraces;
-	}
-
-	/**
-	 * Determine whether the doi info has any stack traces associated with it
-	 * 
-	 * @return <code>true</code> if there are some stack traces else <code>false</code>
-	 */
-	public boolean hasStackTraces() {
-		return !stackTraces.isEmpty();
-	}
-
-	/**
-	 * Add a stack trace to this DoiInfo
-	 * 
-	 * @param stackTrace
-	 *            - The StackTrace to add
-	 */
-	public void addStackTrace(StackTrace stackTrace) {
-		this.stackTraces.add(stackTrace);
-	}
-
-	/**
-	 * Add an array of stack traces to this DoiInfo
-	 * 
-	 * @param stackTracesToAdd
-	 *            - The StackTraces to add
-	 */
-	public void addStackTraces(StackTrace[] stackTracesToAdd) {
-		for (StackTrace element : stackTracesToAdd) {
-			this.stackTraces.add(element);
-		}
-	}
-
-	/**
-	 * Get the name of the bug report
-	 * 
-	 * @return The name of the bug report, max 20 characters
-	 */
-	public String getName() {
-		String description = hit.getSummary();
-		int length = description.length();
-		if (length > MAX_LABEL_LENGTH) {
-			description = description.substring(0, MAX_LABEL_LENGTH) + "..";
-		}
-		return "bug " + hit.getTaskId() + ": " + description;
-	}
-
-	public String getElementHandle() {
-		return hit.getRepositoryUrl() + ";" + hit.getTaskId();
-	}
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/bugs/BugzillaSearchEngine.java b/org.eclipse.mylyn.ide.dev/developer/src-old/bugs/BugzillaSearchEngine.java
deleted file mode 100644
index 0f5e70d..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/bugs/BugzillaSearchEngine.java
+++ /dev/null
@@ -1,545 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004, 2008 Tasktop Technologies and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     Tasktop Technologies - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.mylyn.internal.sandbox.bridge.bugs;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.util.regex.Pattern;
-
-import javax.security.auth.login.LoginException;
-
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.MultiStatus;
-import org.eclipse.core.runtime.OperationCanceledException;
-import org.eclipse.core.runtime.Status;
-import org.eclipse.mylyn.internal.bugzilla.core.BugzillaCorePlugin;
-import org.eclipse.mylyn.internal.bugzilla.core.IBugzillaConstants;
-import org.eclipse.mylyn.internal.bugzilla.ui.BugzillaUiPlugin;
-import org.eclipse.mylyn.internal.tasks.ui.TasksUiPlugin;
-import org.eclipse.mylyn.tasks.core.TaskRepository;
-
-/**
- * Queries the Bugzilla server for the list of bugs matching search criteria.
- * 
- * @author Mik Kersten (hardening of initial prototype)
- */
-// TODO: Delete once not needed by sandbox
-public class BugzillaSearchEngine {
-
-	protected static final String QUERYING_SERVER = "Querying Bugzilla Server...";
-
-	/**
-	 * regular expression matching values of query matches' attributes in Eclipse.org Bugzilla
-	 */
-	public static final Pattern reValue = Pattern.compile("<td><nobr>([^<]*)</nobr>");
-
-	public static final Pattern reValueBugzilla220 = Pattern.compile("<td style=\"white-space: nowrap\">([^<]*)");
-
-//	private final String urlString;
-
-	private final TaskRepository repository;
-
-	private final boolean maxReached = false;
-
-//	private String queryStringWithoutLogin;
-
-	public BugzillaSearchEngine(TaskRepository repository, String queryUrl) {
-//		urlString = queryUrl;
-//		queryStringWithoutLogin = urlString;
-		// urlString = urlString.concat(IBugzillaConstants.CONTENT_TYPE_RDF);
-		this.repository = repository;
-		// this.proxySettings = proxySettings;
-		// if (repository.hasCredentials()) {
-		// try {
-		// urlString = BugzillaClient.addCredentials(urlString,
-		// repository.getCharacterEncoding(), repository
-		// .getUserName(), repository.getPassword());
-		// } catch (UnsupportedEncodingException e) {
-		// /*
-		// * Do nothing. Every implementation of the Java platform is
-		// * required to support the standard charset "UTF-8"
-		// */
-		// }
-		// }
-	}
-
-	/**
-	 * Wrapper for search
-	 * 
-	 * @param collector
-	 *            - The collector for the results to go into
-	 */
-	public IStatus search(ProgressQueryHitCollector collector) throws LoginException {
-		return this.search(collector, 0, IBugzillaConstants.RETURN_ALL_HITS);
-	}
-
-	/**
-	 * Wrapper for search
-	 * 
-	 * @param collector
-	 *            - The collector for the results to go into
-	 * @param startMatches
-	 *            - The number of matches to start with for the progress monitor
-	 */
-	public IStatus search(ProgressQueryHitCollector collector, int startMatches) throws LoginException {
-		return this.search(collector, startMatches, BugzillaUiPlugin.getDefault().getMaxResults());
-	}
-
-	/**
-	 * Executes the query, parses the response, and adds hits to the search result collector.
-	 * 
-	 * @param collector
-	 *            - The collector for the search results
-	 * @param startMatches
-	 *            - The number of matches to start with for the progress monitor
-	 * @param maxHits
-	 *            - the maximum number of matches to return or IBugzillaConstants.RETURN_ALL_HITS for unlimited
-	 */
-	public IStatus search(ProgressQueryHitCollector collector, int startMatches, int maxHits) throws LoginException {
-		IProgressMonitor monitor = collector.getProgressMonitor();
-		IStatus status = null;
-		boolean possibleBadLogin = false;
-		int numCollected = 0;
-		BufferedReader in = null;
-
-		try {
-			monitor.beginTask(QUERYING_SERVER, maxHits);// IProgressMonitor.UNKNOWN
-			collector.aboutToStart(startMatches);
-
-			throw new OperationCanceledException("Bugzilla Active Searchn not implemented");
-
-//			if (monitor.isCanceled()) {
-//				throw new OperationCanceledException("Search cancelled");
-//			}
-//
-//			BugzillaRepositoryQuery query = new BugzillaRepositoryQuery(repository.getRepositoryUrl(), urlString,
-//					"summary");
-//
-//			BugzillaRepositoryConnector bugzillaConnector = (BugzillaRepositoryConnector) TasksUi.getRepositoryManager()
-//					.getRepositoryConnector(BugzillaCorePlugin.CONNECTOR_KIND);
-//
-//			BugzillaClient client = bugzillaConnector.getClientManager().getClient(repository,
-//					new NullProgressMonitor());
-//			client.getSearchHits(query, collector, bugzillaConnector.getTaskDataHandler()
-//					.getAttributeMapper(repository), new NullProgressMonitor());
-		} catch (CoreException e) {
-			status = new MultiStatus(BugzillaUiPlugin.ID_PLUGIN, IStatus.ERROR,
-					"Core Exception occurred while querying Bugzilla Server " + repository.getRepositoryUrl() + ".\n"
-							+ "\nClick Details for more information.", e);
-			((MultiStatus) status).add(e.getStatus());
-
-			// write error to log
-			BugzillaCorePlugin.log(status);
-		} catch (OperationCanceledException e) {
-			status = new Status(IStatus.CANCEL, BugzillaUiPlugin.ID_PLUGIN, IStatus.CANCEL, "", null);
-//		} catch (final UnrecognizedReponseException e) {
-//
-//			PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {
-//				public void run() {
-//					WebBrowserDialog.openAcceptAgreement(null, "Report Download Failed",
-//							"Unrecognized response from server", e.getMessage());
-//				}
-//			});
-//			status = new MultiStatus(BugzillaUiPlugin.ID_PLUGIN, IStatus.ERROR,
-//					"Unrecognized response from Bugzilla server " + repository.getRepositoryUrl(), e);
-//
-//			IStatus s = new Status(IStatus.ERROR, BugzillaUiPlugin.ID_PLUGIN, IStatus.ERROR, e.getClass().toString()
-//					+ ":  ", e);
-//			((MultiStatus) status).add(s);
-//			s = new Status(IStatus.ERROR, BugzillaUiPlugin.ID_PLUGIN, IStatus.OK, "search failed", e);
-//			((MultiStatus) status).add(s);
-
-		} catch (Exception e) {
-			status = new MultiStatus(BugzillaUiPlugin.ID_PLUGIN, IStatus.ERROR,
-					"An error occurred while querying Bugzilla Server " + repository.getRepositoryUrl() + ".\n"
-							+ "\nCheck network connection and repository configuration in "
-							+ TasksUiPlugin.LABEL_VIEW_REPOSITORIES + ".", e);
-
-			IStatus s = new Status(IStatus.ERROR, BugzillaUiPlugin.ID_PLUGIN, IStatus.ERROR, e.getClass().toString()
-					+ ":  ", e);
-			((MultiStatus) status).add(s);
-			s = new Status(IStatus.ERROR, BugzillaUiPlugin.ID_PLUGIN, IStatus.OK, "search failed", e);
-			((MultiStatus) status).add(s);
-		} finally {
-			if (monitor != null) {
-				monitor.done();
-			}
-			collector.done();
-			try {
-				if (in != null) {
-					in.close();
-				}
-			} catch (IOException e) {
-				BugzillaCorePlugin.log(new Status(IStatus.ERROR, BugzillaUiPlugin.ID_PLUGIN, IStatus.ERROR,
-						"Problem closing the stream", e));
-			}
-		}
-
-		// if we haven't collected any serach results and we suspect a bad
-		// login, we assume it was a bad login
-		if (numCollected == 0 && possibleBadLogin) {
-			throw new LoginException(IBugzillaConstants.MESSAGE_LOGIN_FAILURE + " for repository: "
-					+ repository.getRepositoryUrl() + " username: " + repository.getUserName());
-		}
-
-		if (status == null) {
-			return new Status(IStatus.OK, BugzillaUiPlugin.ID_PLUGIN, IStatus.OK, "", null);
-		} else {
-			return status;
-		}
-	}
-
-	// /** Old code used by a unit test. */
-//	public static BugzillaQueryHit createHit(Pattern regularExpression, IProgressMonitor monitor, BufferedReader in,
-//			String serverUrl, int id) throws IOException {
-//		String line;
-//		// String severity = null;
-//		String priority = null;
-//		// String platform = null;
-//		// String owner = null;
-//		String state = null;
-//		// String result = null;
-//		for (int i = 0; i < 6; i++) {
-//			Matcher matcher;
-//			do {
-//				matcher = null;
-//				if (monitor.isCanceled()) {
-//					throw new OperationCanceledException("Search cancelled");
-//				}
-//				line = in.readLine();
-//				if (line == null)
-//					break;
-//				line = line.trim();
-//				matcher = regularExpression.matcher(line);
-//			} while (!matcher.find());
-//			if (null != matcher) {
-//				switch (i) {
-//				// case 0:
-//				// severity = matcher.group(1);
-//				// break;
-//				case 1:
-//					priority = matcher.group(1);
-//					break;
-//				// case 2:
-//				// platform = matcher.group(1);
-//				// break;
-//				// case 3:
-//				// owner = matcher.group(1);
-//				// break;
-//				case 4:
-//					state = matcher.group(1);
-//					break;
-//				case 5:
-//					// result = matcher.group(1);
-//					// break;
-//				}
-//			}
-//		}
-//
-//		// two more
-//		line = in.readLine();
-//		line = in.readLine();
-//
-//		String description = "<activate to view summary>";
-//		if (line != null) {
-//			description = line.substring(8);
-//		}
-//		if (description.startsWith(">")) {
-//			description = description.substring(1);
-//		}
-//
-//		// String query = "";
-//		// try {
-//		// String recentQuery = BugzillaUiPlugin.getMostRecentQuery();
-//		// if (recentQuery != null)
-//		// query = recentQuery;
-//		// } catch (Exception e) {
-//		// // ignore, for testing
-//		// }
-//
-//		BugzillaQueryHit hit = new BugzillaQueryHit(TasksUiPlugin.getTaskList(), description,
-//				priority, serverUrl, String.valueOf(id), null, state);
-//
-//		return hit;
-//	}
-
-	public boolean isMaxReached() {
-		return maxReached;
-	}
-}
-
-// /** regular expression matching Bugzilla query results format used in
-// Eclipse.org Bugzilla */
-// protected static final Pattern re = Pattern.compile("<a
-// href=\"show_bug.cgi\\?taskId=(\\d+)\">", Pattern.CASE_INSENSITIVE);
-//
-//	
-// /** regular expression matching Bugzilla query results format used in
-// v2.12 */
-// protected static final Pattern reOld = Pattern.compile("<a
-// href=\"show_bug.cgi\\?taskId=(\\d+)\">\\d+</a>\\s*<td
-// class=severity><nobr>([^>]+)</nobr><td
-// class=priority><nobr>([^>]+)</nobr><td
-// class=platform><nobr>([^>]*)</nobr><td
-// class=owner><nobr>([^>]*)</nobr><td class=status><nobr>([^>]*)</nobr><td
-// class=resolution><nobr>([^>]*)</nobr><td class=summary>(.*)$",
-// Pattern.CASE_INSENSITIVE);
-
-// /**
-// * Executes the query, parses the response, and adds hits to the search
-// result collector.
-// *
-// * <p>
-// * The output for a single match looks like this:
-// * <pre>
-// * <tr class="bz_enhancement bz_P5 ">
-// *
-// * <td>
-// * <a href="show_bug.cgi?taskId=6747">6747</a>
-// * </td>
-// *
-// * <td><nobr>enh</nobr>
-// * </td>
-// * <td><nobr>P5</nobr>
-// * </td>
-// * <td><nobr>All</nobr>
-// * </td>
-// * <td><nobr>Olivier_Thomann@oti.com</nobr>
-// * </td>
-// * <td><nobr>ASSI</nobr>
-// * </td>
-// * <td><nobr></nobr>
-// * </td>
-// * <td>Code Formatter exchange several blank lines w/ one
-// * </td>
-// *
-// * </tr>
-// * <pre>
-// *
-// * <p>Or in the older format:
-// * <pre>
-// * <A HREF="show_bug.cgi?taskId=8">8</A> <td
-// class=severity><nobr>blo</nobr><td class=priority><nobr>P1</nobr><td
-// class=platform><nobr>PC</nobr><td
-// class=owner><nobr>cubranic@cs.ubc.ca</nobr><td
-// class=status><nobr>CLOS</nobr><td class=resolution><nobr>DUPL</nobr><td
-// class=summary>"Document root" missing when querying on files and
-// revisions
-// * </pre>
-// * @param collector - The collector for the search results
-// * @param startMatches - The number of matches to start with for the
-// progress monitor
-// * @param maxMatches - the maximum number of matches to return or -1 for
-// unlimited
-// */
-// public IStatus search(IBugzillaSearchResultCollector collector, int
-// startMatches, int maxMatches)
-// throws LoginException {
-// IProgressMonitor monitor = collector.getProgressMonitor();
-// IStatus status = null;
-// boolean possibleBadLogin = false;
-// int numCollected = 0;
-// BufferedReader in = null;
-//
-// try {
-// monitor.beginTask(QUERYING_SERVER, IProgressMonitor.UNKNOWN);
-// collector.aboutToStart(startMatches);
-//
-// URLConnection cntx = BugzillaPlugin.getDefault().getUrlConnection(new
-// URL(urlString));
-// if (cntx == null || !(cntx instanceof HttpURLConnection)) {
-// return null;
-// }
-//
-// HttpURLConnection connect = (HttpURLConnection) cntx;
-// connect.connect();
-// int responseCode = connect.getResponseCode();
-// if (responseCode != HttpURLConnection.HTTP_OK) {
-// String msg;
-// if (responseCode == -1 || responseCode ==
-// HttpURLConnection.HTTP_FORBIDDEN)
-// msg = repository.getUrl()
-// + " does not seem to be a valid Bugzilla server. Check Bugzilla
-// preferences.";
-// else
-// msg = "HTTP Error " + responseCode + " (" + connect.getResponseMessage()
-// + ") while querying Bugzilla Server. Check Bugzilla preferences.";
-//
-// throw new BugzillaException(msg);
-// }
-//
-// if (monitor.isCanceled()) {
-// throw new OperationCanceledException("Search cancelled");
-// }
-//
-// in = new BufferedReader(new InputStreamReader(connect.getInputStream()));
-// if (monitor.isCanceled()) {
-// throw new OperationCanceledException("Search cancelled");
-// }
-//
-// String line;
-// while ((line = in.readLine()) != null) {
-// if (maxMatches != -1 && numCollected >= maxMatches) {
-// maxReached = true;
-// break;
-// }
-//
-// if (monitor.isCanceled()) {
-// throw new OperationCanceledException("Search cancelled");
-// }
-//
-// // create regular expressions that can be mathced to check if we
-// // have
-// // bad login information
-// Pattern loginRe = Pattern.compile("<title>.*login.*</title>.*");
-// Pattern invalidRe =
-// Pattern.compile(".*<title>.*invalid.*password.*</title>.*");
-// Pattern passwordRe =
-// Pattern.compile(".*<title>.*password.*invalid.*</title>.*");
-// Pattern emailRe = Pattern.compile(".*<title>.*check e-mail.*</title>.*");
-// Pattern errorRe = Pattern.compile(".*<title>.*error.*</title>.*");
-//
-// String lowerLine = line.toLowerCase(Locale.ENGLISH);
-//
-// // check if we have anything that suggests bad login info
-// if (loginRe.matcher(lowerLine).find() ||
-// invalidRe.matcher(lowerLine).find() ||
-// passwordRe.matcher(lowerLine).find()
-// || emailRe.matcher(lowerLine).find() ||
-// errorRe.matcher(lowerLine).find())
-// possibleBadLogin = true;
-//
-// Matcher matcher = reOld.matcher(line);
-// if (matcher.find()) {
-// int taskId = Integer.parseInt(matcher.group(1));
-// String severity = matcher.group(2);
-// String priority = matcher.group(3);
-// String platform = matcher.group(4);
-// String owner = matcher.group(5);
-// String state = matcher.group(6);
-// String result = matcher.group(7);
-// String summary = matcher.group(8);
-// String query = BugzillaPlugin.getMostRecentQuery();
-// if (query == null)
-// query = "";
-//
-// String server = repository.getUrl();
-//
-// BugzillaSearchHit hit = new BugzillaSearchHit(server, taskId, summary,
-// severity, priority,
-// platform, state, result, owner, query);
-// collector.accept(hit);
-// numCollected++;
-//
-// } else {
-// matcher = re.matcher(line);
-// if (matcher.find()) {
-// Pattern regularExpression;
-//						
-// BugzillaServerVersion bugzillaServerVersion =
-// IBugzillaConstants.BugzillaServerVersion.fromString(repository.getVersion());
-// if (bugzillaServerVersion != null &&
-// bugzillaServerVersion.compareTo(BugzillaServerVersion.SERVER_220) >= 0) {
-// regularExpression = reValueBugzilla220;
-// } else {
-// regularExpression = reValue;
-// }
-//	
-// int taskId = Integer.parseInt(matcher.group(1));
-// BugzillaSearchHit hit = createHit(regularExpression, monitor, in,
-// repository.getUrl(), taskId);
-// collector.accept(hit);
-// numCollected++;
-// }
-// }
-//				
-// // } else if (re.matches(line, match)) {
-// // RegularExpression regularExpression;
-// // if
-// (repository.getVersion().equals(BugzillaServerVersion.SERVER_220.toString()))
-// {
-// // regularExpression = reValueBugzilla220;
-// // } else {
-// // regularExpression = reValue;
-// // }
-// //
-// // int taskId = Integer.parseInt(match.getCapturedText(1));
-// // BugzillaSearchHit hit = createHit(regularExpression, monitor, in,
-// match, repository.getUrl()
-// // .toExternalForm(), taskId);
-// // collector.accept(hit);
-// // numCollected++;
-// // }
-// if (monitor.isCanceled()) {
-// throw new OperationCanceledException("Search cancelled");
-// }
-// }
-// } catch (CoreException e) {
-// status = new MultiStatus(IBugzillaConstants.PLUGIN_ID, IStatus.ERROR,
-// "Core Exception occurred while querying Bugzilla Server " +
-// repository.getUrl()
-// + ".\n" + "\nClick Details for more information.", e);
-// ((MultiStatus) status).add(e.getStatus());
-//
-// // write error to log
-// BugzillaPlugin.log(status);
-// } catch (OperationCanceledException e) {
-// status = new Status(IStatus.CANCEL, IBugzillaConstants.PLUGIN_ID,
-// IStatus.CANCEL, "", null);
-// } catch (Exception e) {
-// status = new MultiStatus(IBugzillaConstants.PLUGIN_ID, IStatus.ERROR, "An
-// error occurred while querying Bugzilla Server " + repository.getUrl() +
-// ".\n"
-// + "\nCheck network connection repository configuration in Task
-// Repositories view.", e);
-//
-// IStatus s = new Status(IStatus.ERROR, IBugzillaConstants.PLUGIN_ID,
-// IStatus.ERROR, e.getClass().toString()
-// + ": ", e);
-// ((MultiStatus) status).add(s);
-// s = new Status(IStatus.ERROR, IBugzillaConstants.PLUGIN_ID, IStatus.OK,
-// "search failed", e);
-// ((MultiStatus) status).add(s);
-//
-// // write error to log
-// //BugzillaPlugin.log(status);
-//			
-// 
-// } finally {
-// monitor.done();
-// collector.done();
-// try {
-// if (in != null)
-// in.close();
-// } catch (IOException e) {
-// BugzillaPlugin.log(new Status(IStatus.ERROR,
-// IBugzillaConstants.PLUGIN_ID, IStatus.ERROR,
-// "Problem closing the stream", e));
-// }
-// }
-//
-// // if we haven't collected any serach results and we suspect a bad
-// // login, we assume it was a bad login
-// if (numCollected == 0 && possibleBadLogin) {
-// throw new LoginException(IBugzillaConstants.MESSAGE_LOGIN_FAILURE + " for
-// repository: " + repository.getUrl() + " username: " +
-// repository.getUserName());
-// }
-//
-// if (status == null)
-// return new Status(IStatus.OK, NewSearchUI.PLUGIN_ID, IStatus.OK, "",
-// null);
-// else
-// return status;
-// }
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/bugs/BugzillaSearchManager.java b/org.eclipse.mylyn.ide.dev/developer/src-old/bugs/BugzillaSearchManager.java
deleted file mode 100644
index 6cabc26..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/bugs/BugzillaSearchManager.java
+++ /dev/null
@@ -1,152 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004, 2008 Tasktop Technologies and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     Tasktop Technologies - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.mylyn.internal.sandbox.bridge.bugs;
-
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.eclipse.core.runtime.jobs.Job;
-import org.eclipse.jdt.core.IJavaElement;
-import org.eclipse.jdt.core.IMember;
-
-/**
- * Class to handle the bridge between Mylyn and bugzilla
- * 
- * @author Shawn Minto
- */
-public class BugzillaSearchManager {
-
-	/** The hash of all of the landmarks and their related search hits */
-	private final Map<String, Map<Integer, List<BugzillaReportInfo>>> landmarksHash;
-
-	/**
-	 * The currently running search jobs so that we can cancel it if necessary <br>
-	 * KEY: IMember VALUE: Job
-	 */
-	static Map<String, Job> runningJobs = Collections.synchronizedMap(new HashMap<String, Job>());
-
-	/**
-	 * Constructor
-	 */
-	public BugzillaSearchManager() {
-		landmarksHash = Collections.synchronizedMap(new HashMap<String, Map<Integer, List<BugzillaReportInfo>>>());
-	}
-
-	/**
-	 * Remove a landmark from the hash
-	 * 
-	 * @param removed
-	 *            This landmark to remove (IJavaElement)
-	 */
-	public void removeFromLandmarksHash(IJavaElement removed) {
-		landmarksHash.remove(removed.getHandleIdentifier());
-	}
-
-	/**
-	 * Remove all of the landmarks from the hash that are in the list
-	 * 
-	 * @param removed
-	 *            This list of landmarks to remove (IJavaElements)
-	 */
-	public void removeFromLandmarksHash(List<IJavaElement> removed) {
-
-		for (IJavaElement je : removed) {
-			landmarksHash.remove(je.getHandleIdentifier());
-		}
-	}
-
-	/**
-	 * Add data to the landmarks hash
-	 * 
-	 * @param doiList
-	 *            The list of BugzillaSearchHitDoiInfo
-	 * @param m
-	 *            The member that this list is for
-	 */
-	public void addToLandmarksHash(List<BugzillaReportInfo> doiList, IMember m, int scope) {
-		Map<Integer, List<BugzillaReportInfo>> searches = landmarksHash.get(m.getHandleIdentifier());
-
-		if (searches == null) {
-			searches = new HashMap<Integer, List<BugzillaReportInfo>>();
-		}
-		searches.put(scope, doiList);
-		landmarksHash.put(m.getHandleIdentifier(), searches);
-	}
-
-	/**
-	 * Get the doiList for the given IMember from the landmarks hash
-	 * 
-	 * @param m
-	 *            The member to get the doiList for
-	 * @return The doiList or null if it doesn't exist
-	 */
-	public List<BugzillaReportInfo> getFromLandmarksHash(IMember m, int scope) {
-		Map<Integer, List<BugzillaReportInfo>> scopes = landmarksHash.get(m.getHandleIdentifier());
-		if (scopes == null) {
-			return null;
-		} else {
-			return scopes.get(scope);
-		}
-	}
-
-	/**
-	 * Determine whether the current element has a search job running for it
-	 * 
-	 * @param e
-	 *            The element that we want to know whether there is a search job or not
-	 * @return <code>true</code> if it does else <code>false</code>
-	 */
-	public static boolean doesJobExist(String handle) {
-		return runningJobs.containsKey(handle);
-	}
-
-	/**
-	 * Remove search job for the given element
-	 * 
-	 * @param m
-	 *            The element that we want to make sure that the search is canceled for
-	 */
-	public static void removeSearchJob(String handle) {
-
-		// make sure that there wasn't a previous search job that we know
-		// of. If there was, cancel it
-		if (doesJobExist(handle)) {
-			// get the search job and wait until it is cancelled
-			Job prevJob = runningJobs.get(handle);
-			prevJob.cancel();
-			runningJobs.remove(handle);
-		}
-	}
-
-	/**
-	 * Add a search job to our list
-	 * 
-	 * @param handle
-	 *            The handle of the element that we are searching for
-	 * @param searchJob
-	 *            The job that represents the search
-	 */
-	public static void addJob(String handle, Job searchJob) {
-		runningJobs.put(handle, searchJob);
-	}
-
-	public static void cancelAllRunningJobs() {
-		Collection<Job> jobs = runningJobs.values();
-		for (Job j : jobs) {
-			j.cancel();
-		}
-		runningJobs.clear();
-	}
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/bugs/BugzillaStructureBridge.java b/org.eclipse.mylyn.ide.dev/developer/src-old/bugs/BugzillaStructureBridge.java
deleted file mode 100644
index 584951d..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/bugs/BugzillaStructureBridge.java
+++ /dev/null
@@ -1,140 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004, 2008 Tasktop Technologies and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     Tasktop Technologies - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.mylyn.internal.sandbox.bridge.bugs;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-import org.eclipse.mylyn.context.core.AbstractContextStructureBridge;
-import org.eclipse.mylyn.internal.context.core.AbstractRelationProvider;
-import org.eclipse.mylyn.internal.tasks.ui.editors.ContentOutlineTools;
-import org.eclipse.mylyn.internal.tasks.ui.editors.RepositoryTaskOutlineNode;
-import org.eclipse.mylyn.internal.tasks.ui.editors.RepositoryTaskSelection;
-import org.eclipse.mylyn.tasks.core.ITask;
-import org.eclipse.ui.views.markers.internal.ProblemMarker;
-
-/**
- * @author Mik Kersten
- * @author Shawn Minto
- */
-public class BugzillaStructureBridge extends AbstractContextStructureBridge {
-
-	public final static String CONTENT_TYPE = "bugzilla";
-
-	public List<AbstractRelationProvider> providers;
-
-	@Override
-	public String getContentType() {
-		return CONTENT_TYPE;
-	}
-
-	public BugzillaStructureBridge() {
-		super();
-		providers = new ArrayList<AbstractRelationProvider>();
-	}
-
-	/**
-	 * Handle format: <server-name:port>;<bug-taskId>;<comment#>
-	 * 
-	 * Use: OutlineTools ???
-	 */
-	@Override
-	public String getHandleIdentifier(Object object) {
-		if (object instanceof RepositoryTaskOutlineNode) {
-			RepositoryTaskOutlineNode node = (RepositoryTaskOutlineNode) object;
-			return ContentOutlineTools.getHandle(node);
-		} else if (object instanceof RepositoryTaskSelection) {
-			RepositoryTaskSelection n = (RepositoryTaskSelection) object;
-			return ContentOutlineTools.getHandle(n);
-		}
-		return null;
-	}
-
-//	private BugzillaReport result;
-
-	/**
-	 * TODO: this will not return a non-cached handle
-	 */
-	@Override
-	public Object getObjectForHandle(final String handle) {
-		return null;
-	}
-
-	@Override
-	public String getParentHandle(String handle) {
-
-		// check so that we don't need to try to get the parent if we are
-		// already at the bug report
-		if (!handle.matches(".*;.*;.*")) {
-			return null;
-		}
-
-		RepositoryTaskOutlineNode bon = (RepositoryTaskOutlineNode) getObjectForHandle(handle);
-		if (bon != null && bon.getParent() != null) {
-			return ContentOutlineTools.getHandle(bon.getParent());
-		} else {
-			return null;
-		}
-	}
-
-	@Override
-	public String getLabel(Object object) {
-		if (object instanceof RepositoryTaskOutlineNode) {
-			RepositoryTaskOutlineNode b = (RepositoryTaskOutlineNode) object;
-			return ContentOutlineTools.getName(b);
-		} else if (object instanceof BugzillaReportInfo) {
-			ITask hit = ((BugzillaReportInfo) object).getHit();
-			return hit.getRepositoryUrl() + ": Bug#: " + hit.getTaskId() + ": " + hit.getSummary();
-		}
-		return "";
-	}
-
-	@Override
-	public boolean canBeLandmark(String handle) {
-		return false;
-	}
-
-	@Override
-	public boolean acceptsObject(Object object) {
-		return object instanceof RepositoryTaskOutlineNode || object instanceof RepositoryTaskSelection;
-	}
-
-	@Override
-	public boolean canFilter(Object element) {
-		return true;
-	}
-
-	@Override
-	public boolean isDocument(String handle) {
-		return (handle.indexOf(';') == handle.lastIndexOf(';') && handle.indexOf(";") != -1);
-	}
-
-	public String getHandleForMarker(ProblemMarker marker) {
-		return null;
-	}
-
-	@Override
-	public String getContentType(String elementHandle) {
-		return getContentType();
-	}
-
-	@Override
-	public String getHandleForOffsetInObject(Object resource, int offset) {
-		return null;
-	}
-
-	@Override
-	public List<String> getChildHandles(String handle) {
-		return Collections.emptyList();
-	}
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/bugs/BugzillaUiBridge.java b/org.eclipse.mylyn.ide.dev/developer/src-old/bugs/BugzillaUiBridge.java
deleted file mode 100644
index 08a740f..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/bugs/BugzillaUiBridge.java
+++ /dev/null
@@ -1,139 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004, 2008 Tasktop Technologies and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     Tasktop Technologies - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.mylyn.internal.sandbox.bridge.bugs;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.eclipse.jface.text.TextSelection;
-import org.eclipse.jface.viewers.ILabelProvider;
-import org.eclipse.jface.viewers.TreeViewer;
-import org.eclipse.mylyn.context.core.IInteractionElement;
-import org.eclipse.mylyn.context.ui.AbstractContextUiBridge;
-import org.eclipse.mylyn.internal.bugzilla.core.BugzillaClient;
-import org.eclipse.mylyn.internal.tasks.core.AbstractTask;
-import org.eclipse.mylyn.internal.tasks.ui.TasksUiPlugin;
-import org.eclipse.mylyn.internal.tasks.ui.deprecated.AbstractRepositoryTaskEditor;
-import org.eclipse.mylyn.internal.tasks.ui.editors.RepositoryTaskOutlinePage;
-import org.eclipse.mylyn.tasks.ui.TasksUiUtil;
-import org.eclipse.mylyn.tasks.ui.editors.TaskEditor;
-import org.eclipse.ui.IEditorInput;
-import org.eclipse.ui.IEditorPart;
-import org.eclipse.ui.IEditorReference;
-import org.eclipse.ui.IWorkbenchPage;
-import org.eclipse.ui.PlatformUI;
-
-/**
- * @author Mik Kersten
- * @author Shawn Minto
- */
-public class BugzillaUiBridge extends AbstractContextUiBridge {
-
-	protected BugzillaContextLabelProvider labelProvider = new BugzillaContextLabelProvider();
-
-	@Override
-	public void open(IInteractionElement node) {
-		String handle = node.getHandleIdentifier();
-		String bugHandle = handle;
-		String server = handle.substring(0, handle.indexOf(";"));
-
-		handle = handle.substring(handle.indexOf(";") + 1);
-		int next = handle.indexOf(";");
-
-		int bugId;
-		if (next == -1) {
-			bugId = Integer.parseInt(handle);
-		} else {
-			bugId = Integer.parseInt(handle.substring(0, handle.indexOf(";")));
-			bugHandle = bugHandle.substring(0, next);
-		}
-
-		final AbstractTask task = TasksUiPlugin.getTaskList().getTask(handle);
-		if (task != null) {
-			PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {
-				public void run() {
-					TasksUiUtil.openTask(task);
-				}
-			});
-		} else {
-			String bugUrl = BugzillaClient.getBugUrlWithoutLogin(server, "" + bugId);
-			TasksUiUtil.openTask(server, "" + bugId, bugUrl);
-		}
-	}
-
-	public ILabelProvider getLabelProvider() {
-		return labelProvider;
-	}
-
-	@Override
-	public void close(IInteractionElement node) {
-		IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
-		if (page != null) {
-			IEditorReference[] references = page.getEditorReferences();
-			for (IEditorReference reference : references) {
-				IEditorPart part = reference.getEditor(false);
-				if (part != null) {
-					if (part instanceof AbstractRepositoryTaskEditor) {
-						((AbstractRepositoryTaskEditor) part).close();
-					} else if (part instanceof TaskEditor) {
-						((TaskEditor) part).close(true);
-					}
-				}
-			}
-		}
-	}
-
-	@Override
-	public boolean acceptsEditor(IEditorPart editorPart) {
-		return editorPart instanceof AbstractRepositoryTaskEditor;
-	}
-
-	@Override
-	public List<TreeViewer> getContentOutlineViewers(IEditorPart editor) {
-		List<TreeViewer> viewers = new ArrayList<TreeViewer>();
-		TreeViewer outline = getOutlineTreeViewer(editor);
-		if (outline != null) {
-			viewers.add(outline);
-		}
-		return viewers;
-	}
-
-	protected TreeViewer getOutlineTreeViewer(IEditorPart editor) {
-		if (editor instanceof AbstractRepositoryTaskEditor) {
-			AbstractRepositoryTaskEditor abe = (AbstractRepositoryTaskEditor) editor;
-			RepositoryTaskOutlinePage outline = abe.getOutline();
-			if (outline != null) {
-				return outline.getOutlineTreeViewer();
-			}
-		}
-		return null;
-	}
-
-	@Override
-	public Object getObjectForTextSelection(TextSelection selection, IEditorPart editor) {
-		return null;
-	}
-
-	public void restoreEditor(IInteractionElement document) {
-		// ignore
-	}
-
-	@Override
-	public IInteractionElement getElement(IEditorInput input) {
-		return null;
-	}
-
-	@Override
-	public String getContentType() {
-		return BugzillaStructureBridge.CONTENT_TYPE;
-	}
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/bugs/IBugzillaSearchOperation.java b/org.eclipse.mylyn.ide.dev/developer/src-old/bugs/IBugzillaSearchOperation.java
deleted file mode 100644
index c2a33a5..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/bugs/IBugzillaSearchOperation.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004, 2008 Tasktop Technologies and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     Tasktop Technologies - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.mylyn.internal.sandbox.bridge.bugs;
-
-import javax.security.auth.login.LoginException;
-
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.jface.operation.IRunnableWithProgress;
-import org.eclipse.mylyn.internal.tasks.ui.search.AbstractRepositorySearchQuery;
-
-/**
- * Interface for the bugzilla search operation
- * 
- * @author Shawn Minto
- * 
- *         TODO: Delete once not requred by sandbox
- */
-public interface IBugzillaSearchOperation extends IRunnableWithProgress {
-
-	/**
-	 * Get the status of the search operation
-	 * 
-	 * @return The status of the search operation
-	 * @throws LoginException
-	 */
-	public IStatus getStatus() throws LoginException;
-
-	/**
-	 * Get the bugzilla search query
-	 * 
-	 * @return The bugzilla search query
-	 */
-	public AbstractRepositorySearchQuery getQuery();
-
-	/**
-	 * Sets the bugzilla search query
-	 * 
-	 * @param newQuery
-	 *            The bugzilla search query to be set
-	 */
-	public void setQuery(AbstractRepositorySearchQuery newQuery);
-
-	public String getName();
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/bugs/MylynBugsManager.java b/org.eclipse.mylyn.ide.dev/developer/src-old/bugs/MylynBugsManager.java
deleted file mode 100644
index 1b8a315..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/bugs/MylynBugsManager.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004, 2008 Tasktop Technologies and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     Tasktop Technologies - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.mylyn.internal.sandbox.bridge.bugs;
-
-import org.eclipse.jface.resource.ImageDescriptor;
-import org.eclipse.ui.IWorkbench;
-import org.eclipse.ui.IWorkbenchWindow;
-import org.eclipse.ui.PlatformUI;
-import org.eclipse.ui.plugin.AbstractUIPlugin;
-import org.osgi.framework.BundleContext;
-
-/**
- * The main plugin class to be used in the desktop.
- * 
- * @author Mik Kersten
- * @author Shawn Minto
- */
-public class MylynBugsManager {
-
-	public static ImageDescriptor EDGE_REF_BUGZILLA = getImageDescriptor("icons/elcl16/edge-ref-bug.gif");
-
-	private static BugzillaSearchManager bridge = null;
-
-	private static BugzillaReferencesProvider referencesProvider = new BugzillaReferencesProvider();
-
-	private static MylynBugsManager INSTANCE;
-
-//	private BugzillaReportCache cache
-
-	public MylynBugsManager() {
-		INSTANCE = this;
-//		cache = new BugzillaReportCache();
-//		cache.readCacheFile();
-
-		IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
-		if (window != null) {
-			// create a new bridge and initialize it
-			bridge = new BugzillaSearchManager();
-		}
-		final IWorkbench workbench = PlatformUI.getWorkbench();
-		workbench.getDisplay().asyncExec(new Runnable() {
-			public void run() {
-				// bugzillaEditingMonitor = new BugzillaEditingMonitor();
-				// ContextCore.getSelectionMonitors().add(bugzillaEditingMonitor);
-			}
-		});
-	}
-
-	public void dispose(BundleContext context) throws Exception {
-		// ContextCore.getSelectionMonitors().remove(bugzillaEditingMonitor);
-	}
-
-	/**
-	 * Returns the shared instance.
-	 */
-	public static MylynBugsManager getDefault() {
-		return INSTANCE;
-	}
-
-	/**
-	 * Returns an image descriptor for the image file at the given plug-in relative path.
-	 * 
-	 * @param path
-	 *            the path
-	 * @return the image descriptor
-	 */
-	public static ImageDescriptor getImageDescriptor(String path) {
-		return AbstractUIPlugin.imageDescriptorFromPlugin("org.eclipse.mylyn.internal.bugs.bridge", path);
-	}
-
-	public static BugzillaSearchManager getBridge() {
-		// make sure that the bridge initialized, if not, make a new one
-		if (bridge == null) {
-			bridge = new BugzillaSearchManager();
-		}
-		return bridge;
-	}
-
-	public static BugzillaReferencesProvider getReferenceProvider() {
-		return referencesProvider;
-
-	}
-
-//	public BugzillaReportCache getCache() {
-//		return cache;
-//	}
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/bugs/ProgressQueryHitCollector.java b/org.eclipse.mylyn.ide.dev/developer/src-old/bugs/ProgressQueryHitCollector.java
deleted file mode 100644
index 0994756..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/bugs/ProgressQueryHitCollector.java
+++ /dev/null
@@ -1,152 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004, 2008 Tasktop Technologies and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     Tasktop Technologies - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.mylyn.internal.sandbox.bridge.bugs;
-
-import java.text.MessageFormat;
-import java.util.HashSet;
-import java.util.Set;
-
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.NullProgressMonitor;
-import org.eclipse.core.runtime.SubProgressMonitor;
-import org.eclipse.mylyn.internal.tasks.core.AbstractTask;
-import org.eclipse.mylyn.internal.tasks.core.ITaskList;
-import org.eclipse.mylyn.internal.tasks.core.deprecated.ITaskFactory;
-import org.eclipse.mylyn.internal.tasks.core.deprecated.LegacyTaskDataCollector;
-import org.eclipse.mylyn.internal.tasks.core.deprecated.RepositoryTaskData;
-
-/**
- * @author Shawn Minto
- */
-public class ProgressQueryHitCollector extends LegacyTaskDataCollector {
-
-	public static final int MAX_HITS = 5000;
-
-	public static final String MAX_HITS_REACHED = "Max allowed number of hits returned exceeded. Some hits may not be displayed. Please narrow query scope.";
-
-	protected Set<AbstractTask> taskResults = new HashSet<AbstractTask>();
-
-	/** The progress monitor for the search operation */
-	private IProgressMonitor monitor = new NullProgressMonitor();
-
-	/** The number of matches found */
-	private int matchCount;
-
-	/** The string to display to the user while querying */
-	private static final String STARTING = "querying the server";
-
-	/** The string to display to the user when we have 1 match */
-	private static final String MATCH = "1 match";
-
-	/** The string to display to the user when we have multiple or no matches */
-	private static final String MATCHES = "{0} matches";
-
-	/** The string to display to the user when the query is done */
-	private static final String DONE = "done";
-
-	protected ITaskList taskList;
-
-	protected ITaskFactory taskFactory;
-
-	public ProgressQueryHitCollector(ITaskList tasklist, ITaskFactory taskFactory) {
-		this.taskList = tasklist;
-		this.taskFactory = taskFactory;
-	}
-
-	public void aboutToStart(int startMatchCount) throws CoreException {
-		taskResults.clear();
-		matchCount = startMatchCount;
-		monitor.setTaskName(STARTING);
-	}
-
-//	public void accept(AbstractTask task) {
-//
-//		if (!getProgressMonitor().isCanceled()) {
-//			getProgressMonitor().subTask(getFormattedMatchesString(matchCount));
-//			getProgressMonitor().worked(1);
-//		}
-//
-//		if (task == null) {
-//			return;
-//		}
-//
-//		AbstractTask hitTask = taskList.getTask(task.getHandleIdentifier());
-//		if (hitTask == null) {
-//			hitTask = task;
-//			// task is new, add to tasklist
-//			taskList.addTask(hitTask);
-//		}
-//		taskResults.add(hitTask);
-//		matchCount++;
-//	}
-
-	@Override
-	public void accept(RepositoryTaskData taskData) {
-		if (taskData == null) {
-			return;
-		}
-
-		if (!getProgressMonitor().isCanceled()) {
-			getProgressMonitor().subTask(getFormattedMatchesString(matchCount));
-			getProgressMonitor().worked(1);
-		}
-
-		AbstractTask task;
-		try {
-			task = taskFactory.createTask(taskData, new SubProgressMonitor(monitor, 1));
-			taskResults.add(task);
-			matchCount++;
-		} catch (CoreException e) {
-			// FIXME
-			e.printStackTrace();
-		}
-	}
-
-	public void done() {
-		if (monitor != null && !monitor.isCanceled()) {
-			// if the operation is cancelled, finish with the data that we
-			// already have
-			String matchesString = getFormattedMatchesString(matchCount);
-			monitor.setTaskName(MessageFormat.format(DONE, new Object[] { matchesString }));
-			monitor.done();
-		}
-
-		// Cut no longer used references because the collector might be re-used
-		monitor = null;
-	}
-
-	protected String getFormattedMatchesString(int count) {
-		if (count == 1) {
-			return MATCH;
-		}
-		Object[] messageFormatArgs = { new Integer(count) };
-		return MessageFormat.format(MATCHES, messageFormatArgs);
-	}
-
-	public IProgressMonitor getProgressMonitor() {
-		return monitor;
-	}
-
-	public void setProgressMonitor(IProgressMonitor monitor) {
-		this.monitor = monitor;
-	}
-
-	public Set<AbstractTask> getTasks() {
-		return taskResults;
-	}
-
-	public void clear() {
-		taskResults.clear();
-	}
-
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/bugs/Util.java b/org.eclipse.mylyn.ide.dev/developer/src-old/bugs/Util.java
deleted file mode 100644
index 48baef3..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/bugs/Util.java
+++ /dev/null
@@ -1,220 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004, 2008 Tasktop Technologies and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     Tasktop Technologies - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.mylyn.internal.sandbox.bridge.bugs;
-
-import java.io.UnsupportedEncodingException;
-import java.net.URLEncoder;
-import java.nio.charset.Charset;
-
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.NullProgressMonitor;
-import org.eclipse.jdt.core.IMember;
-import org.eclipse.jdt.core.IType;
-import org.eclipse.jface.dialogs.MessageDialog;
-import org.eclipse.mylyn.internal.bugzilla.core.BugzillaCorePlugin;
-import org.eclipse.mylyn.internal.bugzilla.core.IBugzillaConstants;
-import org.eclipse.mylyn.internal.bugzilla.core.RepositoryConfiguration;
-import org.eclipse.mylyn.internal.bugzilla.ui.BugzillaUiPlugin;
-import org.eclipse.mylyn.internal.tasks.ui.TasksUiPlugin;
-import org.eclipse.mylyn.tasks.core.TaskRepository;
-import org.eclipse.mylyn.tasks.ui.TasksUi;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.ui.PlatformUI;
-
-/**
- * Utilities methods for the BugzillaMylarBridge
- * 
- * @author Shawn Minto
- * @author Mik Kersten
- */
-public class Util {
-
-	/**
-	 * List of all of the search repositoryOperations that can be done <br>
-	 * all words, any words, regex
-	 */
-	private static final String[] patternOperationValues = { "allwordssubstr", "anywordssubstr", "regexp" };
-
-	/**
-	 * Sugzilla preferences so that we can get the search params
-	 */
-	// private static IPreferenceStore prefs =
-	// BugzillaPlugin.getDefault().getPreferenceStore();
-	// private static String[] resolutionValues =
-	// BugzillaRepositoryUtil.convertQueryOptionsToArray(prefs.getString(IBugzillaConstants.VALUES_RESOLUTION));
-	//   
-	// private static String[] statusValues =
-	// BugzillaRepositoryUtil.convertQueryOptionsToArray(prefs.getString(IBugzillaConstants.VALUES_STATUS));
-	/**
-	 * Get the bugzilla url used for searching for exact matches
-	 * 
-	 * @param je
-	 *            The IMember to create the query string for
-	 * @return A url string for the search
-	 */
-	public static String getExactSearchURL(String repositoryUrl, IMember je) {
-		StringBuffer sb = getQueryURLStart(repositoryUrl);
-
-		String long_desc = "";
-
-		// get the fully qualified name of the element
-		long_desc += BugzillaMylynSearchOperation.getFullyQualifiedName(je);
-
-		try {
-			// encode the string to be used as a url
-			sb.append(URLEncoder.encode(long_desc, Charset.defaultCharset().toString()));
-		} catch (UnsupportedEncodingException e) {
-			// should never get here since we are using the default encoding
-		}
-		sb.append(getQueryURLEnd(repositoryUrl));
-
-		return sb.toString();
-	}
-
-	/**
-	 * Get the bugzilla url used for searching for inexact matches
-	 * 
-	 * @param je
-	 *            The IMember to create the query string for
-	 * @return A url string for the search
-	 */
-	public static String getInexactSearchURL(String repositoryUrl, IMember je) {
-		StringBuffer sb = getQueryURLStart(repositoryUrl);
-
-		String long_desc = "";
-
-		// add the member, qualified with just its parents name
-		if (!(je instanceof IType)) {
-			long_desc += je.getParent().getElementName() + ".";
-		}
-		long_desc += je.getElementName();
-
-		try {
-			// encode the string to be used as a url
-			sb.append(URLEncoder.encode(long_desc, Charset.defaultCharset().toString()));
-		} catch (UnsupportedEncodingException e) {
-			// should never get here since we are using the default encoding
-		}
-		sb.append(getQueryURLEnd(repositoryUrl));
-
-		return sb.toString();
-	}
-
-	/**
-	 * Create the end of the bugzilla query URL with all of the status' and resolutions that we want
-	 * 
-	 * @return StringBuffer with the end of the query URL in it
-	 */
-	public static StringBuffer getQueryURLEnd(String repositoryUrl) {
-
-		StringBuffer sb = new StringBuffer();
-		TaskRepository repository = TasksUiPlugin.getRepositoryManager().getRepository(repositoryUrl);
-		RepositoryConfiguration repositoryConfiguration = null;
-		try {
-			repositoryConfiguration = BugzillaCorePlugin.getRepositoryConfiguration(repository, false,
-					new NullProgressMonitor());
-		} catch (final CoreException e) {
-			PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {
-				public void run() {
-					MessageDialog.openError(Display.getDefault().getActiveShell(), "Bugzilla Search Page",
-							"Unable to get configuration. Ensure proper repository configuration in "
-									+ TasksUiPlugin.LABEL_VIEW_REPOSITORIES + ".\n\n");
-				}
-			});
-		}
-
-		String[] resolutionValues = BugzillaUiPlugin.getQueryOptions(IBugzillaConstants.VALUES_RESOLUTION, null,
-				repositoryConfiguration);
-
-		String[] statusValues = BugzillaUiPlugin.getQueryOptions(IBugzillaConstants.VALUES_STATUS, null,
-				repositoryConfiguration);
-
-		// add the status and resolutions that we care about
-		sb.append("&bug_status=" + statusValues[0]); // UNCONFIRMED
-		sb.append("&bug_status=" + statusValues[1]); // NEW
-		sb.append("&bug_status=" + statusValues[2]); // ASSIGNED
-		sb.append("&bug_status=" + statusValues[3]); // REOPENED
-		sb.append("&bug_status=" + statusValues[4]); // RESOLVED
-		sb.append("&bug_status=" + statusValues[5]); // VERIFIED
-		sb.append("&bug_status=" + statusValues[6]); // CLOSED
-
-		sb.append("&resolution=" + resolutionValues[0]); // FIXED
-		sb.append("&resolution=" + resolutionValues[3]); // LATER
-		sb.append("&resolution=" + "---"); // ---
-		return sb;
-	}
-
-	/**
-	 * Create the bugzilla query URL start.
-	 * 
-	 * @return The start of the query url as a StringBuffer <br>
-	 *         Example: https://bugs.eclipse.org/bugs/buglist.cgi?long_desc_type=allwordssubstr&long_desc=
-	 */
-	public static StringBuffer getQueryURLStart(String repositoryUrl) {
-		StringBuffer sb = new StringBuffer(repositoryUrl);
-
-		if (sb.charAt(sb.length() - 1) != '/') {
-			sb.append('/');
-		}
-		sb.append("buglist.cgi?");
-
-		TaskRepository repository = TasksUi.getRepositoryManager().getRepository(BugzillaCorePlugin.CONNECTOR_KIND,
-				repositoryUrl);
-		if (repository != null && repository.hasCredentials()) {
-			// if (BugzillaPreferencePage.getUserName() != null
-			// && !BugzillaPreferencePage.getUserName().equals("")
-			// && BugzillaPreferencePage.getPassword() != null
-			// && !BugzillaPreferencePage.getPassword().equals("")) {
-			try {
-				sb.append("GoAheadAndLogIn=1&Bugzilla_login=" + URLEncoder.encode(repository.getUserName(), // BugzillaPreferencePage.getUserName(),
-						Charset.defaultCharset().toString()) + "&Bugzilla_password="
-						+ URLEncoder.encode(repository.getPassword(), // BugzillaPreferencePage.getPassword(),
-								Charset.defaultCharset().toString()) + "&");
-			} catch (UnsupportedEncodingException e) {
-				// should never get here since we are using the default encoding
-			}
-		}
-		// add the summary search type
-		sb.append("long_desc_type=");
-		sb.append(patternOperationValues[0]); // search for all words
-		sb.append("&long_desc=");
-
-		return sb;
-	}
-
-	/**
-	 * Search the given string for another string
-	 * 
-	 * @param elementName
-	 *            The name of the element that we are looking for
-	 * @param comment
-	 *            The text to search for this element name
-	 * @return <code>true</code> if the element is found in the text else <code>false</code>
-	 */
-	public static boolean hasElementName(String elementName, String comment) {
-
-		// setup a regex for the element name
-		String regexElement = ".*" + elementName + ".*";
-
-		// get all of the individual lines for the string
-		String[] lines = comment.split("\n");
-
-		// go through each of the lines of the string
-		for (String line : lines) {
-
-			if (line.matches(regexElement)) {
-				return true;
-			}
-		}
-		return false;
-	}
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/AbstractBugzillaReportWizard.java b/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/AbstractBugzillaReportWizard.java
deleted file mode 100644
index 710a38f..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/AbstractBugzillaReportWizard.java
+++ /dev/null
@@ -1,238 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2003 - 2006 University Of British Columbia and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     University Of British Columbia - initial API and implementation
- *******************************************************************************/
-package org.eclipse.mylyn.internal.bugzilla.ui.wizard;
-
-import org.eclipse.jface.viewers.IStructuredSelection;
-import org.eclipse.jface.wizard.Wizard;
-import org.eclipse.mylyn.internal.bugzilla.core.NewBugzillaReport;
-import org.eclipse.mylyn.internal.bugzilla.ui.BugzillaUiPlugin;
-import org.eclipse.mylyn.provisional.tasklist.MylarTaskListPlugin;
-import org.eclipse.mylyn.provisional.tasklist.TaskRepository;
-import org.eclipse.ui.INewWizard;
-import org.eclipse.ui.IWorkbench;
-
-/**
- * Class that contains shared functions for the wizards that submit bug reports.
- * 
- * @author Eric Booth
- * @author Mik Kersten (some hardening of prototype)
- * @author Rob Elves
- */
-public abstract class AbstractBugzillaReportWizard extends Wizard implements INewWizard {
-
-	// /** The ID of the posted bug report. */
-	// private String id;
-
-	protected boolean fromDialog = false;
-
-	/** The model used to store all of the data for the wizard */
-	protected NewBugzillaReport model;
-	// TODO: Change model to a RepositoryTaskData
-	//protected RepositoryTaskData model;
-
-	/**
-	 * Flag to indicate if the wizard can be completed based on the attributes
-	 * page
-	 */
-	protected boolean completed = false;
-
-	/** The workbench instance */
-	protected IWorkbench workbenchInstance;
-
-	private final TaskRepository repository;
-
-	public AbstractBugzillaReportWizard(TaskRepository repository) {
-		super();
-		this.repository = repository;
-		model = new NewBugzillaReport(repository.getUrl(), MylarTaskListPlugin.getDefault().getOfflineReportsFile()
-				.getNextOfflineBugId());
-		// id = null;
-		super.setDefaultPageImageDescriptor(BugzillaUiPlugin.imageDescriptorFromPlugin(
-				"org.eclipse.mylyn.internal.bugzilla.ui", "icons/wizban/bug-wizard.gif"));
-	}
-
-	public void init(IWorkbench workbench, IStructuredSelection selection) {
-		this.workbenchInstance = workbench;
-	}
-
-	@Override
-	public void addPages() {
-		super.addPages();
-	}
-
-	/**
-	 * Saves the bug report offline on the user's hard-drive. All offline bug
-	 * reports are saved together in a single file in the plug-in's directory.
-	 */
-	abstract protected void saveBugOffline();
-
-	/**
-	 * @return the last page of this wizard
-	 */
-	abstract protected AbstractBugzillaWizardPage getWizardDataPage();
-
-	public TaskRepository getRepository() {
-		return repository;
-	}
-}
-
-// @Override
-// public boolean performFinish() {
-// getWizardDataPage().saveDataToModel();
-// return postBug();
-//
-// // if (postBug()) {
-// // // if (!fromDialog)
-// // // openBugEditor();
-// // return true;
-// // }
-// // // If the report was not sent, keep the wizard open
-// // else {
-// // return false;
-// // }
-// // }
-//
-// // if (getWizardDataPage().offlineSelected()) {
-// // saveBugOffline();
-// // return true;
-// // }
-//
-// // If no action was selected, keep the wizard open.
-// // return false;
-// }
-
-// /**
-// * Attempts to post the bug on the Bugzilla server. If it fails, an error
-// * message pops up.
-// *
-// * @return true if the bug is posted successfully, and false otherwise
-// */
-// protected boolean postBug() {
-//
-// final IRunnableWithProgress op = new IRunnableWithProgress() {
-// public void run(IProgressMonitor monitor) throws InvocationTargetException,
-// InterruptedException {
-// Proxy proxySettings = MylarTaskListPlugin.getDefault().getProxySettings();
-// boolean wrap =
-// IBugzillaConstants.BugzillaServerVersion.SERVER_218.equals(repository.getVersion());
-// try {
-// form = BugzillaReportSubmitForm.makeNewBugPost(repository.getUrl(),
-// repository.getUserName(),
-// repository.getPassword(), proxySettings, repository.getCharacterEncoding(),
-// model, wrap);
-// id = form.submitReportToRepository();
-// if (id != null) {
-// sentSuccessfully = true;
-// }
-// } catch (Exception e) {
-// throw new InvocationTargetException(e);
-// }
-// }
-// };
-//
-// IProgressService service = PlatformUI.getWorkbench().getProgressService();
-// try {
-// service.run(true, false, op);
-// } catch (InvocationTargetException e) {
-// if (e.getCause() instanceof BugzillaException) {
-// MessageDialog.openError(getWizardDataPage().getShell(), "I/O Error",
-// "Bugzilla could not post your bug.");
-// } else if (e.getCause() instanceof PossibleBugzillaFailureException) {
-// WebBrowserDialog.openAcceptAgreement(getWizardDataPage().getShell(),
-// "Bugzilla Submission Error Message", e.getCause().getMessage(),
-// form.getError());
-// } else if (e.getCause() instanceof LoginException) {
-// MessageDialog.openError(getWizardDataPage().getShell(), "Posting Error",
-// "Bugzilla could not post your bug since your login name or password is
-// incorrect."
-// + "\nPlease check your settings in the bugzilla preferences. ");
-// } else if (e.getCause() instanceof UnsupportedEncodingException) {
-// // should never get here but just in case...
-// MessageDialog.openError(getWizardDataPage().getShell(), "Posting Error",
-// "Ensure proper encoding selected in "
-// + TaskRepositoriesView.NAME + ".");
-// }
-// } catch (InterruptedException e) {
-// // ignore
-// }
-// return sentSuccessfully;
-//
-// // final WorkspaceModifyOperation op = new WorkspaceModifyOperation() {
-// // protected void execute(final IProgressMonitor monitor) throws
-// // CoreException {
-// // PlatformUI.getWorkbench().getDisplay().syncExec(new Runnable() {
-// // public void run() {
-// // Proxy proxySettings =
-// // MylarTaskListPlugin.getDefault().getProxySettings();
-// // boolean wrap =
-// //
-// IBugzillaConstants.BugzillaServerVersion.SERVER_218.equals(repository.getVersion());
-// // BugzillaReportSubmitForm form =
-// // BugzillaReportSubmitForm.makeNewBugPost(repository.getUrl(),
-// // repository.getUserName(), repository.getPassword(), proxySettings,
-// // model, wrap);
-// // try {
-// // id = form.submitReportToRepository();
-// //
-// // if (id != null) {
-// // sentSuccessfully = true;
-// // }
-// // } catch (BugzillaException e) {
-// // MessageDialog.openError(null, "I/O Error", "Bugzilla could not post
-// // your bug.");
-// // BugzillaPlugin.log(e);
-// // } catch (PossibleBugzillaFailureException e) {
-// // WebBrowserDialog.openAcceptAgreement(null, "Possible Bugzilla Client
-// // Failure",
-// // "Bugzilla may not have posted your bug.\n" + e.getMessage(),
-// // form.getError());
-// // BugzillaPlugin.log(e);
-// // } catch (LoginException e) {
-// // MessageDialog.openError(null, "Posting Error",
-// // "Bugzilla could not post your bug since your login name or password
-// // is incorrect."
-// // + "\nPlease check your settings in the bugzilla preferences. ");
-// // sentSuccessfully = false;
-// // }
-// // }
-// //
-// // });
-// // }
-// // };
-//
-// }
-
-// /**
-// * Try to open the editor with the newly created bug.
-// */
-// protected void openBugEditor() {
-//
-// IEditorInput input = null;
-// try {
-// input = new ExistingBugEditorInput(repository, Integer.parseInt(id));
-// PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().openEditor(input,
-// BugzillaUiPlugin.EXISTING_BUG_EDITOR_ID, false);
-// } catch (LoginException e) {
-// // if we had an error with logging in, display an error
-// MessageDialog.openError(null, "Posting Error",
-// "Bugzilla could not access and display your bug in the editor because your
-// login name or password is incorrect."
-// + "\nPlease check your settings in the bugzilla preferences. ");
-// } catch (PartInitException e) {
-// // if there was a problem, handle it and log it, then get out of
-// // here
-// ExceptionHandler.handle(e, SearchMessages.Search_Error_search_title,
-// SearchMessages.Search_Error_search_message);
-// BugzillaPlugin.log(e.getStatus());
-// } catch (Exception e) {
-// MylarStatusHandler.fail(e, "Failed to open Bugzilla report", false);
-// }
-// }
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/AbstractBugzillaWizardPage.java b/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/AbstractBugzillaWizardPage.java
deleted file mode 100644
index 572e375..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/AbstractBugzillaWizardPage.java
+++ /dev/null
@@ -1,780 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2003 - 2006 University Of British Columbia and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     University Of British Columbia - initial API and implementation
- *******************************************************************************/
-package org.eclipse.mylyn.internal.bugzilla.ui.wizard;
-
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Set;
-
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.Platform;
-import org.eclipse.core.runtime.Status;
-import org.eclipse.jface.wizard.IWizardPage;
-import org.eclipse.jface.wizard.WizardPage;
-import org.eclipse.mylyn.internal.bugzilla.core.BugzillaReportElement;
-import org.eclipse.mylyn.internal.bugzilla.core.NewBugzillaReport;
-import org.eclipse.mylyn.internal.core.util.MylarStatusHandler;
-import org.eclipse.mylyn.internal.tasklist.RepositoryTaskAttribute;
-import org.eclipse.mylyn.internal.tasklist.ui.editors.AbstractTaskEditor;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.graphics.Font;
-import org.eclipse.swt.graphics.FontData;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Combo;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Event;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Listener;
-import org.eclipse.swt.widgets.Text;
-import org.eclipse.ui.IWorkbench;
-import org.eclipse.ui.PlatformUI;
-import org.eclipse.ui.internal.WorkbenchImages;
-import org.eclipse.ui.internal.ide.IDEInternalWorkbenchImages;
-import org.eclipse.ui.themes.IThemeManager;
-
-/**
- * Class that contains shared functions for the last page of the wizards that
- * submit bug reports. This page allows the user to set the bug report's
- * attributes before submitting it.
- * 
- * @author Mik Kersten (hardening of initial prototype)
- */
-public abstract class AbstractBugzillaWizardPage extends WizardPage implements Listener {
-
-	/** The instance of the workbench */
-	protected IWorkbench workbench;
-
-	/** Text field for the bugs url */
-	protected Text urlText;
-
-	/** Text field for the description of the bug */
-	protected Text descriptionText;
-
-	/** Text field for the summary of the bug */
-	protected Text summaryText;
-
-	/** Text field for the assignedTo of the bug */
-	protected Text assignedToText;
-
-	// /** Radio button to select when sending the new bug report to the server
-	// */
-	// protected Button serverButton;
-	//
-	// /** Radio button to select when saving the new bug report offline */
-	// protected Button offlineButton;
-
-	/** Combo box for the component that caused the bug */
-	protected Combo componentCombo;
-
-	/** Combo box for the priority of the bug */
-	protected Combo priorityCombo;
-
-	/** Combo box for the platform the bug occurred on */
-	protected Combo platformCombo;
-
-	/** Combo box for the severity of the bug */
-	protected Combo severityCombo;
-
-	/** Combo box for the products version */
-	protected Combo versionCombo;
-
-	/** Combo box for the OS that the bug occurred under */
-	protected Combo oSCombo;
-
-	/** Combo box for the Milestone that the bug addresses */
-	protected Combo milestoneCombo;
-
-	/** Enum for value */
-	protected final String VALUE = "VALUE";
-
-	/** Enum for property */
-	protected final String PROPERTY = "PROPERTY";
-
-	/** Enum for header */
-	protected final String HEADER = "HEADER";
-
-	/** The horizontal indentation of the labels */
-	protected final int HORZ_INDENT = 0;
-
-	/** Status variable for the possible errors on this page */
-	protected IStatus attributeStatus;
-
-	/**
-	 * Constructor for AbstractWizardDataPage
-	 * 
-	 * @param pageName
-	 *            the name of the page
-	 * @param title
-	 *            the title of the page
-	 * @param description
-	 *            the description text for the page
-	 * @param workbench
-	 *            the instance of the workbench
-	 */
-	public AbstractBugzillaWizardPage(String pageName, String title, String description, IWorkbench workbench) {
-		super(pageName);
-		setTitle(title);
-		setDescription(description);
-		this.workbench = workbench;
-
-		// set the status for the page
-		attributeStatus = new Status(IStatus.OK, "not_used", 0, "", null);
-	}
-
-	/**
-	 * Applies the status to the status line of a dialog page.
-	 * 
-	 * @param status
-	 *            The status to apply to the status line
-	 */
-	protected void applyToStatusLine(IStatus status) {
-		String message = status.getMessage();
-		if (message.length() == 0)
-			message = null;
-		switch (status.getSeverity()) {
-		case IStatus.OK:
-			setErrorMessage(null);
-			setMessage(message);
-			break;
-		case IStatus.WARNING:
-			setErrorMessage(null);
-			setMessage(message, WizardPage.WARNING);
-			break;
-		case IStatus.INFO:
-			setErrorMessage(null);
-			setMessage(message, WizardPage.INFORMATION);
-			break;
-		default:
-			setErrorMessage(null);
-			setMessage(message, WizardPage.ERROR);
-			break;
-		}
-	}
-
-	/**
-	 * Make sure that a String that is <code>null</code> is changed to a null
-	 * string
-	 * 
-	 * @param text
-	 *            The text to check if it is null or not
-	 * @return The string in its proper format
-	 */
-	public String checkText(String text) {
-		if (text == null)
-			return "";
-		else
-			return text;
-	}
-
-	@Override
-	public boolean canFlipToNextPage() {
-		// no next page for this path through the wizard
-		return false;
-	}
-
-	/**
-	 * Create a new layout for a component
-	 * 
-	 * @param composite
-	 *            The parent composite
-	 * @param colSpan
-	 *            The number of columns that this can span
-	 * @param text
-	 *            The text to add to the control
-	 * @param style
-	 *            The style that the control should have
-	 */
-	public void newLayout(Composite composite, int colSpan, String text, String style) {
-		GridData data = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
-		data.horizontalSpan = colSpan;
-
-		// create the proper layout for the style
-		if (style.equalsIgnoreCase(VALUE)) {
-			Label l = new Label(composite, SWT.NONE);
-			FontData fontData = l.getFont().getFontData()[0];
-			fontData.setStyle(SWT.BOLD | fontData.getStyle());
-			Font font = new Font(null, fontData);
-			l.setFont(font);
-			l.setText(checkText(text));
-
-			data.horizontalIndent = HORZ_INDENT;
-			l.setLayoutData(data);
-		} else if (style.equalsIgnoreCase(PROPERTY)) {
-			Label l = new Label(composite, SWT.NONE);
-			FontData fontData = l.getFont().getFontData()[0];
-			fontData.setStyle(SWT.BOLD | fontData.getStyle());
-			Font font = new Font(null, fontData);
-			l.setFont(font);
-			l.setText(checkText(text));
-
-			data.horizontalIndent = HORZ_INDENT;
-			l.setLayoutData(data);
-		} else {
-			Composite generalTitleGroup = new Composite(composite, SWT.NONE);
-			generalTitleGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-			generalTitleGroup.setLayoutData(data);
-			GridLayout generalTitleLayout = new GridLayout();
-			generalTitleLayout.numColumns = 2;
-			generalTitleLayout.marginWidth = 0;
-			generalTitleLayout.marginHeight = 9;
-			generalTitleGroup.setLayout(generalTitleLayout);
-
-			Label image = new Label(generalTitleGroup, SWT.NONE);
-			image.setImage(WorkbenchImages.getImage(IDEInternalWorkbenchImages.IMG_OBJS_WELCOME_ITEM));
-
-			GridData gd = new GridData(GridData.FILL_BOTH);
-			gd.verticalAlignment = GridData.VERTICAL_ALIGN_BEGINNING;
-			image.setLayoutData(gd);
-			Label l = new Label(composite, SWT.NONE);
-			FontData fontData = l.getFont().getFontData()[0];
-			fontData.setStyle(SWT.BOLD | fontData.getStyle());
-			Font font = new Font(null, fontData);
-			l.setFont(font);
-			l.setText(checkText(text));
-
-			data.horizontalIndent = HORZ_INDENT;
-			l.setLayoutData(data);
-		}
-	}
-
-	/**
-	 * Determine if the page is complete when the summary is changed
-	 * 
-	 * @param e
-	 *            The event which occurred
-	 */
-	public void handleEvent(Event e) {
-		boolean pageComplete = isPageComplete();
-
-		// Initialize a variable with the no error status
-		Status status = new Status(IStatus.OK, "not_used", 0, "", null);
-
-		setPageComplete(pageComplete);
-
-		if (!pageComplete)
-			status = new Status(IStatus.ERROR, "not_used", 0, "You must enter a summary and a description", null);
-
-		attributeStatus = status;
-
-		// Show the most serious error
-		applyToStatusLine(attributeStatus);
-
-		setPageComplete(pageComplete);
-		getWizard().getContainer().updateButtons();
-	}
-
-	@Override
-	public IWizardPage getNextPage() {
-		saveDataToModel();
-		return null;
-	}
-
-	/**
-	 * Sets the completed field on the wizard class when all the needed
-	 * information is entered and the wizard can be completed
-	 * 
-	 * @return true if the wizard can be completed, false otherwise
-	 */
-	@Override
-	public boolean isPageComplete() {
-		AbstractBugzillaReportWizard wizard = (AbstractBugzillaReportWizard) getWizard();
-		if (summaryText.getText() == null || summaryText.getText().equals("") || descriptionText.getText() == null
-				|| descriptionText.getText().equals("")) {
-			wizard.completed = false;
-			return false;
-		}
-		// saveDataToModel();
-		wizard.completed = true;
-		return true;
-	}
-
-	/**
-	 * Save the data obtained from this point in the wizard to the model.
-	 */
-	public void saveDataToModel() {
-		// get the model that we are using
-		AbstractBugzillaReportWizard wizard = (AbstractBugzillaReportWizard) getWizard();
-		NewBugzillaReport nbm = wizard.model;
-
-		nbm.setDescription(descriptionText.getText());
-		nbm.setSummary(summaryText.getText());
-
-		// go through each of the attributes and sync their values with the
-		// combo boxes
-		for (Iterator<RepositoryTaskAttribute> it = nbm.getAttributes().iterator(); it.hasNext();) {
-			RepositoryTaskAttribute attribute = it.next();
-			String key = attribute.getName();
-			Map<String, String> values = attribute.getOptionValues();
-
-			try {
-				if (values == null)
-					values = new HashMap<String, String>();
-				if (key.equals(BugzillaReportElement.OP_SYS.toString())) {
-					String os = oSCombo.getItem(oSCombo.getSelectionIndex());
-					attribute.setValue(os);
-				} else if (key.equals(BugzillaReportElement.VERSION.toString())) {
-					String version = versionCombo.getItem(versionCombo.getSelectionIndex());
-					attribute.setValue(version);
-				} else if (key.equals(BugzillaReportElement.BUG_SEVERITY.toString())) {
-					String severity = severityCombo.getItem(severityCombo.getSelectionIndex());
-					attribute.setValue(severity);
-				} else if (key.equals(BugzillaReportElement.REP_PLATFORM.toString())) {
-					String platform = platformCombo.getItem(platformCombo.getSelectionIndex());
-					attribute.setValue(platform);
-				} else if (key.equals(BugzillaReportElement.TARGET_MILESTONE.toString())) {
-					int index = milestoneCombo.getSelectionIndex();
-					if(index >= 0) {
-						String milestone = milestoneCombo.getItem(milestoneCombo.getSelectionIndex());
-						attribute.setValue(milestone);
-					}
-				} else if (key.equals(BugzillaReportElement.COMPONENT.toString())) {
-					String component = componentCombo.getItem(componentCombo.getSelectionIndex());
-					attribute.setValue(component);
-				} else if (key.equals(BugzillaReportElement.PRIORITY.toString())) {
-					String priority = priorityCombo.getItem(priorityCombo.getSelectionIndex());
-					attribute.setValue(priority);
-				} else if (key.equals(BugzillaReportElement.BUG_FILE_LOC.toString())) {
-					if (urlText != null) {
-						String url = urlText.getText();
-						if (url.equalsIgnoreCase("http://"))
-							url = "";
-						attribute.setValue(url);
-					}					
-				} else if (key.equals(BugzillaReportElement.ASSIGNED_TO.toString())) {
-					String assignTo = assignedToText.getText();
-					attribute.setValue(assignTo);
-				} else {
-					// do nothing
-				}
-			} catch (IllegalArgumentException e) {
-				MylarStatusHandler.fail(e, "could not set attribute: " + attribute, false);
-			}
-		}
-		// wizard.attributeCompleted = true;
-	}
-
-	@Override
-	protected void setControl(Control c) {
-		super.setControl(c);
-	}
-
-	/*
-	 * (non-Javadoc)
-	 * 
-	 * @see org.eclipse.jface.dialogs.IDialogPage#createControl(org.eclipse.swt.widgets.Composite)
-	 */
-	public void createControl(Composite parent) {
-		// whether the priority exists or not
-		boolean priExist = false;
-		boolean mileExist = false;
-
-		String url = null;
-
-		// get the model for the new bug
-		AbstractBugzillaReportWizard wizard = (AbstractBugzillaReportWizard) getWizard();
-		NewBugzillaReport nbm = wizard.model;
-
-		// Set the current platform and OS on the model
-		setPlatformOptions(nbm);
-
-		// Attributes Composite- this holds all the combo fields and text
-		// fields
-		Composite attributesComposite = new Composite(parent, SWT.NONE);
-		GridLayout attributesLayout = new GridLayout();
-		attributesLayout.numColumns = 4;
-		attributesLayout.horizontalSpacing = 14;
-		attributesLayout.verticalSpacing = 6;
-		attributesLayout.makeColumnsEqualWidth = false;
-		attributesComposite.setLayout(attributesLayout);
-
-		GridData attributesData = new GridData(GridData.FILL_BOTH);
-		attributesData.horizontalSpan = 1;
-		attributesData.grabExcessVerticalSpace = false;
-		attributesComposite.setLayoutData(attributesData);
-		// End Attributes Composite
-
-		GridLayout attributesTitleLayout = new GridLayout();
-		attributesTitleLayout.horizontalSpacing = 0;
-		attributesTitleLayout.marginWidth = 0;
-
-		GridData attributesTitleData = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
-		attributesTitleData.horizontalSpan = 4;
-
-		attributesTitleData.grabExcessVerticalSpace = false;
-
-		// Add the product to the composite
-		newLayout(attributesComposite, 1, "Product", PROPERTY);
-		newLayout(attributesComposite, 1, nbm.getProduct(), VALUE);
-
-		// Populate Attributes
-		for (Iterator<RepositoryTaskAttribute> it = nbm.getAttributes().iterator(); it.hasNext();) {
-			RepositoryTaskAttribute attribute = it.next();
-			String key = attribute.getID();
-			String name = attribute.getName();
-			String value = checkText(attribute.getValue());
-			Map<String, String> values = attribute.getOptionValues();
-
-			// if it is a hidden field, don't try to display it
-			if (attribute.isHidden())
-				continue;
-
-			if (key == null)
-				key = "";
-
-			if (values == null)
-				values = new HashMap<String, String>();
-
-			GridData data = new GridData(GridData.BEGINNING);
-			data.horizontalSpan = 1;
-			data.horizontalIndent = HORZ_INDENT;
-			data.widthHint = 150;
-			// create and populate the combo fields for the attributes
-			if (key.equals(BugzillaReportElement.OP_SYS.getKeyString())) {
-				newLayout(attributesComposite, 1, name, PROPERTY);
-				oSCombo = new Combo(attributesComposite, SWT.NO_BACKGROUND | SWT.MULTI | SWT.V_SCROLL | SWT.READ_ONLY);
-
-				oSCombo.setLayoutData(data);
-				Set<String> s = values.keySet();
-				String[] a = s.toArray(new String[s.size()]);
-				for (int i = 0; i < a.length; i++) {
-					oSCombo.add(a[i]);
-				}
-				int index;
-				if ((index = oSCombo.indexOf(value)) == -1)
-					index = 0;
-				oSCombo.select(index);
-				oSCombo.addListener(SWT.Modify, this);
-			} else if (key.equals(BugzillaReportElement.VERSION.getKeyString())) {
-				newLayout(attributesComposite, 1, name, PROPERTY);
-
-				versionCombo = new Combo(attributesComposite, SWT.NO_BACKGROUND | SWT.MULTI | SWT.V_SCROLL
-						| SWT.READ_ONLY);
-
-				versionCombo.setLayoutData(data);
-				Set<String> s = values.keySet();
-				String[] a = s.toArray(new String[s.size()]);
-				for (int i = 0; i < a.length; i++) {
-					versionCombo.add(a[i]);
-				}
-				int index;
-				if ((index = versionCombo.indexOf(value)) == -1)
-					index = 0;
-				versionCombo.select(index);
-				versionCombo.addListener(SWT.Modify, this);
-			} else if (key.equals(BugzillaReportElement.BUG_SEVERITY.getKeyString())) {
-				newLayout(attributesComposite, 1, name, PROPERTY);
-				severityCombo = new Combo(attributesComposite, SWT.NO_BACKGROUND | SWT.MULTI | SWT.V_SCROLL
-						| SWT.READ_ONLY);
-
-				severityCombo.setLayoutData(data);
-				Set<String> s = values.keySet();
-				String[] a = s.toArray(new String[s.size()]);
-				for (int i = 0; i < a.length; i++) {
-					severityCombo.add(a[i]);
-				}
-				int index;
-				if ((index = severityCombo.indexOf(value)) == -1)
-					index = 0;
-				severityCombo.select(index);
-				severityCombo.addListener(SWT.Modify, this);
-
-			} else if (key.equals(BugzillaReportElement.REP_PLATFORM.getKeyString())) {
-				newLayout(attributesComposite, 1, name, PROPERTY);
-				platformCombo = new Combo(attributesComposite, SWT.NO_BACKGROUND | SWT.MULTI | SWT.V_SCROLL
-						| SWT.READ_ONLY);
-
-				platformCombo.setLayoutData(data);
-				Set<String> s = values.keySet();
-				String[] a = s.toArray(new String[s.size()]);
-				for (int i = 0; i < a.length; i++) {
-					platformCombo.add(a[i]);
-				}
-				int index;
-				if ((index = platformCombo.indexOf(value)) == -1)
-					index = 0;
-				platformCombo.select(index);
-				platformCombo.addListener(SWT.Modify, this);
-			} else if (key.equals(BugzillaReportElement.TARGET_MILESTONE.getKeyString())) {
-				newLayout(attributesComposite, 1, name, PROPERTY);
-				milestoneCombo = new Combo(attributesComposite, SWT.NO_BACKGROUND | SWT.MULTI | SWT.V_SCROLL
-						| SWT.READ_ONLY);
-				milestoneCombo.setLayoutData(data);
-				Set<String> s = values.keySet();
-				String[] a = s.toArray(new String[s.size()]);
-				for (int i = 0; i < a.length; i++) {
-					milestoneCombo.add(a[i]);
-				}
-				int index;
-				if ((index = milestoneCombo.indexOf(value)) == -1)
-					index = 0;
-				milestoneCombo.select(index);
-				milestoneCombo.addListener(SWT.Modify, this);
-				//if(s.isEmpty()) milestoneCombo.setEnabled(false);
-				mileExist = true;
-			} else if (key.equals(BugzillaReportElement.COMPONENT.getKeyString())) {
-				newLayout(attributesComposite, 1, name, PROPERTY);
-				componentCombo = new Combo(attributesComposite, SWT.NO_BACKGROUND | SWT.MULTI | SWT.V_SCROLL
-						| SWT.READ_ONLY);
-
-				componentCombo.setLayoutData(data);
-				Set<String> s = values.keySet();
-				String[] a = s.toArray(new String[s.size()]);
-				for (int i = 0; i < a.length; i++) {
-					componentCombo.add(a[i]);
-				}
-				int index;
-				if ((index = componentCombo.indexOf(value)) == -1)
-					index = 0;
-				componentCombo.select(index);
-				componentCombo.addListener(SWT.Modify, this);
-			} else if (key.equals(BugzillaReportElement.PRIORITY.getKeyString())) {
-				newLayout(attributesComposite, 1, name, PROPERTY);
-				priorityCombo = new Combo(attributesComposite, SWT.NO_BACKGROUND | SWT.MULTI | SWT.V_SCROLL
-						| SWT.READ_ONLY);
-
-				priorityCombo.setLayoutData(data);
-				Set<String> s = values.keySet();
-				String[] a = s.toArray(new String[s.size()]);
-				for (int i = 0; i < a.length; i++) {
-					priorityCombo.add(a[i]);
-				}
-				int index;
-				if ((index = priorityCombo.indexOf(value)) == -1)
-					index = 0;
-				priorityCombo.select(index);
-				priorityCombo.addListener(SWT.Modify, this);
-				priExist = true;
-			} else if (key.equals(BugzillaReportElement.BUG_FILE_LOC.getKeyString())) {
-				url = value;
-			} else {
-				// do nothing if it isn't a standard value to change
-			}
-		}
-
-		if (priExist && !mileExist) {
-			newLayout(attributesComposite, 1, "", PROPERTY);
-			newLayout(attributesComposite, 1, "", PROPERTY);
-		}
-
-		Composite textComposite = new Composite(attributesComposite, SWT.NONE);
-		textComposite.setLayout(new GridLayout(3, false));
-		GridData textCompositeGD = new GridData();
-		textCompositeGD.horizontalSpan = 4;
-		textCompositeGD.grabExcessHorizontalSpace = true;
-		textComposite.setLayoutData(textCompositeGD);
-
-	
-		GridData urlTextData;
-		if (url != null) {			
-			newLayout(textComposite, 1, BugzillaReportElement.BUG_FILE_LOC.toString(), PROPERTY);
-			urlText = new Text(textComposite, SWT.BORDER | SWT.SINGLE | SWT.WRAP);
-			urlTextData = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
-
-			urlTextData.horizontalSpan = 2;
-			// summaryTextData.widthHint = 200;
-			urlText.setLayoutData(urlTextData);
-			urlText.setText(url);
-			urlText.addListener(SWT.FocusOut, this);
-		}
-
-		GridData summaryTextData;
-		newLayout(textComposite, 1, BugzillaReportElement.ASSIGNED_TO.toString(), PROPERTY);
-		Label l = new Label(textComposite, SWT.NONE);
-		l.setText("(if email is incorrect submit will not proceed)");
-		summaryTextData = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
-		summaryTextData.horizontalSpan = 1;
-		l.setLayoutData(summaryTextData);
-		assignedToText = new Text(textComposite, SWT.BORDER | SWT.SINGLE | SWT.WRAP);
-		summaryTextData = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
-
-		summaryTextData.horizontalSpan = 1;
-		summaryTextData.widthHint = 200;
-		assignedToText.setLayoutData(summaryTextData);
-		assignedToText.setText("");
-
-		
-		IThemeManager themeManager = PlatformUI.getWorkbench().getThemeManager();
-		Font repositoryFont = themeManager.getCurrentTheme().getFontRegistry().get(AbstractTaskEditor.REPOSITORY_TEXT_ID);
-		
-		// add the summary text field
-		newLayout(textComposite, 1, BugzillaReportElement.SHORT_DESC.toString(), PROPERTY);
-		summaryText = new Text(textComposite, SWT.BORDER | SWT.SINGLE | SWT.WRAP);
-		summaryText.setFont(repositoryFont);
-		summaryTextData = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
-
-		summaryTextData.horizontalSpan = 2;
-		summaryTextData.widthHint = 200;
-		summaryText.setLayoutData(summaryTextData);
-		summaryText.setText(nbm.getSummary());
-		summaryText.addListener(SWT.Modify, this);
-
-		// Description Text
-		Composite descriptionComposite = new Composite(attributesComposite, SWT.NONE);
-
-		descriptionComposite.setLayout(attributesTitleLayout);
-
-		GridData descriptionData = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
-		descriptionData.horizontalSpan = 4;
-		descriptionData.grabExcessVerticalSpace = false;
-		descriptionComposite.setLayoutData(descriptionData);
-		newLayout(descriptionComposite, 4, "Description:", HEADER);
-
-		// add the description text field
-		descriptionText = new Text(attributesComposite, SWT.BORDER | SWT.MULTI | SWT.V_SCROLL | SWT.WRAP);
-
-		//descriptionText.setFont(AbstractTaskEditor.COMMENT_FONT);
-		descriptionText.setFont(repositoryFont);
-		GridData descriptionTextData = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
-		descriptionTextData.horizontalSpan = 4;
-		descriptionTextData.widthHint = AbstractTaskEditor.DESCRIPTION_WIDTH;
-		descriptionTextData.heightHint = AbstractTaskEditor.DESCRIPTION_HEIGHT;
-		descriptionText.setLayoutData(descriptionTextData);
-		descriptionText.addListener(SWT.Modify, this);
-
-		// serverButton = new Button(attributesComposite, SWT.RADIO);
-		// serverButton.setText("Submit bug report to the server.");
-		// GridData toServerButtonData = new
-		// GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
-		// toServerButtonData.horizontalSpan = 4;
-		// serverButton.setLayoutData(toServerButtonData);
-		// serverButton.setSelection(true);
-		//
-		// offlineButton = new Button(attributesComposite, SWT.RADIO);
-		// offlineButton.setText("Save bug report offline.");
-		// GridData offlineButtonData = new
-		// GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
-		// offlineButtonData.horizontalSpan = 4;
-		// offlineButton.setLayoutData(offlineButtonData);
-		// offlineButton.setSelection(false);
-
-		// if (wizard.fromDialog)
-		// offlineButton.setEnabled(false);
-
-		setControl(attributesComposite);
-		return;
-	}
-
-	// /**
-	// * @return <code>true</code> if the radio button to submit the bug to the
-	// * server is selected.
-	// */
-	// public boolean serverSelected() {
-	// return (serverButton == null) ? false : serverButton.getSelection();
-	// }
-	//
-	// /**
-	// * @return <code>true</code> if the radio button to save the bug offline
-	// * is selected.
-	// */
-	// public boolean offlineSelected() {
-	// return (offlineButton == null) ? false : offlineButton.getSelection();
-	// }
-
-	/*
-	 * The following are Bugzilla's: OS's All AIX Windows 95 Windows 98 Windows
-	 * CE Windows Mobile 2003 Windows Mobile 2005 Windows ME Windows 2000
-	 * Windows NT Windows XP Windows 2003 Server Windows All MacOS X Linux
-	 * Linux-GTK Linux-Motif HP-UX Neutrino QNX-Photon Solaris Solaris-GTK
-	 * Solaris-Motif SymbianOS-Series 80 Unix All other
-	 * 
-	 * The following are the platforsm in Bugzilla: All Macintosh PC Power PC
-	 * Sun Other
-	 * 
-	 * The following are Java's Archictures: [PA_RISC, ppc, sparc, x86, x86_64,
-	 * ia64, ia64_32]
-	 * 
-	 * The following are Java's OS's: [aix, hpux, linux, macosx, qnx, solaris,
-	 * win32]
-	 */
-	/**
-	 * Sets the OS and Platform for the new bug
-	 * 
-	 * @param newBugModel
-	 *            The bug to set the options for
-	 */
-	public void setPlatformOptions(NewBugzillaReport newBugModel) {
-		try {
-			// A Map from Java's OS and Platform to Buzilla's
-			Map<String, String> java2buzillaOSMap = new HashMap<String, String>();
-			Map<String, String> java2buzillaPlatformMap = new HashMap<String, String>();
-
-			java2buzillaPlatformMap.put("x86", "PC");
-			java2buzillaPlatformMap.put("x86_64", "PC");
-			java2buzillaPlatformMap.put("ia64", "PC");
-			java2buzillaPlatformMap.put("ia64_32", "PC");
-			java2buzillaPlatformMap.put("sparc", "Sun");
-			java2buzillaPlatformMap.put("ppc", "Power");
-
-			java2buzillaOSMap.put("aix", "AIX");
-			java2buzillaOSMap.put("hpux", "HP-UX");
-			java2buzillaOSMap.put("linux", "Linux");
-			java2buzillaOSMap.put("macosx", "MacOS X");
-			java2buzillaOSMap.put("qnx", "QNX-Photon");
-			java2buzillaOSMap.put("solaris", "Solaris");
-			java2buzillaOSMap.put("win32", "Windows");
-
-			// Get OS Lookup Map
-			// Check that the result is in Values, if it is not, set it to other
-			RepositoryTaskAttribute opSysAttribute = newBugModel.getAttribute(BugzillaReportElement.OP_SYS.getKeyString());
-			RepositoryTaskAttribute platformAttribute = newBugModel.getAttribute(BugzillaReportElement.REP_PLATFORM.getKeyString());
-
-			String OS = Platform.getOS();
-			String platform = Platform.getOSArch();
-
-			String bugzillaOS = null; // Bugzilla String for OS
-			String bugzillaPlatform = null; // Bugzilla String for Platform
-
-			if (java2buzillaOSMap != null && java2buzillaOSMap.containsKey(OS) && opSysAttribute != null
-					&& opSysAttribute.getOptionValues() != null) {
-				bugzillaOS = java2buzillaOSMap.get(OS);
-				if (opSysAttribute != null && !opSysAttribute.getOptionValues().values().contains(bugzillaOS)) {
-					// If the OS we found is not in the list of available
-					// options, set bugzillaOS
-					// to null, and just use "other"
-					bugzillaOS = null;
-				}
-			} else {
-				// If we have a strangeOS, then just set buzillaOS to null, and
-				// use "other"
-				bugzillaOS = null;
-			}
-
-			if (platform != null && java2buzillaPlatformMap.containsKey(platform)) {
-				bugzillaPlatform = java2buzillaPlatformMap.get(platform);
-
-				if (platformAttribute != null
-						&& !platformAttribute.getOptionValues().values().contains(bugzillaPlatform)) {
-					// If the platform we found is not int the list of available
-					// optinos, set the
-					// Bugzilla Platform to null, and juse use "other"
-					bugzillaPlatform = null;
-				}
-			} else {
-				// If we have a strange platform, then just set bugzillaPatforrm
-				// to null, and use "other"
-				bugzillaPlatform = null;
-			}
-
-			// Set the OS and the Platform in the model
-			if (bugzillaOS != null && opSysAttribute != null)
-				opSysAttribute.setValue(bugzillaOS);
-			if (bugzillaPlatform != null && platformAttribute != null)
-				platformAttribute.setValue(bugzillaPlatform);
-
-		} catch (Exception e) {
-			MylarStatusHandler.fail(e, "could not set platform options", false);
-		}
-	}
-
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/AbstractFavoritesAction.java b/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/AbstractFavoritesAction.java
deleted file mode 100644
index 891189b..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/AbstractFavoritesAction.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004 - 2006 University Of British Columbia and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     University Of British Columbia - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.mylyn.internal.bugzilla.ui.actions;
-
-import java.net.MalformedURLException;
-import java.net.URL;
-
-import org.eclipse.jface.action.Action;
-import org.eclipse.jface.resource.ImageDescriptor;
-import org.eclipse.mylyn.internal.bugzilla.core.BugzillaPlugin;
-import org.eclipse.swt.widgets.Shell;
-
-/**
- * Class that contains shared functions for the favorites actions
- */
-public class AbstractFavoritesAction extends Action {
-
-	/**
-	 * Set the actions icon
-	 * 
-	 * @param filename
-	 *            The icons file
-	 */
-	protected void setIcon(String filename) {
-		URL url = null;
-		try {
-			// try to change the default icon
-			url = new URL(BugzillaPlugin.getDefault().getBundle().getEntry("/"), filename);
-			setImageDescriptor(ImageDescriptor.createFromURL(url));
-		} catch (MalformedURLException e) {
-			// Simply don't change the default icon
-		}
-	}
-
-	/**
-	 * Convienience method for getting the current shell
-	 * 
-	 * @return The current shell
-	 */
-	protected Shell getShell() {
-		return PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell();
-	}
-
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/AbstractOfflineReportsAction.java b/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/AbstractOfflineReportsAction.java
deleted file mode 100644
index 2bd9853..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/AbstractOfflineReportsAction.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004 - 2006 University Of British Columbia and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     University Of British Columbia - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.mylyn.internal.bugzilla.ui.actions;
-
-import java.net.MalformedURLException;
-import java.net.URL;
-
-import org.eclipse.jface.action.Action;
-import org.eclipse.jface.resource.ImageDescriptor;
-import org.eclipse.mylyn.internal.bugzilla.core.BugzillaPlugin;
-import org.eclipse.mylyn.internal.bugzilla.ui.BugzillaUiPlugin;
-import org.eclipse.swt.widgets.Shell;
-
-/**
- * Class that contains shared functions for the offline report actions
- */
-public class AbstractOfflineReportsAction extends Action {
-
-	/**
-	 * Set the actions icon
-	 * 
-	 * @param filename
-	 *            The icons file
-	 */
-	protected void setIcon(String filename) {
-		URL url = null;
-		try {
-			// try to change the default icon
-			url = new URL(BugzillaUiPlugin.getDefault().getBundle().getEntry("/"), filename);
-			setImageDescriptor(ImageDescriptor.createFromURL(url));
-		} catch (MalformedURLException e) {
-			// Simply don't change the default icon
-		}
-	}
-
-	/**
-	 * Convienience method for getting the current shell
-	 * 
-	 * @return The current shell
-	 */
-	protected Shell getShell() {
-		return BugzillaPlugin.getDefault().getWorkbench().getActiveWorkbenchWindow().getShell();
-	}
-
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/AbstractWizardListPage.java b/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/AbstractWizardListPage.java
deleted file mode 100644
index f705675..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/AbstractWizardListPage.java
+++ /dev/null
@@ -1,200 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2003 - 2006 University Of British Columbia and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     University Of British Columbia - initial API and implementation
- *******************************************************************************/
-package org.eclipse.mylyn.internal.bugzilla.ui.wizard;
-
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.Status;
-import org.eclipse.jface.wizard.WizardPage;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Event;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.List;
-import org.eclipse.swt.widgets.Listener;
-import org.eclipse.ui.IWorkbench;
-
-/**
- * Class that contains shared functions for the first page of the wizards that
- * submit bug reports. This page provides the user with a list of items to
- * choose from.
- * 
- * TODO: get rid of this unused abstraction?
- * 
- * @author Mik Kersten (hardening of prototype)
- */
-public abstract class AbstractWizardListPage extends WizardPage implements Listener {
-
-	/** The instance of the workbench */
-	protected IWorkbench workbench;
-
-	/** The list box for the list of items to choose from */
-	protected List listBox;
-
-	/** Status variable for the possible errors on this page */
-	protected IStatus listStatus;
-
-	public AbstractWizardListPage(String pageName, String title, String description, IWorkbench workbench) {
-		super(pageName);
-		setTitle(title);
-		setDescription(description);
-		this.workbench = workbench;
-
-		// set the status for the page
-		listStatus = new Status(IStatus.OK, "not_used", 0, "", null);
-	}
-
-	public abstract void createAdditionalControls(Composite parent);
-
-	public void createControl(Composite parent) {
-		// create the composite to hold the widgets
-		GridData gd;
-		Composite composite = new Composite(parent, SWT.NULL);
-
-		// create the desired layout for this wizard page
-		GridLayout gl = new GridLayout();
-		int ncol = 1;
-		gl.numColumns = ncol;
-		composite.setLayout(gl);
-
-		// create the bug report label
-//		Label label = new Label(composite, SWT.NONE);
-//		label.setText(getTableName());
-//		FontData fontData = label.getFont().getFontData()[0];
-//		fontData.setStyle(SWT.BOLD | fontData.getStyle());
-//		int height = (int) Math.abs(fontData.getHeight() * 1.25);
-//		fontData.setHeight(height);
-//		Font font = new Font(null, fontData);
-//		label.setFont(font);
-
-		// create the list of bug reports
-		gd = new GridData(GridData.FILL_HORIZONTAL);
-		gd.heightHint = 200;
-		listBox = new List(composite, SWT.SINGLE | SWT.BORDER | SWT.READ_ONLY | SWT.V_SCROLL);
-		listBox.setLayoutData(gd);
-
-		createLine(composite, ncol);
-
-		// Each wizard has different types of items to add to the list
-		populateList(true);
-
-		createAdditionalControls(composite);
-
-		// set the composite as the control for this page
-		setControl(composite);
-		addListeners();
-	}
-
-	/**
-	 * Populate the list of items
-	 */
-	abstract protected void populateList(boolean init);
-
-	/*
-	 * (non-Javadoc)
-	 * 
-	 * @see org.eclipse.swt.widgets.Listener#handleEvent(org.eclipse.swt.widgets.Event)
-	 */
-	abstract public void handleEvent(Event event);
-
-	/**
-	 * A helper function for "handleEvent"
-	 * 
-	 * @param event
-	 *            the event which occurred
-	 * @param errorMessage
-	 *            the error message unique to the wizard calling this function
-	 */
-	protected void handleEventHelper(Event event, String errorMessage) {
-		// Initialize a variable with the no error status
-		Status status = new Status(IStatus.OK, "not_used", 0, "", null);
-
-		// If the event is triggered by the list of items, respond with the
-		// corresponding status
-		if (event.widget == listBox) {
-			if (listBox.getSelectionIndex() == -1)
-				status = new Status(IStatus.ERROR, "not_used", 0, errorMessage, null);
-			listStatus = status;
-		}
-
-		// Show the most serious error
-		applyToStatusLine(listStatus);
-		
-		getWizard().getContainer().updateButtons();
-	}
-
-	/**
-	 * Applies the status to the status line of a dialog page.
-	 * 
-	 * @param status
-	 *            The status to apply to the status line
-	 */
-	protected void applyToStatusLine(IStatus status) {
-		String message = status.getMessage();
-		if (message.length() == 0)
-			message = null;
-		switch (status.getSeverity()) {
-		case IStatus.OK:
-			setErrorMessage(null);
-			setMessage(message);
-			break;
-		case IStatus.WARNING:
-			setErrorMessage(null);
-			setMessage(message, WizardPage.WARNING);
-			break;
-		case IStatus.INFO:
-			setErrorMessage(null);
-			setMessage(message, WizardPage.INFORMATION);
-			break;
-		default:
-			setErrorMessage(null);
-			setMessage(message, WizardPage.ERROR);
-			break;
-		}
-	}
-
-	/**
-	 * Create a separator line in the dialog
-	 * 
-	 * @param parent
-	 *            The composite to create the line on
-	 * @param ncol
-	 *            The number of columns to span
-	 */
-	protected void createLine(Composite parent, int ncol) {
-		Label line = new Label(parent, SWT.SEPARATOR | SWT.HORIZONTAL | SWT.BOLD);
-		GridData gridData = new GridData(GridData.FILL_HORIZONTAL);
-		gridData.horizontalSpan = ncol;
-		line.setLayoutData(gridData);
-	}
-
-//	@Override
-//	public boolean canFlipToNextPage() {
-//		if (getErrorMessage() != null)
-//			return false;
-//		if (listBox.getSelectionIndex() != -1)
-//			return true;
-//		return false;
-//	}
-
-	/**
-	 * Add any listeners that we need
-	 */
-	protected void addListeners() {
-		listBox.addListener(SWT.Selection, this);
-	}
-	
-	@Override
-	public boolean isPageComplete() {
-		return listBox.getSelectionIndex() != -1;		
-	}
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/AddFavoriteAction.java b/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/AddFavoriteAction.java
deleted file mode 100644
index 8409761..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/AddFavoriteAction.java
+++ /dev/null
@@ -1,123 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2003 - 2006 University Of British Columbia and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     University Of British Columbia - initial API and implementation
- *******************************************************************************/
-package org.eclipse.mylyn.internal.bugzilla.ui.actions;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-
-import org.eclipse.core.resources.IMarker;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.jface.action.IAction;
-import org.eclipse.jface.viewers.ISelection;
-import org.eclipse.jface.viewers.IStructuredSelection;
-import org.eclipse.mylyn.internal.bugzilla.core.BugzillaPlugin;
-import org.eclipse.mylyn.internal.bugzilla.core.IBugzillaConstants;
-import org.eclipse.mylyn.internal.bugzilla.core.internal.Favorite;
-import org.eclipse.mylyn.internal.bugzilla.ui.BugzillaImages;
-import org.eclipse.mylyn.internal.bugzilla.ui.FavoritesView;
-import org.eclipse.mylyn.internal.bugzilla.ui.search.BugzillaSearchResultView;
-
-/**
- * Bookmark a returned Bugzilla Search result.
- */
-public class AddFavoriteAction extends AbstractFavoritesAction {
-
-	/** Selected objects */
-	private List<Favorite> selected;
-
-	/** The view where the Bugzilla search results are displayed */
-	private BugzillaSearchResultView resultView;
-
-	/**
-	 * Constructor
-	 * 
-	 * @param text
-	 *            The label for the context menu item
-	 * @param resultView
-	 *            The view where the Bugzilla search results are displayed
-	 */
-	public AddFavoriteAction(String text, BugzillaSearchResultView resultView) {
-		setText(text);
-		setImageDescriptor(BugzillaImages.IMG_TOOL_ADD_TO_FAVORITES);
-		this.resultView = resultView;
-		selected = null;
-	}
-
-	/**
-	 * Bookmark the selected items
-	 * 
-	 * @see org.eclipse.ui.actions.ActionDelegate#run(IAction)
-	 */
-	@Override
-	public void run() {
-		FavoritesView.checkWindow();
-
-		selected = new ArrayList<Favorite>();
-		buildSelection();
-
-		// go through each of the selected items and add its data to the
-		// favorites file
-		for (int i = 0; i < selected.size(); i++) {
-			BugzillaPlugin.getDefault().getFavorites().add(selected.get(i));
-		}
-		FavoritesView.add();
-		FavoritesView.updateActionEnablement();
-	}
-
-	/**
-	 * Gets the entire selection and puts each bug report into a list. Only the
-	 * relevent parts of each bug report are put into the list.
-	 */
-	@SuppressWarnings("unchecked")
-	private void buildSelection() {
-		ISelection s = resultView.getViewer().getSelection();
-		if (s instanceof IStructuredSelection) {
-			IStructuredSelection selection = (IStructuredSelection) s;
-			for (Iterator<IMarker> it = selection.iterator(); it.hasNext();) {
-				IMarker marker = it.next();
-
-				try {
-					// try to get the attribute for the marker
-					Integer attributeId = (Integer) marker.getAttribute(IBugzillaConstants.HIT_MARKER_ATTR_ID);
-					String repositoryUrl = (String) marker.getAttribute(IBugzillaConstants.HIT_MARKER_ATTR_REPOSITORY);
-
-					// add the selected item to the list of items that are
-					// selected
-					String description = (String) marker.getAttribute(IBugzillaConstants.HIT_MARKER_ATTR_DESC);
-					String query = (String) marker.getAttribute(IBugzillaConstants.HIT_MARKER_ATTR_QUERY);
-
-					// create a map to add attributes to so that the favorites
-					// file can sort
-					HashMap<String, Object> attributes = new HashMap<String, Object>();
-					attributes.put(IBugzillaConstants.HIT_MARKER_ATTR_ID, attributeId);
-					attributes.put(IBugzillaConstants.HIT_MARKER_ATTR_REPOSITORY, repositoryUrl);
-					attributes.put(IBugzillaConstants.HIT_MARKER_ATTR_PRIORITY, marker
-							.getAttribute(IBugzillaConstants.HIT_MARKER_ATTR_PRIORITY));
-					attributes.put(IBugzillaConstants.HIT_MARKER_ATTR_SEVERITY, marker
-							.getAttribute(IBugzillaConstants.HIT_MARKER_ATTR_SEVERITY));
-					attributes.put(IBugzillaConstants.HIT_MARKER_ATTR_STATE, marker
-							.getAttribute(IBugzillaConstants.HIT_MARKER_ATTR_STATE));
-					attributes.put(IBugzillaConstants.HIT_MARKER_ATTR_RESULT, marker
-							.getAttribute(IBugzillaConstants.HIT_MARKER_ATTR_RESULT));
-
-					Favorite favorite = new Favorite(repositoryUrl, attributeId.intValue(), description, query,
-							attributes);
-					selected.add(favorite);
-				} catch (CoreException ignored) {
-					// do nothing
-				}
-			}
-		}
-	}
-
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/AttachmentPartSource.java b/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/AttachmentPartSource.java
deleted file mode 100644
index e287ae3..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/AttachmentPartSource.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004, 2008 Tasktop Technologies and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     Tasktop Technologies - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.mylyn.bugzilla.deprecated;
-
-import java.io.IOException;
-import java.io.InputStream;
-
-import org.apache.commons.httpclient.methods.multipart.PartSource;
-import org.eclipse.mylyn.internal.tasks.core.deprecated.ITaskAttachment;
-
-/**
- * @author Steffen Pingel
- */
-public class AttachmentPartSource implements PartSource {
-
-	private final ITaskAttachment attachment;
-
-	public AttachmentPartSource(ITaskAttachment attachment) {
-		this.attachment = attachment;
-	}
-
-	public InputStream createInputStream() throws IOException {
-		return attachment.createInputStream();
-	}
-
-	public String getFileName() {
-		return attachment.getFilename();
-	}
-
-	public long getLength() {
-		return attachment.getLength();
-	}
-
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/BugParser.java b/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/BugParser.java
deleted file mode 100644
index e621585..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/BugParser.java
+++ /dev/null
@@ -1,1107 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2003 - 2006 University Of British Columbia and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     University Of British Columbia - initial API and implementation
- *******************************************************************************/
-package org.eclipse.mylyn.internal.bugzilla.core.internal;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.io.Reader;
-import java.net.URL;
-import java.net.URLConnection;
-import java.net.URLEncoder;
-import java.nio.charset.Charset;
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
-import java.util.Calendar;
-import java.util.Date;
-import java.util.Iterator;
-import java.util.List;
-
-import javax.security.auth.login.LoginException;
-
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.Status;
-import org.eclipse.mylyn.bugzilla.core.AbstractRepositoryReportAttribute;
-import org.eclipse.mylyn.bugzilla.core.BugReport;
-import org.eclipse.mylyn.bugzilla.core.Comment;
-import org.eclipse.mylyn.bugzilla.core.Operation;
-import org.eclipse.mylyn.internal.bugzilla.core.BugzillaPlugin;
-import org.eclipse.mylyn.internal.bugzilla.core.IBugzillaConstants;
-import org.eclipse.mylyn.internal.bugzilla.core.internal.HtmlStreamTokenizer.Token;
-
-/**
- * @author Shawn Minto
- * @author Mik Kersten (hardening of prototype)
- * @author Rob Elves (attachments) This class parses bugs so that they can be
- *         displayed using the bug editor
- */
-public class BugParser {
-
-	private static final String VALUE_ATTACHMENT_OBSOLETE = "bz_obsolete";
-
-	private static final String ATTRIBUTE_CLASS = "class";
-
-	private static final String TAG_SPAN = "span";
-
-	private static final String ATTRIBUTE_ID_TITLE = "title";
-
-	private static final String ATTRIBUTE_ID_HREF = "href";
-
-	private static final String ATTACHMENT_CGI_ID = "attachment.cgi?id=";
-
-	private static final String KEY_BUG_NUM = "Bug#";
-
-	private static final String KEY_RESOLUTION = "resolution";
-
-	private static final String KEY_VALUE = "value";
-
-	private static final String KEY_NAME = "name";
-
-	private static final String ATTR_CHARSET = "charset";
-
-	/** Parser for dates in the report */
-	private static SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm");
-
-	private static final String keywordsUrl = "describekeywords.cgi";
-
-	/**
-	 * Parse the case where we have found an attribute name
-	 * 
-	 * @param in
-	 *            The input stream for the bug
-	 * @return The name of the attribute that we are parsing
-	 * @throws IOException
-	 */
-	private static String parseAttributeName(HtmlStreamTokenizer tokenizer) throws IOException, ParseException {
-		StringBuffer sb = new StringBuffer();
-
-		parseTableCell(tokenizer, sb);
-		HtmlStreamTokenizer.unescape(sb);
-		// remove the colon if there is one
-		if (sb.length() > 0 && sb.charAt(sb.length() - 1) == ':') {
-			sb.deleteCharAt(sb.length() - 1);
-		}
-		return sb.toString();
-	}
-
-	/**
-	 * Parse the case where we have found attribute values
-	 * 
-	 * @param in
-	 *            The input stream of the bug
-	 * @param bug
-	 *            The bug report for the current bug
-	 * @param attribute
-	 *            The name of the attribute
-	 * @throws IOException
-	 */
-	private static void parseAttributeValue(BugReport bug, String originalAttributeName, HtmlStreamTokenizer tokenizer,
-			String serverUrl, String userName, String password) throws IOException, ParseException {
-
-		// NOTE: special rule to deal with change in 2.20.1
-		String attributeName = originalAttributeName;
-		if (attributeName.endsWith(KEY_BUG_NUM) && attributeName.length() > KEY_BUG_NUM.length()) {
-			attributeName = originalAttributeName.substring(attributeName.length() - KEY_BUG_NUM.length(),
-					attributeName.length());
-		}
-
-		Token token = tokenizer.nextToken();
-		if (token.getType() == Token.TAG) {
-			HtmlTag tag = (HtmlTag) token.getValue();
-
-			// make sure that we are on a tag that we care about, not a label
-			// fix added so that we can parse the mozilla bug pages
-			if (tag.getTagType() == HtmlTag.Type.LABEL) {
-				token = tokenizer.nextToken();
-				if (token.getType() == Token.TAG)
-					tag = (HtmlTag) token.getValue();
-				else {
-					StringBuffer sb = new StringBuffer();
-					if (token.getType() == Token.TEXT) {
-						sb.append((StringBuffer) token.getValue());
-						parseAttributeValueCell(bug, attributeName, tokenizer, sb);
-					}
-				}
-			}
-
-			if (tag.getTagType() == HtmlTag.Type.SELECT && !tag.isEndTag()) {
-				String parameterName = tag.getAttribute(KEY_NAME);
-				parseSelect(bug, attributeName, parameterName, tokenizer);
-			} else if (tag.getTagType() == HtmlTag.Type.INPUT && !tag.isEndTag()) {
-				parseInput(bug, attributeName, tag, serverUrl, userName, password);
-			} else if (!tag.isEndTag() || attributeName.equalsIgnoreCase(KEY_RESOLUTION)) {
-				if (tag.isEndTag() && attributeName.equalsIgnoreCase(KEY_RESOLUTION)) {
-					AbstractRepositoryReportAttribute a = new AbstractRepositoryReportAttribute(attributeName);
-					a.setValue("");
-					bug.addAttribute(a);
-				}
-				parseAttributeValueCell(bug, attributeName, tokenizer);
-			}
-		} else {
-			StringBuffer sb = new StringBuffer();
-			if (token.getType() == Token.TEXT) {
-				sb.append((StringBuffer) token.getValue());
-				parseAttributeValueCell(bug, attributeName, tokenizer, sb);
-			}
-		}
-	}
-
-	/**
-	 * Parse the case where the attribute value is just text in a table cell
-	 * 
-	 * @param in
-	 *            The input stream of the bug
-	 * @param bug
-	 *            The bug report for the current bug
-	 * @param attributeName
-	 *            The name of the attribute that we are parsing
-	 * @throws IOException
-	 */
-	private static void parseAttributeValueCell(BugReport bug, String attributeName, HtmlStreamTokenizer tokenizer)
-			throws IOException, ParseException {
-		StringBuffer sb = new StringBuffer();
-		parseAttributeValueCell(bug, attributeName, tokenizer, sb);
-	}
-
-	private static void parseAttributeValueCell(BugReport bug, String attributeName, HtmlStreamTokenizer tokenizer,
-			StringBuffer sb) throws IOException, ParseException {
-
-		parseTableCell(tokenizer, sb);
-		HtmlStreamTokenizer.unescape(sb);
-
-		// create a new attribute and set its value to the value that we
-		// retrieved
-		AbstractRepositoryReportAttribute a = new AbstractRepositoryReportAttribute(attributeName);
-		a.setValue(sb.toString());
-
-		// if we found an attachment attribute, forget about it, else add the
-		// attribute to the bug report
-		if (attributeName.toLowerCase()).startsWith("attachments")) {
-			// do nothing
-		} else {
-			if (attributeName.equals(KEY_BUG_NUM))
-				a.setValue(a.getValue().replaceFirst("alias:", ""));
-			bug.addAttribute(a);
-		}
-	}
-
-	/**
-	 * Reads text into a StringBuffer until it encounters a close table cell tag
-	 * (&lt;/TD&gt;) or start of another cell. The text is appended to the
-	 * existing value of the buffer. <b>NOTE:</b> Does not handle nested cells!
-	 * 
-	 * @param tokenizer
-	 * @param sb
-	 * @throws IOException
-	 * @throws ParseException
-	 */
-	private static void parseTableCell(HtmlStreamTokenizer tokenizer, StringBuffer sb) throws IOException,
-			ParseException {
-		boolean noWhitespace = false;
-		for (Token token = tokenizer.nextToken(); token.getType() != Token.EOF; token = tokenizer.nextToken()) {
-			if (token.getType() == Token.TAG) {
-				HtmlTag tag = (HtmlTag) token.getValue();
-				if (tag.getTagType() == HtmlTag.Type.TD) {
-					if (!tag.isEndTag()) {
-						tokenizer.pushback(token);
-					}
-					break;
-				}
-				noWhitespace = token.getWhitespace().length() == 0;
-			} else if (token.getType() == Token.TEXT) {
-				// if there was no whitespace between the tag and the
-				// preceding text, don't insert whitespace before this text
-				// unless it is there in the source
-				if (!noWhitespace && token.getWhitespace().length() > 0 && sb.length() > 0) {
-					sb.append(' ');
-				}
-				sb.append((StringBuffer) token.getValue());
-			}
-		}
-	}
-
-	/**
-	 * Parse the case where the attribute value is an option
-	 * 
-	 * @param in
-	 *            The input stream for the bug
-	 * @param bug
-	 *            The bug report for the current bug
-	 * @param attribute
-	 *            The name of the attribute that we are parsing
-	 * @param parameterName
-	 *            the SELECT tag's name
-	 * @throws IOException
-	 */
-	private static void parseSelect(BugReport bug, String attributeName, String parameterName,
-			HtmlStreamTokenizer tokenizer) throws IOException, ParseException {
-
-		boolean first = false;
-		AbstractRepositoryReportAttribute a = new AbstractRepositoryReportAttribute(attributeName);
-		a.setID(parameterName);
-
-		Token token = tokenizer.nextToken();
-		while (token.getType() != Token.EOF) {
-			if (token.getType() == Token.TAG) {
-				HtmlTag tag = (HtmlTag) token.getValue();
-				if (tag.getTagType() == HtmlTag.Type.SELECT && tag.isEndTag())
-					break;
-				if (tag.getTagType() == HtmlTag.Type.OPTION && !tag.isEndTag()) {
-					String optionName = tag.getAttribute(KEY_VALUE);
-					boolean selected = tag.hasAttribute("selected");
-					StringBuffer optionText = new StringBuffer();
-					for (token = tokenizer.nextToken(); token.getType() == Token.TEXT; token = tokenizer.nextToken()) {
-						if (optionText.length() > 0) {
-							optionText.append(' ');
-						}
-						optionText.append((StringBuffer) token.getValue());
-					}
-					a.addOptionValue(optionText.toString(), optionName);
-					if (selected || first) {
-						a.setValue(optionText.toString());
-						first = false;
-					}
-				} else {
-					token = tokenizer.nextToken();
-				}
-			} else {
-				token = tokenizer.nextToken();
-			}
-		}
-
-		// if we parsed the cc field add the e-mails to the bug report else add
-		// the attribute to the bug report
-		if (attributeName.toLowerCase().startsWith("cc")) {
-			for (Iterator<String> it = a.getOptionValues().keySet().iterator(); it.hasNext();) {
-				String email = it.next();
-				bug.addCC(HtmlStreamTokenizer.unescape(email));
-			}
-		} else {
-			bug.addAttribute(a);
-		}
-	}
-
-	/**
-	 * Parse the case where the attribute value is an input
-	 * 
-	 * @param bug
-	 *            The bug report for the current bug
-	 * @param attributeName
-	 *            The name of the attribute
-	 * @param tag
-	 *            The INPUT tag
-	 * @throws IOException
-	 */
-	private static void parseInput(BugReport bug, String attributeName, HtmlTag tag, String serverUrl, String userName,
-			String password) throws IOException {
-
-		AbstractRepositoryReportAttribute a = new AbstractRepositoryReportAttribute(attributeName);
-		a.setID(tag.getAttribute(KEY_NAME));
-		String name = tag.getAttribute(KEY_NAME);
-		String value = tag.getAttribute(KEY_VALUE);
-		if (value == null)
-			value = "";
-
-		// if we found the summary, add it to the bug report
-		if (name.equalsIgnoreCase("short_desc")) {
-			bug.setSummary(value);
-		} else if (name.equalsIgnoreCase("bug_file_loc")) {
-			a.setValue(value);
-			bug.addAttribute(a);
-		} else if (name.equalsIgnoreCase("newcc")) {
-			a.setValue(value);
-			bug.addAttribute(a);
-		} else {
-			// otherwise just add the attribute
-			a.setValue(value);
-			bug.addAttribute(a);
-
-			if (attributeName.equalsIgnoreCase("keywords") && serverUrl != null) {
-
-				BufferedReader input = null;
-				try {
-
-					String urlText = "";
-
-					// if we have a user name, may as well log in just in case
-					// it is required
-					if (userName != null && !userName.equals("") && password != null && !password.equals("")) {
-						/*
-						 * The UnsupportedEncodingException exception for
-						 * URLEncoder.encode() should not be thrown, since every
-						 * implementation of the Java platform is required to
-						 * support the standard charset "UTF-8"
-						 */
-						urlText += "?GoAheadAndLogIn=1&Bugzilla_login=" + URLEncoder.encode(userName, "UTF-8")
-								+ "&Bugzilla_password=" + URLEncoder.encode(password, "UTF-8");
-					}
-
-					// connect to the bugzilla server to get the keyword list
-					URL url = new URL(serverUrl + "/" + keywordsUrl + urlText);
-					URLConnection urlConnection = BugzillaPlugin.getDefault().getUrlConnection(url);
-					input = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
-
-					// parse the valid keywords and add them to the bug
-					List<String> keywords = new KeywordParser(input).getKeywords();
-					bug.setKeywords(keywords);
-
-				} catch (Exception e) {
-					// throw an exception if there is a problem reading the bug
-					// from the server
-					throw new IOException("Exception while fetching the list of keywords from the server: "
-							+ e.getMessage());
-				} finally {
-					try {
-						if (input != null)
-							input.close();
-					} catch (IOException e) {
-						BugzillaPlugin.log(new Status(IStatus.ERROR, IBugzillaConstants.PLUGIN_ID, IStatus.ERROR,
-								"Problem closing the stream", e));
-					}
-				}
-			}
-		}
-	}
-
-	/**
-	 * Parse the case where we are dealing with the description
-	 * 
-	 * @param bug
-	 *            The bug report for the bug
-	 * @throws IOException
-	 */
-	private static void parseDescription(BugReport bug, HtmlStreamTokenizer tokenizer) throws IOException,
-			ParseException {
-
-		StringBuffer sb = new StringBuffer();
-		for (Token token = tokenizer.nextToken(); token.getType() != Token.EOF; token = tokenizer.nextToken()) {
-			if (token.getType() == Token.TAG) {
-				HtmlTag tag = (HtmlTag) token.getValue();
-				if (sb.length() > 0) {
-					sb.append(token.getWhitespace());
-				}
-				if (tag.getTagType() == HtmlTag.Type.PRE && tag.isEndTag())
-					break;
-			} else if (token.getType() == Token.TEXT) {
-				if (sb.length() > 0) {
-					sb.append(token.getWhitespace());
-				}
-				sb.append((StringBuffer) token.getValue());
-			}
-		}
-
-		// set the bug to have the description we retrieved
-		String text = HtmlStreamTokenizer.unescape(sb).toString();
-		bug.setDescription(text);
-	}
-
-	// /**
-	// * parses the description of an attachment on the report
-	// */
-	// private static String parseAttachementDescription(HtmlStreamTokenizer
-	// tokenizer) throws IOException,
-	// ParseException {
-	//
-	// StringBuffer sb = new StringBuffer();
-	// for (Token token = tokenizer.nextToken(); token.getType() != Token.EOF;
-	// token = tokenizer.nextToken()) {
-	// if (token.getType() == Token.TAG) {
-	// HtmlTag tag = (HtmlTag) token.getValue();
-	// if (tag.getTagType() == HtmlTag.Type.A && tag.isEndTag())
-	// break;
-	// } else if (token.getType() == Token.TEXT) {
-	// if (sb.length() > 0) {
-	// sb.append(token.getWhitespace());
-	// }
-	// sb.append((StringBuffer) token.getValue());
-	// }
-	// }
-	//
-	// // set the bug to have the description we retrieved
-	// String text = HtmlStreamTokenizer.unescape(sb).toString();
-	// return text;
-	// }
-
-	/**
-	 * Parse the case where we have found the start of a comment
-	 * 
-	 * @param in
-	 *            The input stream of the bug
-	 * @param bug
-	 *            The bug report for the current bug
-	 * @return The comment that we have created with the information
-	 * @throws IOException
-	 * @throws ParseException
-	 */
-	private static Comment parseCommentHead(BugReport bug, HtmlStreamTokenizer tokenizer) throws IOException,
-			ParseException {
-		int number = 0;
-		Date date = null;
-		String author = null;
-		String authorName = null;
-
-		// get the comment's number
-		for (Token token = tokenizer.nextToken(); token.getType() != Token.EOF; token = tokenizer.nextToken()) {
-			if (token.getType() == Token.TAG) {
-				HtmlTag tag = (HtmlTag) token.getValue();
-				if (tag.getTagType() == HtmlTag.Type.A) {
-					String href = tag.getAttribute(ATTRIBUTE_ID_HREF);
-					if (href != null) {
-						int index = href.toLowerCase().indexOf("#c");
-						if (index == -1)
-							continue;
-						token = tokenizer.nextToken();
-						number = Integer.parseInt(((StringBuffer) token.getValue()).toString().substring(1));
-						break;
-					}
-				}
-			}
-		}
-
-		for (Token token = tokenizer.nextToken(); token.getType() != Token.EOF; token = tokenizer.nextToken()) {
-			if (token.getType() == Token.TAG) {
-				HtmlTag tag = (HtmlTag) token.getValue();
-				if (tag.getTagType() == HtmlTag.Type.A) {
-					String href = tag.getAttribute(ATTRIBUTE_ID_HREF);
-					if (href != null) {
-						int index = href.toLowerCase().indexOf("mailto");
-						if (index == -1)
-							continue;
-						author = href.substring(index + 7);
-						break;
-					}
-				}
-			}
-		}
-
-		// get the author's real name
-		StringBuffer sb = new StringBuffer();
-		for (Token token = tokenizer.nextToken(); token.getType() != Token.EOF; token = tokenizer.nextToken()) {
-			if (token.getType() == Token.TAG) {
-				HtmlTag tag = (HtmlTag) token.getValue();
-				if (tag.getTagType() == HtmlTag.Type.A && tag.isEndTag())
-					break;
-			} else if (token.getType() == Token.TEXT) {
-				if (sb.length() > 0) {
-					sb.append(' ');
-				}
-				sb.append((StringBuffer) token.getValue());
-			}
-		}
-		authorName = sb.toString();
-
-		// get the comment's date
-		sb.setLength(0);
-		for (Token token = tokenizer.nextToken(); token.getType() != Token.EOF; token = tokenizer.nextToken()) {
-			if (token.getType() == Token.TAG) {
-				HtmlTag tag = (HtmlTag) token.getValue();
-				if (tag.getTagType() == HtmlTag.Type.I && tag.isEndTag())
-					break;
-			} else if (token.getType() == Token.TEXT) {
-				if (sb.length() > 0) {
-					sb.append(' ');
-				}
-				sb.append((StringBuffer) token.getValue());
-			}
-		}
-		try {
-			if (sb.length() >= 16) {
-				date = df.parse(sb.substring(0, 16));
-			}
-		} catch (Exception e) {
-			date = Calendar.getInstance().getTime(); // XXX: could not
-			// determine date
-		}
-		return new Comment(bug, number, date, author, authorName);
-	}
-
-	/**
-	 * Parse the case where we have comment text
-	 * 
-	 * @param in
-	 *            The input stream for the bug
-	 * @param bug
-	 *            The bug report for the current bug
-	 * @param comment
-	 *            The comment to add the text to
-	 * @throws IOException
-	 */
-	private static void parseCommentText(BugReport bug, Comment comment, HtmlStreamTokenizer tokenizer)
-			throws IOException, ParseException {
-
-		StringBuffer commentStringBuffer = new StringBuffer();
-		for (Token token = tokenizer.nextToken(); token.getType() != Token.EOF; token = tokenizer.nextToken()) {
-			if (token.getType() == Token.TAG) {
-				HtmlTag tag = (HtmlTag) token.getValue();
-				if (tag.getTagName().equals(TAG_SPAN)) {
-					if(tag.hasAttribute(ATTRIBUTE_CLASS) && tag.getAttribute(ATTRIBUTE_CLASS).equals("")) {
-						parseAttachment(commentStringBuffer, comment, tokenizer, false);
-						continue;
-					} else if(tag.hasAttribute(ATTRIBUTE_CLASS) && tag.getAttribute(ATTRIBUTE_CLASS).equals(VALUE_ATTACHMENT_OBSOLETE)) {
-						parseAttachment(commentStringBuffer, comment, tokenizer, true);
-						continue;
-					}
-				}
-				// added to ensure whitespace is not
-				// lost if adding a tag within a tag
-				if (commentStringBuffer.length() > 0) {
-					commentStringBuffer.append(token.getWhitespace());
-				}
-				if (tag.getTagType() == HtmlTag.Type.PRE && tag.isEndTag())
-					break;
-			} else if (token.getType() == Token.TEXT) {
-				if (commentStringBuffer.length() > 0) {
-					commentStringBuffer.append(token.getWhitespace());
-				}
-				commentStringBuffer.append((StringBuffer) token.getValue());
-			}
-			// remove attachment description from comment body
-			if (comment.hasAttachment() && commentStringBuffer.indexOf(comment.getAttachmentDescription()) == 0) {
-				commentStringBuffer = new StringBuffer();
-			}
-		}
-
-		HtmlStreamTokenizer.unescape(commentStringBuffer);
-		comment.setText(commentStringBuffer.toString());
-		bug.addComment(comment);
-	}
-
-	private static void parseAttachment(StringBuffer stringBuffer, Comment comment, HtmlStreamTokenizer tokenizer, boolean obsolete)
-			throws IOException, ParseException {
-
-		int attachmentID = -1;
-		String attachmentDescription = "";
-		for (Token token = tokenizer.nextToken(); token.getType() != Token.EOF; token = tokenizer.nextToken()) {
-			if (token.getType() == Token.TAG) {
-				HtmlTag tag = (HtmlTag) token.getValue();
-
-				if (tag.getTagType() == HtmlTag.Type.A && !comment.hasAttachment()) {
-					if (tag.getAttribute(ATTRIBUTE_ID_HREF) != null) {
-						String link = tag.getAttribute(ATTRIBUTE_ID_HREF);
-						if (link.startsWith(ATTACHMENT_CGI_ID)) {
-							try {
-								int endIndex = link.indexOf("&");
-								if (endIndex > 0 && endIndex < link.length()) {
-									attachmentID = Integer.parseInt(link
-											.substring(ATTACHMENT_CGI_ID.length(), endIndex));
-								}
-							} catch (NumberFormatException e) {
-								return;
-							}
-						}
-						if (tag.getAttribute(ATTRIBUTE_ID_TITLE) != null) {
-							attachmentDescription = tag.getAttribute(ATTRIBUTE_ID_TITLE);
-						}
-						if (attachmentID > 0) {
-							comment.setHasAttachment(true);
-							comment.setAttachmentId(attachmentID);
-							comment.setAttachmentDescription(attachmentDescription);
-							comment.setObsolete(obsolete);
-						}
-
-					}
-				}
-				if (tag.getTagName().equals(TAG_SPAN) && tag.isEndTag())
-					break;
-			}
-		}
-	}
-
-	/**
-	 * Parse the full html version of the bug
-	 * 
-	 * @param in -
-	 *            the input stream for the bug
-	 * @param id -
-	 *            the id of the bug that is to be parsed
-	 * @return A bug report for the bug that was parsed
-	 * @throws IOException
-	 * @throws ParseException
-	 */
-	public static BugReport parseBug(Reader in, int id, String serverUrl, boolean is218, String userName,
-			String password, String contentType) throws IOException, ParseException, LoginException {
-		// create a new bug report and set the parser state to the start state
-		BugReport bug = new BugReport(id, serverUrl);
-		boolean contentTypeResolved = false;
-		if (contentType != null) {
-			String charsetFromContentType = getCharsetFromString(contentType);
-			if (charsetFromContentType != null) {
-				bug.setCharset(charsetFromContentType);
-				contentTypeResolved = true;
-			}
-		}
-		ParserState state = ParserState.START;
-		Comment comment = null;
-		String attribute = null;
-
-		HtmlStreamTokenizer tokenizer = new HtmlStreamTokenizer(in, null);
-
-		boolean isTitle = false;
-		boolean possibleBadLogin = false;
-		boolean checkBody = false;
-		String title = "";
-		StringBuffer body = new StringBuffer();
-
-		for (Token token = tokenizer.nextToken(); token.getType() != Token.EOF; token = tokenizer.nextToken()) {
-
-			// get the charset from the HTML if not specified
-			if (!contentTypeResolved) {
-				if (token.getType() == Token.TAG && ((HtmlTag) (token.getValue())).getTagType() == HtmlTag.Type.META
-						&& !((HtmlTag) (token.getValue())).isEndTag()) {
-					String charsetFromHtml = getCharsetFromString(token.toString());
-					if (charsetFromHtml != null)
-						bug.setCharset(charsetFromHtml);
-				}
-			}
-
-			// make sure that bugzilla doesn't want us to login
-			if (token.getType() == Token.TAG && ((HtmlTag) (token.getValue())).getTagType() == HtmlTag.Type.TITLE
-					&& !((HtmlTag) (token.getValue())).isEndTag()) {
-				isTitle = true;
-				continue;
-			}
-
-			if (isTitle) {
-				// get all of the data in the title tag
-				if (token.getType() != Token.TAG) {
-					title += ((StringBuffer) token.getValue()).toString().toLowerCase() + " ";
-					continue;
-				} else if (token.getType() == Token.TAG
-						&& ((HtmlTag) token.getValue()).getTagType() == HtmlTag.Type.TITLE
-						&& ((HtmlTag) token.getValue()).isEndTag()) {
-					// check and see if the title seems as though we have wrong
-					// login info
-					if (title.indexOf("login") != -1
-							|| (title.indexOf("invalid") != -1 && title.indexOf("password") != -1)
-							|| title.indexOf("check e-mail") != -1)
-						possibleBadLogin = true; // we possibly have a bad
-					// login
-
-					// if the title starts with error, we may have a login
-					// problem, or
-					// there is a problem with the bug (doesn't exist), so we
-					// must do
-					// some more checks
-					if (title.startsWith("error"))
-						checkBody = true;
-
-					isTitle = false;
-					title = "";
-				}
-				continue;
-			}
-
-			// if we have to add all of the text so that we can check it later
-			// for problems with the username and password
-			if (checkBody && token.getType() == Token.TEXT) {
-				body.append((StringBuffer) token.getValue());
-				body.append(" ");
-			}
-
-			// we have found the start of an attribute name
-			if ((state == ParserState.ATT_NAME || state == ParserState.START) && token.getType() == Token.TAG) {
-				HtmlTag tag = (HtmlTag) token.getValue();
-				if (tag.getTagType() == HtmlTag.Type.TD && "right".equalsIgnoreCase(tag.getAttribute("align"))) {
-					// parse the attribute's name
-					attribute = parseAttributeName(tokenizer);
-					if (attribute != null && attribute.contains(IBugzillaConstants.INVALID_2201_ATTRIBUTE_IGNORED)) {
-						continue;
-					}
-					if (attribute.toLowerCase().startsWith("opened")) {
-						// find the colon so we can get the date
-						int index = attribute.toLowerCase().indexOf(":");
-						String date;
-						if (index != -1)
-							date = attribute.substring(index + 1).trim();
-						else
-							date = attribute.substring(6).trim();
-
-						// set the bugs opened date to be the date we parsed
-						bug.setCreated(df.parse(date));
-						state = ParserState.ATT_NAME;
-						continue;
-					}
-
-					// in 2.18, the last modified looks like the opened so we
-					// need to parse it differently
-					if (attribute.toLowerCase().startsWith("last modified") && is218) {
-						// find the colon so we can get the date
-						int index = attribute.toLowerCase().indexOf(":");
-						String date;
-						if (index != -1)
-							date = attribute.substring(index + 1).trim();
-						else
-							date = attribute.substring(6).trim();
-
-						// create a new attribute and set the date
-						AbstractRepositoryReportAttribute t = new AbstractRepositoryReportAttribute("Last Modified");
-						t.setValue(date);
-
-						// add the attribute to the bug report
-						bug.addAttribute(t);
-						bug.setLastModified(df.parse(date));
-						state = ParserState.ATT_NAME;
-						continue;
-					}
-
-					state = ParserState.ATT_VALUE;
-					continue;
-				} else if (tag.getTagType() == HtmlTag.Type.INPUT && "radio".equalsIgnoreCase(tag.getAttribute("type"))
-						&& "knob".equalsIgnoreCase(tag.getAttribute(KEY_NAME))) {
-					// we found a radio button
-					parseOperations(bug, tokenizer, tag, is218);
-				}
-			}
-
-			// we have found the start of attribute values
-			if (state == ParserState.ATT_VALUE && token.getType() == Token.TAG) {
-				HtmlTag tag = (HtmlTag) token.getValue();
-				if (tag.getTagType() == HtmlTag.Type.TD) {
-					// parse the attribute values
-					parseAttributeValue(bug, attribute, tokenizer, serverUrl, userName, password);
-
-					state = ParserState.ATT_NAME;
-					attribute = null;
-					continue;
-				}
-			}
-
-			// we have found the start of a comment
-			if (state == ParserState.DESC_START && token.getType() == Token.TAG) {
-				HtmlTag tag = (HtmlTag) token.getValue();
-				if (tag.getTagType() == HtmlTag.Type.I) {
-					// parse the comment's start
-					comment = parseCommentHead(bug, tokenizer);
-
-					state = ParserState.DESC_VALUE;
-					continue;
-				}
-			}
-
-			// we have found the start of the comment text
-			if (state == ParserState.DESC_VALUE && token.getType() == Token.TAG) {
-				HtmlTag tag = (HtmlTag) token.getValue();
-				if (tag.getTagType() == HtmlTag.Type.PRE) {
-					// parse the text of the comment
-					parseCommentText(bug, comment, tokenizer);
-
-					comment = null;
-					state = ParserState.DESC_START;
-					continue;
-				}
-			}
-			
-			// last modification date
-			if (bug.getCreated() == null && (state == ParserState.ATT_NAME || state == ParserState.START) && token.getType() == Token.TAG) {
-				HtmlTag tag = (HtmlTag) token.getValue();
-				if (tag.getTagType() == HtmlTag.Type.DIV && tag.getAttribute("id") != null && "header".equalsIgnoreCase(tag.getAttribute("id"))) {
-					StringBuffer sb = new StringBuffer();
-					parseLastModified(sb, tokenizer);					
-					if(sb.length() > 0) {
-						int index = sb.indexOf(":");
-						String date;
-						if (index != -1)
-							date = sb.substring(index + 1).trim();
-						else
-							date = sb.substring(6).trim();
-
-						// create a new attribute and set the date
-						AbstractRepositoryReportAttribute t = new AbstractRepositoryReportAttribute("Last Modified");
-						t.setValue(date);
-
-						// add the attribute to the bug report
-						bug.setLastModified(df.parse(date));
-						bug.addAttribute(t);
-					}
-					continue;
-				}
-			}
-			
-
-			// look for date opened field
-			if (bug.getCreated() == null && (state == ParserState.ATT_NAME || state == ParserState.START) && token.getType() == Token.TAG) {
-				HtmlTag tag = (HtmlTag) token.getValue();
-				if (tag.getTagType() == HtmlTag.Type.TD && tag.getAttribute("align") != null && "left".equalsIgnoreCase(tag.getAttribute("align")) && tag.getAttribute("width") != null && "30%".equals(tag.getAttribute("width"))) {
-					StringBuffer sb = new StringBuffer();
-					parseDateOpened(sb, tokenizer);					
-					if(sb.length() > 0) {
-						int index = sb.indexOf(":");
-						String date;
-						if (index != -1)
-							date = sb.substring(index + 1).trim();
-						else
-							date = sb.substring(6).trim();
-
-						// set the bugs opened date to be the date we parsed
-						bug.setCreated(df.parse(date));
-					}
-					continue;
-				}
-			}
-
-			// we have found the description of the bug
-			if ((state == ParserState.ATT_NAME || state == ParserState.START) && token.getType() == Token.TAG) {
-				HtmlTag tag = (HtmlTag) token.getValue();
-				if (tag.getTagType() == HtmlTag.Type.PRE) {
-					// parse the description for the bug
-					parseDescription(bug, tokenizer);
-
-					state = ParserState.DESC_START;
-					continue;
-				}
-			}
-
-			// parse hidden fields
-
-			if ((state == ParserState.ATT_NAME || state == ParserState.START) && token.getType() == Token.TAG) {
-				HtmlTag tag = (HtmlTag) token.getValue();
-				if (tag.getTagType() == HtmlTag.Type.INPUT && tag.getAttribute("type") != null
-						&& "hidden".equalsIgnoreCase(tag.getAttribute("type").trim())) {
-
-					AbstractRepositoryReportAttribute a = new AbstractRepositoryReportAttribute(tag.getAttribute(KEY_NAME));
-					a.setID(tag.getAttribute(KEY_NAME));
-					a.setValue(tag.getAttribute(KEY_VALUE));
-					a.setHidden(true);
-					bug.addAttribute(a);
-					continue;
-				}
-			}
-
-			// // parse out attachments
-			// if(token.getType() == Token.TAG) {
-			// HtmlTag tag = (HtmlTag) token.getValue();
-			// if(tag.getTagType() == HtmlTag.Type.A && tag.getAttribute("href")
-			// != null) {
-			// String link = tag.getAttribute("href");
-			// if(link.startsWith("attachment.cgi?id=") &&
-			// !link.contains("action")) {
-			// int attachmentID = Integer.parseInt(link.substring(18));
-			// String description = parseAttachementDescription(tokenizer);
-			// bug.addAttachment(attachmentID, description);
-			// }
-			// }
-			// }
-
-		}
-
-		// if we are to check the body, make sure that there wasn't a bad login
-		if (checkBody) {
-			String b = body.toString();
-			if (b.indexOf("login") != -1
-					|| ((b.indexOf("invalid") != -1 || b.indexOf("not valid") != -1) && b.indexOf("password") != -1)
-					|| b.indexOf("check e-mail") != -1)
-				possibleBadLogin = true; // we possibly have a bad login
-		}
-
-		// if there is no summary or created date, we expect that
-		// the bug doesn't exist, so set it to null
-
-		// if the bug seems like it doesn't exist, and we suspect a login
-		// problem, assume that there was a login problem
-		if (bug.getCreated() == null && bug.getAttributes().isEmpty()) {
-			if (possibleBadLogin) {
-				throw new LoginException(IBugzillaConstants.MESSAGE_LOGIN_FAILURE);
-			} else {
-				return null;
-			}
-		}
-		// we are done...return the bug
-		return bug;
-	}
-
-	private static void parseDateOpened(StringBuffer sb, HtmlStreamTokenizer tokenizer) throws IOException, ParseException {
-		for (Token token = tokenizer.nextToken(); token.getType() != Token.EOF; token = tokenizer.nextToken()) {
-			if (token.getType() == Token.TAG) {
-				HtmlTag tag = (HtmlTag) token.getValue();
-				if (tag.getTagType() == HtmlTag.Type.TD && tag.isEndTag())
-					break;
-			} else if (token.getType() == Token.TEXT) {
-				if (sb.length() > 0) {
-					sb.append(' ');
-				}
-				sb.append((StringBuffer) token.getValue());
-			}
-		}
-		
-	}
-	
-	private static void parseLastModified(StringBuffer sb, HtmlStreamTokenizer tokenizer) throws IOException, ParseException {
-		boolean inH3 = false;
-		for (Token token = tokenizer.nextToken(); token.getType() != Token.EOF; token = tokenizer.nextToken()) {
-			if (token.getType() == Token.TAG) {
-				HtmlTag tag = (HtmlTag) token.getValue();				
-				if (tag.getTagType() == HtmlTag.Type.H3 && !tag.isEndTag()) {
-					inH3 = true;
-					continue;
-				} else if (tag.getTagType() == HtmlTag.Type.DIV && tag.isEndTag()) {
-					break;
-				}
-			} else if (token.getType() == Token.TEXT && inH3) {
-				if (sb.length() > 0) {
-					sb.append(' ');
-				}
-				sb.append((StringBuffer) token.getValue());
-			}
-		}
-		
-	}
-
-	public static String getCharsetFromString(String string) {
-		int charsetStartIndex = string.indexOf(ATTR_CHARSET);
-		if (charsetStartIndex != -1) {
-			int charsetEndIndex = string.indexOf("\"", charsetStartIndex); // TODO:
-			// could
-			// be
-			// space
-			// after?
-			if (charsetEndIndex == -1) {
-				charsetEndIndex = string.length();
-			}
-			String charsetString = string.substring(charsetStartIndex + 8, charsetEndIndex);
-			if (Charset.availableCharsets().containsKey(charsetString)) {
-				return charsetString;
-			}
-		}
-		return null;
-	}
-
-	/**
-	 * Parse the operations that are allowed on the bug (Assign, Re-open, fix)
-	 * 
-	 * @param bug
-	 *            The bug to add the operations to
-	 * @param tokenizer
-	 *            The stream tokenizer for the bug
-	 * @param tag
-	 *            The last tag that we were on
-	 */
-	private static void parseOperations(BugReport bug, HtmlStreamTokenizer tokenizer, HtmlTag tag, boolean is218)
-			throws ParseException, IOException {
-
-		String knobName = tag.getAttribute(KEY_VALUE);
-		boolean isChecked = false;
-		if (tag.getAttribute("checked") != null && tag.getAttribute("checked").equals("checked"))
-			isChecked = true;
-		StringBuffer sb = new StringBuffer();
-
-		Token lastTag = null;
-
-		for (Token token = tokenizer.nextToken(); token.getType() != Token.EOF; token = tokenizer.nextToken()) {
-			if (token.getType() == Token.TAG) {
-				tag = (HtmlTag) token.getValue();
-
-				if (!(tag.getTagType() == HtmlTag.Type.A || tag.getTagType() == HtmlTag.Type.B
-						|| tag.getTagType() == HtmlTag.Type.STRONG || tag.getTagType() == HtmlTag.Type.LABEL)) {
-					lastTag = token;
-					break;
-				} else {
-
-					if (is218 && tag.getTagType() == HtmlTag.Type.LABEL) {
-						continue;
-					} else if (tag.getTagType() == HtmlTag.Type.A || tag.getTagType() == HtmlTag.Type.B
-							|| tag.getTagType() == HtmlTag.Type.STRONG) {
-						sb.append(tag.toString().trim() + " ");
-					} else {
-						break;
-					}
-				}
-			} else if (token.getType() == Token.TEXT && !token.toString().trim().equals("\n"))
-				sb.append(token.toString().trim() + " ");
-		}
-
-		String displayName = HtmlStreamTokenizer.unescape(sb).toString();
-		Operation o = new Operation(knobName, displayName);
-		o.setChecked(isChecked);
-
-		if (lastTag != null) {
-			tag = (HtmlTag) lastTag.getValue();
-			if (tag.getTagType() != HtmlTag.Type.SELECT) {
-				tokenizer.pushback(lastTag);
-				if (tag.getTagType() == HtmlTag.Type.INPUT
-						&& !("radio".equalsIgnoreCase(tag.getAttribute("type")) && "knob".equalsIgnoreCase(tag
-								.getAttribute(KEY_NAME)))) {
-					o.setInputName(((HtmlTag) lastTag.getValue()).getAttribute(KEY_NAME));
-					o.setInputValue(((HtmlTag) lastTag.getValue()).getAttribute(KEY_VALUE));
-				}
-			} else {
-				Token token = tokenizer.nextToken();
-				// parse the options
-
-				tag = (HtmlTag) token.getValue();
-				o.setUpOptions(((HtmlTag) lastTag.getValue()).getAttribute(KEY_NAME));
-
-				while (token.getType() != Token.EOF) {
-					if (token.getType() == Token.TAG) {
-						tag = (HtmlTag) token.getValue();
-						if (tag.getTagType() == HtmlTag.Type.SELECT && tag.isEndTag())
-							break;
-						if (tag.getTagType() == HtmlTag.Type.OPTION && !tag.isEndTag()) {
-							String optionName = tag.getAttribute(KEY_VALUE);
-							StringBuffer optionText = new StringBuffer();
-							for (token = tokenizer.nextToken(); token.getType() == Token.TEXT; token = tokenizer
-									.nextToken()) {
-								if (optionText.length() > 0) {
-									optionText.append(' ');
-								}
-								optionText.append((StringBuffer) token.getValue());
-							}
-							o.addOption(optionText.toString(), optionName);
-						} else {
-							token = tokenizer.nextToken();
-						}
-					} else {
-						token = tokenizer.nextToken();
-					}
-				}
-			}
-		}
-
-		bug.addOperation(o);
-	}
-
-	/**
-	 * Enum class for describing current state of Bugzilla report parser.
-	 */
-	private static class ParserState {
-		/** An instance of the start state */
-		protected static final ParserState START = new ParserState("start");
-
-		/** An instance of the state when the parser found an attribute name */
-		protected static final ParserState ATT_NAME = new ParserState("att_name");
-
-		/** An instance of the state when the parser found an attribute value */
-		protected static final ParserState ATT_VALUE = new ParserState("att_value");
-
-		/** An instance of the state when the parser found a description */
-		protected static final ParserState DESC_START = new ParserState("desc_start");
-
-		/** An instance of the state when the parser found a description value */
-		protected static final ParserState DESC_VALUE = new ParserState("desc_value");
-
-		/** State's human-readable name */
-		private String name;
-
-		/**
-		 * Constructor
-		 * 
-		 * @param description -
-		 *            The states human readable name
-		 */
-		private ParserState(String description) {
-			this.name = description;
-		}
-
-		@Override
-		public String toString() {
-			return name;
-		}
-	}
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/BugSubmissionHandler.java b/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/BugSubmissionHandler.java
deleted file mode 100644
index 0330075..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/BugSubmissionHandler.java
+++ /dev/null
@@ -1,186 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004 - 2006 University Of British Columbia and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     University Of British Columbia - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.mylyn.internal.bugzilla.ui.editor;
-
-import java.io.IOException;
-import java.security.GeneralSecurityException;
-import java.util.Collections;
-import java.util.Set;
-
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.Status;
-import org.eclipse.core.runtime.jobs.IJobChangeListener;
-import org.eclipse.core.runtime.jobs.Job;
-import org.eclipse.mylyn.internal.bugzilla.core.BugzillaClient;
-import org.eclipse.mylyn.internal.bugzilla.core.BugzillaException;
-import org.eclipse.mylyn.internal.bugzilla.core.BugzillaReportSubmitForm;
-import org.eclipse.mylyn.internal.bugzilla.core.BugzillaRepositoryConnector;
-import org.eclipse.mylyn.internal.bugzilla.core.BugzillaTask;
-import org.eclipse.mylyn.internal.bugzilla.core.PossibleBugzillaFailureException;
-import org.eclipse.mylyn.internal.bugzilla.ui.BugzillaUiPlugin;
-import org.eclipse.mylyn.internal.tasks.core.UnrecognizedReponseException;
-import org.eclipse.mylyn.internal.tasks.ui.views.TaskRepositoriesView;
-import org.eclipse.mylyn.tasks.core.AbstractRepositoryConnector;
-import org.eclipse.mylyn.tasks.core.AbstractRepositoryQuery;
-import org.eclipse.mylyn.tasks.core.AbstractTask;
-import org.eclipse.mylyn.tasks.core.AbstractTaskContainer;
-import org.eclipse.mylyn.tasks.core.ITask;
-import org.eclipse.mylyn.tasks.core.RepositoryTaskData;
-import org.eclipse.mylyn.tasks.core.TaskRepository;
-import org.eclipse.mylyn.tasks.ui.TasksUiPlugin;
-
-/**
- * @author Mik Kersten
- */
-public class BugSubmissionHandler {
-
-	private static final String LABEL_JOB_SUBMIT = "Submitting to Bugzilla repository";
-
-	private AbstractRepositoryConnector connector;
-
-	public BugSubmissionHandler(AbstractRepositoryConnector connector) {
-		this.connector = connector;
-	}
-
-	public void submitBugReport(BugzillaReportSubmitForm form, IJobChangeListener listener, boolean synchExec,
-			boolean addToTaskListRoot) {
-		submitBugReport(form, listener, synchExec, addToTaskListRoot ? TasksUiPlugin.getTaskList()
-				.getRootCategory() : null);
-	}
-
-	public void submitBugReport(final BugzillaReportSubmitForm form, IJobChangeListener listener, boolean synchExec,
-			final AbstractTaskContainer container) {
-		if (synchExec) {
-			try {
-				TaskRepository repository = TasksUiPlugin.getRepositoryManager().getRepository(
-						form.getTaskData().getRepositoryKind(), form.getTaskData().getRepositoryUrl());
-				if (repository != null) {
-					BugzillaClient client = ((BugzillaRepositoryConnector) connector).getClientManager().getClient(
-							repository);
-					String submittedBugId = form.submitReportToRepository(client);
-					if (form.isNewBugPost()) {
-						handleNewBugPost(form.getTaskData(), submittedBugId, container);
-					} else {
-						handleExistingBugPost(form.getTaskData(), submittedBugId);
-					}
-				}
-			} catch (Exception e) {
-				throw new RuntimeException(e);
-			}
-		} else {
-			Job submitJob = new Job(LABEL_JOB_SUBMIT) {
-
-				@Override
-				protected IStatus run(IProgressMonitor monitor) {
-					try {
-						String submittedBugId = "";
-						TaskRepository repository = TasksUiPlugin.getRepositoryManager().getRepository(
-								form.getTaskData().getRepositoryKind(), form.getTaskData().getRepositoryUrl());
-						BugzillaClient client = ((BugzillaRepositoryConnector) connector).getClientManager().getClient(
-								repository);
-						
-						submittedBugId = form.submitReportToRepository(client);						
-
-						if (form.isNewBugPost()) {
-							handleNewBugPost(form.getTaskData(), submittedBugId, container);
-							return new Status(Status.OK, BugzillaUiPlugin.PLUGIN_ID, Status.OK, submittedBugId, null);
-						} else {
-							// NOTE: sync now handled by editor
-							//handleExistingBugPost(form.getTaskData(), submittedBugId);
-							return Status.OK_STATUS;
-						}
-					} catch (GeneralSecurityException e) {
-						return new Status(
-								Status.OK,
-								BugzillaUiPlugin.PLUGIN_ID,
-								Status.ERROR,
-								"Bugzilla could not post your bug, probably because your credentials are incorrect. Ensure proper repository configuration in "
-										+ TaskRepositoriesView.NAME + ".", e);
-					} catch (UnrecognizedReponseException e) {
-						return new Status(Status.OK, BugzillaUiPlugin.PLUGIN_ID, Status.INFO,
-								"Unrecognized response from server", e);
-					} catch (IOException e) {
-						return new Status(Status.OK, BugzillaUiPlugin.PLUGIN_ID, Status.ERROR, "IO Error: \n\n"
-								+ e.getMessage(), e);
-					} catch (BugzillaException e) {
-						// MylarStatusHandler.fail(e, "Failed to submit",
-						// false);
-						String message = e.getMessage();
-						return new Status(Status.OK, BugzillaUiPlugin.PLUGIN_ID, Status.ERROR,
-								"Bugzilla could not post your bug. \n\n" + message, e);
-					} catch (PossibleBugzillaFailureException e) {
-						return new Status(Status.OK, BugzillaUiPlugin.PLUGIN_ID, Status.INFO,
-								"Possible bugzilla failure", e);
-					}
-				}
-			};
-
-			submitJob.addJobChangeListener(listener);
-			submitJob.schedule();
-		}
-	}
-
-	private void handleNewBugPost(RepositoryTaskData taskData, String resultId, AbstractTaskContainer category)
-			throws BugzillaException {
-		int bugId = -1;
-		try {
-			bugId = Integer.parseInt(resultId);
-		} catch (NumberFormatException e) {
-			throw new BugzillaException("Invalid bug id returned by repository.");
-		}
-
-		TaskRepository repository = TasksUiPlugin.getRepositoryManager().getRepository(taskData.getRepositoryKind(),
-				taskData.getRepositoryUrl());
-
-		BugzillaTask newTask = new BugzillaTask(AbstractTask.getHandle(repository.getUrl(), bugId),
-				"<bugzilla info>", true);
-
-		if (category != null) {
-			TasksUiPlugin.getTaskList().addTask(newTask, category);
-		} else {
-			TasksUiPlugin.getTaskList().addTask(newTask);
-		}
-		TasksUiPlugin.getSynchronizationScheduler().synchNow(0, Collections.singletonList(repository));
-
-	}
-
-	// Used when run in forced sync mode for testing
-	private void handleExistingBugPost(RepositoryTaskData repositoryTaskData, String resultId) {
-		try {
-			String handle = AbstractTask.getHandle(repositoryTaskData.getRepositoryUrl(), repositoryTaskData
-					.getId());
-			final ITask task = TasksUiPlugin.getTaskList().getTask(handle);
-			if (task != null) {				
-				Set<AbstractRepositoryQuery> queriesWithHandle = TasksUiPlugin.getTaskList()
-						.getQueriesForHandle(task.getHandleIdentifier());
-				TasksUiPlugin.getSynchronizationManager().synchronize(connector, queriesWithHandle, null, Job.SHORT, 0,
-						false);
-				TaskRepository repository = TasksUiPlugin.getRepositoryManager().getRepository(
-						repositoryTaskData.getRepositoryKind(), repositoryTaskData.getRepositoryUrl());
-				TasksUiPlugin.getSynchronizationManager().synchronizeChanged(connector, repository);
-				if (task instanceof AbstractTask) {
-					AbstractTask repositoryTask = (AbstractTask) task;
-					// TODO: This is set to null in order for update to bypass
-					// ui override check with user
-					// Need to change how this is achieved.
-					repositoryTask.setTaskData(null);
-					TasksUiPlugin.getSynchronizationManager().synchronize(connector, repositoryTask, true, null);
-				}
-			}
-
-		} catch (Exception e) {
-			throw new RuntimeException(e);
-		}
-	}
-
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/Bugzilla220ParserTest.java b/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/Bugzilla220ParserTest.java
deleted file mode 100644
index a102e79..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/Bugzilla220ParserTest.java
+++ /dev/null
@@ -1,92 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004 - 2006 University Of British Columbia and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     University Of British Columbia - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.mylyn.bugzilla.tests;
-
-import java.io.File;
-import java.io.FileReader;
-import java.io.Reader;
-
-import junit.framework.TestCase;
-
-import org.eclipse.core.runtime.Path;
-import org.eclipse.mylyn.bugzilla.core.BugReport;
-import org.eclipse.mylyn.core.tests.support.FileTool;
-import org.eclipse.mylyn.internal.bugzilla.core.IBugzillaConstants;
-import org.eclipse.mylyn.internal.bugzilla.core.NewBugzillaReport;
-import org.eclipse.mylyn.internal.bugzilla.core.internal.BugParser;
-import org.eclipse.mylyn.internal.bugzilla.core.internal.NewBugParser;
-
-/**
- * @author Mik Kersten
- * @author Rob Elves
- */
-public class Bugzilla220ParserTest extends TestCase {
-
-	public static final String TEST_SERVER = IBugzillaConstants.ECLIPSE_BUGZILLA_URL;
-	
-	private static final String PRODUCT_MYLAR = "Mylar";
-
-	private static final String PRODUCT_TEST = "TestProduct";
-
-	public void testId220() throws Exception {
-
-		File f = FileTool.getFileInPlugin(BugzillaTestPlugin.getDefault(), new Path(
-				"testdata/pages/test-report-220.html"));
-		Reader in = new FileReader(f);
-
-		BugReport bug = BugParser.parseBug(in, 7, TEST_SERVER, false, null, null, null);
-
-		assertEquals(7, bug.getId());
-		assertEquals("summary", bug.getSummary());
-		assertEquals("7", bug.getAttribute("Bug#").getValue());
-		assertEquals("7", bug.getAttribute("id").getValue());
-	}
-
-	public void testId2201() throws Exception {
-
-		File f = FileTool.getFileInPlugin(BugzillaTestPlugin.getDefault(), new Path(
-				"testdata/pages/test-report-2201.html"));
-		Reader in = new FileReader(f);
-
-		BugReport bug = BugParser.parseBug(in, 125527, TEST_SERVER, false, null, null, null);
-
-		assertEquals(125527, bug.getId());
-		assertEquals("bugzilla refresh incorrect for new reports and newly opened hits", bug.getSummary());
-		assertEquals("125527", bug.getAttribute("Bug#").getValue());
-		assertEquals("125527", bug.getAttribute("id").getValue());
-	}
-
-	public void testNewBugProduct220() throws Exception {
-
-		NewBugzillaReport nbm = new NewBugzillaReport();
-
-		File f = FileTool
-				.getFileInPlugin(BugzillaTestPlugin.getDefault(), new Path("testdata/pages/enter-bug220.html"));
-		Reader in = new FileReader(f);
-
-		new NewBugParser(in).parseBugAttributes(nbm, true);
-		assertEquals(PRODUCT_TEST, nbm.getAttribute("product").getValue());
-	}
-
-	public void testNewBugProduct2201() throws Exception {
-
-		NewBugzillaReport nbm = new NewBugzillaReport();
-
-		File f = FileTool.getFileInPlugin(BugzillaTestPlugin.getDefault(),
-				new Path("testdata/pages/enter-bug2201.html"));
-		Reader in = new FileReader(f);
-
-		new NewBugParser(in).parseBugAttributes(nbm, true);
-		assertEquals(PRODUCT_MYLAR, nbm.getAttribute("product").getValue());
-	}
-
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/BugzillaAttributeFactory.java b/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/BugzillaAttributeFactory.java
deleted file mode 100644
index c9f0fa3..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/BugzillaAttributeFactory.java
+++ /dev/null
@@ -1,161 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004, 2008 Tasktop Technologies and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     Tasktop Technologies - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.mylyn.bugzilla.deprecated;
-
-import java.text.SimpleDateFormat;
-import java.util.Date;
-import java.util.Locale;
-
-import org.eclipse.mylyn.internal.bugzilla.core.BugzillaAttribute;
-import org.eclipse.mylyn.internal.tasks.core.deprecated.AbstractAttributeFactory;
-import org.eclipse.mylyn.internal.tasks.core.deprecated.RepositoryTaskAttribute;
-
-/**
- * @author Rob Elves
- * @author Mik Kersten
- * @deprecated
- */
-@Deprecated
-public class BugzillaAttributeFactory extends AbstractAttributeFactory {
-
-	private static final String DATE_FORMAT_1 = "yyyy-MM-dd HH:mm";
-
-	private static final String DATE_FORMAT_2 = "yyyy-MM-dd HH:mm:ss";
-
-	private static final String delta_ts_format = DATE_FORMAT_2;
-
-	private static final String creation_ts_format = DATE_FORMAT_1;
-
-	/**
-	 * public for testing Bugzilla 2.18 uses DATE_FORMAT_1 but later versions use DATE_FORMAT_2 Using lowest common
-	 * denominator DATE_FORMAT_1
-	 */
-	public static final String comment_creation_ts_format = DATE_FORMAT_1;
-
-	private static final String attachment_creation_ts_format = DATE_FORMAT_1;
-
-	private static final long serialVersionUID = 5087501781682994759L;
-
-	@Override
-	public String mapCommonAttributeKey(String key) {
-		if (key.equals(RepositoryTaskAttribute.NEW_CC)) {
-			return BugzillaAttribute.NEWCC.getKey();
-		} else if (key.equals(RepositoryTaskAttribute.COMMENT_DATE)) {
-			return BugzillaAttribute.BUG_WHEN.getKey();
-		} else if (key.equals(RepositoryTaskAttribute.COMMENT_AUTHOR)) {
-			return BugzillaAttribute.WHO.getKey();
-		} else if (key.equals(RepositoryTaskAttribute.COMMENT_AUTHOR_NAME)) {
-			return BugzillaAttribute.WHO_NAME.getKey();
-		} else if (key.equals(RepositoryTaskAttribute.USER_CC)) {
-			return BugzillaAttribute.CC.getKey();
-		} else if (key.equals(RepositoryTaskAttribute.COMMENT_TEXT)) {
-			return BugzillaAttribute.THETEXT.getKey();
-		} else if (key.equals(RepositoryTaskAttribute.DATE_CREATION)) {
-			return BugzillaAttribute.CREATION_TS.getKey();
-		} else if (key.equals(RepositoryTaskAttribute.DESCRIPTION)) {
-			return BugzillaAttribute.DESC.getKey();
-		} else if (key.equals(RepositoryTaskAttribute.ATTACHMENT_ID)) {
-			return BugzillaAttribute.ATTACHID.getKey();
-		} else if (key.equals(RepositoryTaskAttribute.ATTACHMENT_TYPE)) {
-			return BugzillaAttribute.TYPE.getKey();
-		} else if (key.equals(RepositoryTaskAttribute.ATTACHMENT_CTYPE)) {
-			return BugzillaAttribute.CTYPE.getKey();
-		} else if (key.equals(RepositoryTaskAttribute.USER_ASSIGNED)) {
-			return BugzillaAttribute.ASSIGNED_TO.getKey();
-		} else if (key.equals(RepositoryTaskAttribute.USER_ASSIGNED_NAME)) {
-			return BugzillaAttribute.ASSIGNED_TO_NAME.getKey();
-		} else if (key.equals(RepositoryTaskAttribute.RESOLUTION)) {
-			return BugzillaAttribute.RESOLUTION.getKey();
-		} else if (key.equals(RepositoryTaskAttribute.STATUS)) {
-			return BugzillaAttribute.BUG_STATUS.getKey();
-		} else if (key.equals(RepositoryTaskAttribute.DATE_MODIFIED)) {
-			return BugzillaAttribute.DELTA_TS.getKey();
-		} else if (key.equals(RepositoryTaskAttribute.USER_REPORTER)) {
-			return BugzillaAttribute.REPORTER.getKey();
-		} else if (key.equals(RepositoryTaskAttribute.USER_REPORTER_NAME)) {
-			return BugzillaAttribute.REPORTER_NAME.getKey();
-		} else if (key.equals(RepositoryTaskAttribute.SUMMARY)) {
-			return BugzillaAttribute.SHORT_DESC.getKey();
-		} else if (key.equals(RepositoryTaskAttribute.PRODUCT)) {
-			return BugzillaAttribute.PRODUCT.getKey();
-		} else if (key.equals(RepositoryTaskAttribute.KEYWORDS)) {
-			return BugzillaAttribute.KEYWORDS.getKey();
-		} else if (key.equals(RepositoryTaskAttribute.ATTACHMENT_DATE)) {
-			return BugzillaAttribute.DATE.getKey();
-		} else if (key.equals(RepositoryTaskAttribute.ATTACHMENT_SIZE)) {
-			return BugzillaAttribute.SIZE.getKey();
-		} else if (key.equals(RepositoryTaskAttribute.ADD_SELF_CC)) {
-			return BugzillaAttribute.ADDSELFCC.getKey();
-		} else if (key.equals(RepositoryTaskAttribute.PRIORITY)) {
-			return BugzillaAttribute.PRIORITY.getKey();
-		} else if (key.equals(RepositoryTaskAttribute.COMMENT_NEW)) {
-			return BugzillaAttribute.NEW_COMMENT.getKey();
-		} else if (key.equals(RepositoryTaskAttribute.COMPONENT)) {
-			return BugzillaAttribute.COMPONENT.getKey();
-		} else {
-			return key;
-		}
-	}
-
-	@Override
-	public boolean isHidden(String key) {
-		try {
-			return BugzillaAttribute.valueOf(key.trim().toUpperCase(Locale.ENGLISH)).isHidden();
-		} catch (IllegalArgumentException e) {
-			return false;
-		}
-	}
-
-	@Override
-	public String getName(String key) {
-		try {
-			return BugzillaAttribute.valueOf(key.trim().toUpperCase(Locale.ENGLISH)).toString();
-		} catch (IllegalArgumentException e) {
-			return "<unknown>";
-		}
-	}
-
-	@Override
-	public boolean isReadOnly(String key) {
-		try {
-			return BugzillaAttribute.valueOf(key.trim().toUpperCase(Locale.ENGLISH)).isReadOnly();
-		} catch (IllegalArgumentException e) {
-			return true;
-		}
-	}
-
-	@Override
-	public Date getDateForAttributeType(String attributeKey, String dateString) {
-		if (dateString == null || dateString.equals("")) {
-			return null;
-		}
-		try {
-			String mappedKey = mapCommonAttributeKey(attributeKey);
-			Date parsedDate = null;
-			if (mappedKey.equals(BugzillaAttribute.DELTA_TS.getKey())) {
-				parsedDate = new SimpleDateFormat(delta_ts_format).parse(dateString);
-			} else if (mappedKey.equals(BugzillaAttribute.CREATION_TS.getKey())) {
-				parsedDate = new SimpleDateFormat(creation_ts_format).parse(dateString);
-			} else if (mappedKey.equals(BugzillaAttribute.BUG_WHEN.getKey())) {
-				parsedDate = new SimpleDateFormat(comment_creation_ts_format).parse(dateString);
-			} else if (mappedKey.equals(BugzillaAttribute.DATE.getKey())) {
-				parsedDate = new SimpleDateFormat(attachment_creation_ts_format).parse(dateString);
-			}
-			return parsedDate;
-		} catch (Exception e) {
-			return null;
-			// throw new CoreException(new Status(IStatus.ERROR,
-			// "Error parsing date string: " + dateString, e));
-		}
-	}
-
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/BugzillaCategorySearchOperation.java b/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/BugzillaCategorySearchOperation.java
deleted file mode 100644
index a7c98b2..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/BugzillaCategorySearchOperation.java
+++ /dev/null
@@ -1,163 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004 - 2006 University Of British Columbia and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     University Of British Columbia - initial API and implementation
- *******************************************************************************/
-/*
- * Created on Oct 14, 2004
- */
-package org.eclipse.mylyn.internal.bugzilla.ui.tasklist;
-
-import java.net.Proxy;
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.security.auth.login.LoginException;
-
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.jface.resource.ImageDescriptor;
-import org.eclipse.mylyn.internal.bugzilla.ui.search.BugzillaSearchEngine;
-import org.eclipse.mylyn.internal.bugzilla.ui.search.BugzillaSearchResultCollector;
-import org.eclipse.mylyn.internal.bugzilla.ui.search.IBugzillaSearchOperation;
-import org.eclipse.mylyn.internal.tasks.ui.search.AbstractRepositorySearchQuery;
-import org.eclipse.mylyn.tasks.core.QueryHitCollector;
-import org.eclipse.mylyn.tasks.core.TaskRepository;
-import org.eclipse.mylyn.tasks.ui.TasksUiPlugin;
-import org.eclipse.ui.actions.WorkspaceModifyOperation;
-
-/**
- * TODO: delete?
- * 
- * @author Shawn Minto
- */
-public class BugzillaCategorySearchOperation extends WorkspaceModifyOperation implements IBugzillaSearchOperation {
-	/** The IMember we are doing the search for */
-
-	public interface ICategorySearchListener {
-		public void searchCompleted(QueryHitCollector collector);
-	}
-
-	/** The bugzilla collector for the search */
-	private QueryHitCollector collector = null;
-
-	/** The status of the search operation */
-	private IStatus status;
-
-	/** The LoginException that was thrown when trying to do the search */
-	private LoginException loginException = null;
-
-	private String queryUrl;
-
-	private TaskRepository repository;
-
-	private int maxHits;
-
-	private boolean isMaxReached;
-
-	/**
-	 * Constructor
-	 * 
-	 * @param m
-	 *            The member that we are doing the search for
-	 */
-	public BugzillaCategorySearchOperation(TaskRepository repository, String queryUrl, int maxHits,
-			QueryHitCollector collector) {
-		this.queryUrl = queryUrl;
-		this.maxHits = maxHits;
-		this.repository = repository;
-		this.collector = collector;
-	}
-
-	@Override
-	public void execute(IProgressMonitor monitor) {
-		// XXX: Hack
-		if (collector instanceof BugzillaSearchResultCollector) {
-			((BugzillaSearchResultCollector) collector).setOperation(this);
-		}
-		collector.setProgressMonitor(monitor);
-		Proxy proxySettings = TasksUiPlugin.getDefault().getProxySettings();
-		search(queryUrl, proxySettings, monitor);
-		for (ICategorySearchListener listener : listeners)
-			listener.searchCompleted(collector);
-	}
-
-	/**
-	 * Perform the actual search on the Bugzilla server
-	 * 
-	 * @param queryUrl
-	 *            The queryUrl to use for the search
-	 * @param searchCollector
-	 *            The collector to put the search results into
-	 * @param monitor
-	 *            The progress monitor to use for the search
-	 * @return The QueryHitCollector with the search results
-	 */
-	private QueryHitCollector search(String queryUrl, Proxy proxySettings, IProgressMonitor monitor) {
-
-		// set the initial number of matches to 0
-		int matches = 0;
-		// setup the progress monitor and start the search
-		collector.setProgressMonitor(monitor);
-		BugzillaSearchEngine engine = new BugzillaSearchEngine(repository, queryUrl, proxySettings);
-		try {
-			// perform the search
-			status = engine.search(collector, matches, maxHits);
-
-			// check the status so that we don't keep searching if there
-			// is a problem
-			if (status.getCode() == IStatus.CANCEL) {
-				return null;
-			} else if (!status.isOK()) {
-				return null;
-			}
-			isMaxReached = engine.isMaxReached();
-			return collector;
-		} catch (LoginException e) {
-			// save this exception to throw later
-			this.loginException = e;
-		}
-		return null;
-	}
-
-	/**
-	 * @see org.eclipse.mylyn.internal.bugzilla.ui.search.IBugzillaSearchOperation#getStatus()
-	 */
-	public IStatus getStatus() throws LoginException {
-		// if a LoginException was thrown while trying to search, throw this
-		if (loginException == null)
-			return status;
-		else
-			throw loginException;
-	}
-
-	public ImageDescriptor getImageDescriptor() {
-		return null;
-	}
-
-	public AbstractRepositorySearchQuery getQuery() {
-		return null;
-	}
-
-	public void setQuery(AbstractRepositorySearchQuery newQuery) {
-	}
-
-	private List<ICategorySearchListener> listeners = new ArrayList<ICategorySearchListener>();
-
-	public void addResultsListener(ICategorySearchListener listener) {
-		listeners.add(listener);
-	}
-
-	public String getName() {
-		return null;
-	}
-
-	public boolean isMaxReached() {
-		return isMaxReached;
-	}
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/BugzillaCompareInput.java b/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/BugzillaCompareInput.java
deleted file mode 100644
index a481f8e..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/BugzillaCompareInput.java
+++ /dev/null
@@ -1,121 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004, 2008 Tasktop Technologies and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     Tasktop Technologies - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.mylyn.bugzilla.deprecated;
-
-import org.eclipse.compare.CompareConfiguration;
-import org.eclipse.compare.CompareEditorInput;
-import org.eclipse.compare.structuremergeviewer.Differencer;
-import org.eclipse.compare.structuremergeviewer.IStructureComparator;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.mylyn.internal.tasks.core.deprecated.RepositoryTaskData;
-
-/**
- * A two-way or three-way compare for <code>BugReport</code> objects.
- * 
- * @author Shawn Minto
- * @author Mik Kersten
- */
-public class BugzillaCompareInput extends CompareEditorInput {
-
-	private boolean threeWay = false;
-
-	private Object root;
-
-	private IStructureComparator ancestor = null;
-
-	private IStructureComparator left = null;
-
-	private IStructureComparator right = null;
-
-	/**
-	 * Constructor.
-	 * 
-	 * @param configuration
-	 *            The compare configuration used in this compare input.
-	 * @see CompareConfiguration
-	 */
-	public BugzillaCompareInput(CompareConfiguration configuration) {
-		super(configuration);
-	}
-
-	@Override
-	protected Object prepareInput(IProgressMonitor monitor) {
-		if (left == null || right == null) {
-			return null;
-		}
-		Differencer d = new Differencer();
-		root = d.findDifferences(threeWay, monitor, null, ancestor, left, right);
-		return root;
-	}
-
-	/**
-	 * @return The original object that's to be compared (appears on the top of the compare view).
-	 */
-	public IStructureComparator getAncestor() {
-		return ancestor;
-	}
-
-	/**
-	 * Sets the original object that's to be compared (appears on the top of the compare view).
-	 * 
-	 * @param newAncestor
-	 *            The new original object.
-	 */
-	public void setAncestor(RepositoryTaskData newAncestor) {
-		threeWay = (newAncestor != null);
-		BugzillaCompareStructureCreator structureCreator = new BugzillaCompareStructureCreator();
-		ancestor = structureCreator.getStructure(newAncestor);
-	}
-
-	/**
-	 * @return The local object that's to be compared (appears on the left side of the compare view).
-	 */
-	public IStructureComparator getLeft() {
-		return left;
-	}
-
-	/**
-	 * Sets the local object that's to be compared (appears on the left side of the compare view).
-	 * 
-	 * @param newLeft
-	 *            The new local object.
-	 */
-	public void setLeft(RepositoryTaskData newLeft) {
-		BugzillaCompareStructureCreator structureCreator = new BugzillaCompareStructureCreator();
-		left = structureCreator.getStructure(newLeft);
-	}
-
-	/**
-	 * @return The online object that's to be compared (appears on the right side of the compare view).
-	 */
-	public IStructureComparator getRight() {
-		return right;
-	}
-
-	/**
-	 * Sets the online object that's to be compared (appears on the right side of the compare view).
-	 * 
-	 * @param newRight
-	 *            The new online object.
-	 */
-	public void setRight(RepositoryTaskData newRight) {
-		BugzillaCompareStructureCreator structureCreator = new BugzillaCompareStructureCreator();
-		right = structureCreator.getStructure(newRight);
-	}
-
-	/**
-	 * @return <code>true</code> if a three-way comparison is to be done.
-	 */
-	public boolean isThreeWay() {
-		return threeWay;
-	}
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/BugzillaCompareNode.java b/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/BugzillaCompareNode.java
deleted file mode 100644
index abc8f98..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/BugzillaCompareNode.java
+++ /dev/null
@@ -1,284 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004, 2008 Tasktop Technologies and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     Tasktop Technologies - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.mylyn.bugzilla.deprecated;
-
-import java.io.ByteArrayInputStream;
-import java.io.InputStream;
-import java.util.ArrayList;
-
-import org.eclipse.compare.IStreamContentAccessor;
-import org.eclipse.compare.ITypedElement;
-import org.eclipse.compare.structuremergeviewer.IStructureComparator;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.mylyn.internal.bugzilla.core.BugzillaAttribute;
-import org.eclipse.mylyn.internal.tasks.core.deprecated.RepositoryTaskAttribute;
-import org.eclipse.mylyn.internal.tasks.core.deprecated.RepositoryTaskData;
-import org.eclipse.mylyn.internal.tasks.core.deprecated.TaskComment;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.ui.ISharedImages;
-import org.eclipse.ui.PlatformUI;
-
-/**
- * A node for the tree used to compare bugs in the compare viewer.
- * 
- * @author Rob Elves
- */
-public class BugzillaCompareNode implements IStreamContentAccessor, IStructureComparator, ITypedElement {
-
-	/** The label for this piece of data. */
-	private String key;
-
-	/** The data for this node. */
-	private String value;
-
-	/** The children of this node. */
-	private ArrayList<BugzillaCompareNode> nodeChildren;
-
-	/** This node's image. */
-	private Image image;
-
-	/**
-	 * Constructor. The image for this node is set to <code>null</code>.
-	 * 
-	 * @param key
-	 *            The label for this node.
-	 * @param value
-	 *            The data for this node.
-	 */
-	public BugzillaCompareNode(String key, String value) {
-		this(key, value, null);
-	}
-
-	/**
-	 * Constructor.
-	 * 
-	 * @param key
-	 *            The label for this node.
-	 * @param value
-	 *            The data for this node.
-	 * @param image
-	 *            The image for this node.
-	 */
-	public BugzillaCompareNode(String key, String value, Image image) {
-		super();
-		this.key = key;
-		this.value = checkText(value);
-		this.nodeChildren = null;
-		this.image = image;
-	}
-
-	/**
-	 * This function checks to make sure the given string is not <code>null</code>. If it is, the empty string is
-	 * returned instead.
-	 * 
-	 * @param newValue
-	 *            The string to be checked.
-	 * @return If the text is <code>null</code>, then return the null string (<code>""</code>). Otherwise, return the
-	 *         text.
-	 */
-	private String checkText(String newValue) {
-		return ((newValue == null) ? "" : newValue);
-	}
-
-	public Object[] getChildren() {
-		return (nodeChildren == null) ? new Object[0] : nodeChildren.toArray();
-	}
-
-	/**
-	 * Adds a node to this node's list of children.
-	 * 
-	 * @param bugNode
-	 *            The new child.
-	 */
-	public void addChild(BugzillaCompareNode bugNode) {
-		if (nodeChildren == null) {
-			nodeChildren = new ArrayList<BugzillaCompareNode>();
-		}
-		nodeChildren.add(bugNode);
-	}
-
-	public InputStream getContents() throws CoreException {
-		return new ByteArrayInputStream(getValue().getBytes());
-	}
-
-	/**
-	 * @return The label for this node.
-	 */
-	public String getKey() {
-		return key;
-	}
-
-	/**
-	 * Set the label for this node.
-	 * 
-	 * @param key
-	 *            The new label.
-	 */
-	public void setKey(String key) {
-		this.key = key;
-	}
-
-	/**
-	 * @return The data for this node.
-	 */
-	public String getValue() {
-		return value;
-	}
-
-	/**
-	 * Set the data for this node.
-	 * 
-	 * @param value
-	 *            The new data.
-	 */
-	public void setValue(String value) {
-		this.value = checkText(value);
-	}
-
-	public Image getImage() {
-		return image;
-	}
-
-	/**
-	 * Sets the image for this object. This image is used when displaying this object in the UI.
-	 * 
-	 * @param newImage
-	 *            The new image.
-	 */
-	public void setImage(Image newImage) {
-		this.image = newImage;
-	}
-
-	@Override
-	public boolean equals(Object arg0) {
-		if (arg0 instanceof BugzillaCompareNode) {
-			BugzillaCompareNode bugNode = (BugzillaCompareNode) arg0;
-			return getKey().equals(bugNode.getKey());
-		}
-		return super.equals(arg0);
-	}
-
-	@Override
-	public int hashCode() {
-		return getKey().hashCode();
-	}
-
-	public String getName() {
-		return getKey();
-	}
-
-	public String getType() {
-		return "bug report";
-	}
-
-	/**
-	 * Parses the given <code>BugReport</code> into a tree of <code>BugzillaCompareNode</code>'s suitable for use in a
-	 * compare viewer.
-	 * 
-	 * @param bug
-	 *            The <code>BugReport</code> that needs parsing.
-	 * @return The tree of <code>BugzillaCompareNode</code>'s.
-	 */
-	public static BugzillaCompareNode parseBugReport(RepositoryTaskData bug) {
-		Image defaultImage = PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_DEF_VIEW);
-		BugzillaCompareNode topNode = new BugzillaCompareNode("Bug #" + bug.getTaskId(), null, defaultImage);
-
-		Image attributeImage = PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_OBJ_ELEMENT);
-		BugzillaCompareNode attributes = new BugzillaCompareNode("Attributes", null, attributeImage);
-		for (RepositoryTaskAttribute attribute : bug.getAttributes()) {
-			BugzillaCompareNode child = new BugzillaCompareNode(attribute.toString(), attribute.getValue(),
-					defaultImage);
-			attributes.addChild(child);
-		}
-
-		BugzillaCompareNode comments = new BugzillaCompareNode("Comments", null, defaultImage);
-		for (TaskComment taskComment : bug.getComments()) {
-			String bodyString = "Comment from " + taskComment.getAuthorName() + ":\n\n" + taskComment.getText();
-			comments.addChild(new BugzillaCompareNode(
-					taskComment.getAttributeValue(BugzillaAttribute.BUG_WHEN.getKey()), bodyString, defaultImage));
-		}
-		topNode.addChild(comments);
-
-		topNode.addChild(new BugzillaCompareNode("New Comment", bug.getNewComment(), defaultImage));
-
-		BugzillaCompareNode ccList = new BugzillaCompareNode("CC List", null, defaultImage);
-		for (String cc : bug.getCc()) {
-			ccList.addChild(new BugzillaCompareNode("CC", cc, defaultImage));
-		}
-		topNode.addChild(ccList);
-
-		BugzillaCompareNode titleNode = new BugzillaCompareNode("BugReport Object", null, defaultImage);
-		titleNode.addChild(topNode);
-
-		return titleNode;
-	}
-
-//	public static BugzillaCompareNode parseBugReport(BugzillaReport bug) {
-//		Image defaultImage = PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_DEF_VIEW);
-//		BugzillaCompareNode topNode = new BugzillaCompareNode("Bug #" + bug.getId(), null, defaultImage);
-//		Date creationDate = bug.getCreated();
-//		if (creationDate == null) {
-//			// XXX: this could be backwards
-//			creationDate = Calendar.getInstance().getTime();
-//		}
-//		BugzillaCompareNode child = new BugzillaCompareNode("Creation Date", creationDate.toString(), defaultImage);
-//		topNode.addChild(child);
-//
-//		String keywords = "";
-//		if (bug.getKeywords() != null) {
-//			for (Iterator<String> iter = bug.getKeywords().iterator(); iter.hasNext();) {
-//				keywords += iter.next() + " ";
-//			}
-//		}
-//		topNode.addChild(new BugzillaCompareNode("Keywords", keywords, defaultImage));
-//
-//		Image attributeImage = PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_OBJ_ELEMENT);
-//		BugzillaCompareNode attributes = new BugzillaCompareNode("Attributes", null, attributeImage);
-//		for (Iterator<RepositoryTaskAttribute> iter = bug.getAttributes().iterator(); iter.hasNext();) {
-//			RepositoryTaskAttribute attribute = iter.next();
-//			if (attribute.getName().compareTo("delta_ts") == 0 || attribute.getName().compareTo("Last Modified") == 0
-//					|| attribute.getName().compareTo("longdesclength") == 0)
-//				continue;
-//			// Since the bug report may not be saved offline, get the
-//			// attribute's new
-//			// value, which is what is in the submit viewer.
-//
-//			attributes.addChild(new BugzillaCompareNode(attribute.getName(), attribute.getValue(), attributeImage));
-//		}
-//		topNode.addChild(attributes);
-//
-//		topNode.addChild(new BugzillaCompareNode("Description", bug.getDescription(), defaultImage));
-//
-//		BugzillaCompareNode comments = new BugzillaCompareNode("Comments", null, defaultImage);
-//		for (Iterator<Comment> iter = bug.getComments().iterator(); iter.hasNext();) {
-//			Comment comment = iter.next();
-//			String bodyString = "Comment from " + comment.getAuthorName() + ":\n\n" + comment.getText();
-//			comments.addChild(new BugzillaCompareNode(comment.getAttributeValue(BugzillaReportElement.CREATION_TS), bodyString, defaultImage));
-//		}
-//		topNode.addChild(comments);
-//
-//		topNode.addChild(new BugzillaCompareNode("New Comment", bug.getNewComment(), defaultImage));
-//
-//		BugzillaCompareNode ccList = new BugzillaCompareNode("CC List", null, defaultImage);
-//		for (Iterator<String> iter = bug.getCC().iterator(); iter.hasNext();) {
-//			String cc = iter.next();
-//			ccList.addChild(new BugzillaCompareNode("CC", cc, defaultImage));
-//		}
-//		topNode.addChild(ccList);
-//
-//		BugzillaCompareNode titleNode = new BugzillaCompareNode("BugReport Object", null, defaultImage);
-//		titleNode.addChild(topNode);
-//
-//		return titleNode;
-//	}
-
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/BugzillaCompareStructureCreator.java b/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/BugzillaCompareStructureCreator.java
deleted file mode 100644
index 200492b..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/BugzillaCompareStructureCreator.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004, 2008 Tasktop Technologies and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     Tasktop Technologies - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.mylyn.bugzilla.deprecated;
-
-import org.eclipse.compare.structuremergeviewer.IStructureComparator;
-import org.eclipse.compare.structuremergeviewer.IStructureCreator;
-import org.eclipse.mylyn.internal.tasks.core.deprecated.RepositoryTaskData;
-
-/**
- * This implementation of the <code>IStructureCreator</code> interface makes the contents of a <code>BugReport</code>
- * object available as a hierarchical structure of <code>IStructureComparator</code>s.
- * <p>
- * It is used when comparing a modified bug report to the one on the corresponding server.
- * 
- * @author Rob Elves
- */
-public class BugzillaCompareStructureCreator implements IStructureCreator {
-
-	/**
-	 * Create a new BugzillaStructureCreator.
-	 */
-	public BugzillaCompareStructureCreator() {
-		super();
-	}
-
-	public String getName() {
-		return "Bugzilla Structure Creator";
-	}
-
-	public IStructureComparator getStructure(Object input) {
-		if (input instanceof RepositoryTaskData) {
-			RepositoryTaskData bugReport = (RepositoryTaskData) input;
-			return BugzillaCompareNode.parseBugReport(bugReport);
-		} else {
-			return null;
-		}
-	}
-
-	public IStructureComparator locate(Object path, Object input) {
-		return null;
-	}
-
-	public String getContents(Object node, boolean ignoreWhitespace) {
-		if (node instanceof BugzillaCompareNode) {
-			String s = ((BugzillaCompareNode) node).getValue();
-			if (ignoreWhitespace) {
-				s = s.trim();
-			}
-			return s;
-		}
-		return null;
-	}
-
-	/**
-	 * Called whenever a copy operation has been performed on a tree node. This implementation throws an
-	 * <code>AssertionFailedException</code> since we cannot update a bug report object.
-	 * 
-	 * @param structure
-	 *            the node for which to save the new content
-	 * @param input
-	 *            the object from which the structure tree was created in <code>getStructure</code>
-	 */
-	public void save(IStructureComparator node, Object input) {
-		// ignore
-	}
-
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/BugzillaException.java b/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/BugzillaException.java
deleted file mode 100644
index b800a78..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/BugzillaException.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004 - 2006 University Of British Columbia and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     University Of British Columbia - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.mylyn.internal.bugzilla.core;
-
-import java.io.PrintStream;
-import java.io.PrintWriter;
-
-public class BugzillaException extends Exception {
-
-	/** Automatically generated serialVersionUID */
-	private static final long serialVersionUID = 3257849887386449974L;
-
-	private Throwable cause;
-
-	/**
-	 * Constructor for BugzillaException.
-	 */
-	public BugzillaException() {
-		super();
-	}
-
-	/**
-	 * Constructor for BugzillaException.
-	 * 
-	 * @param detailMessage
-	 */
-	public BugzillaException(String detailMessage) {
-		super(detailMessage);
-	}
-
-	public BugzillaException(String detailMessage, Throwable cause) {
-		super(detailMessage);
-		this.cause = cause;
-	}
-
-	public BugzillaException(Throwable cause) {
-		this.cause = cause;
-	}
-
-	@Override
-	public synchronized void printStackTrace(PrintStream err) {
-		super.printStackTrace(err);
-		if (cause != null) {
-			err.println("\n--- Cause was:");
-			cause.printStackTrace(err);
-		}
-	}
-
-	@Override
-	public synchronized void printStackTrace(PrintWriter err) {
-		super.printStackTrace(err);
-		if (cause != null) {
-			err.println("\n--- Cause was:");
-			cause.printStackTrace(err);
-		}
-	}
-
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/BugzillaHyperLink.java b/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/BugzillaHyperLink.java
deleted file mode 100644
index 33a2e17..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/BugzillaHyperLink.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004 - 2006 University Of British Columbia and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     University Of British Columbia - initial API and implementation
- *******************************************************************************/
-package org.eclipse.mylyn.internal.bugzilla.ui;
-
-import org.eclipse.jface.dialogs.MessageDialog;
-import org.eclipse.jface.text.IRegion;
-import org.eclipse.jface.text.hyperlink.IHyperlink;
-import org.eclipse.mylyn.internal.bugzilla.core.IBugzillaConstants;
-import org.eclipse.mylyn.tasks.ui.TasksUiUtil;
-
-/**
- * @author Mik Kersten
- */
-public class BugzillaHyperLink implements IHyperlink {
-
-	private static final String SHOW_BUG_CGI = "/show_bug.cgi?taskId=";
-
-	private IRegion region;
-
-	private String id;
-
-	private String repositoryUrl;
-
-	public BugzillaHyperLink(IRegion nlsKeyRegion, String id, String repositoryUrl) {
-		this.region = nlsKeyRegion;
-		this.id = id;
-		this.repositoryUrl = repositoryUrl;
-	}
-
-	public IRegion getHyperlinkRegion() {
-		return region;
-	}
-
-	public String getTypeLabel() {
-		return null;
-	}
-
-	public String getHyperlinkText() {
-		return SHOW_BUG_CGI + id;
-	}
-
-	public void open() {
-		// TaskRepository repository =
-		// MylarTaskListPlugin.getRepositoryManager().getRepositoryForActiveTask(BugzillaPlugin.REPOSITORY_KIND);
-		// TaskRepository repository =
-		// MylarTaskListPlugin.getRepositoryManager().getDefaultRepository(
-		// BugzillaPlugin.REPOSITORY_KIND);
-		if (repositoryUrl != null) {
-			TasksUiUtil.openRepositoryTask(repositoryUrl, id, repositoryUrl + IBugzillaConstants.URL_GET_SHOW_BUG
-					+ id);
-			// OpenBugzillaReportJob job = new
-			// OpenBugzillaReportJob(repository.getUrl(), taskId);
-			// IProgressService service =
-			// PlatformUI.getWorkbench().getProgressService();
-			// try {
-			// service.run(true, false, job);
-			// } catch (Exception e) {
-			// MylarStatusHandler.fail(e, "Could not open report", true);
-			// }
-		} else {
-			MessageDialog.openError(null, IBugzillaConstants.TITLE_MESSAGE_DIALOG,
-					"Could not determine repository for report");
-		}
-	}
-
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/BugzillaLabelProvider.java b/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/BugzillaLabelProvider.java
deleted file mode 100644
index 96e0c19..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/BugzillaLabelProvider.java
+++ /dev/null
@@ -1,84 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004 - 2006 University Of British Columbia and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     University Of British Columbia - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.mylyn.internal.bugzilla.core.search;
-
-import org.eclipse.core.resources.IMarker;
-import org.eclipse.jface.viewers.LabelProvider;
-import org.eclipse.mylyn.internal.bugzilla.core.IBugzillaConstants;
-import org.eclipse.mylyn.internal.bugzilla.core.internal.HtmlStreamTokenizer;
-
-/**
- * Label provider for Bugzilla search items.
- */
-public class BugzillaLabelProvider extends LabelProvider {
-	/** A list of the default severity labels */
-	private static final String[] severityLabel = { "blocker", "critical", "major", "normal", "minor", "trivial",
-			"enhancement" };
-
-	/** A list of the default priority labels */
-	private static final String[] priorityLabel = { "P1", "P2", "P3", "P4", "P5", "--" };
-
-	/** A list of the default state labels */
-	private static final String[] stateLabel = { "Unconfirmed", "New", "Assigned", "Reopened", "Resolved", "Verified",
-			"Closed" };
-
-	/** A list of the default result labels */
-	private static final String[] resultLabel = { "", "fixed", "invalid", "wont fix", "later", "remind", "duplicate",
-			"works for me" };
-
-	/**
-	 * Returns the text for the label of the given element.
-	 * 
-	 * @see org.eclipse.jface.viewers.ILabelProvider#getText(java.lang.Object)
-	 */
-	@Override
-	public String getText(Object element) {
-		if (element instanceof IMarker) {
-
-			try {
-				IMarker marker = (IMarker) element;
-
-				// get the severity of the bug
-				String severity = severityLabel[((Integer) marker
-						.getAttribute(IBugzillaConstants.HIT_MARKER_ATTR_SEVERITY)).intValue()];
-
-				// get the priority of the bug
-				String priority = priorityLabel[((Integer) marker
-						.getAttribute(IBugzillaConstants.HIT_MARKER_ATTR_PRIORITY)).intValue()];
-
-				// get the state of the bug
-				String state = stateLabel[((Integer) marker.getAttribute(IBugzillaConstants.HIT_MARKER_ATTR_STATE))
-						.intValue()];
-
-				// get the resolution of the bug
-				String result = resultLabel[((Integer) marker.getAttribute(IBugzillaConstants.HIT_MARKER_ATTR_RESULT))
-						.intValue()];
-
-				// return a string containing the information about the bug to
-				// be displayed
-				// in the searh window
-				String assignedTo = HtmlStreamTokenizer.unescape(marker.getAttribute(
-						IBugzillaConstants.HIT_MARKER_ATTR_OWNER).toString());
-				String description = HtmlStreamTokenizer.unescape(marker.getAttribute(
-						IBugzillaConstants.HIT_MARKER_ATTR_DESC).toString());
-				return "Bug " + marker.getAttribute(IBugzillaConstants.HIT_MARKER_ATTR_ID) + " (" + severity + " - "
-						+ priority + " - " + state + (result.length() > 0 ? " " + result : "") + ") " + " - "
-						+ description + " (" + assignedTo + ") ";
-			} catch (Exception ignored) {
-				// ignore if there is a problem
-			}
-		}
-
-		// return an empty string if there is a problem
-		return "";
-	}
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/BugzillaNewBugParserTestCDT.java b/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/BugzillaNewBugParserTestCDT.java
deleted file mode 100644
index 819fc4c..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/BugzillaNewBugParserTestCDT.java
+++ /dev/null
@@ -1,213 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004 - 2006 University Of British Columbia and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     University Of British Columbia - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.mylyn.bugzilla.tests;
-
-import java.io.File;
-import java.io.FileReader;
-import java.io.Reader;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-import junit.framework.TestCase;
-
-import org.eclipse.core.runtime.Path;
-import org.eclipse.mylyn.bugzilla.core.AbstractRepositoryReportAttribute;
-import org.eclipse.mylyn.core.tests.support.FileTool;
-import org.eclipse.mylyn.internal.bugzilla.core.NewBugzillaReport;
-import org.eclipse.mylyn.internal.bugzilla.core.internal.NewBugParser;
-
-/**
- * Tests NewBugParser -- parses product attributes for new bug reports
- */
-public class BugzillaNewBugParserTestCDT extends TestCase {
-
-	public BugzillaNewBugParserTestCDT() {
-		super();
-	}
-
-	public BugzillaNewBugParserTestCDT(String arg0) {
-		super(arg0);
-	}
-
-	public void testProductCDT() throws Exception {
-
-		File f = FileTool.getFileInPlugin(BugzillaTestPlugin.getDefault(), new Path("testdata/pages/cdt-page.html"));
-
-		Reader in = new FileReader(f);
-
-		NewBugzillaReport nbm = new NewBugzillaReport();
-		new NewBugParser(in).parseBugAttributes(nbm, true); // ** TRUE vs FALSE
-															// **
-
-		// attributes for this bug model
-		List<AbstractRepositoryReportAttribute> attributes = nbm.getAttributes();
-		// printList(attributes);
-
-		Iterator<AbstractRepositoryReportAttribute> itr = attributes.iterator();
-		AbstractRepositoryReportAttribute att = itr.next();
-
-		// Attribute: Severity
-		assertEquals("Attribute: Severity", "Severity", att.getName());
-
-		Map<String, String> attOptions = att.getOptionValues(); // HashMap of
-		// options for the
-		// current
-		// attribute
-		Object[] options = attOptions.keySet().toArray(); // Array of keys for
-		// the options of the
-		// current attribute
-		assertEquals("# Severity options", 7, options.length);
-
-		int i = 0;
-		while (i < options.length) {
-			assertEquals("severity options", "blocker", options[i++]);
-			assertEquals("severity options", "critical", options[i++]);
-			assertEquals("severity options", "major", options[i++]);
-			assertEquals("severity options", "normal", options[i++]);
-			assertEquals("severity options", "minor", options[i++]);
-			assertEquals("severity options", "trivial", options[i++]);
-			assertEquals("severity options", "enhancement", options[i++]);
-		}
-
-		// Attribute: product
-		att = itr.next();
-		assertEquals("Attribute: product", "product", att.getName());
-
-		attOptions = att.getOptionValues();
-		options = attOptions.keySet().toArray();
-		assertEquals("No product options", 0, options.length);
-
-		// Attribute: AssignedTo
-		att = itr.next();
-		assertEquals("Attribute: AssignedTo", "AssignedTo", att.getName());
-
-		attOptions = att.getOptionValues();
-		options = attOptions.keySet().toArray();
-		assertEquals("No AssignedTo options", 0, options.length);
-
-		// Attribute: OS
-		att = itr.next();
-		assertEquals("Attribute: OS", "OS", att.getName());
-
-		attOptions = att.getOptionValues();
-		options = attOptions.keySet().toArray();
-		assertEquals("# of options", 20, options.length);
-
-		i = 0;
-		while (i < options.length) {
-			assertEquals("OS options", "All", options[i++]);
-			assertEquals("OS options", "AIX Motif", options[i++]);
-			assertEquals("OS options", "Windows 95", options[i++]);
-			assertEquals("OS options", "Windows 98", options[i++]);
-			assertEquals("OS options", "Windows CE", options[i++]);
-			assertEquals("OS options", "Windows ME", options[i++]);
-			assertEquals("OS options", "Windows 2000", options[i++]);
-			assertEquals("OS options", "Windows NT", options[i++]);
-			assertEquals("OS options", "Windows XP", options[i++]);
-			assertEquals("OS options", "Windows All", options[i++]);
-			assertEquals("OS options", "MacOS X", options[i++]);
-			assertEquals("OS options", "Linux", options[i++]);
-			assertEquals("OS options", "Linux-GTK", options[i++]);
-			assertEquals("OS options", "Linux-Motif", options[i++]);
-			assertEquals("OS options", "HP-UX", options[i++]);
-			assertEquals("OS options", "Neutrino", options[i++]);
-			assertEquals("OS options", "QNX-Photon", options[i++]);
-			assertEquals("OS options", "Solaris", options[i++]);
-			assertEquals("OS options", "Unix All", options[i++]);
-			assertEquals("OS options", "other", options[i++]);
-		}
-
-		// Attribute: Version
-		att = itr.next();
-		assertEquals("Attribute: Version", "Version", att.getName());
-
-		// attOptions = (HashMap) att.getOptionValues();
-		options = att.getOptionValues().keySet().toArray();
-		assertEquals("# Version options", 5, options.length);
-
-		i = 0;
-		while (i < options.length) {
-			assertEquals("Version options", "1.0", options[i++]);
-			assertEquals("Version options", "1.0.1", options[i++]);
-			assertEquals("Version options", "1.1", options[i++]);
-			assertEquals("Version options", "1.2", options[i++]);
-			assertEquals("Version options", "2.0", options[i++]);
-		}
-
-		// Attribute: Platform
-		att = itr.next();
-		assertEquals("Attribute: Platform", "Platform", att.getName());
-
-		options = att.getOptionValues().keySet().toArray();
-		assertEquals("# Platform options", 6, options.length);
-
-		i = 0;
-		while (i < options.length) {
-			assertEquals("Platform options", "All", options[i++]);
-			assertEquals("Platform options", "Macintosh", options[i++]);
-			assertEquals("Platform options", "PC", options[i++]);
-			assertEquals("Platform options", "Power PC", options[i++]);
-			assertEquals("Platform options", "Sun", options[i++]);
-			assertEquals("Platform options", "Other", options[i++]);
-		}
-
-		// Attribute: Component
-		att = itr.next();
-		assertEquals("Attribute: Component", "Component", att.getName());
-
-		options = att.getOptionValues().keySet().toArray();
-		assertEquals("# Component options", 9, options.length);
-
-		i = 0;
-		while (i < options.length) {
-			assertEquals("Component options", "CDT-parser", options[i++]);
-			assertEquals("Component options", "Core", options[i++]);
-			assertEquals("Component options", "Cpp-Extensions", options[i++]);
-			assertEquals("Component options", "Debug", options[i++]);
-			assertEquals("Component options", "Debug-MI", options[i++]);
-			assertEquals("Component options", "Doc", options[i++]);
-			assertEquals("Component options", "Generic-Extensions", options[i++]);
-			assertEquals("Component options", "Launcher", options[i++]);
-			assertEquals("Component options", "UI", options[i++]);
-		}
-
-		// Attribute: bug_status
-		att = itr.next();
-		assertEquals("Attribute: bug_status", "bug_status", att.getName());
-
-		options = att.getOptionValues().keySet().toArray();
-		assertEquals("# bug_status options [none]", 0, options.length);
-
-		// Attribute: form_name
-		att = itr.next();
-		assertEquals("Attribute: form_name", "form_name", att.getName());
-
-		options = att.getOptionValues().keySet().toArray();
-		assertEquals("No form_name options", 0, options.length);
-
-		// Attribute: bug_file_loc
-		att = itr.next();
-		assertEquals("Attribute: bug_file_loc", "bug_file_loc", att.getName());
-
-		options = att.getOptionValues().keySet().toArray();
-		assertEquals("No bug_file_loc options", 0, options.length);
-
-		// Attribute: priority
-		att = itr.next();
-		assertEquals("Attribute: priority", "priority", att.getName());
-
-		options = att.getOptionValues().keySet().toArray();
-		assertEquals("No priority options", 0, options.length);
-
-	}
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/BugzillaNewBugParserTestEquinox.java b/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/BugzillaNewBugParserTestEquinox.java
deleted file mode 100644
index f7870d4..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/BugzillaNewBugParserTestEquinox.java
+++ /dev/null
@@ -1,219 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004 - 2006 University Of British Columbia and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     University Of British Columbia - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.mylyn.bugzilla.tests;
-
-import java.io.File;
-import java.io.FileReader;
-import java.io.Reader;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-import junit.framework.TestCase;
-
-import org.eclipse.core.runtime.Path;
-import org.eclipse.mylyn.bugzilla.core.AbstractRepositoryReportAttribute;
-import org.eclipse.mylyn.core.tests.support.FileTool;
-import org.eclipse.mylyn.internal.bugzilla.core.NewBugzillaReport;
-import org.eclipse.mylyn.internal.bugzilla.core.internal.NewBugParser;
-
-/**
- * Tests NewBugParser -- parses product attributes
- */
-public class BugzillaNewBugParserTestEquinox extends TestCase {
-
-	public BugzillaNewBugParserTestEquinox() {
-		super();
-	}
-
-	public BugzillaNewBugParserTestEquinox(String arg0) {
-		super(arg0);
-	}
-
-	public void testProductEquinox() throws Exception {
-
-		File f = FileTool
-				.getFileInPlugin(BugzillaTestPlugin.getDefault(), new Path("testdata/pages/equinox-page.html"));
-
-		Reader in = new FileReader(f);
-
-		NewBugzillaReport nbm = new NewBugzillaReport();
-		new NewBugParser(in).parseBugAttributes(nbm, true); // ** TRUE vs FALSE
-															// **
-
-		// attributes for this bug model
-		List<AbstractRepositoryReportAttribute> attributes = nbm.getAttributes();
-		// printList(attributes);
-
-		Iterator<AbstractRepositoryReportAttribute> itr = attributes.iterator();
-		AbstractRepositoryReportAttribute att = itr.next();
-
-		// Attribute: Severity
-		assertEquals("Attribute: Severity", "Severity", att.getName());
-
-		Map<String, String> attOptions = att.getOptionValues(); // HashMap of
-		// options for the
-		// current
-		// attribute
-		Object[] options = attOptions.keySet().toArray(); // Array of keys for
-		// the options of the
-		// current attribute
-		assertEquals("# Severity options", 7, options.length);
-
-		int i = 0;
-		while (i < options.length) {
-			assertEquals("severity options", "blocker", options[i++]);
-			assertEquals("severity options", "critical", options[i++]);
-			assertEquals("severity options", "major", options[i++]);
-			assertEquals("severity options", "normal", options[i++]);
-			assertEquals("severity options", "minor", options[i++]);
-			assertEquals("severity options", "trivial", options[i++]);
-			assertEquals("severity options", "enhancement", options[i++]);
-		}
-
-		// Attribute: product
-		att = itr.next();
-		assertEquals("Attribute: prodcut", "product", att.getName());
-
-		options = att.getOptionValues().keySet().toArray();
-		assertEquals("No product options", 0, options.length);
-
-		// Attribute: AssignedTo
-		att = itr.next();
-		assertEquals("Attribute: AssignedTo", "AssignedTo", att.getName());
-
-		options = att.getOptionValues().keySet().toArray();
-		assertEquals("No AssignedTo options", 0, options.length);
-
-		// Attribute: OS
-		att = itr.next();
-		assertEquals("Attribute: OS", "OS", att.getName());
-
-		options = att.getOptionValues().keySet().toArray();
-		assertEquals("# OS options", 20, options.length);
-
-		i = 0;
-		while (i < options.length) {
-			assertEquals("OS options", "All", options[i++]);
-			assertEquals("OS options", "AIX Motif", options[i++]);
-			assertEquals("OS options", "Windows 95", options[i++]);
-			assertEquals("OS options", "Windows 98", options[i++]);
-			assertEquals("OS options", "Windows CE", options[i++]);
-			assertEquals("OS options", "Windows ME", options[i++]);
-			assertEquals("OS options", "Windows 2000", options[i++]);
-			assertEquals("OS options", "Windows NT", options[i++]);
-			assertEquals("OS options", "Windows XP", options[i++]);
-			assertEquals("OS options", "Windows All", options[i++]);
-			assertEquals("OS options", "MacOS X", options[i++]);
-			assertEquals("OS options", "Linux", options[i++]);
-			assertEquals("OS options", "Linux-GTK", options[i++]);
-			assertEquals("OS options", "Linux-Motif", options[i++]);
-			assertEquals("OS options", "HP-UX", options[i++]);
-			assertEquals("OS options", "Neutrino", options[i++]);
-			assertEquals("OS options", "QNX-Photon", options[i++]);
-			assertEquals("OS options", "Solaris", options[i++]);
-			assertEquals("OS options", "Unix All", options[i++]);
-			assertEquals("OS options", "other", options[i++]);
-		}
-
-		// Attribute: Version
-		att = itr.next();
-		assertEquals("Attribute: Version", "Version", att.getName());
-
-		options = att.getOptionValues().keySet().toArray();
-		assertEquals("# Version options", 1, options.length);
-
-		i = 0;
-		while (i < options.length) {
-			assertEquals("Version options", "unspecified", options[i++]);
-		}
-
-		// Attribute: Platform
-		att = itr.next();
-		assertEquals("Attribute: Platform", "Platform", att.getName());
-
-		options = att.getOptionValues().keySet().toArray();
-		assertEquals("# Platform options", 6, options.length);
-
-		i = 0;
-		while (i < options.length) {
-			assertEquals("Platform options", "All", options[i++]);
-			assertEquals("Platform options", "Macintosh", options[i++]);
-			assertEquals("Platform options", "PC", options[i++]);
-			assertEquals("Platform options", "Power PC", options[i++]);
-			assertEquals("Platform options", "Sun", options[i++]);
-			assertEquals("Platform options", "Other", options[i++]);
-		}
-
-		// Attribute: Component
-		att = itr.next();
-		assertEquals("Attribute: Component", "Component", att.getName());
-
-		options = att.getOptionValues().keySet().toArray();
-		assertEquals("# Component options", 3, options.length);
-
-		i = 0;
-		while (i < options.length) {
-			assertEquals("Component options", "Dynamic Plugins", options[i++]);
-			assertEquals("Component options", "General", options[i++]);
-			assertEquals("Component options", "OSGi", options[i++]);
-		}
-
-		// Attribute: bug_status
-		att = itr.next();
-		assertEquals("Attribute: bug_status", "bug_status", att.getName());
-
-		options = att.getOptionValues().keySet().toArray();
-		assertEquals("No bug_status options", 0, options.length);
-
-		// Attribute: form_name
-		att = itr.next();
-		assertEquals("Attribute: form_name", "form_name", att.getName());
-
-		options = att.getOptionValues().keySet().toArray();
-		assertEquals("No form_name options", 0, options.length);
-
-		// Attribute: bug_file_loc
-		att = itr.next();
-		assertEquals("Attribute: bug_file_loc", "bug_file_loc", att.getName());
-
-		options = att.getOptionValues().keySet().toArray();
-		assertEquals("No bug_file_loc options", 0, options.length);
-
-		// Attribute: priority
-		att = itr.next();
-		assertEquals("Attribute: priority", "priority", att.getName());
-
-		options = att.getOptionValues().keySet().toArray();
-		assertEquals("No priority options", 0, options.length);
-
-	}
-
-	// private void printList(List<Attribute> attributes) {
-	//
-	// Iterator<Attribute> itr = attributes.iterator();
-	// System.out.println("Attributes for this Product:");
-	// System.out.println("============================");
-	//
-	// while (itr.hasNext()) {
-	// Attribute attr = itr.next();
-	// System.out.println();
-	// System.out.println(attr.getName() + ": ");
-	// System.out.println("-----------");
-	//
-	// Map<String, String> options = attr.getOptionValues();
-	// Object[] it = options.keySet().toArray();
-	// for (int i = 0; i < it.length; i++)
-	// System.out.println((String) it[i]);
-	// }
-	// }
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/BugzillaNewBugParserTestGMT.java b/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/BugzillaNewBugParserTestGMT.java
deleted file mode 100644
index 738a40e..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/BugzillaNewBugParserTestGMT.java
+++ /dev/null
@@ -1,219 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004 - 2006 University Of British Columbia and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     University Of British Columbia - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.mylyn.bugzilla.tests;
-
-import java.io.File;
-import java.io.FileReader;
-import java.io.Reader;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-import junit.framework.TestCase;
-
-import org.eclipse.core.runtime.Path;
-import org.eclipse.mylyn.bugzilla.core.AbstractRepositoryReportAttribute;
-import org.eclipse.mylyn.core.tests.support.FileTool;
-import org.eclipse.mylyn.internal.bugzilla.core.NewBugzillaReport;
-import org.eclipse.mylyn.internal.bugzilla.core.internal.NewBugParser;
-
-/**
- * Tests NewBugParser -- parses product attributes
- */
-public class BugzillaNewBugParserTestGMT extends TestCase {
-
-	public BugzillaNewBugParserTestGMT() {
-		super();
-	}
-
-	public BugzillaNewBugParserTestGMT(String arg0) {
-		super(arg0);
-	}
-
-	public void testProductGMT() throws Exception {
-
-		File f = FileTool.getFileInPlugin(BugzillaTestPlugin.getDefault(), new Path("testdata/pages/gmt-page.html"));
-
-		Reader in = new FileReader(f);
-
-		NewBugzillaReport nbm = new NewBugzillaReport();
-		new NewBugParser(in).parseBugAttributes(nbm, true); // ** TRUE vs FALSE
-															// **
-
-		// attributes for this bug model
-		List<AbstractRepositoryReportAttribute> attributes = nbm.getAttributes();
-		// printList(attributes);
-
-		Iterator<AbstractRepositoryReportAttribute> itr = attributes.iterator();
-		AbstractRepositoryReportAttribute att = itr.next();
-
-		// Attribute: Severity
-		assertEquals("Attribute: Severity", "Severity", att.getName());
-
-		Map<String, String> attOptions = att.getOptionValues(); // HashMap of
-		// options for the
-		// current
-		// attribute
-		Object[] options = attOptions.keySet().toArray(); // Array of keys for
-		// the options of the
-		// current attribute
-		assertEquals("# Severity options", 7, options.length);
-
-		int i = 0;
-		while (i < options.length) {
-			assertEquals("severity options", "blocker", options[i++]);
-			assertEquals("severity options", "critical", options[i++]);
-			assertEquals("severity options", "major", options[i++]);
-			assertEquals("severity options", "normal", options[i++]);
-			assertEquals("severity options", "minor", options[i++]);
-			assertEquals("severity options", "trivial", options[i++]);
-			assertEquals("severity options", "enhancement", options[i++]);
-		}
-
-		// Attribute: product
-		att = itr.next();
-		assertEquals("Attribute: product", "product", att.getName());
-
-		attOptions = att.getOptionValues();
-		options = attOptions.keySet().toArray();
-		assertEquals("No product options", 0, options.length);
-
-		// Attribute: AssignedTo
-		att = itr.next();
-		assertEquals("Attribute: AssignedTo", "AssignedTo", att.getName());
-
-		attOptions = att.getOptionValues();
-		options = attOptions.keySet().toArray();
-		assertEquals("No AssignedTo options", 0, options.length);
-
-		// Attribute: OS
-		att = itr.next();
-		assertEquals("Attribute: OS", "OS", att.getName());
-
-		attOptions = att.getOptionValues();
-		options = attOptions.keySet().toArray();
-		assertEquals("# of options", 20, options.length);
-
-		i = 0;
-		while (i < options.length) {
-			assertEquals("OS options", "All", options[i++]);
-			assertEquals("OS options", "AIX Motif", options[i++]);
-			assertEquals("OS options", "Windows 95", options[i++]);
-			assertEquals("OS options", "Windows 98", options[i++]);
-			assertEquals("OS options", "Windows CE", options[i++]);
-			assertEquals("OS options", "Windows ME", options[i++]);
-			assertEquals("OS options", "Windows 2000", options[i++]);
-			assertEquals("OS options", "Windows NT", options[i++]);
-			assertEquals("OS options", "Windows XP", options[i++]);
-			assertEquals("OS options", "Windows All", options[i++]);
-			assertEquals("OS options", "MacOS X", options[i++]);
-			assertEquals("OS options", "Linux", options[i++]);
-			assertEquals("OS options", "Linux-GTK", options[i++]);
-			assertEquals("OS options", "Linux-Motif", options[i++]);
-			assertEquals("OS options", "HP-UX", options[i++]);
-			assertEquals("OS options", "Neutrino", options[i++]);
-			assertEquals("OS options", "QNX-Photon", options[i++]);
-			assertEquals("OS options", "Solaris", options[i++]);
-			assertEquals("OS options", "Unix All", options[i++]);
-			assertEquals("OS options", "other", options[i++]);
-		}
-
-		// Attribute: Version
-		att = itr.next();
-		assertEquals("Attribute: Version", "Version", att.getName());
-
-		// attOptions = (HashMap) att.getOptionValues();
-		options = att.getOptionValues().keySet().toArray();
-		assertEquals("# Version options", 1, options.length);
-
-		i = 0;
-		while (i < options.length) {
-			assertEquals("Version options", "unspecified", options[i++]);
-		}
-
-		// Attribute: Platform
-		att = itr.next();
-		assertEquals("Attribute: Platform", "Platform", att.getName());
-
-		options = att.getOptionValues().keySet().toArray();
-		assertEquals("# Platform options", 6, options.length);
-
-		i = 0;
-		while (i < options.length) {
-			assertEquals("Platform options", "All", options[i++]);
-			assertEquals("Platform options", "Macintosh", options[i++]);
-			assertEquals("Platform options", "PC", options[i++]);
-			assertEquals("Platform options", "Power PC", options[i++]);
-			assertEquals("Platform options", "Sun", options[i++]);
-			assertEquals("Platform options", "Other", options[i++]);
-		}
-
-		att = itr.next();
-		assertEquals("Attribute: Component", "Component", att.getName());
-
-		options = att.getOptionValues().keySet().toArray();
-		assertEquals("# Component options", 1, options.length);
-
-		i = 0;
-		while (i < options.length) {
-			assertEquals("Component options", "Core", options[i++]);
-		}
-
-		// Attribute: bug_status
-		att = itr.next();
-		assertEquals("Attribute: bug_status", "bug_status", att.getName());
-
-		options = att.getOptionValues().keySet().toArray();
-		assertEquals("No bug_status options", 0, options.length);
-
-		// Attribute: form_name
-		att = itr.next();
-		assertEquals("Attribute: form_name", "form_name", att.getName());
-
-		options = att.getOptionValues().keySet().toArray();
-		assertEquals("No form_name options", 0, options.length);
-
-		// Attribute: bug_file_loc
-		att = itr.next();
-		assertEquals("Attribute: bug_file_loc", "bug_file_loc", att.getName());
-
-		options = att.getOptionValues().keySet().toArray();
-		assertEquals("No bug_file_loc options", 0, options.length);
-
-		// Attribute: priority
-		att = itr.next();
-		assertEquals("Attribute: priority", "priority", att.getName());
-
-		options = att.getOptionValues().keySet().toArray();
-		assertEquals("No priority options", 0, options.length);
-
-	}
-
-	// private void printList(List<Attribute> attributes) {
-	//
-	// Iterator<Attribute> itr = attributes.iterator();
-	// System.out.println("Attributes for this Product:");
-	// System.out.println("============================");
-	//
-	// while (itr.hasNext()) {
-	// Attribute attr = itr.next();
-	// System.out.println();
-	// System.out.println(attr.getName() + ": ");
-	// System.out.println("-----------");
-	//
-	// Map<String, String> options = attr.getOptionValues();
-	// Object[] it = options.keySet().toArray();
-	// for (int i = 0; i < it.length; i++)
-	// System.out.println((String) it[i]);
-	// }
-	// }
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/BugzillaNewBugParserTestPlatform.java b/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/BugzillaNewBugParserTestPlatform.java
deleted file mode 100644
index 6fe1fc2..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/BugzillaNewBugParserTestPlatform.java
+++ /dev/null
@@ -1,246 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004 - 2006 University Of British Columbia and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     University Of British Columbia - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.mylyn.bugzilla.tests;
-
-import java.io.File;
-import java.io.FileReader;
-import java.io.Reader;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-import junit.framework.TestCase;
-
-import org.eclipse.core.runtime.Path;
-import org.eclipse.mylyn.bugzilla.core.AbstractRepositoryReportAttribute;
-import org.eclipse.mylyn.core.tests.support.FileTool;
-import org.eclipse.mylyn.internal.bugzilla.core.NewBugzillaReport;
-import org.eclipse.mylyn.internal.bugzilla.core.internal.NewBugParser;
-
-/**
- * Tests NewBugParser -- parses product attributes
- */
-public class BugzillaNewBugParserTestPlatform extends TestCase {
-
-	public BugzillaNewBugParserTestPlatform() {
-		super();
-	}
-
-	public BugzillaNewBugParserTestPlatform(String arg0) {
-		super(arg0);
-	}
-
-	public void testProductPlatform() throws Exception {
-
-		File f = FileTool.getFileInPlugin(BugzillaTestPlugin.getDefault(),
-				new Path("testdata/pages/platform-page.html"));
-
-		Reader in = new FileReader(f);
-
-		NewBugzillaReport nbm = new NewBugzillaReport();
-		new NewBugParser(in).parseBugAttributes(nbm, true); // ** TRUE vs FALSE
-															// **
-
-		// attributes for this bug model
-		List<AbstractRepositoryReportAttribute> attributes = nbm.getAttributes();
-		// printList(attributes);
-
-		// to iterator over the ArrayList of attributes
-		Iterator<AbstractRepositoryReportAttribute> itr = attributes.iterator();
-
-		// Attribute: Severity
-		AbstractRepositoryReportAttribute att = itr.next(); // current attribute
-
-		// Attribute: Severity
-		assertEquals("Attribute: Severity", "Severity", att.getName());
-
-		Map<String, String> attOptions = att.getOptionValues(); // HashMap of
-		// options for the
-		// current
-		// attribute
-		Object[] options = attOptions.keySet().toArray(); // Array of keys for
-		// the options of the
-		// current attribute
-		assertEquals("# Severity options", 7, options.length);
-
-		int i = 0;
-		while (i < options.length) {
-			assertEquals("severity options", "blocker", options[i++]);
-			assertEquals("severity options", "critical", options[i++]);
-			assertEquals("severity options", "major", options[i++]);
-			assertEquals("severity options", "normal", options[i++]);
-			assertEquals("severity options", "minor", options[i++]);
-			assertEquals("severity options", "trivial", options[i++]);
-			assertEquals("severity options", "enhancement", options[i++]);
-		}
-
-		// Attribute: product
-		att = itr.next();
-		assertEquals("Attribute: product", "product", att.getName());
-
-		attOptions = att.getOptionValues();
-		options = attOptions.keySet().toArray();
-		assertEquals("No product optins", 0, options.length);
-
-		// Attribute: AssignedTo
-		att = itr.next();
-		assertEquals("Attribute: Assigned To", "Assigned To", att.getName());
-
-		options = att.getOptionValues().keySet().toArray();
-		assertEquals("No AssingedTo options", 0, options.length);
-
-		// Attribute: OS
-		att = itr.next();
-		assertEquals("Attribute: OS", "OS", att.getName());
-
-		attOptions = att.getOptionValues();
-		options = attOptions.keySet().toArray();
-		assertEquals("# OS options", 20, options.length);
-
-		i = 0;
-		while (i < options.length) {
-			assertEquals("OS options", "All", options[i++]);
-			assertEquals("OS options", "AIX Motif", options[i++]);
-			assertEquals("OS options", "Windows 95", options[i++]);
-			assertEquals("OS options", "Windows 98", options[i++]);
-			assertEquals("OS options", "Windows CE", options[i++]);
-			assertEquals("OS options", "Windows ME", options[i++]);
-			assertEquals("OS options", "Windows 2000", options[i++]);
-			assertEquals("OS options", "Windows NT", options[i++]);
-			assertEquals("OS options", "Windows XP", options[i++]);
-			assertEquals("OS options", "Windows All", options[i++]);
-			assertEquals("OS options", "MacOS X", options[i++]);
-			assertEquals("OS options", "Linux", options[i++]);
-			assertEquals("OS options", "Linux-GTK", options[i++]);
-			assertEquals("OS options", "Linux-Motif", options[i++]);
-			assertEquals("OS options", "HP-UX", options[i++]);
-			assertEquals("OS options", "Neutrino", options[i++]);
-			assertEquals("OS options", "QNX-Photon", options[i++]);
-			assertEquals("OS options", "Solaris", options[i++]);
-			assertEquals("OS options", "Unix All", options[i++]);
-			assertEquals("OS options", "other", options[i++]);
-		}
-
-		// Attribute: Version
-		att = itr.next();
-		assertEquals("Attribute: Version", "Version", att.getName());
-
-		attOptions = att.getOptionValues();
-		options = attOptions.keySet().toArray();
-		assertEquals("# Version options", 8, options.length);
-
-		i = 0;
-		while (i < options.length) {
-			assertEquals("Version options", "1.0", options[i++]);
-			assertEquals("Version options", "2.0", options[i++]);
-			assertEquals("Version options", "2.0.1", options[i++]);
-			assertEquals("Version options", "2.0.2", options[i++]);
-			assertEquals("Version options", "2.1", options[i++]);
-			assertEquals("Version options", "2.1.1", options[i++]);
-			assertEquals("Version options", "2.1.2", options[i++]);
-			assertEquals("Version options", "3.0", options[i++]);
-		}
-
-		// Attribute: Platform
-		att = itr.next();
-		assertEquals("Attribute: Platform", "Platform", att.getName());
-
-		options = att.getOptionValues().keySet().toArray();
-		assertEquals("# Platform options", 6, options.length);
-
-		i = 0;
-		while (i < options.length) {
-			assertEquals("Platform options", "All", options[i++]);
-			assertEquals("Platform options", "Macintosh", options[i++]);
-			assertEquals("Platform options", "PC", options[i++]);
-			assertEquals("Platform options", "Power PC", options[i++]);
-			assertEquals("Platform options", "Sun", options[i++]);
-			assertEquals("Platform options", "Other", options[i++]);
-		}
-
-		// Attribute: Component
-		att = itr.next();
-		assertEquals("Attribute: Component", "Component", att.getName());
-
-		attOptions = att.getOptionValues();
-		options = attOptions.keySet().toArray();
-		assertEquals("# Component options", 16, options.length);
-
-		i = 0;
-		while (i < options.length) {
-			assertEquals("Component options", "Ant", options[i++]);
-			assertEquals("Component options", "Compare", options[i++]);
-			assertEquals("Component options", "Core", options[i++]);
-			assertEquals("Component options", "CVS", options[i++]);
-			assertEquals("Component options", "Debug", options[i++]);
-			assertEquals("Component options", "Doc", options[i++]);
-			assertEquals("Component options", "Help", options[i++]);
-			assertEquals("Component options", "Releng", options[i++]);
-			assertEquals("Component options", "Scripting", options[i++]);
-			assertEquals("Component options", "Search", options[i++]);
-			assertEquals("Component options", "SWT", options[i++]);
-			assertEquals("Component options", "Team", options[i++]);
-			assertEquals("Component options", "Text", options[i++]);
-			assertEquals("Component options", "UI", options[i++]);
-			assertEquals("Component options", "Update", options[i++]);
-			assertEquals("Component options", "WebDAV", options[i++]);
-		}
-
-		// Attribute: bug_status
-		att = itr.next();
-		assertEquals("Attribute: bug_status", "bug_status", att.getName());
-
-		attOptions = att.getOptionValues();
-		options = attOptions.keySet().toArray();
-		assertEquals("No bug_status options", 0, options.length);
-
-		// Attribute: form_name
-		att = itr.next();
-		assertEquals("Attribute: form_name", "form_name", att.getName());
-
-		options = att.getOptionValues().keySet().toArray();
-		assertEquals("No form_name options", 0, options.length);
-
-		// Attribute: bug_file_loc
-		att = itr.next();
-		assertEquals("Attribute: bug_file_loc", "bug_file_loc", att.getName());
-
-		options = att.getOptionValues().keySet().toArray();
-		assertEquals("No bug_file_loc options", 0, options.length);
-
-		// Attribute: priority
-		att = itr.next();
-		assertEquals("Attribute: priority", "priority", att.getName());
-
-		options = att.getOptionValues().keySet().toArray();
-		assertEquals("No priority options", 0, options.length);
-	}
-
-	// private void printList(List<Attribute> attributes) {
-	//
-	// Iterator<Attribute> itr = attributes.iterator();
-	// System.out.println("Attributes for this Product:");
-	// System.out.println("============================");
-	//
-	// while (itr.hasNext()) {
-	// Attribute attr = itr.next();
-	// System.out.println();
-	// System.out.println(attr.getName() + ": ");
-	// System.out.println("-----------");
-	//
-	// Map<String, String> options = attr.getOptionValues();
-	// Object[] it = options.keySet().toArray();
-	// for (int i = 0; i < it.length; i++)
-	// System.out.println((String) it[i]);
-	// }
-	// }
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/BugzillaNewBugParserTestVE.java b/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/BugzillaNewBugParserTestVE.java
deleted file mode 100644
index 7f6f0dc..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/BugzillaNewBugParserTestVE.java
+++ /dev/null
@@ -1,225 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004 - 2006 University Of British Columbia and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     University Of British Columbia - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.mylyn.bugzilla.tests;
-
-import java.io.File;
-import java.io.FileReader;
-import java.io.Reader;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-import junit.framework.TestCase;
-
-import org.eclipse.core.runtime.Path;
-import org.eclipse.mylyn.bugzilla.core.AbstractRepositoryReportAttribute;
-import org.eclipse.mylyn.core.tests.support.FileTool;
-import org.eclipse.mylyn.internal.bugzilla.core.NewBugzillaReport;
-import org.eclipse.mylyn.internal.bugzilla.core.internal.NewBugParser;
-
-/**
- * Tests NewBugParser -- parses product attributes
- */
-public class BugzillaNewBugParserTestVE extends TestCase {
-
-	public BugzillaNewBugParserTestVE() {
-		super();
-	}
-
-	public BugzillaNewBugParserTestVE(String arg0) {
-		super(arg0);
-	}
-
-	public void testProductVE() throws Exception {
-		File f = FileTool.getFileInPlugin(BugzillaTestPlugin.getDefault(), new Path("testdata/pages/ve-page.html"));
-
-		Reader in = new FileReader(f);
-
-		NewBugzillaReport nbm = new NewBugzillaReport();
-		new NewBugParser(in).parseBugAttributes(nbm, true); // ** TRUE vs FALSE
-															// **
-
-		// attributes for this but model
-		List<AbstractRepositoryReportAttribute> attributes = nbm.getAttributes();
-		// printList(attributes);
-
-		Iterator<AbstractRepositoryReportAttribute> itr = attributes.iterator();
-		AbstractRepositoryReportAttribute att = itr.next();
-
-		// Attribute: Severity
-		assertEquals("Attribute: Severity", "Severity", att.getName());
-
-		Map<String, String> attOptions = att.getOptionValues(); // HashMap of
-		// options for the
-		// current
-		// attribute
-		Object[] options = attOptions.keySet().toArray(); // Array of keys for
-		// the options of the
-		// current attribute
-		assertEquals("# Severity options", 7, options.length);
-
-		int i = 0;
-		while (i < options.length) {
-			assertEquals("severity options", "blocker", options[i++]);
-			assertEquals("severity options", "critical", options[i++]);
-			assertEquals("severity options", "major", options[i++]);
-			assertEquals("severity options", "normal", options[i++]);
-			assertEquals("severity options", "minor", options[i++]);
-			assertEquals("severity options", "trivial", options[i++]);
-			assertEquals("severity options", "enhancement", options[i++]);
-		}
-
-		// Attribute: product
-		att = itr.next();
-		assertEquals("Attribute: product", "product", att.getName());
-
-		attOptions = att.getOptionValues();
-		options = attOptions.keySet().toArray();
-		assertEquals("No product options", 0, options.length);
-
-		// Attribute: AssignedTo
-		att = itr.next();
-		assertEquals("Attribute: AssignedTo", "AssignedTo", att.getName());
-
-		attOptions = att.getOptionValues();
-		options = attOptions.keySet().toArray();
-		assertEquals("No AssignedTo options", 0, options.length);
-
-		// Attribute: OS
-		att = itr.next();
-		assertEquals("Attribute: OS", "OS", att.getName());
-
-		attOptions = att.getOptionValues();
-		options = attOptions.keySet().toArray();
-		assertEquals("# of options", 20, options.length);
-
-		i = 0;
-		while (i < options.length) {
-			assertEquals("OS options", "All", options[i++]);
-			assertEquals("OS options", "AIX Motif", options[i++]);
-			assertEquals("OS options", "Windows 95", options[i++]);
-			assertEquals("OS options", "Windows 98", options[i++]);
-			assertEquals("OS options", "Windows CE", options[i++]);
-			assertEquals("OS options", "Windows ME", options[i++]);
-			assertEquals("OS options", "Windows 2000", options[i++]);
-			assertEquals("OS options", "Windows NT", options[i++]);
-			assertEquals("OS options", "Windows XP", options[i++]);
-			assertEquals("OS options", "Windows All", options[i++]);
-			assertEquals("OS options", "MacOS X", options[i++]);
-			assertEquals("OS options", "Linux", options[i++]);
-			assertEquals("OS options", "Linux-GTK", options[i++]);
-			assertEquals("OS options", "Linux-Motif", options[i++]);
-			assertEquals("OS options", "HP-UX", options[i++]);
-			assertEquals("OS options", "Neutrino", options[i++]);
-			assertEquals("OS options", "QNX-Photon", options[i++]);
-			assertEquals("OS options", "Solaris", options[i++]);
-			assertEquals("OS options", "Unix All", options[i++]);
-			assertEquals("OS options", "other", options[i++]);
-		}
-
-		// Attribute: Version
-		att = itr.next();
-		assertEquals("Attribute: Version", "Version", att.getName());
-
-		// attOptions = (HashMap) att.getOptionValues();
-		options = att.getOptionValues().keySet().toArray();
-		assertEquals("# Version options", 3, options.length);
-
-		i = 0;
-		while (i < options.length) {
-			assertEquals("Version options", "0.5.0", options[i++]);
-			assertEquals("Version options", "1.0.0", options[i++]);
-			assertEquals("Version options", "unspecified", options[i++]);
-		}
-
-		// Attribute: Platform
-		att = itr.next();
-		assertEquals("Attribute: Platform", "Platform", att.getName());
-
-		options = att.getOptionValues().keySet().toArray();
-		assertEquals("# Platform options", 6, options.length);
-
-		i = 0;
-		while (i < options.length) {
-			assertEquals("Platform options", "All", options[i++]);
-			assertEquals("Platform options", "Macintosh", options[i++]);
-			assertEquals("Platform options", "PC", options[i++]);
-			assertEquals("Platform options", "Power PC", options[i++]);
-			assertEquals("Platform options", "Sun", options[i++]);
-			assertEquals("Platform options", "Other", options[i++]);
-		}
-
-		att = itr.next();
-		assertEquals("Attribute: Component", "Component", att.getName());
-
-		options = att.getOptionValues().keySet().toArray();
-		assertEquals("# Component options", 6, options.length);
-
-		i = 0;
-		while (i < options.length) {
-			assertEquals("Component options", "CDE", options[i++]);
-			assertEquals("Component options", "Doc", options[i++]);
-			assertEquals("Component options", "Java Core", options[i++]);
-			assertEquals("Component options", "Java Model (JEM)", options[i++]);
-			assertEquals("Component options", "JFC/Swing", options[i++]);
-			assertEquals("Component options", "SWT", options[i++]);
-		}
-
-		// Attribute: bug_status
-		att = itr.next();
-		assertEquals("Attribute: bug_status", "bug_status", att.getName());
-
-		options = att.getOptionValues().keySet().toArray();
-		assertEquals("No bug_status options", 0, options.length);
-
-		// Attribute: form_name
-		att = itr.next();
-		assertEquals("Attribute: form_name", "form_name", att.getName());
-
-		options = att.getOptionValues().keySet().toArray();
-		assertEquals("No form_name options", 0, options.length);
-
-		// Attribute: bug_file_loc
-		att = itr.next();
-		assertEquals("Attribute: bug_file_loc", "bug_file_loc", att.getName());
-
-		options = att.getOptionValues().keySet().toArray();
-		assertEquals("No bug_file_loc options", 0, options.length);
-
-		// Attribute: priority
-		att = itr.next();
-		assertEquals("Attribute: priority", "priority", att.getName());
-
-		options = att.getOptionValues().keySet().toArray();
-		assertEquals("No priority options", 0, options.length);
-
-	}
-
-	// private void printList(List<Attribute> attributes) {
-	//
-	// Iterator<Attribute> itr = attributes.iterator();
-	// System.out.println("Attributes for this Product:");
-	// System.out.println("============================");
-	//
-	// while (itr.hasNext()) {
-	// Attribute attr = itr.next();
-	// System.out.println();
-	// System.out.println(attr.getName() + ": ");
-	// System.out.println("-----------");
-	//
-	// Map<String, String> options = attr.getOptionValues();
-	// Object[] it = options.keySet().toArray();
-	// for (int i = 0; i < it.length; i++)
-	// System.out.println((String) it[i]);
-	// }
-	// }
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/BugzillaParserTest.java b/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/BugzillaParserTest.java
deleted file mode 100644
index dea3c34..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/BugzillaParserTest.java
+++ /dev/null
@@ -1,196 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2003 - 2006 University Of British Columbia and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     University Of British Columbia - initial API and implementation
- *******************************************************************************/
-package org.eclipse.mylyn.bugzilla.tests;
-
-import java.io.File;
-import java.io.FileReader;
-import java.io.Reader;
-import java.util.Iterator;
-
-import junit.framework.TestCase;
-
-import org.eclipse.core.runtime.Path;
-import org.eclipse.mylyn.bugzilla.core.BugReport;
-import org.eclipse.mylyn.bugzilla.core.Comment;
-import org.eclipse.mylyn.core.tests.support.FileTool;
-import org.eclipse.mylyn.internal.bugzilla.core.internal.BugParser;
-
-/**
- * Tests for parsing Bugzilla reports
- */
-public class BugzillaParserTest extends TestCase {
-
-	public BugzillaParserTest() {
-		super();
-	}
-
-	public BugzillaParserTest(String arg0) {
-		super(arg0);
-	}
-
-	public void testFullReportBug1() throws Exception {
-
-		File f = FileTool.getFileInPlugin(BugzillaTestPlugin.getDefault(), new Path("testdata/pages/bug-1-full.html"));
-
-		Reader in = new FileReader(f);
-
-		BugReport bug = BugParser.parseBug(in, 1, "<server>", false, null, null, null);
-
-		// displayBug(bug);
-		assertEquals("Bug id", 1, bug.getId());
-		assertEquals("Bug summary", "Usability issue with external editors (1GE6IRL)", bug.getSummary());
-		assertEquals("Reporter", "andre_weinand@ch.ibm.com (Andre Weinand)", bug.getReporter());
-		assertEquals("Reporter", "andre_weinand@ch.ibm.com (Andre Weinand)", bug.getAttribute("Reporter").getValue());
-		assertEquals("Summary", "Usability issue with external editors (1GE6IRL)", bug.getSummary());
-		assertEquals("Status", "VERIFIED", bug.getStatus());
-		assertEquals("Resolution", "FIXED", bug.getResolution());
-		assertEquals("Keywords", null, bug.getKeywords());
-		assertEquals("Assigned To", "James_Moody@ca.ibm.com (James Moody)", bug.getAssignedTo());
-		assertEquals("Priority", "P3", bug.getAttribute("Priority").getValue());
-		assertEquals("OS", "All", bug.getAttribute("OS").getValue());
-		assertEquals("Version", "2.0", bug.getAttribute("Version").getValue());
-		assertEquals("Target Milestone", "---", bug.getAttribute("Target Milestone").getValue());
-		assertEquals("Keywords", "", bug.getAttribute("Keywords").getValue());
-		assertEquals("Severity", "normal", bug.getAttribute("Severity").getValue());
-		assertEquals("Component", "VCM", bug.getAttribute("Component").getValue());
-		assertEquals("CC", "Kevin_McGuire@oti.com", bug.getCC().iterator().next());
-		assertEquals("Platform", "All", bug.getAttribute("Platform").getValue());
-		assertEquals("Product", "Platform", bug.getAttribute("Product").getValue());
-		assertEquals("URL", "", bug.getAttribute("URL").getValue());
-		assertEquals("Bug#", "1", bug.getAttribute("Bug#").getValue());
-
-		// Description
-		String description = "- Setup a project that contains a *.gif resource\n"
-				+ "\t- release project to CVS\n"
-				+ "\t- edit the *.gif resource with an external editor, e.g. PaintShop\n"
-				+ "\t- save and close external editor\n"
-				+ "\t- in Navigator open the icon resource and verify that your changes are there\n"
-				+ "\t- release project\n"
-				+ "\t\t-> nothing to release!\n"
-				+ "\t- in Navigator open the icon resource and verify that your changes are still there\n\n"
-				+
-
-				"\tProblem: because I never \"Refreshed from local\", the workspace hasn't changed so \"Release\" didn't find anything.\n"
-				+ "\tHowever opening the resource with an external editor found the modified file on disk and showed the changes.\n\n"
-				+
-
-				"\tThe real problem occurs if \"Release\" actually finds something to release but you don't spot that some resources are missing.\n"
-				+ "\tThis is extremely error prone: one of my changes didn't made it into build 110 because of this!\n\n"
-				+
-
-				"NOTES:\n"
-				+ "EG (5/23/01 3:00:33 PM)\n"
-				+ "\tRelease should do a refresh from local before doing the release.\n"
-				+ "\tMoving to VCM\n\n\n"
-				+
-
-				"KM (05/27/01 5:10:19 PM)\n"
-				+ "\tComments from JM in related email:\n\n"
-				+
-
-				"\tShould not do this for free.  Could have a setting which made it optoinal but should nt be mandatory.  Default setting could be to have it on.\n"
-				+ "\tConsider the SWT team who keep their workspaces on network drives.  This will be slow.  \n\n"
-				+
-
-				"\tSide effects will be that a build runs when the refresh is completed unless you somehow do it in a workspace runnable and don't end the\n"
-				+ "\trunnable until after the release.  This would be less than optimal as some builders may be responsible for maintaining some invariants and deriving resources which are releasable.  If you don't run the builders before releasing, the invariants will not be maintained and you will release inconsistent state.\n\n"
-				+
-
-				"\tSummary:  Offer to \"ensure local consistency\" before releasing.\n\n" +
-
-				"KM (5/31/01 1:30:35 PM)\n"
-				+ "\tSee also 1GEAG1A: ITPVCM:WINNT - Internal error comparing with a document\n"
-				+ "\twhich failed with an error.  Never got log from Tod though.";
-
-		assert (description.length() == bug.getDescription().length());
-		assertEquals("Description", description, bug.getDescription());
-
-		// Comments:
-		Iterator<Comment> it = bug.getComments().iterator();
-		while (it.hasNext()) {
-			// COMMENT #1
-			Comment comment = it.next();
-			assertEquals("Author1", "James_Moody@ca.ibm.com", comment.getAuthor());
-			assertEquals("Name1", "James Moody", comment.getAuthorName());
-			assertEquals("Text1", "*** Bug 183 has been marked as a duplicate of this bug. ***", comment.getText());
-
-			// COMMENT #2
-			comment = it.next();
-			assertEquals("Author2", "James_Moody@ca.ibm.com", comment.getAuthor());
-			assertEquals("Name2", "James Moody", comment.getAuthorName());
-			assertEquals("Text2", "Implemented 'auto refresh' option. Default value is off.", comment.getText());
-
-			// COMMENT 3
-			comment = it.next();
-			assertEquals("Author3", "dj_houghton@ca.ibm.com", comment.getAuthor());
-			assertEquals("Name3", "DJ Houghton", comment.getAuthorName());
-			assertEquals("Text3", "PRODUCT VERSION:\n\t109\n\n", comment.getText());
-
-			// COMMENT 4
-			comment = it.next();
-			assertEquals("Author4", "James_Moody@ca.ibm.com", comment.getAuthor());
-			assertEquals("Name4", "James Moody", comment.getAuthorName());
-			assertEquals("Text4", "Fixed in v206", comment.getText());
-		}
-	}
-
-	// private static void displayBug(BugReport bug) {
-	// System.out.println("Bug " + bug.getId() + ": " + bug.getSummary());
-	// System.out.println("Opened: " + bug.getCreated());
-	// for (Iterator<Attribute> it = bug.getAttributes().iterator();
-	// it.hasNext();) {
-	// Attribute attribute = it.next();
-	// String key = attribute.getName();
-	// System.out.println(key + ": " + attribute.getValue()
-	// + (attribute.isEditable() ? " [OK]" : " %%"));
-	// }
-	//
-	// System.out.print("CC: ");
-	// for (Iterator<String> it = bug.getCC().iterator(); it.hasNext();) {
-	// String email = it.next();
-	// System.out.print(email + " ");
-	// }
-	// System.out.println();
-	//
-	// System.out.println(bug.getDescription());
-	// for (Iterator<Comment> it = bug.getComments().iterator(); it.hasNext();)
-	// {
-	// Comment comment = it.next();
-	// System.out.println(comment.getAuthorName() + " <"
-	// + comment.getAuthor() + "> (" + comment.getCreated() + ")");
-	// System.out.print(comment.getText());
-	// System.out.println();
-	// }
-	// }
-	//
-	// private static void printComments(BugReport bug) {
-	// for (Iterator<Comment> it = bug.getComments().iterator(); it.hasNext();)
-	// {
-	// Comment comment = it.next();
-	// System.out.println("Author: " + comment.getAuthor());
-	// System.out.println("Name: " + comment.getAuthorName());
-	// System.out.println("Date: " + comment.getCreated());
-	// System.out.println("Bug ID: " + comment.getBug().getId());
-	// System.out.println("Comment: " + comment.getText());
-	// System.out.println();
-	// }
-	// }
-	//
-	// /** prints names of attributes */
-	// private static void printAttributes(BugReport bug) {
-	// System.out.println("ATTRIBUTE KEYS:");
-	// for (Iterator<Attribute> it = bug.getAttributes().iterator();
-	// it.hasNext();) {
-	// Attribute att = it.next();
-	// System.out.println(att.getName());
-	// }
-	// }
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/BugzillaParserTestNoBug.java b/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/BugzillaParserTestNoBug.java
deleted file mode 100644
index 3f888fc..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/BugzillaParserTestNoBug.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2003 - 2006 University Of British Columbia and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     University Of British Columbia - initial API and implementation
- *******************************************************************************/
-package org.eclipse.mylyn.bugzilla.tests;
-
-import java.io.File;
-import java.io.FileReader;
-import java.io.Reader;
-
-import junit.framework.TestCase;
-
-import org.eclipse.core.runtime.Path;
-import org.eclipse.mylyn.bugzilla.core.BugReport;
-import org.eclipse.mylyn.core.tests.support.FileTool;
-import org.eclipse.mylyn.internal.bugzilla.core.internal.BugParser;
-
-/**
- * Tests for parsing Bugzilla reports
- */
-public class BugzillaParserTestNoBug extends TestCase {
-
-	public BugzillaParserTestNoBug() {
-		super();
-	}
-
-	public BugzillaParserTestNoBug(String arg0) {
-		super(arg0);
-	}
-
-	public void testBugNotFound() throws Exception {
-
-		File f = FileTool.getFileInPlugin(BugzillaTestPlugin.getDefault(), new Path(
-				"testdata/pages/bug-not-found-eclipse.html"));
-
-		Reader in = new FileReader(f);
-
-		BugReport bug = BugParser.parseBug(in, 666, "<server>", false, null, null, null);
-		assertNull(bug);
-	}
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/BugzillaPreferencePage.java b/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/BugzillaPreferencePage.java
deleted file mode 100644
index 3d5f93d..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/BugzillaPreferencePage.java
+++ /dev/null
@@ -1,235 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2003 - 2006 University Of British Columbia and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     University Of British Columbia - initial API and implementation
- *******************************************************************************/
-package org.eclipse.mylyn.internal.bugzilla.ui.preferences;
-
-import org.eclipse.jface.preference.FieldEditorPreferencePage;
-import org.eclipse.jface.preference.IPreferenceStore;
-import org.eclipse.jface.preference.RadioGroupFieldEditor;
-import org.eclipse.mylyn.internal.bugzilla.core.BugzillaPlugin;
-import org.eclipse.mylyn.internal.bugzilla.core.IBugzillaConstants;
-import org.eclipse.mylyn.internal.bugzilla.ui.BugzillaUiPlugin;
-import org.eclipse.swt.widgets.Button;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.ui.IWorkbench;
-import org.eclipse.ui.IWorkbenchPreferencePage;
-
-/**
- * @author Gail Murphy
- * @author Mik Kersten
- */
-public class BugzillaPreferencePage extends FieldEditorPreferencePage implements IWorkbenchPreferencePage {
-
-	private RadioGroupFieldEditor bugzillaVersionEditor;
-
-//	private static final String bugzillaMaxResultsLabel = "Maximum returned results: ";
-
-//	private IntegerFieldEditor maxResults;
-
-	/**
-	 * Constructor for the preferences page
-	 */
-	public BugzillaPreferencePage() {
-		super(GRID);
-
-		// set the preference store for this preference page
-		setPreferenceStore(BugzillaUiPlugin.getDefault().getPreferenceStore());
-	}
-
-	@Override
-	protected Control createContents(Composite parent) {
-		return super.createContents(parent);
-	}
-
-	@Override
-	public void createControl(Composite parent) {
-		super.createControl(parent);
-
-		// HACK: there has to be an easier way
-		Control[] radios = bugzillaVersionEditor.getRadioBoxControl(getFieldEditorParent()).getChildren();
-		String currentVersion = BugzillaPlugin.getDefault().getPreferenceStore().getString(
-				IBugzillaConstants.SERVER_VERSION);
-		for (int i = 0; i < radios.length; i++) {
-			Button button = (Button) radios[i];
-			if (button.getText().equals(currentVersion)) {
-				button.setSelection(true);
-			} else {
-				button.setSelection(false);
-			}
-		}
-	}
-
-	@Override
-	protected void createFieldEditors() {
-
-//		maxResults = new IntegerFieldEditor(IBugzillaConstants.MAX_RESULTS, bugzillaMaxResultsLabel,
-//				getFieldEditorParent());
-
-		// bugzillaVersionEditor.setPreferenceStore(BugzillaPlugin.getDefault().getPreferenceStore());
-		bugzillaVersionEditor = new RadioGroupFieldEditor(IBugzillaConstants.SERVER_VERSION, "Bugzilla Version", 3,
-				new String[][] { { IBugzillaConstants.SERVER_220, IBugzillaConstants.SERVER_VERSION },
-						{ IBugzillaConstants.SERVER_218, IBugzillaConstants.SERVER_VERSION } }, getFieldEditorParent());
-//		refreshQueries = new BooleanFieldEditor(IBugzillaConstants.REFRESH_QUERY,
-//				"Automatically refresh Bugzilla reports and queries on startup", BooleanFieldEditor.DEFAULT,
-//				getFieldEditorParent());
-
-//		addField(maxResults);
-		addField(bugzillaVersionEditor);
-//		addField(refreshQueries);
-	}
-
-	public static void initDefaults(IPreferenceStore store) {
-		store.setDefault(IBugzillaConstants.MOST_RECENT_QUERY, "");
-		store.setDefault(IBugzillaConstants.SERVER_VERSION, IBugzillaConstants.SERVER_220);
-		store.setDefault(IBugzillaConstants.REFRESH_QUERY, false);
-		store.setDefault(IBugzillaConstants.MAX_RESULTS, 100);
-	}
-
-	@Override
-	protected void performDefaults() {
-		super.performDefaults();
-	}
-
-	@Override
-	public boolean performOk() {
-		// HACK: there has to be an easier way
-		Control[] radios = bugzillaVersionEditor.getRadioBoxControl(getFieldEditorParent()).getChildren();
-		for (int i = 0; i < radios.length; i++) {
-			Button button = (Button) radios[i];
-			if (button.getSelection()) {
-				BugzillaPlugin.getDefault().getPreferenceStore().setValue(IBugzillaConstants.SERVER_VERSION,
-						button.getText());
-			}
-		}
-
-//		BugzillaPlugin.getDefault().getPreferenceStore().setValue(IBugzillaConstants.REFRESH_QUERY,
-//				refreshQueries.getBooleanValue());
-
-//		try {
-//			int numMaxResults = maxResults.getIntValue();
-//			BugzillaPlugin.getDefault().getPreferenceStore().setValue(IBugzillaConstants.MAX_RESULTS, numMaxResults);
-//		} catch (NumberFormatException nfe) {
-//			// ignore and leave as default
-//			BugzillaPlugin.getDefault().getPreferenceStore().setValue(IBugzillaConstants.MAX_RESULTS,
-//					BugzillaPlugin.getDefault().getPreferenceStore().getDefaultInt(IBugzillaConstants.MAX_RESULTS));
-//		}
-
-		// ProductConfiguration configuration = null;
-		// String urlString = bugzillaServer.getStringValue();
-		// try {
-		// URL serverURL = new URL(urlString + "/show_bug.cgi");
-		// URLConnection cntx =
-		// BugzillaPlugin.getDefault().getUrlConnection(serverURL);
-		// if (cntx == null || !(cntx instanceof HttpURLConnection))
-		// return false;
-		//
-		// HttpURLConnection serverConnection = (HttpURLConnection) cntx;
-		//
-		// serverConnection.connect();
-		//
-		// int responseCode = serverConnection.getResponseCode();
-		//
-		// if (responseCode != HttpURLConnection.HTTP_OK)
-		// throw new BugzillaException("No Bugzilla server detected at " +
-		// bugzillaServer.getStringValue() + ".");
-		//
-		// try {
-		// configuration =
-		// ProductConfigurationFactory.getInstance().getConfiguration(
-		// bugzillaServer.getStringValue());
-		// } catch (IOException ex) {
-		// MessageDialog.openInformation(null, "Bugzilla query parameters
-		// check",
-		// "An error occurred while pre-fetching valid search attributes: \n\n"
-		// + ex.getClass().getName()
-		// + ": " + ex.getMessage() + "\n\nOffline submission of new bugs will
-		// be disabled.");
-		// }
-		// } catch (Exception e) {
-		// if (!MessageDialog.openQuestion(null, "Bugzilla Server Error", "Error
-		// validating Bugzilla Server.\n\n"
-		// + e.getMessage() + "\n\nKeep specified server location anyway?")) {
-		// return false;
-		// }
-		// }
-		// BugzillaPlugin.getDefault().setProductConfiguration(urlString,
-		// configuration);
-		// IPath configFile =
-		// BugzillaPlugin.getDefault().getProductConfigurationCachePath(urlString);
-		// if (configuration != null) {
-		//
-		// try {
-		// ProductConfigurationFactory.getInstance().writeConfiguration(configuration,
-		// configFile.toFile());
-		// } catch (IOException e) {
-		// BugzillaPlugin.log(e);
-		// configFile.toFile().delete();
-		// }
-		// } else {
-		// configFile.toFile().delete();
-		// }
-
-		// save the preferences that were changed
-		// BugzillaPlugin.getDefault().savePluginPreferences();
-
-		// bugzillaServer.store();
-
-		// store the username and password from the editor field
-		// user = bugzillaUser.getStringValue();
-		// password = bugzillaPassword.getStringValue();
-		// storeCache(user, password, true);
-		return true;
-	}
-
-	@Override
-	public boolean performCancel() {
-		// refreshQueries.setSelection(getPreferenceStore().getBoolean(MylarTasksPlugin.REFRESH_QUERIES));
-		return true;
-	}
-
-	@Override
-	protected void initialize() {
-		super.initialize();
-	}
-
-	public void init(IWorkbench workbench) {
-		// Don't need to do anything here with the workbench
-	}
-
-	// /**
-	// * Hack private class to make StringFieldEditor.refreshValidState() a
-	// * publicly acessible method.
-	// *
-	// * @see org.eclipse.jface.preference.StringFieldEditor#refreshValidState()
-	// */
-	// private static class MyStringFieldEditor extends StringFieldEditor {
-	// public MyStringFieldEditor(String name, String labelText, int style,
-	// Composite parent) {
-	// super(name, labelText, style, parent);
-	// }
-	//
-	// @Override
-	// public void refreshValidState() {
-	// super.refreshValidState();
-	// }
-	//
-	// @Override
-	// public Text getTextControl() {
-	// return super.getTextControl();
-	// }
-	// }
-
-	public static final String INFO_PASSWORD = "org.eclipse.team.cvs.core.password"; //$NON-NLS-1$ 
-
-	public static final String INFO_USERNAME = "org.eclipse.team.cvs.core.username"; //$NON-NLS-1$ 
-
-	public static final String AUTH_SCHEME = "";
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/BugzillaProductPage.java b/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/BugzillaProductPage.java
deleted file mode 100644
index 6e55e01..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/BugzillaProductPage.java
+++ /dev/null
@@ -1,472 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004, 2008 Tasktop Technologies and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     Tasktop Technologies - initial API and implementation
- *     Eugene Kuleshov - improvements
- *     Willian Mitsuda - improvements
- *******************************************************************************/
-
-package org.eclipse.mylyn.internal.bugzilla.ui.wizard;
-
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-import java.lang.reflect.InvocationTargetException;
-import java.net.URLDecoder;
-import java.security.GeneralSecurityException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IAdaptable;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.NullProgressMonitor;
-import org.eclipse.core.runtime.Status;
-import org.eclipse.jface.dialogs.Dialog;
-import org.eclipse.jface.dialogs.IMessageProvider;
-import org.eclipse.jface.dialogs.MessageDialog;
-import org.eclipse.jface.layout.GridDataFactory;
-import org.eclipse.jface.operation.IRunnableWithProgress;
-import org.eclipse.jface.preference.IPreferenceStore;
-import org.eclipse.jface.viewers.IOpenListener;
-import org.eclipse.jface.viewers.ISelection;
-import org.eclipse.jface.viewers.ISelectionChangedListener;
-import org.eclipse.jface.viewers.IStructuredSelection;
-import org.eclipse.jface.viewers.ITreeContentProvider;
-import org.eclipse.jface.viewers.LabelProvider;
-import org.eclipse.jface.viewers.OpenEvent;
-import org.eclipse.jface.viewers.SelectionChangedEvent;
-import org.eclipse.jface.viewers.StructuredSelection;
-import org.eclipse.jface.viewers.TreeViewer;
-import org.eclipse.jface.viewers.Viewer;
-import org.eclipse.jface.wizard.WizardDialog;
-import org.eclipse.jface.wizard.WizardPage;
-import org.eclipse.mylyn.commons.core.StatusHandler;
-import org.eclipse.mylyn.internal.bugzilla.core.BugzillaAttribute;
-import org.eclipse.mylyn.internal.bugzilla.core.BugzillaCorePlugin;
-import org.eclipse.mylyn.internal.bugzilla.core.IBugzillaConstants;
-import org.eclipse.mylyn.internal.bugzilla.core.RepositoryConfiguration;
-import org.eclipse.mylyn.internal.bugzilla.ui.BugzillaUiPlugin;
-import org.eclipse.mylyn.tasks.core.AbstractRepositoryConnector;
-import org.eclipse.mylyn.tasks.core.IRepositoryQuery;
-import org.eclipse.mylyn.tasks.core.ITask;
-import org.eclipse.mylyn.tasks.core.TaskRepository;
-import org.eclipse.mylyn.tasks.ui.TasksUi;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.SelectionAdapter;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Button;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.swt.widgets.TreeItem;
-import org.eclipse.ui.IWorkbenchWindow;
-import org.eclipse.ui.PlatformUI;
-import org.eclipse.ui.dialogs.FilteredTree;
-import org.eclipse.ui.dialogs.PatternFilter;
-import org.eclipse.ui.plugin.AbstractUIPlugin;
-import org.eclipse.ui.progress.UIJob;
-
-/**
- * Product selection page of new bug wizard
- * 
- * @author Shawn Minto
- * @author Rob Elves
- * @author Mik Kersten
- */
-public class BugzillaProductPage extends WizardPage {
-
-	private static final String NEW_BUGZILLA_TASK_ERROR_TITLE = Messages.BugzillaProductPage_New_Bugzilla_Task_Error;
-
-	private static final String DESCRIPTION = Messages.BugzillaProductPage_PICK_PRODUCT_TO_OPEN_NEW_BUG_EDITOR
-			+ Messages.BugzillaProductPage_PRESS_UPDATE_BUTTON;
-
-	private static final String LABEL_UPDATE = Messages.BugzillaProductPage_Update_Products_from_Repository;
-
-	/** The list of products to submit a bug report for */
-	private List<String> products = null;
-
-	/**
-	 * Handle product selection
-	 */
-	private FilteredTree productList;
-
-	private final TaskRepository repository;
-
-	protected IPreferenceStore prefs = BugzillaUiPlugin.getDefault().getPreferenceStore();
-
-	/**
-	 * Constructor for BugzillaProductPage
-	 * 
-	 * @param repository
-	 *            The repository the data is coming from
-	 * @param workbench
-	 *            The instance of the workbench
-	 * @param selection
-	 */
-	public BugzillaProductPage(TaskRepository repository) {
-		super(Messages.BugzillaProductPage_PAGE_1);
-		setTitle(IBugzillaConstants.TITLE_NEW_BUG);
-		setDescription(DESCRIPTION);
-		this.repository = repository;
-		setImageDescriptor(AbstractUIPlugin.imageDescriptorFromPlugin("org.eclipse.mylyn.bugzilla.ui", //$NON-NLS-1$
-				"icons/wizban/bug-wizard.gif")); //$NON-NLS-1$
-
-	}
-
-	private class ComponentFilter extends PatternFilter {
-
-		@Override
-		public void setPattern(String patternString) {
-			// ignore
-			super.setPattern(patternString);
-			// HACK: waiting on delayed refresh of filtered tree after setting the new pattern
-			new UIJob("") { //$NON-NLS-1$
-				@Override
-				public IStatus runInUIThread(IProgressMonitor monitor) {
-					if (BugzillaProductPage.this.getControl() != null
-							&& BugzillaProductPage.this.getControl().isDisposed()) {
-						return Status.OK_STATUS;
-					}
-					final TreeViewer productViewer = productList.getViewer();
-					if (productViewer.getTree().getItemCount() == 1) {
-						TreeItem aq = productViewer.getTree().getItem(0);
-						String qq = aq.getText();
-						productViewer.setSelection(new StructuredSelection(qq));
-					}
-					return Status.OK_STATUS;
-				}
-			}.schedule(300L);
-
-		}
-	}
-
-	@SuppressWarnings("deprecation")
-	public void createControl(Composite parent) {
-		// create the composite to hold the widgets
-		Composite composite = new Composite(parent, SWT.NULL);
-
-		// create the desired layout for this wizard page
-		composite.setLayout(new GridLayout());
-
-		// create the list of bug reports
-		// TODO e3.5 move to new FilteredTree API
-		productList = new FilteredTree(composite, SWT.SINGLE | SWT.BORDER, new ComponentFilter());
-		productList.setLayoutData(GridDataFactory.swtDefaults().align(SWT.FILL, SWT.FILL).grab(true, true).hint(
-				SWT.DEFAULT, 200).create());
-		final TreeViewer productViewer = productList.getViewer();
-		productViewer.setLabelProvider(new LabelProvider());
-		productViewer.setContentProvider(new ITreeContentProvider() {
-
-			public Object[] getChildren(Object parentElement) {
-				if (parentElement instanceof Collection<?>) {
-					return ((Collection<?>) parentElement).toArray();
-				}
-				return null;
-			}
-
-			public Object getParent(Object element) {
-				return null;
-			}
-
-			public boolean hasChildren(Object element) {
-				return false;
-			}
-
-			public Object[] getElements(Object inputElement) {
-				return getChildren(inputElement);
-			}
-
-			public void dispose() {
-			}
-
-			public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
-			}
-		});
-
-		productViewer.addOpenListener(new IOpenListener() {
-			public void open(OpenEvent event) {
-				if (getWizard().canFinish()) {
-					if (getWizard().performFinish()) {
-						((WizardDialog) getContainer()).close();
-					}
-				}
-			}
-		});
-
-		initProducts();
-		productViewer.setInput(products);
-		productViewer.addPostSelectionChangedListener(new ISelectionChangedListener() {
-
-			public void selectionChanged(SelectionChangedEvent event) {
-				// Initialize a variable with the no error status
-				Status status = new Status(IStatus.OK, BugzillaUiPlugin.ID_PLUGIN, 0, "", null); //$NON-NLS-1$
-				if (productViewer.getSelection().isEmpty()) {
-					status = new Status(IStatus.ERROR, BugzillaUiPlugin.ID_PLUGIN, 0,
-							Messages.BugzillaProductPage_YOU_MUST_SELECT_PRODUCT, null);
-				}
-
-				// Show the most serious error
-				applyToStatusLine(status);
-				isPageComplete();
-				getWizard().getContainer().updateButtons();
-			}
-
-		});
-
-		// HACK: waiting on delayed refresh of filtered tree
-		final String[] selectedProducts = getSelectedProducts();
-		if (selectedProducts.length > 0) {
-			new UIJob("") { //$NON-NLS-1$
-				@Override
-				public IStatus runInUIThread(IProgressMonitor monitor) {
-					if (BugzillaProductPage.this.getControl() != null
-							&& BugzillaProductPage.this.getControl().isDisposed()) {
-						return Status.OK_STATUS;
-					}
-					productViewer.setSelection(new StructuredSelection(selectedProducts), true);
-					productViewer.getControl().setFocus();
-					return Status.OK_STATUS;
-				}
-			}.schedule(300L);
-		} else {
-			productList.setFocus();
-		}
-
-		Button updateButton = new Button(composite, SWT.LEFT | SWT.PUSH);
-		updateButton.setText(LABEL_UPDATE);
-		updateButton.setLayoutData(new GridData());
-
-		updateButton.addSelectionListener(new SelectionAdapter() {
-
-			@Override
-			public void widgetSelected(SelectionEvent e) {
-				updateProdcts();
-				productViewer.setInput(products);
-			}
-		});
-
-		Dialog.applyDialogFont(composite);
-		// set the composite as the control for this page
-		setControl(composite);
-
-		isPageComplete();
-		getWizard().getContainer().updateButtons();
-	}
-
-	private void initProducts() {
-		// try to get the list of products from the server
-		try {
-			products = BugzillaCorePlugin.getRepositoryConfiguration(repository, false, new NullProgressMonitor())
-					.getProducts();
-
-			if (products.isEmpty()) {
-				updateProdcts();
-			}
-
-		} catch (final CoreException e) {
-			PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {
-				public void run() {
-					MessageDialog.openError(Display.getDefault().getActiveShell(), NEW_BUGZILLA_TASK_ERROR_TITLE,
-							Messages.BugzillaProductPage_Unable_to_get_products);
-				}
-			});
-		}
-	}
-
-	private String[] getSelectedProducts() {
-		IStructuredSelection selection = getSelection();
-		if (selection == null) {
-			return new String[0];
-		}
-
-		ArrayList<String> products = new ArrayList<String>();
-
-		Object element = selection.getFirstElement();
-		if (element instanceof ITask) {
-			ITask bugzillaTask = (ITask) element;
-			if (bugzillaTask.getAttribute(BugzillaAttribute.PRODUCT.getKey()) != null) {
-				products.add(bugzillaTask.getAttribute(BugzillaAttribute.PRODUCT.getKey()));
-			}
-		} else {
-			IRepositoryQuery query = null;
-			if (element instanceof IRepositoryQuery) {
-				query = (IRepositoryQuery) element;
-			}
-
-			if (query != null && query.getConnectorKind().equals(BugzillaCorePlugin.CONNECTOR_KIND)) {
-				String queryUrl = query.getUrl();
-				queryUrl = queryUrl.substring(queryUrl.indexOf("?") + 1); //$NON-NLS-1$
-				String[] options = queryUrl.split("&"); //$NON-NLS-1$
-
-				for (String option : options) {
-					int index = option.indexOf("="); //$NON-NLS-1$
-					if (index != -1) {
-						String key = option.substring(0, index);
-						if ("product".equals(key)) { //$NON-NLS-1$
-							try {
-								products.add(URLDecoder.decode(option.substring(index + 1),
-										repository.getCharacterEncoding()));
-								// TODO: list box only accepts a single selection so
-								// we break on first found
-								break;
-							} catch (UnsupportedEncodingException ex) {
-								// ignore
-							}
-						}
-					}
-				}
-			} else {
-				if (element instanceof IAdaptable) {
-					IAdaptable adaptable = (IAdaptable) element;
-					ITask task = (ITask) adaptable.getAdapter(ITask.class);
-					if (task != null) {
-						ITask bugzillaTask = (ITask) element;
-						if (bugzillaTask.getAttribute(BugzillaAttribute.PRODUCT.getKey()) != null) {
-							products.add(bugzillaTask.getAttribute(BugzillaAttribute.PRODUCT.getKey()));
-						}
-					}
-				}
-			}
-		}
-
-		return products.toArray(new String[products.size()]);
-	}
-
-	private IStructuredSelection getSelection() {
-		IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
-		ISelection selection = window.getSelectionService().getSelection();
-		if (selection instanceof IStructuredSelection) {
-			return (IStructuredSelection) selection;
-		}
-		return null;
-	}
-
-	/**
-	 * Applies the status to the status line of a dialog page.
-	 * 
-	 * @param status
-	 *            The status to apply to the status line
-	 */
-	protected void applyToStatusLine(IStatus status) {
-		String message = status.getMessage();
-		if (message.length() == 0) {
-			message = null;
-		}
-		switch (status.getSeverity()) {
-		case IStatus.OK:
-			setErrorMessage(null);
-			setMessage(message);
-			break;
-		case IStatus.WARNING:
-			setErrorMessage(null);
-			setMessage(message, IMessageProvider.WARNING);
-			break;
-		case IStatus.INFO:
-			setErrorMessage(null);
-			setMessage(message, IMessageProvider.INFORMATION);
-			break;
-		default:
-			setErrorMessage(null);
-			setMessage(message, IMessageProvider.ERROR);
-			break;
-		}
-	}
-
-//	/**
-//	 * Save the currently selected product to the taskData when next is clicked
-//	 */
-//	public void saveDataToModel() throws CoreException {
-//		RepositoryTaskData model = bugWizard.taskData;
-//		model.setAttributeValue(BugzillaReportElement.PRODUCT.getKey(), getSelectedProduct());
-//		AbstractLegacyRepositoryConnector connector = (AbstractLegacyRepositoryConnector) TasksUi.getRepositoryManager()
-//				.getRepositoryConnector(repository.getConnectorKind());
-//		if (connector == null) {
-//			throw new CoreException(new Status(IStatus.ERROR, BugzillaUiPlugin.PLUGIN_ID,
-//					"Error AbstractRepositoryConnector could not been retrieved.\n\n"));
-//		}
-//		AbstractTaskDataHandler taskDataHandler = connector.getLegacyTaskDataHandler();
-//		if (taskDataHandler == null) {
-//			throw new CoreException(new Status(IStatus.ERROR, BugzillaUiPlugin.PLUGIN_ID,
-//					"Error AbstractTaskDataHandler could not been retrieved.\n\n"));
-//		}
-//		taskDataHandler.initializeTaskData(repository, model, null);
-//
-//		// platform/os are now set to All/All
-//		BugzillaCorePlugin.getDefault().setPlatformDefaultsOrGuess(repository, model);
-//	}
-
-	public String getSelectedProduct() {
-		return (String) ((IStructuredSelection) productList.getViewer().getSelection()).getFirstElement();
-	}
-
-	@Override
-	public boolean isPageComplete() {
-		return !productList.getViewer().getSelection().isEmpty();
-//		return bugWizard.completed;
-	}
-
-	private void updateProdcts() {
-		final AbstractRepositoryConnector connector = TasksUi.getRepositoryManager().getRepositoryConnector(
-				repository.getConnectorKind());
-		try {
-			getContainer().run(true, true, new IRunnableWithProgress() {
-				public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
-					monitor.beginTask(Messages.BugzillaProductPage_Updating_repository_report_options_,
-							IProgressMonitor.UNKNOWN);
-					try {
-						connector.updateRepositoryConfiguration(repository, monitor);
-					} catch (CoreException e) {
-						// TODO: remove exceptions from communication of connectivity errors to the user
-						if (e.getStatus().getException() instanceof GeneralSecurityException) {
-							StatusHandler.fail(new Status(IStatus.WARNING, BugzillaUiPlugin.ID_PLUGIN,
-									"Bugzilla could not log you in to get the information you requested since login name or password is incorrect.\n" //$NON-NLS-1$
-											+ "Please ensure your task repository is properly configured.", e)); //$NON-NLS-1$
-						} else if (e.getStatus().getException() instanceof IOException) {
-							StatusHandler.fail(new Status(IStatus.WARNING, BugzillaUiPlugin.ID_PLUGIN,
-									"Connection Error, please ensure your task repository is properly configured.", e)); //$NON-NLS-1$
-						} else {
-							StatusHandler.fail(new Status(IStatus.WARNING, BugzillaUiPlugin.ID_PLUGIN,
-									"Error updating repository attributes for " + repository.getRepositoryUrl(), e)); //$NON-NLS-1$
-						}
-						return;
-					}
-
-					RepositoryConfiguration repositoryConfiguration = null;
-					try {
-						repositoryConfiguration = BugzillaCorePlugin.getRepositoryConfiguration(repository, false,
-								monitor);
-					} catch (final CoreException e) {
-						PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {
-							public void run() {
-								MessageDialog.openError(Display.getDefault().getActiveShell(),
-										Messages.BugzillaProductPage_Bugzilla_Search_Page,
-										Messages.BugzillaProductPage_Unable_to_get_configuration);
-							}
-						});
-					}
-					products = new ArrayList<String>();
-					if (repositoryConfiguration != null) {
-						for (String product : repositoryConfiguration.getProducts()) {
-							products.add(product);
-						}
-					}
-				}
-			});
-
-		} catch (InvocationTargetException ex) {
-			MessageDialog.openError(null, Messages.BugzillaProductPage_Error_updating_product_list,
-					Messages.BugzillaProductPage_Error_reported + ex.getCause().getMessage());
-		} catch (InterruptedException ex) {
-			// canceled
-		}
-	}
-
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/BugzillaQueryHit.java b/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/BugzillaQueryHit.java
deleted file mode 100644
index fa123b7..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/BugzillaQueryHit.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004 - 2006 University Of British Columbia and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     University Of British Columbia - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.mylyn.internal.bugzilla.core;
-
-import org.eclipse.mylyn.tasks.core.AbstractQueryHit;
-import org.eclipse.mylyn.tasks.core.AbstractTask;
-import org.eclipse.mylyn.tasks.core.TaskList;
-
-/**
- * @author Ken Sueda
- * @author Mik Kersten (hardening of prototype)
- */
-public class BugzillaQueryHit extends AbstractQueryHit {
-
-	private String status;
-
-	public BugzillaQueryHit(TaskList taskList, String description, String priority, String repositoryUrl, String id,
-			BugzillaTask task, String status) {
-		super(taskList, repositoryUrl, description, id);
-		super.priority = priority;
-		this.task = task;
-		this.status = status;
-	}
-
-	@Override
-	protected AbstractTask createTask() {		
-		return new BugzillaTask(this, true);
-	}
-
-	@Override
-	public String getUrl() {
-		return BugzillaClient.getBugUrlWithoutLogin(repositoryUrl, taskId);
-	}
-
-	@Override
-	public boolean isCompleted() {
-		if (status != null
-				&& (status.startsWith("RESO") || status.startsWith("CLO") || status.startsWith("VERI") || status
-						.startsWith("FIXED"))) {
-			return true;
-		}
-		return false;
-	}
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/BugzillaQueryPageParser.java b/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/BugzillaQueryPageParser.java
deleted file mode 100644
index 81e91fc..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/BugzillaQueryPageParser.java
+++ /dev/null
@@ -1,540 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2003 - 2006 University Of British Columbia and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     University Of British Columbia - initial API and implementation
- *******************************************************************************/
-package org.eclipse.mylyn.internal.bugzilla.core.search;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.Reader;
-import java.io.UnsupportedEncodingException;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.net.URLConnection;
-import java.net.URLEncoder;
-import java.text.ParseException;
-import java.util.ArrayList;
-
-import javax.security.auth.login.LoginException;
-
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.Status;
-import org.eclipse.jface.dialogs.ErrorDialog;
-import org.eclipse.jface.dialogs.MessageDialog;
-import org.eclipse.mylyn.internal.bugzilla.core.BugzillaPlugin;
-import org.eclipse.mylyn.internal.bugzilla.core.IBugzillaConstants;
-import org.eclipse.mylyn.internal.bugzilla.core.internal.HtmlStreamTokenizer;
-import org.eclipse.mylyn.internal.bugzilla.core.internal.HtmlTag;
-import org.eclipse.mylyn.internal.bugzilla.core.internal.HtmlStreamTokenizer.Token;
-import org.eclipse.mylyn.provisional.tasklist.TaskRepository;
-
-/**
- * Class to parse the update data from the server
- * 
- * author: kvesik
- * 
- * created on: Feb 25, 2003
- * 
- */
-public class BugzillaQueryPageParser {
-	
-	private static final String POST_ARGS_PASSWORD = "&Bugzilla_password=";
-
-	private static final String POST_ARGS_LOGIN_FIRST = "&GoAheadAndLogIn=1&Bugzilla_login=";
-
-	/** The name of the bugzilla server */
-	private String urlString;
-
-	/** The input stream */
-	private BufferedReader in = null;
-
-	/** True if the operation was successful */
-	private boolean successful;
-
-	/** Exception to be displayed if there was an error */
-	private Exception exception;
-
-	/** The progress monitor for the update */
-	private IProgressMonitor monitor;
-
-	/** Selection lists as ArrayLists */
-	private ArrayList<String> statusValues = new ArrayList<String>();
-
-	private ArrayList<String> preselectedStatusValues = new ArrayList<String>();
-
-	private ArrayList<String> resolutionValues = new ArrayList<String>();
-
-	private ArrayList<String> severityValues = new ArrayList<String>();
-
-	private ArrayList<String> priorityValues = new ArrayList<String>();
-
-	private ArrayList<String> hardwareValues = new ArrayList<String>();
-
-	private ArrayList<String> osValues = new ArrayList<String>();
-
-	private ArrayList<String> productValues = new ArrayList<String>();
-
-	private ArrayList<String> componentValues = new ArrayList<String>();
-
-	private ArrayList<String> versionValues = new ArrayList<String>();
-
-	private ArrayList<String> targetValues = new ArrayList<String>();
-
-	public BugzillaQueryPageParser(TaskRepository repository, IProgressMonitor monitor) throws LoginException, IOException {
-		this.monitor = monitor;
-
-		// get the servers url
-		urlString = repository.getUrl() + "/query.cgi";
-
-		// if we are dealing with 2.18 or higher we need to use the folowing in the
-		// query string to get the right search page
-		// UPDATE: There doesn't appear to be any harm in appending this to 2.18, 2.20, 2.20.1 and without it we
-		// don't get the advanced view so 2.20 and 2.20.1 break
-		//if (repository.getVersion().equals(BugzillaServerVersion.SERVER_218.toString())) {
-			urlString += "?format=advanced";
-		//}
-
-		// use the user name and password if we have it
-		if (repository.hasCredentials()) {
-			try {
-				// if we are dealing with 2.18 we already have the ? from before
-				// so we need
-				// an & instead. If other version, still add ?
-				// if (repository.getVersion().equals(BugzillaServerVersion.SERVER_218.toString()))
-				//	urlString += "&";
-				// else
-				// urlString += "?";
-
-				urlString += POST_ARGS_LOGIN_FIRST
-						+ URLEncoder.encode(repository.getUserName(), BugzillaPlugin.ENCODING_UTF_8)
-						+ POST_ARGS_PASSWORD
-						+ URLEncoder.encode(repository.getPassword(), BugzillaPlugin.ENCODING_UTF_8);
-			} catch (UnsupportedEncodingException e) {
-				/*
-				 * Do nothing. Every implementation of the Java platform is
-				 * required to support the standard charset
-				 * BugzillaPlugin.ENCODING_UTF_8
-				 */
-			}
-		}
-
-		successful = false;
-
-		// try to get the new options from the page
-		parseDocument();
-		if (!successful) {
-			if (exception instanceof MalformedURLException) {
-				MessageDialog
-						.openError(
-								null,
-								"Unsupported Protocol",
-								"The server that was specified for Bugzilla is not supported by your JVM.\nPlease make sure that you are using a JDK that supports SSL.");
-			} else {
-//				throw exception
-				// if there was a problem with the operation, display an error
-				// message
-				ErrorDialog.openError(null, IBugzillaConstants.TITLE_MESSAGE_DIALOG, "Bugzilla could not complete the the update.",
-						new Status(IStatus.ERROR, IBugzillaConstants.PLUGIN_ID, IStatus.OK, "url may be invalid",
-								exception));
-			}
-		}
-	}
-
-	/**
-	 * Get whether the update was successful
-	 * 
-	 * @return <code>true</code> if the update was successful
-	 */
-	public boolean wasSuccessful() {
-		return successful;
-	}
-
-	/**
-	 * Parse the data from the server for the query options
-	 * @throws IOException 
-	 */
-	private void parseDocument() throws LoginException, IOException {
-		try {
-			// if the operation has been cancelled already, return
-			if (monitor.isCanceled()) {
-				monitor.done();
-				return;
-			}
-
-			// try to connect to the server
-			monitor.subTask("Connecting to server");
-
-			URL url = new URL(this.urlString);
-			URLConnection cntx = BugzillaPlugin.getDefault().getUrlConnection(url);
-
-			if (cntx != null) {
-				InputStream input = cntx.getInputStream();
-				if (input != null) {
-
-					monitor.worked(1);
-
-					// initialize the input stream
-					in = new BufferedReader(new InputStreamReader(input));
-
-					// increment the position of the status monitor
-					monitor.worked(2);
-
-					// check if the operation has been cancelled so we can end
-					// if it has been
-					if (monitor.isCanceled())
-						monitor.done();
-					else
-						monitor.subTask("Reading values from server");
-
-					// parse the data from the server
-					parseQueryPage(in);
-
-					// set the operation to being successful
-					successful = true;
-				}
-			}
-
-		} catch (LoginException e) {
-			throw e;
-		} catch (IOException e) {
-			throw e;
-		} catch (Exception e) {
-			// if we can't connect, log the problem and save the exception to
-			// handle later
-			monitor.done();
-			exception = e;
-			BugzillaPlugin.log(new Status(IStatus.ERROR, IBugzillaConstants.PLUGIN_ID, IStatus.OK,
-					"Failed to create URL and open input stream: " + urlString, e));
-			return;
-		} finally {
-			try {
-				if (in != null)
-					in.close();
-			} catch (IOException exitAnyway) {
-				in = null;
-			}
-		}
-	}
-
-	/**
-	 * Check if all of the lists of options are empty
-	 * 
-	 * @return true if all of the options lists are empty
-	 */
-	private boolean allListsEmpty() {
-		return statusValues.isEmpty() && preselectedStatusValues.isEmpty() && resolutionValues.isEmpty()
-				&& severityValues.isEmpty() && priorityValues.isEmpty() && hardwareValues.isEmpty()
-				&& osValues.isEmpty() && productValues.isEmpty() && componentValues.isEmpty()
-				&& versionValues.isEmpty() && targetValues.isEmpty();
-	}
-
-	/**
-	 * Get the new status values
-	 * 
-	 * @return An array of the new status values
-	 */
-	public String[] getStatusValues() {
-		String[] array = new String[statusValues.size()];
-
-		// create the array and return it
-		for (int i = 0; i < statusValues.size(); i++)
-			array[i] = statusValues.get(i);
-		return array;
-	}
-
-	/**
-	 * Get the new preselected status values
-	 * 
-	 * @return An array of the new preselected status values
-	 */
-	public String[] getPreselectedStatusValues() {
-		String[] array = new String[preselectedStatusValues.size()];
-
-		// create the array and return it
-		for (int i = 0; i < preselectedStatusValues.size(); i++)
-			array[i] = preselectedStatusValues.get(i);
-		return array;
-	}
-
-	/**
-	 * Get the new resolution values
-	 * 
-	 * @return An array of the new resolution values
-	 */
-	public String[] getResolutionValues() {
-		String[] array = new String[resolutionValues.size()];
-
-		// create the array and return it
-		for (int i = 0; i < resolutionValues.size(); i++)
-			array[i] = resolutionValues.get(i);
-		return array;
-	}
-
-	/**
-	 * Get the new severity values
-	 * 
-	 * @return An array of the new severity values
-	 */
-	public String[] getSeverityValues() {
-		String[] array = new String[severityValues.size()];
-
-		// create the array and return it
-		for (int i = 0; i < severityValues.size(); i++)
-			array[i] = severityValues.get(i);
-		return array;
-	}
-
-	/**
-	 * Get the new priority values
-	 * 
-	 * @return An array of the new priority values
-	 */
-	public String[] getPriorityValues() {
-		String[] array = new String[priorityValues.size()];
-
-		// create the array and return it
-		for (int i = 0; i < priorityValues.size(); i++)
-			array[i] = priorityValues.get(i);
-		return array;
-	}
-
-	/**
-	 * Get the new hardware values
-	 * 
-	 * @return An array of the new hardware values
-	 */
-	public String[] getHardwareValues() {
-		String[] array = new String[hardwareValues.size()];
-
-		// create the array and return it
-		for (int i = 0; i < hardwareValues.size(); i++)
-			array[i] = hardwareValues.get(i);
-		return array;
-	}
-
-	/**
-	 * Get the new OS values
-	 * 
-	 * @return An array of the new OS values
-	 */
-	public String[] getOSValues() {
-		String[] array = new String[osValues.size()];
-
-		// create the array and return it
-		for (int i = 0; i < osValues.size(); i++)
-			array[i] = osValues.get(i);
-		return array;
-	}
-
-	/**
-	 * Get the new product values
-	 * 
-	 * @return An array of the new product values
-	 */
-	public String[] getProductValues() {
-		String[] array = new String[productValues.size()];
-
-		// create the array and return it
-		for (int i = 0; i < productValues.size(); i++)
-			array[i] = productValues.get(i);
-		return array;
-	}
-
-	/**
-	 * Get the new component values
-	 * 
-	 * @return An array of the new component values
-	 */
-	public String[] getComponentValues() {
-		String[] array = new String[componentValues.size()];
-
-		// create the array and return it
-		for (int i = 0; i < componentValues.size(); i++)
-			array[i] = componentValues.get(i);
-		return array;
-	}
-
-	/**
-	 * Get the new version values
-	 * 
-	 * @return An array of the new version values
-	 */
-	public String[] getVersionValues() {
-		String[] array = new String[versionValues.size()];
-
-		// create the array and return it
-		for (int i = 0; i < versionValues.size(); i++)
-			array[i] = versionValues.get(i);
-		return array;
-	}
-
-	/**
-	 * Get the new milestone values
-	 * 
-	 * @return An array of the new milestone values
-	 */
-	public String[] getTargetValues() {
-		String[] array = new String[targetValues.size()];
-
-		// create the array and return it
-		for (int i = 0; i < targetValues.size(); i++)
-			array[i] = targetValues.get(i);
-		return array;
-	}
-
-	/**
-	 * Parse the bugzilla query.cgi page for some seach options
-	 * 
-	 * @param inputReader
-	 *            The input stream for the page
-	 * @throws LoginException
-	 * @throws ParseException
-	 * @throws IOException
-	 */
-	private void parseQueryPage(Reader inputReader) throws LoginException, ParseException, IOException {
-		HtmlStreamTokenizer tokenizer = new HtmlStreamTokenizer(inputReader, null);
-
-		boolean isTitle = false;
-		boolean possibleBadLogin = false;
-		String title = "";
-
-		for (HtmlStreamTokenizer.Token token = tokenizer.nextToken(); token.getType() != Token.EOF; token = tokenizer
-				.nextToken()) {
-
-			// make sure that bugzilla doesn't want us to login
-			if (token.getType() == Token.TAG && ((HtmlTag) (token.getValue())).getTagType() == HtmlTag.Type.TITLE
-					&& !((HtmlTag) (token.getValue())).isEndTag()) {
-				isTitle = true;
-				continue;
-			}
-
-			if (isTitle) {
-				// get all of the data in the title tag to compare with
-				if (token.getType() != Token.TAG) {
-					title += ((StringBuffer) token.getValue()).toString().toLowerCase() + " ";
-					continue;
-				} else if (token.getType() == Token.TAG
-						&& ((HtmlTag) token.getValue()).getTagType() == HtmlTag.Type.TITLE
-						&& ((HtmlTag) token.getValue()).isEndTag()) {
-					// check if the title looks like we may have a problem with
-					// login
-					if ((title.indexOf("login") != -1
-							|| (title.indexOf("invalid") != -1 && title.indexOf("password") != -1)
-							|| title.indexOf("check e-mail") != -1 || title.indexOf("error") != -1))
-						possibleBadLogin = true;
-					isTitle = false;
-					title = "";
-				}
-				continue;
-			}
-
-			// we have found the start of attribute values
-			if (token.getType() == Token.TAG) {
-				HtmlTag tag = (HtmlTag) token.getValue();
-				if (tag.getTagType() == HtmlTag.Type.TD && "left".equalsIgnoreCase(tag.getAttribute("align"))) {
-					// parse the attribute values
-					parseAttributeValue(tokenizer);
-					continue;
-				}
-			}
-		}
-
-		// if all of the lists are empty and we suspect bad login info, assume
-		// that it was a bad login
-		if (possibleBadLogin && allListsEmpty())
-			throw new LoginException(IBugzillaConstants.MESSAGE_LOGIN_FAILURE);
-	}
-
-	/**
-	 * Parse the case where the attribute value is an option
-	 * 
-	 * @param parameterName
-	 *            The name of the attribute value
-	 * @param tokenizer
-	 *            The tokenizer to get data from the stream
-	 * @throws IOException
-	 * @throws ParseException
-	 */
-	private void parseSelect(String parameterName, HtmlStreamTokenizer tokenizer) throws IOException, ParseException {
-
-		HtmlStreamTokenizer.Token token = tokenizer.nextToken();
-		while (token.getType() != Token.EOF) {
-			if (token.getType() == Token.TAG) {
-				HtmlTag tag = (HtmlTag) token.getValue();
-				if (tag.getTagType() == HtmlTag.Type.SELECT && tag.isEndTag())
-					break;
-				if (tag.getTagType() == HtmlTag.Type.OPTION && !tag.isEndTag()) {
-					String optionName = tag.getAttribute("value");
-					boolean selected = tag.hasAttribute("selected");
-					StringBuffer optionText = new StringBuffer();
-					for (token = tokenizer.nextToken(); token.getType() == Token.TEXT; token = tokenizer.nextToken()) {
-						if (optionText.length() > 0) {
-							optionText.append(' ');
-						}
-						optionText.append((StringBuffer) token.getValue());
-					}
-					// add the value to the appropriate list of attributes
-					if (parameterName.equals("bug_status")) {
-						statusValues.add(optionName);
-
-						// check if the status is to be preselected or not
-						if (selected)
-							preselectedStatusValues.add(optionName);
-					} else if (parameterName.equals("resolution"))
-						resolutionValues.add(optionName);
-					else if (parameterName.equals("bug_severity"))
-						severityValues.add(optionName);
-					else if (parameterName.equals("priority"))
-						priorityValues.add(optionName);
-					else if (parameterName.equals("rep_platform"))
-						hardwareValues.add(optionName);
-					else if (parameterName.equals("op_sys"))
-						osValues.add(optionName);
-					else if (parameterName.equals("product"))
-						productValues.add(optionName);
-					else if (parameterName.equals("component"))
-						componentValues.add(optionName);
-					else if (parameterName.equals("version"))
-						versionValues.add(optionName);
-					else if (parameterName.equals("target_milestone"))
-						targetValues.add(optionName);
-				} else {
-					token = tokenizer.nextToken();
-				}
-			} else {
-				token = tokenizer.nextToken();
-			}
-		}
-	}
-
-	/**
-	 * Parse the case where we think we found an attribute value
-	 * 
-	 * @param tokenizer
-	 *            The tokenizer to get the data from the stream
-	 * @throws IOException
-	 * @throws ParseException
-	 */
-	private void parseAttributeValue(HtmlStreamTokenizer tokenizer) throws IOException, ParseException {
-
-		HtmlStreamTokenizer.Token token = tokenizer.nextToken();
-		if (token.getType() == Token.TAG) {
-			HtmlTag tag = (HtmlTag) token.getValue();
-			if (tag.getTagType() == HtmlTag.Type.SELECT && !tag.isEndTag()) {
-				String parameterName = tag.getAttribute("name");
-				parseSelect(parameterName, tokenizer);
-			} else if (tag.getTagType() == HtmlTag.Type.LABEL && !tag.isEndTag()) {
-				parseAttributeValue(tokenizer);
-			}
-		}
-	}
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/BugzillaReportSubmitForm.java b/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/BugzillaReportSubmitForm.java
deleted file mode 100644
index 604027d..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/BugzillaReportSubmitForm.java
+++ /dev/null
@@ -1,738 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2003 - 2006 University Of British Columbia and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     University Of British Columbia - initial API and implementation
- *******************************************************************************/
-package org.eclipse.mylyn.internal.bugzilla.core;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.StringReader;
-import java.io.UnsupportedEncodingException;
-import java.security.GeneralSecurityException;
-import java.text.ParseException;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.commons.httpclient.NameValuePair;
-import org.apache.commons.httpclient.methods.PostMethod;
-import org.eclipse.mylyn.internal.tasks.core.HtmlStreamTokenizer;
-import org.eclipse.mylyn.internal.tasks.core.HtmlTag;
-import org.eclipse.mylyn.internal.tasks.core.HtmlStreamTokenizer.Token;
-import org.eclipse.mylyn.tasks.core.RepositoryOperation;
-import org.eclipse.mylyn.tasks.core.RepositoryTaskAttribute;
-import org.eclipse.mylyn.tasks.core.RepositoryTaskData;
-
-/**
- * 
- * @author Shawn Minto
- * @author Mik Kersten (hardening of prototype)
- * @author Rob Elves
- * 
- * Class to handle the positing of a bug
- */
-public class BugzillaReportSubmitForm {
-
-	private static final String KEY_ID = "id";
-
-	private static final String VAL_TRUE = "true";
-
-	private static final String KEY_REMOVECC = "removecc";
-
-	private static final String KEY_CC = "cc";
-
-	// private static final String POST_CONTENT_TYPE =
-	// "application/x-www-form-urlencoded";
-	//
-	// private static final String REQUEST_PROPERTY_CONTENT_TYPE =
-	// "Content-Type";
-	//
-	// private static final String REQUEST_PROPERTY_CONTENT_LENGTH =
-	// "Content-Length";
-	//
-	// private static final String METHOD_POST = "POST";
-	//
-	// private static final String KEY_BUGZILLA_PASSWORD = "Bugzilla_password";
-	//
-	// private static final String KEY_BUGZILLA_LOGIN = "Bugzilla_login";
-	// private URL postUrl;
-	// private Proxy proxySettings = Proxy.NO_PROXY;
-	// private String charset;
-
-	private static final String POST_BUG_CGI = "/post_bug.cgi";
-
-	private static final String PROCESS_BUG_CGI = "/process_bug.cgi";
-
-	public static final int WRAP_LENGTH = 90;
-
-	private static final String VAL_PROCESS_BUG = "process_bug";
-
-	private static final String KEY_FORM_NAME = "form_name";
-
-	private static final String VAL_NONE = "none";
-
-	private static final String KEY_KNOB = "knob";
-
-	// TODO change to BugzillaReportElement.ADD_COMMENT
-	private static final String KEY_COMMENT = "comment";
-
-	private static final String KEY_SHORT_DESC = "short_desc";
-
-	public static final String FORM_POSTFIX_218 = IBugzillaConstants.FORM_POSTFIX_218;
-
-	public static final String FORM_POSTFIX_216 = IBugzillaConstants.FORM_POSTFIX_216;
-
-	public static final String FORM_PREFIX_BUG_218 = IBugzillaConstants.FORM_PREFIX_BUG_218;
-
-	public static final String FORM_PREFIX_BUG_220 = IBugzillaConstants.FORM_PREFIX_BUG_220;
-
-	/** The fields that are to be changed/maintained */
-	// private List<NameValuePair> fields = new ArrayList<NameValuePair>();
-	private Map<String, NameValuePair> fields = new HashMap<String, NameValuePair>();
-
-	/** The prefix for how to find the bug number from the return */
-	private String prefix;
-
-	private String prefix2;
-
-	/** The postfix for how to find the bug number from the return */
-	private String postfix;
-
-	/** An alternate postfix for how to find the bug number from the return */
-	private String postfix2;
-
-	private String error = null;
-
-	private RepositoryTaskData taskData = null;
-
-	public boolean isNewBugPost = false;
-
-	public BugzillaReportSubmitForm() {
-		// charset = charEncoding;
-	}
-
-	public static BugzillaReportSubmitForm makeNewBugPost(String repositoryUrl, String userName, String password,
-			String characterEncoding, RepositoryTaskData model, boolean wrapDescription)
-			throws UnsupportedEncodingException {
-
-		BugzillaReportSubmitForm form = new BugzillaReportSubmitForm();
-
-		// if (characterEncoding != null) {
-		// form = new BugzillaReportSubmitForm(characterEncoding);
-		// } else {
-		// form = new
-		// BugzillaReportSubmitForm(IBugzillaConstants.ENCODING_UTF_8);
-		// }
-
-		form.setTaskData(model);
-
-		form.setPrefix(IBugzillaConstants.FORM_PREFIX_BUG_218);
-		form.setPrefix2(IBugzillaConstants.FORM_PREFIX_BUG_220);
-
-		form.setPostfix(IBugzillaConstants.FORM_POSTFIX_216);
-		form.setPostfix2(IBugzillaConstants.FORM_POSTFIX_218);
-
-		// setConnectionsSettings(form, repositoryUrl, userName, password,
-		// proxySettings, POST_BUG_CGI);
-
-		// go through all of the attributes and add them to
-		// the bug post
-		Iterator<RepositoryTaskAttribute> itr = model.getAttributes().iterator();
-		while (itr.hasNext()) {
-			RepositoryTaskAttribute a = itr.next();
-			if (a != null && a.getID() != null && a.getID().compareTo("") != 0) {
-				String value = null;
-				value = a.getValue();
-				if (value == null)
-					continue;
-				form.add(a.getID(), value);
-			}
-		}
-
-		// form.add(KEY_BUG_FILE_LOC, "");
-
-		// specify the product
-		form.add(BugzillaReportElement.PRODUCT.getKeyString(), model.getProduct());
-
-		// add the summary to the bug post
-		form.add(BugzillaReportElement.SHORT_DESC.getKeyString(), model.getSummary());
-
-		String formattedDescription = formatTextToLineWrap(model.getDescription(), wrapDescription);
-		model.setDescription(formattedDescription);
-
-		if (model.getDescription().length() != 0) {
-			// add the new comment to the bug post if there
-			// is some text in
-			// it
-			form.add(KEY_COMMENT, model.getDescription());
-		}
-
-		form.setNewBugPost(true);
-
-		return form;
-	}
-
-	/**
-	 * TODO: refactor common stuff with new bug post
-	 * 
-	 * @param characterEncoding
-	 *            TODO
-	 * 
-	 * @throws UnsupportedEncodingException
-	 */
-	public static BugzillaReportSubmitForm makeExistingBugPost(RepositoryTaskData model, String repositoryUrl,
-			String userName, String password, String characterEncoding) throws UnsupportedEncodingException {
-
-		BugzillaReportSubmitForm form = new BugzillaReportSubmitForm();
-
-		// if (characterEncoding != null) {
-		// form = new BugzillaReportSubmitForm(characterEncoding);
-		// } else {
-		// form = new
-		// BugzillaReportSubmitForm(IBugzillaConstants.ENCODING_UTF_8);
-		// }
-
-		form.setTaskData(model);
-
-		// setDefaultCCValue(bug, userName);
-		// setConnectionsSettings(form, repositoryUrl, userName, password,
-		// proxySettings, PROCESS_BUG_CGI);
-
-		// go through all of the attributes and add them to the bug post
-		for (Iterator<RepositoryTaskAttribute> it = model.getAttributes().iterator(); it.hasNext();) {
-			RepositoryTaskAttribute a = it.next();
-			if (a.getID().equals(BugzillaReportElement.CC.getKeyString())
-					|| a.getID().equals(RepositoryTaskAttribute.REMOVE_CC)
-					|| a.getID().equals(BugzillaReportElement.REPORTER.getKeyString())
-					|| a.getID().equals(BugzillaReportElement.ASSIGNED_TO.getKeyString())
-					|| a.getID().equals(BugzillaReportElement.CREATION_TS.getKeyString())) {
-				continue;
-			}
-			if (a != null && a.getID() != null && a.getID().compareTo("") != 0 && !a.isHidden()) {
-				String value = a.getValue();
-				// add the attribute to the bug post
-				form.add(a.getID(), value != null ? value : "");
-			} else if (a != null && a.getID() != null && a.getID().compareTo("") != 0 && a.isHidden()) {
-				// we have a hidden attribute and we should send it back.
-				String value = a.getValue();
-
-				// Strip off timezone information
-				// 149513: Constant bugzilla mid-air collisions
-				if (a.getID().equals(BugzillaReportElement.DELTA_TS.getKeyString()) && value != null) {
-					value = stripTimeZone(value);
-				}
-				form.add(a.getID(), value);
-			}
-		}
-
-		// when posting the bug id is encoded in a hidden field named 'id'
-		form.add(KEY_ID, model.getAttributeValue(BugzillaReportElement.BUG_ID.getKeyString()));
-
-		// add the operation to the bug post
-		RepositoryOperation o = model.getSelectedOperation();
-		if (o == null)
-			form.add(KEY_KNOB, VAL_NONE);
-		else {
-			form.add(KEY_KNOB, o.getKnobName());
-			if (o.hasOptions()) {
-				String sel = o.getOptionValue(o.getOptionSelection());
-				form.add(o.getOptionName(), sel);
-			} else if (o.isInput()) {
-				String sel = o.getInputValue();
-				form.add(o.getInputName(), sel);
-			}
-		}
-		form.add(KEY_FORM_NAME, VAL_PROCESS_BUG);
-
-		if (model.getAttribute(BugzillaReportElement.SHORT_DESC.getKeyString()) != null) {
-			form.add(KEY_SHORT_DESC, model.getAttribute(BugzillaReportElement.SHORT_DESC.getKeyString()).getValue());
-		}
-
-		if (model.getNewComment().length() != 0) {
-			form.add(KEY_COMMENT, model.getNewComment());
-		}
-
-		List<String> removeCC = model.getAttributeValues(RepositoryTaskAttribute.REMOVE_CC);
-		if (removeCC != null && removeCC.size() > 0) {
-			String[] s = new String[removeCC.size()];
-			form.add(KEY_CC, toCommaSeparatedList(removeCC.toArray(s)));
-			form.add(KEY_REMOVECC, VAL_TRUE);
-		}
-
-		return form;
-	}
-
-	public static String stripTimeZone(String longTime) {
-		String result = longTime;
-		if (longTime != null) {
-			String[] values = longTime.split(" ");
-			if (values != null && values.length > 2) {
-				result = values[0] + " " + values[1];
-			}
-		}
-		return result;
-	}
-
-	private static String toCommaSeparatedList(String[] strings) {
-		StringBuffer buffer = new StringBuffer();
-		for (int i = 0; i < strings.length; i++) {
-			buffer.append(strings[i]);
-			if (i != strings.length - 1) {
-				buffer.append(",");
-			}
-		}
-		return buffer.toString();
-	}
-
-	/**
-	 * Add a value to be posted to the bug
-	 * 
-	 * @param key
-	 *            The key for the value to be added
-	 * @param value
-	 *            The value to be added
-	 * @throws UnsupportedEncodingException
-	 */
-	private void add(String key, String value) throws UnsupportedEncodingException {
-		// try {
-		// fields.add(new NameValuePair(key, URLEncoder.encode(value == null ?
-		// "" : value, charset)));
-		fields.put(key, new NameValuePair(key, value));
-		// BugzillaPlugin.ENCODING_UTF_8
-		// } catch (UnsupportedEncodingException e) {
-		// // ignore
-		// }
-	}
-
-	/**
-	 * Post the bug to the bugzilla server TODO: fix this mess
-	 */
-	public String submitReportToRepository(BugzillaClient client) throws IOException, BugzillaException,
-			PossibleBugzillaFailureException, GeneralSecurityException {
-		NameValuePair[] formData = fields.values().toArray(new NameValuePair[fields.size()]);
-		InputStream inputStream = null;
-		String result = null;
-		PostMethod method = null;
-		try {
-			if (isNewBugPost()) {
-				method = client.postFormData(POST_BUG_CGI, formData);
-			} else {
-				method = client.postFormData(PROCESS_BUG_CGI, formData);
-			}
-
-			if (method == null)
-				throw new BugzillaException("Could not post form");
-
-			BufferedReader in = new BufferedReader(new InputStreamReader(method.getResponseBodyAsStream()));
-			in.mark(10);
-			HtmlStreamTokenizer tokenizer = new HtmlStreamTokenizer(in, null);
-
-			boolean existingBugPosted = false;
-			boolean isTitle = false;
-			String title = "";
-			for (Token token = tokenizer.nextToken(); token.getType() != Token.EOF; token = tokenizer.nextToken()) {
-
-				if (token.getType() == Token.TAG && ((HtmlTag) (token.getValue())).getTagType() == HtmlTag.Type.TITLE
-						&& !((HtmlTag) (token.getValue())).isEndTag()) {
-					isTitle = true;
-					continue;
-				}
-
-				if (isTitle) {
-					// get all of the data in the title tag
-					if (token.getType() != Token.TAG) {
-						title += ((StringBuffer) token.getValue()).toString().toLowerCase() + " ";
-						continue;
-					} else if (token.getType() == Token.TAG
-							&& ((HtmlTag) token.getValue()).getTagType() == HtmlTag.Type.TITLE
-							&& ((HtmlTag) token.getValue()).isEndTag()) {
-						if (!isNewBugPost
-								&& (title.toLowerCase().matches(".*bug\\s+processed.*") || title.toLowerCase().matches(
-										".*defect\\s+processed.*"))) {
-							existingBugPosted = true;
-						} else if (isNewBugPost && prefix != null && prefix2 != null && postfix != null
-								&& postfix2 != null && result == null) {
-							int startIndex = -1;
-							int startIndexPrefix = title.toLowerCase().indexOf(prefix.toLowerCase());
-							int startIndexPrefix2 = title.toLowerCase().indexOf(prefix2.toLowerCase());
-
-							if (startIndexPrefix != -1 || startIndexPrefix2 != -1) {
-								if (startIndexPrefix != -1) {
-									startIndex = startIndexPrefix + prefix.length();
-								} else {
-									startIndex = startIndexPrefix2 + prefix2.length();
-								}
-								int stopIndex = title.toLowerCase().indexOf(postfix.toLowerCase(), startIndex);
-								if (stopIndex == -1)
-									stopIndex = title.toLowerCase().indexOf(postfix2.toLowerCase(), startIndex);
-								if (stopIndex > -1) {
-									result = (title.substring(startIndex, stopIndex)).trim();
-								}
-							}
-						}
-						break;
-					}
-				}
-			}
-
-			if ((!isNewBugPost && existingBugPosted != true) || (isNewBugPost && result == null)) {
-				in.reset();
-				BugzillaClient.parseHtmlError(in);
-			}
-		} catch (ParseException e) {
-			throw new IOException("Could not parse response from server.");
-		} finally {
-			if (inputStream != null) {
-				inputStream.close();
-			}
-			if (method != null) {
-				method.releaseConnection();
-			}
-		}
-		// return the bug number
-		return result;
-	}
-
-	private void setPrefix(String prefix) {
-		this.prefix = prefix;
-	}
-
-	private void setPostfix(String postfix) {
-		this.postfix = postfix;
-	}
-
-	private void setPostfix2(String postfix) {
-		this.postfix2 = postfix;
-	}
-
-	public String getError() {
-		return parseError();
-	}
-
-	/**
-	 * remove all of the hyperlinks and erroneous info
-	 * 
-	 * @return
-	 */
-	private String parseError() {
-		String newError = "";
-		try {
-			HtmlStreamTokenizer tokenizer = new HtmlStreamTokenizer(new StringReader(error), null);
-			for (Token token = tokenizer.nextToken(); token.getType() != Token.EOF; token = tokenizer.nextToken()) {
-				if (token.getType() == Token.TAG && ((HtmlTag) (token.getValue())).getTagType() == HtmlTag.Type.A) {
-
-				} else if (token.getType() == Token.TAG
-						&& ((HtmlTag) (token.getValue())).getTagType() == HtmlTag.Type.FORM) {
-					for (Token token2 = tokenizer.nextToken(); token2.getType() != Token.EOF; token2 = tokenizer
-							.nextToken()) {
-						if (token2.getType() == Token.TAG) {
-							HtmlTag tag = (HtmlTag) token2.getValue();
-							if (tag.getTagType() == HtmlTag.Type.FORM && tag.isEndTag())
-								break;
-
-						}
-					}
-				} else {
-					newError += token.getWhitespace().toString() + token.getValue();
-				}
-			}
-		} catch (Exception e) {
-			newError = error;
-		}
-		return newError;
-	}
-
-	private void setPrefix2(String prefix2) {
-		this.prefix2 = prefix2;
-	}
-
-	/**
-	 * Break text up into lines of about 80 characters so that it is displayed
-	 * properly in bugzilla
-	 */
-	private static String formatTextToLineWrap(String origText, boolean hardWrap) {
-		// BugzillaServerVersion bugzillaServerVersion =
-		// IBugzillaConstants.BugzillaServerVersion.fromString(repository
-		// .getVersion());
-		// if (bugzillaServerVersion != null &&
-		// bugzillaServerVersion.compareTo(BugzillaServerVersion.SERVER_220) >=
-		// 0) {
-		// return origText;
-		if (!hardWrap) {
-			return origText;
-		} else {
-			String[] textArray = new String[(origText.length() / WRAP_LENGTH + 1) * 2];
-			for (int i = 0; i < textArray.length; i++)
-				textArray[i] = null;
-			int j = 0;
-			while (true) {
-				int spaceIndex = origText.indexOf(" ", WRAP_LENGTH - 5);
-				if (spaceIndex == origText.length() || spaceIndex == -1) {
-					textArray[j] = origText;
-					break;
-				}
-				textArray[j] = origText.substring(0, spaceIndex);
-				origText = origText.substring(spaceIndex + 1, origText.length());
-				j++;
-			}
-
-			String newText = "";
-
-			for (int i = 0; i < textArray.length; i++) {
-				if (textArray[i] == null)
-					break;
-				newText += textArray[i] + "\n";
-			}
-			return newText;
-		}
-	}
-
-	public boolean isNewBugPost() {
-		return isNewBugPost;
-	}
-
-	public void setNewBugPost(boolean isNewBugPost) {
-		this.isNewBugPost = isNewBugPost;
-	}
-
-	public RepositoryTaskData getTaskData() {
-		return taskData;
-	}
-
-	public void setTaskData(RepositoryTaskData taskData) {
-		this.taskData = taskData;
-	}
-}
-// public void setProxySettings(Proxy proxySettings) {
-// this.proxySettings = proxySettings;
-// }
-
-// /**
-// * Post the bug to the bugzilla server
-// *
-// * @return The result of the responses
-// * @throws GeneralSecurityException
-// */
-// public String submitReportToRepository() throws IOException,
-// BugzillaException, PossibleBugzillaFailureException, GeneralSecurityException
-// {
-// BufferedOutputStream out = null;
-// BufferedReader in = null;
-// String result = null;
-// try {
-// // connect to the bugzilla server
-// HttpURLConnection postConnection = WebClientUtil.getUrlConnection(postUrl,
-// proxySettings, false, null, null);
-//
-// // set the connection method
-// postConnection.setRequestMethod(METHOD_POST);
-// String contentTypeString = POST_CONTENT_TYPE;
-// if (charset != null) {
-// contentTypeString += ";charset=" + charset;
-// }
-// postConnection.setRequestProperty(REQUEST_PROPERTY_CONTENT_TYPE,
-// contentTypeString);
-// // get the url for the update with all of the changed values
-//
-// byte[] body = getPostBody().getBytes();
-// postConnection.setRequestProperty(REQUEST_PROPERTY_CONTENT_LENGTH,
-// String.valueOf(body.length));
-//
-// // allow outgoing streams and open a stream to post to
-// postConnection.setDoOutput(true);
-//
-// out = new BufferedOutputStream(postConnection.getOutputStream());
-//
-// // write the data and close the stream
-// out.write(body);
-// out.flush();
-//
-// int responseCode = postConnection.getResponseCode();
-// if (responseCode != HttpURLConnection.HTTP_OK && responseCode !=
-// HttpURLConnection.HTTP_CREATED) {
-// throw new BugzillaException("Server returned HTTP error: " + responseCode + "
-// - "
-// + postConnection.getResponseMessage());
-// }
-//
-// // open a stream to receive response from bugzilla
-// in = new BufferedReader(new
-// InputStreamReader(postConnection.getInputStream()));
-// in.mark(10);
-// HtmlStreamTokenizer tokenizer = new HtmlStreamTokenizer(in, null);
-//
-// boolean existingBugPosted = false;
-// boolean isTitle = false;
-// String title = "";
-// for (Token token = tokenizer.nextToken(); token.getType() != Token.EOF; token
-// = tokenizer.nextToken()) {
-//
-// if (token.getType() == Token.TAG && ((HtmlTag)
-// (token.getValue())).getTagType() == HtmlTag.Type.TITLE
-// && !((HtmlTag) (token.getValue())).isEndTag()) {
-// isTitle = true;
-// continue;
-// }
-//
-// if (isTitle) {
-// // get all of the data in the title tag
-// if (token.getType() != Token.TAG) {
-// title += ((StringBuffer) token.getValue()).toString().toLowerCase() + " ";
-// continue;
-// } else if (token.getType() == Token.TAG
-// && ((HtmlTag) token.getValue()).getTagType() == HtmlTag.Type.TITLE
-// && ((HtmlTag) token.getValue()).isEndTag()) {
-// if (!isNewBugPost
-// && (title.toLowerCase().matches(".*bug\\s+processed.*") ||
-// title.toLowerCase().matches(
-// ".*defect\\s+processed.*"))) {
-// existingBugPosted = true;
-// } else if (isNewBugPost && prefix != null && prefix2 != null && postfix !=
-// null
-// && postfix2 != null && result == null) {
-// int startIndex = -1;
-// int startIndexPrefix = title.toLowerCase().indexOf(prefix.toLowerCase());
-// int startIndexPrefix2 = title.toLowerCase().indexOf(prefix2.toLowerCase());
-//
-// if (startIndexPrefix != -1 || startIndexPrefix2 != -1) {
-// if (startIndexPrefix != -1) {
-// startIndex = startIndexPrefix + prefix.length();
-// } else {
-// startIndex = startIndexPrefix2 + prefix2.length();
-// }
-// int stopIndex = title.toLowerCase().indexOf(postfix.toLowerCase(),
-// startIndex);
-// if (stopIndex == -1)
-// stopIndex = title.toLowerCase().indexOf(postfix2.toLowerCase(), startIndex);
-// if (stopIndex > -1) {
-// result = (title.substring(startIndex, stopIndex)).trim();
-// }
-// }
-// }
-// break;
-// }
-// }
-// }
-//
-// if ((!isNewBugPost && existingBugPosted != true) || (isNewBugPost && result
-// == null)) {
-// in.reset();
-// BugzillaClient.parseHtmlError(in);
-// }
-// } catch (KeyManagementException e) {
-// throw new BugzillaException("Could not POST form. Communications error: " +
-// e.getMessage(), e);
-// } catch (NoSuchAlgorithmException e) {
-// throw new BugzillaException("Could not POST form. Communications error: " +
-// e.getMessage(), e);
-// } catch (ParseException e) {
-// throw new IOException("Could not parse response from server.");
-// } finally {
-// try {
-// if (in != null)
-// in.close();
-// if (out != null)
-// out.close();
-//
-// } catch (IOException e) {
-// BugzillaCorePlugin.log(new Status(IStatus.ERROR,
-// BugzillaCorePlugin.PLUGIN_ID, IStatus.ERROR,
-// "Problem posting the bug", e));
-// }
-// }
-// // return the bug number
-// return result;
-// }
-
-// /**
-// * Get the url that contains the attributes to be posted
-// *
-// * @return The url for posting
-// */
-// private String getPostBody() {
-// String postBody = "";
-//
-// // go through all of the attributes and add them to the body of the post
-// Iterator<Map.Entry<String, String>> anIterator =
-// fields.entrySet().iterator();
-// while (anIterator.hasNext()) {
-// Map.Entry<String, String> entry = anIterator.next();
-// postBody = postBody + entry.getKey() + "=" + entry.getValue();
-// if (anIterator.hasNext())
-// postBody = postBody + "&";
-// }
-// return postBody;
-// }
-
-// private void setCharset(String charset) {
-// this.charset = charset;
-// }
-
-// private static void setConnectionsSettings(BugzillaReportSubmitForm form,
-// String repositoryUrl, String userName,
-// String password, Proxy proxySettings, String formName) throws
-// UnsupportedEncodingException {
-//
-// String baseURL = repositoryUrl;
-//
-// if (!baseURL.endsWith("/"))
-// baseURL += "/";
-// try {
-// form.postUrl = new URL(baseURL + formName);
-// if (proxySettings != null) {
-// form.proxySettings = proxySettings;
-// }
-// } catch (MalformedURLException e) {
-// // we should be ok here
-// }
-//
-// // add the login information to the bug post
-// //form.add(KEY_BUGZILLA_LOGIN, userName);
-// //form.add(KEY_BUGZILLA_PASSWORD, password);
-// }
-
-// /**
-// * Sets the cc field to the user's address if a cc has not been specified
-// to
-// * ensure that commenters are on the cc list. TODO: Review this mechanism
-// *
-// * @author Wesley Coelho
-// */
-// private static void setDefaultCCValue(BugzillaReport bug, String
-// userName) {
-// // RepositoryTaskAttribute newCCattr =
-// // bug.getAttributeForKnobName(KEY_NEWCC);
-// RepositoryTaskAttribute owner =
-// bug.getAttribute(BugzillaReportElement.ASSIGNED_TO);
-//
-// // Don't add the cc if the user is the bug owner
-// if (userName == null || (owner != null &&
-// owner.getValue().indexOf(userName) != -1)) {
-// // MylarStatusHandler.log("Could not determine CC value for
-// // repository: " + repository, null);
-// return;
-// }
-// // Don't add cc if already there
-// RepositoryTaskAttribute ccAttribute =
-// bug.getAttribute(BugzillaReportElement.CC);
-// if (ccAttribute != null && ccAttribute.getValues().contains(userName)) {
-// return;
-// }
-// RepositoryTaskAttribute newCCattr =
-// bug.getAttribute(BugzillaReportElement.NEWCC);
-// if (newCCattr == null) {
-// newCCattr = new RepositoryTaskAttribute(BugzillaReportElement.NEWCC);
-// bug.addAttribute(BugzillaReportElement.NEWCC, newCCattr);
-// }
-// // Add the user to the cc list
-// newCCattr.setValue(userName);
-// }
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/BugzillaRepositoryQuery.java b/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/BugzillaRepositoryQuery.java
deleted file mode 100644
index 544f510..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/BugzillaRepositoryQuery.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004, 2008 Tasktop Technologies and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     Tasktop Technologies - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.mylyn.bugzilla.deprecated;
-
-import org.eclipse.mylyn.internal.bugzilla.core.BugzillaCorePlugin;
-import org.eclipse.mylyn.internal.tasks.core.RepositoryQuery;
-
-/**
- * @author Shawn Minto
- * @author Mik Kersten
- */
-@Deprecated
-public class BugzillaRepositoryQuery extends RepositoryQuery {
-
-	private boolean customQuery = false;
-
-	public BugzillaRepositoryQuery(String repositoryUrl, String queryUrl, String description) {
-		super(description);
-		setUrl(queryUrl);
-		this.repositoryUrl = repositoryUrl;
-	}
-
-	@Override
-	public String getConnectorKind() {
-		return BugzillaCorePlugin.CONNECTOR_KIND;
-	}
-
-	public boolean isCustomQuery() {
-		return customQuery;
-	}
-
-	public void setCustomQuery(boolean customQuery) {
-		this.customQuery = customQuery;
-	}
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/BugzillaResultMatchAdapter.java b/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/BugzillaResultMatchAdapter.java
deleted file mode 100644
index d27f36b..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/BugzillaResultMatchAdapter.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004 - 2006 University Of British Columbia and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     University Of British Columbia - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.mylyn.internal.bugzilla.ui;
-
-import org.eclipse.mylyn.internal.bugzilla.ui.search.IBugzillaResultEditorMatchAdapter;
-import org.eclipse.mylyn.tasks.ui.editors.AbstractTaskEditorInput;
-import org.eclipse.mylyn.tasks.ui.editors.RepositoryTaskEditorInput;
-import org.eclipse.mylyn.tasks.ui.search.RepositorySearchResult;
-import org.eclipse.search.ui.text.AbstractTextSearchResult;
-import org.eclipse.search.ui.text.Match;
-import org.eclipse.ui.IEditorInput;
-import org.eclipse.ui.IEditorPart;
-
-/**
- * @author Mik Kersten (clean-up)
- */
-public class BugzillaResultMatchAdapter implements IBugzillaResultEditorMatchAdapter {
- 
-	/** An empty array of matches */
-	private final Match[] EMPTY_ARR = new Match[0];
-
-	private RepositorySearchResult result;
-
-	/*
-	 * (non-Javadoc)
-	 * 
-	 * @see org.eclipse.search.ui.text.IEditorMatchAdapter#isShownInEditor(org.eclipse.search.ui.text.Match,
-	 *      org.eclipse.ui.IEditorPart)
-	 */
-	public boolean isShownInEditor(Match match, IEditorPart editor) {
-		if (result == null)
-			return false;
-		IEditorInput ei = editor.getEditorInput();
-		if (ei instanceof RepositoryTaskEditorInput) {
-			AbstractTaskEditorInput bi = (AbstractTaskEditorInput) ei;
-			return match.getElement().equals(bi.getTaskData());
-		}
-		return false;
-	}
-
-	/*
-	 * (non-Javadoc)
-	 * 
-	 * @see org.eclipse.search.ui.text.IEditorMatchAdapter#computeContainedMatches(org.eclipse.search.ui.text.AbstractTextSearchResult,
-	 *      org.eclipse.ui.IEditorPart)
-	 */
-	public Match[] computeContainedMatches(AbstractTextSearchResult result, IEditorPart editor) {
-		if (result == null)
-			return EMPTY_ARR;
-		IEditorInput ei = editor.getEditorInput();
-		if (ei instanceof RepositoryTaskEditorInput) {
-			AbstractTaskEditorInput bi = (AbstractTaskEditorInput) ei;
-			return result.getMatches(bi.getTaskData());
-		}
-		return EMPTY_ARR;
-	}
-
-	public void setResult(RepositorySearchResult result) {
-		this.result = result;
-	}
-
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/BugzillaSearchHit.java b/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/BugzillaSearchHit.java
deleted file mode 100644
index bd01e50..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/BugzillaSearchHit.java
+++ /dev/null
@@ -1,215 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2003 - 2006 University Of British Columbia and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     University Of British Columbia - initial API and implementation
- *******************************************************************************/
-package org.eclipse.mylyn.internal.bugzilla.ui.search;
-
-/**
- * An item in the Bugzilla database matching the search criteria.
- */
-public class BugzillaSearchHit {
-	/** The server that the result was from */
-	private String repositoryUrl;
-
-	/** The bug id */
-	private int id;
-
-	/** The description of the bug */
-	private String description;
-
-	/** The severity of the bug */
-	private String severity;
-
-	/** The priority of the bug */
-	private String priority;
-
-	/** The platform that the bug was found in */
-	private String platform;
-
-	/** The state of the bug */
-	private String state;
-
-	/** The resolution of the bug */
-	private String resolution;
-
-	/** The owner of the bug */
-	private String owner;
-
-	/** The query that the bug was a result of */
-	private String query;
-
-	public BugzillaSearchHit() {		
-	}
-	
-	/**
-	 * Constructor
-	 * 
-	 * @param id
-	 *            The id of the bug
-	 * @param description
-	 *            The description of the bug
-	 * @param severity
-	 *            The severity of the bug
-	 * @param priority
-	 *            The priority of the bug
-	 * @param platform
-	 *            The platform the bug was found in
-	 * @param state
-	 *            The state of the bug
-	 * @param result
-	 *            The resolution of the bug
-	 * @param owner
-	 *            The owner of the bug
-	 * @param query
-	 *            the query that the bug was a result of
-	 */
-	public BugzillaSearchHit(String server, int id, String description, String severity, String priority,
-			String platform, String state, String result, String owner, String query) {
-		this.repositoryUrl = server;
-		this.id = id;
-		this.description = description;
-		this.severity = severity;
-		this.priority = priority;
-		this.platform = platform;
-		this.state = state;
-		this.resolution = result;
-		this.owner = owner;
-		this.query = query;
-	}
-
-	public String getRepositoryUrl() {
-		return repositoryUrl;
-	}
-	
-	public void setRepository(String url) {
-		repositoryUrl = url;
-	}
-
-	/**
-	 * Get the bugs id
-	 * 
-	 * @return The bugs id
-	 */
-	public int getId() {
-		return id;
-	}
-
-	/**
-	 * Get the bugs description
-	 * 
-	 * @return The description of the bug
-	 */
-	public String getDescription() {
-		return description;
-	}
-
-	/**
-	 * Get the bugs priority
-	 * 
-	 * @return The priority of the bug
-	 */
-	public String getPriority() {
-		return priority;
-	}
-
-	/**
-	 * Get the bugs severity
-	 * 
-	 * @return The severity of the bug
-	 */
-	public String getSeverity() {
-		return severity;
-	}
-
-	/**
-	 * Get the platform the bug occurred under
-	 * 
-	 * @return The platform that the bug occured under
-	 */
-	public String getPlatform() {
-		return platform;
-	}
-
-	/**
-	 * Get the bugs state
-	 * 
-	 * @return The state of the bug
-	 */
-	public String getState() {
-		return state;
-	}
-
-	/**
-	 * Get the bugs resolution
-	 * 
-	 * @return The resolution of the bug
-	 */
-	public String getResolution() {
-		return resolution;
-	}
-
-	/**
-	 * Get the bugs owner
-	 * 
-	 * @return The owner of the bug
-	 */
-	public String getOwner() {
-		return owner;
-	}
-
-	/**
-	 * Get the query that the bug was a result of
-	 * 
-	 * @return The query that the bug was a result of
-	 */
-	public String getQuery() {
-		return query;
-	}
-
-	@Override
-	public String toString() {
-		return id + " " + description + "\n";
-	}
-
-	public void setDescription(String description) {
-		this.description = description;
-	}
-
-	public void setId(int id) {
-		this.id = id;
-	}
-
-	public void setOwner(String owner) {
-		this.owner = owner;
-	}
-
-	public void setPlatform(String platform) {
-		this.platform = platform;
-	}
-
-	public void setPriority(String priority) {
-		this.priority = priority;
-	}
-
-	public void setQuery(String query) {
-		this.query = query;
-	}
-
-	public void setResolution(String resolution) {
-		this.resolution = resolution;
-	}
-
-	public void setSeverity(String severity) {
-		this.severity = severity;
-	}
-
-	public void setState(String state) {
-		this.state = state;
-	}
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/BugzillaSearchOperation.java b/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/BugzillaSearchOperation.java
deleted file mode 100644
index 9f532d6..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/BugzillaSearchOperation.java
+++ /dev/null
@@ -1,103 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2003 - 2006 University Of British Columbia and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     University Of British Columbia - initial API and implementation
- *******************************************************************************/
-package org.eclipse.mylyn.internal.bugzilla.ui.search;
-
-import java.net.Proxy;
-
-import javax.security.auth.login.LoginException;
-
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.mylyn.internal.tasks.ui.search.AbstractRepositorySearchQuery;
-import org.eclipse.mylyn.tasks.core.QueryHitCollector;
-import org.eclipse.mylyn.tasks.core.TaskRepository;
-
-/**
- * An operation to perform Bugzilla search query.
- * 
- * @author Mik Kersten (hardening of prototype)
- */
-public class BugzillaSearchOperation implements IBugzillaSearchOperation {
-	private String queryUrl;
-
-	private QueryHitCollector collector;
-
-	private AbstractRepositorySearchQuery query;
-
-	/** The status of the search operation */
-	private IStatus status;
-
-	/** The LoginException that was thrown when trying to do the search */
-	private LoginException loginException = null;
-
-	private int maxHits;
-
-	private TaskRepository repository;
-
-	private Proxy proxySettings;
-	
-	public BugzillaSearchOperation(TaskRepository repository, String queryUrl, Proxy proxySettings,
-			BugzillaSearchResultCollector collector, String maxHits) {
-		this.repository = repository;
-		this.queryUrl = queryUrl;
-		this.collector = collector;
-		this.proxySettings = proxySettings;				
-		collector.setOperation(this);	
-		
-		try {
-			this.maxHits = Integer.parseInt(maxHits);
-		} catch (Exception e) {
-			this.maxHits = -1;
-		}
-	}
-	
-	public void run(IProgressMonitor monitor) {
-		// set the progress monitor for the search collector and start the
-		// search
-		collector.setProgressMonitor(monitor);
-		BugzillaSearchEngine engine = new BugzillaSearchEngine(repository, queryUrl, proxySettings);
-		try {
-			status = engine.search(collector, 0, maxHits);
-		} catch (LoginException e) {
-			// save this exception to throw later
-			this.loginException = e;
-		}
-	}
-
-	/**
-	 * @see org.eclipse.mylyn.internal.bugzilla.ui.search.IBugzillaSearchOperation#getStatus()
-	 */
-	public IStatus getStatus() throws LoginException {
-		// if a LoginException was thrown while trying to search, throw this
-		if (loginException == null)
-			return status;
-		else
-			throw loginException;
-	}
-
-	/**
-	 * @see org.eclipse.mylyn.internal.bugzilla.core.search.IBugzillaSearchOperation#getQuery()
-	 */
-	public AbstractRepositorySearchQuery getQuery() {
-		return query;
-	}
-
-	/**
-	 * @see org.eclipse.mylyn.internal.bugzilla.core.search.IBugzillaSearchOperation#setQuery(org.eclipse.mylyn.internal.tasks.ui.search.AbstractRepositorySearchQuery)
-	 */
-	public void setQuery(AbstractRepositorySearchQuery newQuery) {
-		this.query = newQuery;
-	}
-
-	public String getName() {
-		return null;
-	}
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/BugzillaSearchQuery.java b/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/BugzillaSearchQuery.java
deleted file mode 100644
index a622ea0..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/BugzillaSearchQuery.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004 - 2006 University Of British Columbia and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     University Of British Columbia - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.mylyn.internal.bugzilla.ui.search;
-
-import java.lang.reflect.InvocationTargetException;
-
-import javax.security.auth.login.LoginException;
-
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.OperationCanceledException;
-import org.eclipse.core.runtime.Status;
-import org.eclipse.jface.dialogs.MessageDialog;
-import org.eclipse.mylyn.internal.bugzilla.core.BugzillaCorePlugin;
-import org.eclipse.mylyn.internal.bugzilla.ui.BugzillaUiPlugin;
-import org.eclipse.mylyn.internal.tasks.ui.search.AbstractRepositorySearchQuery;
-import org.eclipse.search.ui.text.AbstractTextSearchResult;
-import org.eclipse.ui.PlatformUI;
-
-/**
- * This class performs a search query on Bugzilla bug reports.
- * 
- * @author Rob Elves (modifications)
- */
-public class BugzillaSearchQuery extends AbstractRepositorySearchQuery {
-
-	private static final String MESSAGE_LOGIN_FAILURE = "Could not log you in to get the information you requested since login name or password is incorrect.\nPlease check settings.";
-
-	/** The operation that performs the Bugzilla search query. */
-	private IBugzillaSearchOperation operation;
-
-	public BugzillaSearchQuery(IBugzillaSearchOperation operation) {
-		this.operation = operation;
-		operation.setQuery(this);
-	}
-
-	public IStatus run(IProgressMonitor monitor) throws OperationCanceledException {
-		final IStatus[] status = new IStatus[1];
-		final AbstractTextSearchResult textResult = (AbstractTextSearchResult) getSearchResult();
-		textResult.removeAll();
-
-		try {
-			operation.run(monitor);
-
-			status[0] = operation.getStatus();
-
-			if (status[0].getCode() == IStatus.CANCEL) {
-				status[0] = Status.OK_STATUS;
-			} else if (!status[0].isOK()) {
-				PlatformUI.getWorkbench().getDisplay().syncExec(new Runnable() {
-					public void run() {
-						MessageDialog.openError(null, "Repository Search Error", status[0].getMessage());
-					}
-				});
-				status[0] = Status.OK_STATUS;
-			}
-		} catch (InvocationTargetException e) {
-			PlatformUI.getWorkbench().getDisplay().syncExec(new Runnable() {
-				public void run() {
-					MessageDialog.openInformation(null, "Bugzilla Login Error", MESSAGE_LOGIN_FAILURE);
-				}
-			});
-		} catch (InterruptedException e) {
-			// ignore
-		} catch (final LoginException e) {
-			PlatformUI.getWorkbench().getDisplay().syncExec(new Runnable() {
-				public void run() {
-					MessageDialog.openInformation(null, "Bugzilla Login Error", MESSAGE_LOGIN_FAILURE);
-					BugzillaCorePlugin.log(new Status(IStatus.ERROR, BugzillaUiPlugin.PLUGIN_ID, IStatus.OK, "", e));
-				}
-			});
-		}
-
-		return status[0];
-	}
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/BugzillaStackTraceDuplicateDetector.java b/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/BugzillaStackTraceDuplicateDetector.java
deleted file mode 100644
index 815355f..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/BugzillaStackTraceDuplicateDetector.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004, 2008 Tasktop Technologies and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     Meghan Allen - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.mylyn.bugzilla.deprecated;
-
-import java.io.UnsupportedEncodingException;
-import java.net.URLEncoder;
-
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.Status;
-import org.eclipse.mylyn.commons.core.StatusHandler;
-import org.eclipse.mylyn.internal.bugzilla.core.BugzillaCorePlugin;
-import org.eclipse.mylyn.internal.tasks.core.RepositoryQuery;
-import org.eclipse.mylyn.internal.tasks.core.deprecated.AbstractLegacyDuplicateDetector;
-import org.eclipse.mylyn.internal.tasks.core.deprecated.RepositoryTaskData;
-import org.eclipse.mylyn.tasks.core.TaskRepository;
-
-/**
- * @author Meghan Allen
- */
-public class BugzillaStackTraceDuplicateDetector extends AbstractLegacyDuplicateDetector {
-
-	private static final int DESCRIPTION_MAX_CHARS = 6000;
-
-	//private static final String NO_STACK_MESSAGE = "Unable to locate a stack trace in the description text.";
-
-	@Override
-	public RepositoryQuery getDuplicatesQuery(TaskRepository repository, RepositoryTaskData taskData) {
-		String queryUrl = "";
-		String searchString = AbstractLegacyDuplicateDetector.getStackTraceFromDescription(taskData.getDescription());
-		if (searchString != null && searchString.length() > DESCRIPTION_MAX_CHARS) {
-			searchString = searchString.substring(0, DESCRIPTION_MAX_CHARS);
-		}
-
-		if (searchString == null) {
-			//MessageDialog.openWarning(null, "No Stack Trace Found", NO_STACK_MESSAGE);
-			return null;
-		}
-
-		try {
-			queryUrl = repository.getRepositoryUrl() + "/buglist.cgi?long_desc_type=allwordssubstr&long_desc="
-					+ URLEncoder.encode(searchString, repository.getCharacterEncoding());
-		} catch (UnsupportedEncodingException e) {
-			StatusHandler.log(new Status(IStatus.WARNING, BugzillaCorePlugin.ID_PLUGIN,
-					"Error during duplicate detection", e));
-			return null;
-		}
-
-		queryUrl += "&product=" + taskData.getProduct();
-
-		BugzillaRepositoryQuery bugzillaQuery = new BugzillaRepositoryQuery(repository.getRepositoryUrl(), queryUrl,
-				"search");
-		return bugzillaQuery;
-	}
-
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/BugzillaStackTraceTest.java b/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/BugzillaStackTraceTest.java
deleted file mode 100644
index 84ddd6a..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/BugzillaStackTraceTest.java
+++ /dev/null
@@ -1,196 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004 - 2006 University Of British Columbia and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     University Of British Columbia - initial API and implementation
- *******************************************************************************/
-////Created on Oct 12, 2004
-package org.eclipse.mylyn.tests.misc;
-
-import java.io.File;
-import java.io.FileReader;
-import java.io.Reader;
-import java.util.ArrayList;
-import java.util.List;
-
-import junit.framework.TestCase;
-
-import org.eclipse.core.runtime.Path;
-import org.eclipse.mylyn.bugzilla.tests.BugzillaTestPlugin;
-import org.eclipse.mylyn.core.tests.support.FileTool;
-import org.eclipse.mylyn.internal.bugs.search.BugzillaMylarSearchOperation;
-import org.eclipse.mylyn.internal.bugzilla.core.internal.BugParser;
-import org.eclipse.mylyn.internal.bugzilla.core.search.BugzillaSearchHit;
-import org.eclipse.mylyn.internal.bugzilla.ui.tasklist.BugzillaReportNode;
-import org.eclipse.mylyn.internal.bugzilla.ui.tasklist.StackTrace;
-
-/**
- * Class to test the Bridge methods that do not require server queries
- * 
- * @author Shawn Minto
- */
-public class BugzillaStackTraceTest extends TestCase {
-
-	private static final String TEST_FILE_LOC = "testdata/reports-stacktrace/";
-
-	private static final String BUGZILLA_SERVER_NAME = "https://bugs.eclipse.org/bugs";
-
-	/**
-	 * Test that the regular expression escaping mechanism works properly
-	 */
-	public void testREGEX() {
-		String r = ".*+(){}[]^$|?/\\";
-		String r2 = StackTrace.escapeForRegex(r);
-		String ans = "\\.\\*\\+\\(\\)\\{\\}\\[\\]\\^\\$\\|\\?\\/\\\\";
-		String msg = "Regular Expression matching wrong:\nwas: " + r2 + "\nshould be:" + ans;
-		assertTrue(msg, r2.equals(ans));
-	}
-
-	// /**
-	// * Test parsing the bug for multiple stacks in in
-	// */
-	// public void testMultipleStacksDiffComments(){
-	// // REPORT_REPOSITORY 4862 - 2 stack traces - 1 in description, 1 in
-	// comment - text
-	// before and after
-	// performParse(4862, "4862.html", 2, false);
-	// }
-
-	// /**
-	// * Test parsing the bug for a single stack in the description with some
-	// * text before it
-	// */
-	// public void testSingleStackCodeBeforeInDescription(){
-	// // REPORT_REPOSITORY 76388 - 1 stack trace - description - text before
-	// and formatted
-	// ugly
-	// performParse(76388, "76388.html", 1, false);
-	// }
-
-	/**
-	 * Test parsing the bug for a single stack trace in the description with
-	 * text before and after it
-	 */
-	public void testSingleStackCodeBeforeAndAfterInDescription() {
-
-		// REPORT_REPOSITORY 76146 - 1 stack trace - description - text before
-		// and code after
-		performParse(76146, "76146.html", 1, false);
-	}
-
-	/**
-	 * Test parsing a bug that has 1 stack trace in the description with no
-	 * extra text, but has lines in it that span 3 lines
-	 */
-	public void testSingleStackPoorFormatInDescription() {
-		// REPORT_REPOSITORY 67395 - 1 stack trace - description - no extra
-		// text, 1 at line
-		// spans 3 lines
-		performParse(67395, "67395.html", 1, false);
-	}
-
-	/**
-	 * Test parsing a bug with no stack traces and no qualified exception names
-	 */
-	public void testNoStackNoQualified() {
-		// REPORT_REPOSITORY 4548 - no stack traces, no qualified reference to
-		// an exception
-		performParse(4548, "4548.html", 0, false);
-	}
-
-	/**
-	 * Test parsing a bug with no stack traces, but a qualified reference to an
-	 * exception
-	 */
-	public void testNoStackQual() {
-		// REPORT_REPOSITORY 1 - no stack traces, qualified reference to
-		// exception - made up
-		// bug
-		performParse(1, "1.html", 0, false);
-	}
-
-	/**
-	 * Test parsing of a bug with 1 stack trace and multiple qualified
-	 * references
-	 */
-	public void testSingleStackQual() {
-		// REPORT_REPOSITORY 2 - 1 stack trace- 2 qual ref, stack trace, 1 qual
-		// ref - made up
-		// bug
-		performParse(2, "2.html", 1, false);
-	}
-
-	/**
-	 * Test parsing of a bug with many stacks traces in a single comment
-	 */
-	public void testMultipleStackSingleComment() {
-		// REPORT_REPOSITORY 40152 - 1 stack trace- 2 qual ref, stack trace, 1
-		// qual ref - made
-		// up bug
-		performParse(40152, "40152.html", 33, false);
-	}
-
-	/**
-	 * Print out the stack traces
-	 * 
-	 * @param l
-	 *            List of stack traces
-	 */
-	private void printStackTraces(List<StackTrace> l) {
-		System.out.println("\n\n");
-		for (int i = 0; i < l.size(); i++) {
-			StackTrace trace = l.get(i);
-			System.out.println("*****************?????????????????*****************\n");
-			System.out.println("OFFSET: " + trace.getOffset() + " LENGTH: " + trace.getLength());
-			System.out.println(trace.getStackTrace());
-			System.out.println("*****************?????????????????*****************\n\n");
-		}
-	}
-
-	private void performParse(int bugNumber, String bugFileName, int numTracesExpected, boolean printStackTraces) {
-
-		BugzillaSearchHit hit = new BugzillaSearchHit("<TEST-SERVER>", bugNumber, "", "", "", "", "", "", "", ""); // stack
-		// trace
-		// in
-		// desc
-		// and
-		// com
-
-		// create a new doi info
-		BugzillaReportNode doi = new BugzillaReportNode(0, hit, false);
-		try {
-
-			// read the bug in from a file
-			File f = FileTool.getFileInPlugin(BugzillaTestPlugin.getDefault(), new Path(TEST_FILE_LOC + bugFileName)); // used
-			// if
-			// run
-			// as a
-			// plugin
-			// test
-			// File f = new File(TEST_FILE_LOC+bugFileName); // used if run as a
-			// standalone test
-			Reader reader = new FileReader(f);
-			doi.setBug(BugParser.parseBug(reader, hit.getId(), BUGZILLA_SERVER_NAME, true, null, null, null));
-			reader.close();
-		} catch (Exception e) {
-			e.printStackTrace();
-		}
-
-		// do a second pass parse on the bug
-		List<BugzillaReportNode> l = new ArrayList<BugzillaReportNode>();
-		l.add(doi);
-		BugzillaMylarSearchOperation.secondPassBugzillaParser(l);
-
-		// make sure that we received the right number of stack traces back
-		// System.out.println("*** REPORT_REPOSITORY " + hit.getId() + " ***");
-		// System.out.println("NumStackTraces = " +
-		// doi.getStackTraces().size());
-		assertEquals("Wrong Number stack traces", numTracesExpected, doi.getStackTraces().size());
-		if (printStackTraces)
-			printStackTraces(doi.getStackTraces());
-	}
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/BugzillaTask.java b/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/BugzillaTask.java
deleted file mode 100644
index 52d0b6a..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/BugzillaTask.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004, 2008 Tasktop Technologies and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     Tasktop Technologies - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.mylyn.bugzilla.deprecated;
-
-import org.eclipse.mylyn.internal.bugzilla.core.BugzillaClient;
-import org.eclipse.mylyn.internal.bugzilla.core.BugzillaCorePlugin;
-import org.eclipse.mylyn.internal.bugzilla.core.IBugzillaConstants;
-import org.eclipse.mylyn.internal.tasks.core.AbstractTask;
-
-/**
- * @author Mik Kersten
- * @author Rob Elves
- * @deprecated
- */
-@Deprecated
-public class BugzillaTask extends AbstractTask {
-
-	private String severity;
-
-	private String product;
-
-	public BugzillaTask(String repositoryUrl, String id, String label) {
-		super(repositoryUrl, id, label);
-		setUrl(BugzillaClient.getBugUrlWithoutLogin(repositoryUrl, id));
-	}
-
-	@Override
-	public String getTaskKind() {
-		return IBugzillaConstants.BUGZILLA_TASK_KIND;
-	}
-
-	@Override
-	public String toString() {
-		return "Bugzilla task: " + getHandleIdentifier();
-	}
-
-	@Override
-	public String getConnectorKind() {
-		return BugzillaCorePlugin.CONNECTOR_KIND;
-	}
-
-	public String getSeverity() {
-		return severity;
-	}
-
-	public void setSeverity(String severity) {
-		this.severity = severity;
-	}
-
-	public String getProduct() {
-		return product;
-	}
-
-	public void setProduct(String product) {
-		this.product = product;
-	}
-
-	@Override
-	public boolean isLocal() {
-		// ignore
-		return false;
-	}
-
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/BugzillaTaskEditor.java b/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/BugzillaTaskEditor.java
deleted file mode 100644
index ae24b4d..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/BugzillaTaskEditor.java
+++ /dev/null
@@ -1,822 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004, 2008 Tasktop Technologies and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     Tasktop Technologies - initial API and implementation
- *     Jeff Pound - Attachments
- *******************************************************************************/
-
-package org.eclipse.mylyn.bugzilla.deprecated;
-
-import java.io.IOException;
-import java.text.DateFormat;
-import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.Calendar;
-import java.util.Date;
-import java.util.List;
-
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.NullProgressMonitor;
-import org.eclipse.core.runtime.Status;
-import org.eclipse.jface.dialogs.MessageDialog;
-import org.eclipse.jface.fieldassist.ContentProposalAdapter;
-import org.eclipse.jface.layout.GridDataFactory;
-import org.eclipse.jface.layout.GridLayoutFactory;
-import org.eclipse.jface.text.ITextListener;
-import org.eclipse.jface.text.TextEvent;
-import org.eclipse.jface.text.TextViewer;
-import org.eclipse.jface.viewers.ILabelProvider;
-import org.eclipse.jface.window.Window;
-import org.eclipse.mylyn.commons.core.StatusHandler;
-import org.eclipse.mylyn.internal.bugzilla.core.BugzillaAttribute;
-import org.eclipse.mylyn.internal.bugzilla.core.BugzillaCorePlugin;
-import org.eclipse.mylyn.internal.bugzilla.core.BugzillaCustomField;
-import org.eclipse.mylyn.internal.bugzilla.core.BugzillaOperation;
-import org.eclipse.mylyn.internal.bugzilla.core.IBugzillaConstants;
-import org.eclipse.mylyn.internal.bugzilla.core.RepositoryConfiguration;
-import org.eclipse.mylyn.internal.bugzilla.ui.BugzillaUiPlugin;
-import org.eclipse.mylyn.internal.bugzilla.ui.editor.KeywordsDialog;
-import org.eclipse.mylyn.internal.provisional.commons.ui.CommonImages;
-import org.eclipse.mylyn.internal.provisional.commons.ui.DatePicker;
-import org.eclipse.mylyn.internal.tasks.core.AbstractTask;
-import org.eclipse.mylyn.internal.tasks.core.deprecated.RepositoryOperation;
-import org.eclipse.mylyn.internal.tasks.core.deprecated.RepositoryTaskAttribute;
-import org.eclipse.mylyn.internal.tasks.ui.TasksUiPlugin;
-import org.eclipse.mylyn.internal.tasks.ui.deprecated.AbstractRepositoryTaskEditor;
-import org.eclipse.mylyn.internal.tasks.ui.util.TasksUiInternal;
-import org.eclipse.mylyn.tasks.ui.TasksUiUtil;
-import org.eclipse.mylyn.tasks.ui.editors.TaskEditor;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.custom.CCombo;
-import org.eclipse.swt.custom.StyledText;
-import org.eclipse.swt.events.ModifyEvent;
-import org.eclipse.swt.events.ModifyListener;
-import org.eclipse.swt.events.SelectionAdapter;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.events.SelectionListener;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.layout.RowLayout;
-import org.eclipse.swt.widgets.Button;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Shell;
-import org.eclipse.swt.widgets.Text;
-import org.eclipse.ui.PlatformUI;
-import org.eclipse.ui.fieldassist.ContentAssistCommandAdapter;
-import org.eclipse.ui.forms.IFormColors;
-import org.eclipse.ui.forms.editor.FormEditor;
-import org.eclipse.ui.forms.events.HyperlinkAdapter;
-import org.eclipse.ui.forms.events.HyperlinkEvent;
-import org.eclipse.ui.forms.widgets.ExpandableComposite;
-import org.eclipse.ui.forms.widgets.FormToolkit;
-import org.eclipse.ui.forms.widgets.Hyperlink;
-import org.eclipse.ui.forms.widgets.ImageHyperlink;
-import org.eclipse.ui.forms.widgets.Section;
-
-/**
- * An editor used to view a bug report that exists on a server. It uses a <code>BugReport</code> object to store the
- * data.
- * 
- * @author Mik Kersten (hardening of prototype)
- * @author Rob Elves
- * @author Jeff Pound (Attachment work)
- */
-public class BugzillaTaskEditor extends AbstractRepositoryTaskEditor {
-
-	private static final String LABEL_TIME_TRACKING = "Bugzilla Time Tracking";
-
-	protected Text keywordsText;
-
-	protected Text estimateText;
-
-	protected Text actualText;
-
-	protected Text remainingText;
-
-	protected Text addTimeText;
-
-	protected Text deadlineText;
-
-	protected DatePicker deadlinePicker;
-
-	protected Text votesText;
-
-	protected Text assignedTo;
-
-	/**
-	 * Creates a new <code>ExistingBugEditor</code>.
-	 */
-	public BugzillaTaskEditor(FormEditor editor) {
-		super(editor);
-		// Set up the input for comparing the bug report to the server
-		// CompareConfiguration config = new CompareConfiguration();
-		// config.setLeftEditable(false);
-		// config.setRightEditable(false);
-		// config.setLeftLabel("Local Bug Report");
-		// config.setRightLabel("Remote Bug Report");
-		// config.setLeftImage(PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_OBJ_ELEMENT));
-		// config.setRightImage(PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_OBJ_ELEMENT));
-		// compareInput = new BugzillaCompareInput(config);
-	}
-
-	@Override
-	protected boolean supportsCommentSort() {
-		return false;
-	}
-
-	@Override
-	protected void createCustomAttributeLayout(Composite composite) {
-		RepositoryTaskAttribute attribute = null;
-		try {
-			RepositoryConfiguration configuration = BugzillaCorePlugin.getRepositoryConfiguration(this.repository,
-					false, new NullProgressMonitor());
-
-			if (configuration != null) {
-				List<BugzillaCustomField> customFields = configuration.getCustomFields();
-				if (!customFields.isEmpty()) {
-					for (BugzillaCustomField bugzillaCustomField : customFields) {
-						List<String> optionList = bugzillaCustomField.getOptions();
-						attribute = this.taskData.getAttribute(bugzillaCustomField.getName());
-						if (attribute == null) {
-							RepositoryTaskAttribute newattribute = new RepositoryTaskAttribute(
-									bugzillaCustomField.getName(), bugzillaCustomField.getDescription(), false);
-							newattribute.setReadOnly(false);
-							this.taskData.addAttribute(bugzillaCustomField.getName(), newattribute);
-						}
-						final RepositoryTaskAttribute cfattribute = this.taskData.getAttribute(bugzillaCustomField.getName());
-						Label label = createLabel(composite, cfattribute);
-						GridDataFactory.fillDefaults().align(SWT.RIGHT, SWT.CENTER).applyTo(label);
-						if (optionList != null && !optionList.isEmpty()) {
-							GridData data = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
-							data.horizontalSpan = 1;
-							final CCombo attributeCombo = new CCombo(composite, SWT.FLAT | SWT.READ_ONLY);
-							getManagedForm().getToolkit().adapt(attributeCombo, true, true);
-							attributeCombo.setFont(TEXT_FONT);
-							attributeCombo.setData(FormToolkit.KEY_DRAW_BORDER, FormToolkit.TEXT_BORDER);
-							if (hasChanged(cfattribute)) {
-								attributeCombo.setBackground(getColorIncoming());
-							}
-							attributeCombo.setLayoutData(data);
-
-							for (String val : optionList) {
-								if (val != null) {
-									attributeCombo.add(val);
-								}
-							}
-							String value = cfattribute.getValue();
-							if (value == null) {
-								value = "";
-							}
-							if (attributeCombo.indexOf(value) != -1) {
-								attributeCombo.select(attributeCombo.indexOf(value));
-							}
-							attributeCombo.clearSelection();
-							attributeCombo.addSelectionListener(new SelectionAdapter() {
-								@Override
-								public void widgetSelected(SelectionEvent event) {
-									if (attributeCombo.getSelectionIndex() > -1) {
-										String sel = attributeCombo.getItem(attributeCombo.getSelectionIndex());
-										cfattribute.setValue(sel);
-										attributeChanged(cfattribute);
-										attributeCombo.clearSelection();
-									}
-								}
-							});
-						} else {
-							Text cfField = createTextField(composite, cfattribute, SWT.FLAT);
-							GridDataFactory.fillDefaults().hint(135, SWT.DEFAULT).applyTo(cfField);
-						}
-					}
-
-					getManagedForm().getToolkit().paintBordersFor(composite);
-				}
-			}
-		} catch (CoreException e) {
-			// ignore
-		}
-
-		attribute = this.taskData.getAttribute(BugzillaAttribute.DEPENDSON.getKey());
-		if (attribute != null && !attribute.isReadOnly()) {
-			Label label = createLabel(composite, attribute);
-			GridDataFactory.fillDefaults().align(SWT.RIGHT, SWT.CENTER).applyTo(label);
-
-			Composite textFieldComposite = getManagedForm().getToolkit().createComposite(composite);
-			GridDataFactory.swtDefaults().align(SWT.FILL, SWT.CENTER).applyTo(textFieldComposite);
-			GridLayoutFactory.swtDefaults().margins(1, 3).spacing(0, 3).applyTo(textFieldComposite);
-
-			GridData textData = new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL);
-			textData.horizontalSpan = 1;
-			textData.widthHint = 135;
-
-			final Text text = createTextField(textFieldComposite, attribute, SWT.FLAT);
-			text.setLayoutData(textData);
-			getManagedForm().getToolkit().paintBordersFor(textFieldComposite);
-		}
-
-		attribute = this.taskData.getAttribute(BugzillaAttribute.BLOCKED.getKey());
-		if (attribute != null && !attribute.isReadOnly()) {
-			Label label = createLabel(composite, attribute);
-			GridDataFactory.fillDefaults().align(SWT.RIGHT, SWT.CENTER).applyTo(label);
-			Composite textFieldComposite = getManagedForm().getToolkit().createComposite(composite);
-			GridLayout textLayout = new GridLayout();
-			textLayout.marginWidth = 1;
-			textLayout.marginHeight = 3;
-			textLayout.verticalSpacing = 3;
-			textFieldComposite.setLayout(textLayout);
-			GridData textData = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
-			textData.horizontalSpan = 1;
-			textData.widthHint = 135;
-			final Text text = createTextField(textFieldComposite, attribute, SWT.FLAT);
-			text.setLayoutData(textData);
-			getManagedForm().getToolkit().paintBordersFor(textFieldComposite);
-		}
-
-		String dependson = taskData.getAttributeValue(BugzillaAttribute.DEPENDSON.getKey());
-		String blocked = taskData.getAttributeValue(BugzillaAttribute.BLOCKED.getKey());
-		boolean addHyperlinks = (dependson != null && dependson.length() > 0)
-				|| (blocked != null && blocked.length() > 0);
-
-		if (addHyperlinks) {
-			getManagedForm().getToolkit().createLabel(composite, "");
-			addBugHyperlinks(composite, BugzillaAttribute.DEPENDSON.getKey());
-		}
-
-		if (addHyperlinks) {
-			getManagedForm().getToolkit().createLabel(composite, "");
-			addBugHyperlinks(composite, BugzillaAttribute.BLOCKED.getKey());
-		}
-
-		// NOTE: urlText should not be back ported to 3.3 due to background color failure
-		attribute = this.taskData.getAttribute(BugzillaAttribute.BUG_FILE_LOC.getKey());
-		if (attribute != null && !attribute.isReadOnly()) {
-			Label label = createLabel(composite, attribute);
-			GridDataFactory.fillDefaults().align(SWT.RIGHT, SWT.CENTER).applyTo(label);
-			TextViewer urlTextViewer = addTextEditor(repository, composite, attribute.getValue(), //
-					false, SWT.FLAT);
-			final StyledText urlText = urlTextViewer.getTextWidget();
-			urlText.setData(FormToolkit.KEY_DRAW_BORDER, FormToolkit.TEXT_BORDER);
-			urlText.setIndent(2);
-			final RepositoryTaskAttribute urlAttribute = attribute;
-
-			urlTextViewer.setEditable(true);
-			urlTextViewer.addTextListener(new ITextListener() {
-				public void textChanged(TextEvent event) {
-					String newValue = urlText.getText();
-					if (!newValue.equals(urlAttribute.getValue())) {
-						urlAttribute.setValue(newValue);
-						attributeChanged(urlAttribute);
-					}
-				}
-			});
-			GridData textData = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
-			textData.horizontalSpan = 1;
-			textData.widthHint = 135;
-			urlText.setLayoutData(textData);
-			if (hasChanged(attribute)) {
-				urlText.setBackground(getColorIncoming());
-			}
-		}
-
-		attribute = this.taskData.getAttribute(BugzillaAttribute.STATUS_WHITEBOARD.getKey());
-		if (attribute == null) {
-			this.taskData.setAttributeValue(BugzillaAttribute.STATUS_WHITEBOARD.getKey(), "");
-			attribute = this.taskData.getAttribute(BugzillaAttribute.STATUS_WHITEBOARD.getKey());
-		}
-		if (attribute != null && !attribute.isReadOnly()) {
-			Label label = createLabel(composite, attribute);
-			GridDataFactory.fillDefaults().align(SWT.RIGHT, SWT.CENTER).applyTo(label);
-			Text whiteboardField = createTextField(composite, attribute, SWT.FLAT);
-			GridDataFactory.fillDefaults().hint(135, SWT.DEFAULT).applyTo(whiteboardField);
-		}
-
-		try {
-			addKeywordsList(composite);
-		} catch (IOException e) {
-			MessageDialog.openInformation(null, "Attribute Display Error",
-					"Could not retrieve keyword list, ensure proper configuration in "
-							+ TasksUiPlugin.LABEL_VIEW_REPOSITORIES + "\n\nError reported: " + e.getMessage());
-		}
-
-		addVoting(composite);
-
-		// If groups is available add roles
-		if (taskData.getAttribute(BugzillaAttribute.GROUP.getKey()) != null) {
-			addRoles(composite);
-		}
-
-		if (taskData.getAttribute(BugzillaAttribute.ESTIMATED_TIME.getKey()) != null) {
-			addBugzillaTimeTracker(getManagedForm().getToolkit(), composite);
-		}
-	}
-
-	private boolean hasCustomAttributeChanges() {
-		if (taskData == null) {
-			return false;
-		}
-		String customAttributeKeys[] = { BugzillaAttribute.BUG_FILE_LOC.getKey(), BugzillaAttribute.DEPENDSON.getKey(),
-				BugzillaAttribute.BLOCKED.getKey(), BugzillaAttribute.KEYWORDS.getKey(),
-				BugzillaAttribute.VOTES.getKey(), BugzillaAttribute.REPORTER_ACCESSIBLE.getKey(),
-				BugzillaAttribute.CCLIST_ACCESSIBLE.getKey(), BugzillaAttribute.ESTIMATED_TIME.getKey(),
-				BugzillaAttribute.REMAINING_TIME.getKey(), BugzillaAttribute.ACTUAL_TIME.getKey(),
-				BugzillaAttribute.DEADLINE.getKey(), BugzillaAttribute.STATUS_WHITEBOARD.getKey() };
-		for (String key : customAttributeKeys) {
-			RepositoryTaskAttribute attribute = taskData.getAttribute(key);
-			if (hasChanged(attribute)) {
-				return true;
-			}
-		}
-		return false;
-	}
-
-	@Override
-	protected boolean hasVisibleAttributeChanges() {
-		return super.hasVisibleAttributeChanges() || this.hasCustomAttributeChanges();
-
-	}
-
-	private void addBugHyperlinks(Composite composite, String key) {
-		Composite hyperlinksComposite = getManagedForm().getToolkit().createComposite(composite);
-		RowLayout rowLayout = new RowLayout();
-		rowLayout.marginBottom = 0;
-		rowLayout.marginLeft = 0;
-		rowLayout.marginRight = 0;
-		rowLayout.marginTop = 0;
-		rowLayout.spacing = 0;
-		hyperlinksComposite.setLayout(new RowLayout());
-		String values = taskData.getAttributeValue(key);
-
-		if (values != null && values.length() > 0) {
-			for (String bugNumber : values.split(",")) {
-				final String bugId = bugNumber.trim();
-				final String bugUrl = repository.getRepositoryUrl() + IBugzillaConstants.URL_GET_SHOW_BUG + bugId;
-				final AbstractTask task = (AbstractTask) TasksUiInternal.getTaskList().getTask(
-						repository.getRepositoryUrl(), bugId);
-				createTaskListHyperlink(hyperlinksComposite, bugId, bugUrl, task);
-			}
-		}
-	}
-
-	protected void addRoles(Composite parent) {
-		Section rolesSection = getManagedForm().getToolkit().createSection(parent, ExpandableComposite.SHORT_TITLE_BAR);
-		rolesSection.setText("Users in the roles selected below can always view this bug");
-		rolesSection.setDescription("(The assignee can always see a bug, and this section does not take effect unless the bug is restricted to at least one group.)");
-		GridLayout gl = new GridLayout();
-		GridData gd = new GridData(SWT.FILL, SWT.NONE, false, false);
-		gd.horizontalSpan = 4;
-		rolesSection.setLayout(gl);
-		rolesSection.setLayoutData(gd);
-
-		Composite rolesComposite = getManagedForm().getToolkit().createComposite(rolesSection);
-		GridLayout attributesLayout = new GridLayout();
-		attributesLayout.numColumns = 4;
-		attributesLayout.horizontalSpacing = 5;
-		attributesLayout.verticalSpacing = 4;
-		rolesComposite.setLayout(attributesLayout);
-		GridData attributesData = new GridData(GridData.FILL_BOTH);
-		attributesData.horizontalSpan = 1;
-		attributesData.grabExcessVerticalSpace = false;
-		rolesComposite.setLayoutData(attributesData);
-		rolesSection.setClient(rolesComposite);
-
-		RepositoryTaskAttribute attribute = taskData.getAttribute(BugzillaAttribute.REPORTER_ACCESSIBLE.getKey());
-		if (attribute == null) {
-			taskData.setAttributeValue(BugzillaAttribute.REPORTER_ACCESSIBLE.getKey(), "0");
-			attribute = taskData.getAttribute(BugzillaAttribute.REPORTER_ACCESSIBLE.getKey());
-		}
-		Button button = addButtonField(rolesComposite, attribute, SWT.CHECK);
-		if (hasChanged(attribute)) {
-			button.setBackground(getColorIncoming());
-		}
-
-		attribute = null;
-		attribute = taskData.getAttribute(BugzillaAttribute.CCLIST_ACCESSIBLE.getKey());
-		if (attribute == null) {
-			taskData.setAttributeValue(BugzillaAttribute.CCLIST_ACCESSIBLE.getKey(), "0");
-			attribute = taskData.getAttribute(BugzillaAttribute.CCLIST_ACCESSIBLE.getKey());
-		}
-		button = addButtonField(rolesComposite, attribute, SWT.CHECK);
-		if (hasChanged(attribute)) {
-			button.setBackground(getColorIncoming());
-		}
-	}
-
-	@Override
-	protected boolean hasContentAssist(RepositoryTaskAttribute attribute) {
-		return BugzillaAttribute.NEWCC.getKey().equals(attribute.getId());
-	}
-
-	@Override
-	protected boolean hasContentAssist(RepositoryOperation repositoryOperation) {
-		BugzillaOperation operation;
-		try {
-			operation = BugzillaOperation.valueOf(repositoryOperation.getKnobName());
-		} catch (RuntimeException e) {
-			// FIXME: ?
-			StatusHandler.log(new Status(IStatus.INFO, BugzillaUiPlugin.ID_PLUGIN, "Unrecognized operation: "
-					+ repositoryOperation.getKnobName(), e));
-			operation = null;
-		}
-
-		if (operation != null && operation == BugzillaOperation.reassign) {
-			return true;
-		} else {
-			return false;
-		}
-	}
-
-	private Button addButtonField(Composite rolesComposite, RepositoryTaskAttribute attribute, int style) {
-		if (attribute == null) {
-			return null;
-		}
-		String name = attribute.getName();
-		if (hasOutgoingChange(attribute)) {
-			name += "*";
-		}
-
-		final Button button = getManagedForm().getToolkit().createButton(rolesComposite, name, style);
-		if (!attribute.isReadOnly()) {
-			button.setData(attribute);
-			button.setSelection(attribute.getValue().equals("1"));
-			button.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));
-			button.addSelectionListener(new SelectionAdapter() {
-
-				@Override
-				public void widgetSelected(SelectionEvent e) {
-					String sel = "1";
-					if (!button.getSelection()) {
-						sel = "0";
-					}
-					RepositoryTaskAttribute a = (RepositoryTaskAttribute) button.getData();
-					a.setValue(sel);
-					attributeChanged(a);
-				}
-			});
-		}
-		return button;
-	}
-
-	protected void addBugzillaTimeTracker(FormToolkit toolkit, Composite parent) {
-
-		Section timeSection = toolkit.createSection(parent, ExpandableComposite.SHORT_TITLE_BAR);
-		timeSection.setText(LABEL_TIME_TRACKING);
-		GridLayout gl = new GridLayout();
-		GridData gd = new GridData(SWT.FILL, SWT.NONE, false, false);
-		gd.horizontalSpan = 4;
-		timeSection.setLayout(gl);
-		timeSection.setLayoutData(gd);
-
-		Composite timeComposite = toolkit.createComposite(timeSection);
-		gl = new GridLayout(4, false);
-		timeComposite.setLayout(gl);
-		gd = new GridData();
-		gd.horizontalSpan = 5;
-		timeComposite.setLayoutData(gd);
-
-		RepositoryTaskAttribute attribute = this.taskData.getAttribute(BugzillaAttribute.ESTIMATED_TIME.getKey());
-		if (attribute != null && !attribute.isReadOnly()) {
-			createLabel(timeComposite, attribute);
-			estimateText = createTextField(timeComposite, attribute, SWT.FLAT);
-			estimateText.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));
-		}
-
-		Label label = toolkit.createLabel(timeComposite, "Current Estimate:");
-		label.setForeground(toolkit.getColors().getColor(IFormColors.TITLE));
-		float total = 0;
-		try {
-			total = (Float.parseFloat(taskData.getAttributeValue(BugzillaAttribute.ACTUAL_TIME.getKey())) + Float.parseFloat(taskData.getAttributeValue(BugzillaAttribute.REMAINING_TIME.getKey())));
-		} catch (Exception e) {
-			// ignore likely NumberFormatException
-		}
-
-		Text currentEstimate = toolkit.createText(timeComposite, "" + total);
-		currentEstimate.setFont(TEXT_FONT);
-		currentEstimate.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));
-		currentEstimate.setEditable(false);
-
-		attribute = this.taskData.getAttribute(BugzillaAttribute.ACTUAL_TIME.getKey());
-		if (attribute != null) {
-
-			createLabel(timeComposite, attribute);
-			Text actualText = createTextField(timeComposite, attribute, SWT.FLAT);
-			actualText.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));
-			actualText.setEditable(false);
-		}
-
-		// Add Time
-		taskData.setAttributeValue(BugzillaAttribute.WORK_TIME.getKey(), "0");
-		final RepositoryTaskAttribute addTimeAttribute = this.taskData.getAttribute(BugzillaAttribute.WORK_TIME.getKey());
-		if (addTimeAttribute != null) {
-
-			createLabel(timeComposite, addTimeAttribute);
-			addTimeText = toolkit.createText(timeComposite,
-					taskData.getAttributeValue(BugzillaAttribute.WORK_TIME.getKey()), SWT.BORDER);
-			addTimeText.setFont(TEXT_FONT);
-			addTimeText.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));
-			addTimeText.addModifyListener(new ModifyListener() {
-				public void modifyText(ModifyEvent e) {
-					addTimeAttribute.setValue(addTimeText.getText());
-					attributeChanged(addTimeAttribute);
-				}
-			});
-		}
-		attribute = this.taskData.getAttribute(BugzillaAttribute.REMAINING_TIME.getKey());
-		if (attribute != null) {
-			createLabel(timeComposite, attribute);
-			createTextField(timeComposite, attribute, SWT.FLAT);
-		}
-
-		attribute = this.taskData.getAttribute(BugzillaAttribute.DEADLINE.getKey());
-		if (attribute != null) {
-			createLabel(timeComposite, attribute);
-
-			Composite dateWithClear = toolkit.createComposite(timeComposite);
-			GridLayout layout = new GridLayout(2, false);
-			layout.marginWidth = 1;
-			dateWithClear.setLayout(layout);
-
-			deadlinePicker = new DatePicker(dateWithClear, /* SWT.NONE */SWT.BORDER,
-					taskData.getAttributeValue(BugzillaAttribute.DEADLINE.getKey()), false, 0);
-			deadlinePicker.setFont(TEXT_FONT);
-			deadlinePicker.setDatePattern("yyyy-MM-dd");
-			if (hasChanged(attribute)) {
-				deadlinePicker.setBackground(getColorIncoming());
-			}
-			deadlinePicker.addPickerSelectionListener(new SelectionListener() {
-
-				public void widgetDefaultSelected(SelectionEvent e) {
-					// ignore
-				}
-
-				public void widgetSelected(SelectionEvent e) {
-					Calendar cal = deadlinePicker.getDate();
-					if (cal != null) {
-						Date d = cal.getTime();
-						SimpleDateFormat f = (SimpleDateFormat) DateFormat.getDateInstance();
-						f.applyPattern("yyyy-MM-dd");
-
-						taskData.setAttributeValue(BugzillaAttribute.DEADLINE.getKey(), f.format(d));
-						attributeChanged(taskData.getAttribute(BugzillaAttribute.DEADLINE.getKey()));
-						// TODO goes dirty even if user presses cancel
-						// markDirty(true);
-					} else {
-						taskData.setAttributeValue(BugzillaAttribute.DEADLINE.getKey(), "");
-						attributeChanged(taskData.getAttribute(BugzillaAttribute.DEADLINE.getKey()));
-						deadlinePicker.setDate(null);
-					}
-				}
-			});
-
-			ImageHyperlink clearDeadlineDate = toolkit.createImageHyperlink(dateWithClear, SWT.NONE);
-			clearDeadlineDate.setImage(CommonImages.getImage(CommonImages.REMOVE));
-			clearDeadlineDate.setToolTipText("Clear");
-			clearDeadlineDate.addHyperlinkListener(new HyperlinkAdapter() {
-
-				@Override
-				public void linkActivated(HyperlinkEvent e) {
-					taskData.setAttributeValue(BugzillaAttribute.DEADLINE.getKey(), "");
-					attributeChanged(taskData.getAttribute(BugzillaAttribute.DEADLINE.getKey()));
-					deadlinePicker.setDate(null);
-				}
-			});
-
-		}
-
-		timeSection.setClient(timeComposite);
-	}
-
-	protected void addKeywordsList(Composite attributesComposite) throws IOException {
-		// newLayout(attributesComposite, 1, "Keywords:", PROPERTY);
-		final RepositoryTaskAttribute attribute = taskData.getAttribute(RepositoryTaskAttribute.KEYWORDS);
-		if (attribute == null) {
-			return;
-		}
-		Label label = createLabel(attributesComposite, attribute);
-		GridDataFactory.fillDefaults().align(SWT.RIGHT, SWT.CENTER).applyTo(label);
-
-		// toolkit.createText(attributesComposite, keywords)
-		keywordsText = createTextField(attributesComposite, attribute, SWT.FLAT);
-		keywordsText.setFont(TEXT_FONT);
-		GridData keywordsData = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
-		keywordsData.horizontalSpan = 2;
-		keywordsData.widthHint = 200;
-		keywordsText.setLayoutData(keywordsData);
-
-		Button changeKeywordsButton = getManagedForm().getToolkit().createButton(attributesComposite, "Edit...",
-				SWT.FLAT);
-		GridData keyWordsButtonData = new GridData();
-		changeKeywordsButton.setLayoutData(keyWordsButtonData);
-		changeKeywordsButton.addSelectionListener(new SelectionListener() {
-
-			public void widgetDefaultSelected(SelectionEvent e) {
-			}
-
-			public void widgetSelected(SelectionEvent e) {
-
-				String keywords = attribute.getValue();
-
-				Shell shell = null;
-				if (PlatformUI.getWorkbench().getActiveWorkbenchWindow() != null) {
-					shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell();
-				} else {
-					shell = new Shell(PlatformUI.getWorkbench().getDisplay());
-				}
-
-				List<String> validKeywords = new ArrayList<String>();
-				try {
-					validKeywords = BugzillaCorePlugin.getRepositoryConfiguration(repository, false,
-							new NullProgressMonitor()).getKeywords();
-				} catch (Exception ex) {
-					// ignore
-				}
-
-				KeywordsDialog keywordsDialog = new KeywordsDialog(shell, keywords, validKeywords);
-				int responseCode = keywordsDialog.open();
-
-				String newKeywords = keywordsDialog.getSelectedKeywordsString();
-				if (responseCode == Window.OK && keywords != null) {
-					keywordsText.setText(newKeywords);
-					attribute.setValue(newKeywords);
-					attributeChanged(attribute);
-				} else {
-					return;
-				}
-
-			}
-
-		});
-	}
-
-	protected void addVoting(Composite attributesComposite) {
-		Label label = getManagedForm().getToolkit().createLabel(attributesComposite, "Votes:");
-		label.setForeground(getManagedForm().getToolkit().getColors().getColor(IFormColors.TITLE));
-		GridDataFactory.fillDefaults().align(SWT.RIGHT, SWT.CENTER).applyTo(label);
-		Composite votingComposite = getManagedForm().getToolkit().createComposite(attributesComposite);
-		GridLayout layout = new GridLayout(3, false);
-		layout.marginHeight = 0;
-		layout.marginWidth = 0;
-		votingComposite.setLayout(layout);
-
-		RepositoryTaskAttribute votesAttribute = taskData.getAttribute(BugzillaAttribute.VOTES.getKey());
-
-		votesText = createTextField(votingComposite, votesAttribute, SWT.FLAT | SWT.READ_ONLY);
-		votesText.setFont(TEXT_FONT);
-		GridDataFactory.fillDefaults().minSize(30, SWT.DEFAULT).hint(30, SWT.DEFAULT).applyTo(votesText);
-
-		if (votesAttribute != null && hasChanged(votesAttribute)) {
-			votesText.setBackground(getColorIncoming());
-		}
-		votesText.setEditable(false);
-
-		Hyperlink showVotesHyperlink = getManagedForm().getToolkit().createHyperlink(votingComposite, "Show votes",
-				SWT.NONE);
-		showVotesHyperlink.addHyperlinkListener(new HyperlinkAdapter() {
-			@Override
-			public void linkActivated(HyperlinkEvent e) {
-				if (BugzillaTaskEditor.this.getEditor() instanceof TaskEditor) {
-					TasksUiUtil.openUrl(repository.getRepositoryUrl() + IBugzillaConstants.URL_SHOW_VOTES
-							+ taskData.getTaskId());
-				}
-			}
-		});
-
-		Hyperlink voteHyperlink = getManagedForm().getToolkit().createHyperlink(votingComposite, "Vote", SWT.NONE);
-		voteHyperlink.addHyperlinkListener(new HyperlinkAdapter() {
-			@Override
-			public void linkActivated(HyperlinkEvent e) {
-				if (BugzillaTaskEditor.this.getEditor() instanceof TaskEditor) {
-					TasksUiUtil.openUrl(repository.getRepositoryUrl() + IBugzillaConstants.URL_VOTE
-							+ taskData.getTaskId());
-				}
-			}
-		});
-	}
-
-	@Override
-	protected void validateInput() {
-
-	}
-
-	@Override
-	protected String getHistoryUrl() {
-		if (repository != null && taskData != null) {
-			return repository.getRepositoryUrl() + IBugzillaConstants.URL_BUG_ACTIVITY + taskData.getTaskId();
-		} else {
-			return null;
-		}
-	}
-
-	/**
-	 * @author Frank Becker (bug 198027) FIXME: A lot of duplicated code here between this and NewBugzillataskEditor
-	 */
-	@Override
-	protected void addAssignedTo(Composite peopleComposite) {
-		RepositoryTaskAttribute assignedAttribute = taskData.getAttribute(RepositoryTaskAttribute.USER_ASSIGNED);
-		if (assignedAttribute != null) {
-			String bugzillaVersion;
-			try {
-				bugzillaVersion = BugzillaCorePlugin.getRepositoryConfiguration(repository, false,
-						new NullProgressMonitor()).getInstallVersion();
-			} catch (CoreException e1) {
-				// ignore
-				bugzillaVersion = "2.18";
-			}
-			if (bugzillaVersion.compareTo("3.1") < 0) {
-				// old bugzilla workflow is used
-				super.addAssignedTo(peopleComposite);
-				return;
-			}
-			Label label = createLabel(peopleComposite, assignedAttribute);
-			GridDataFactory.fillDefaults().align(SWT.RIGHT, SWT.CENTER).applyTo(label);
-			assignedTo = createTextField(peopleComposite, assignedAttribute, SWT.FLAT);
-			GridDataFactory.fillDefaults().hint(150, SWT.DEFAULT).applyTo(assignedTo);
-			assignedTo.addModifyListener(new ModifyListener() {
-				public void modifyText(ModifyEvent e) {
-					String sel = assignedTo.getText();
-					RepositoryTaskAttribute a = taskData.getAttribute(RepositoryTaskAttribute.USER_ASSIGNED);
-					if (!(a.getValue().equals(sel))) {
-						a.setValue(sel);
-						markDirty(true);
-					}
-				}
-			});
-			ContentAssistCommandAdapter adapter = applyContentAssist(assignedTo,
-					createContentProposalProvider(assignedAttribute));
-			ILabelProvider propsalLabelProvider = createProposalLabelProvider(assignedAttribute);
-			if (propsalLabelProvider != null) {
-				adapter.setLabelProvider(propsalLabelProvider);
-			}
-			adapter.setProposalAcceptanceStyle(ContentProposalAdapter.PROPOSAL_REPLACE);
-
-			FormToolkit toolkit = getManagedForm().getToolkit();
-			Label dummylabel = toolkit.createLabel(peopleComposite, "");
-			GridDataFactory.fillDefaults().align(SWT.RIGHT, SWT.CENTER).applyTo(dummylabel);
-			RepositoryTaskAttribute attribute = taskData.getAttribute(BugzillaAttribute.SET_DEFAULT_ASSIGNEE.getKey());
-			if (attribute == null) {
-				taskData.setAttributeValue(BugzillaAttribute.SET_DEFAULT_ASSIGNEE.getKey(), "0");
-				attribute = taskData.getAttribute(BugzillaAttribute.SET_DEFAULT_ASSIGNEE.getKey());
-			}
-			addButtonField(peopleComposite, attribute, SWT.CHECK);
-		}
-	}
-
-	@Override
-	protected boolean attributeChanged(RepositoryTaskAttribute attribute) {
-		if (attribute == null) {
-			return false;
-		}
-
-		// Support comment wrapping for bugzilla 2.18
-		if (attribute.getId().equals(BugzillaAttribute.NEW_COMMENT.getKey())) {
-			if (repository.getVersion().startsWith("2.18")) {
-				attribute.setValue(BugzillaUiPlugin.formatTextToLineWrap(attribute.getValue(), true));
-			}
-		}
-		return super.attributeChanged(attribute);
-	}
-
-	@Override
-	protected void addSelfToCC(Composite composite) {
-
-		// XXX: Work around for adding QAContact to People section. Update once bug#179254 is complete
-		boolean haveRealName = false;
-		RepositoryTaskAttribute qaContact = taskData.getAttribute(BugzillaAttribute.QA_CONTACT_NAME.getKey());
-		if (qaContact == null) {
-			qaContact = taskData.getAttribute(BugzillaAttribute.QA_CONTACT.getKey());
-		} else {
-			haveRealName = true;
-		}
-		if (qaContact != null) {
-			Label label = createLabel(composite, qaContact);
-			GridDataFactory.fillDefaults().align(SWT.RIGHT, SWT.CENTER).applyTo(label);
-			Text textField;
-			if (qaContact.isReadOnly()) {
-				textField = createTextField(composite, qaContact, SWT.FLAT | SWT.READ_ONLY);
-			} else {
-				textField = createTextField(composite, qaContact, SWT.FLAT);
-				ContentAssistCommandAdapter adapter = applyContentAssist(textField,
-						createContentProposalProvider(qaContact));
-				ILabelProvider propsalLabelProvider = createProposalLabelProvider(qaContact);
-				if (propsalLabelProvider != null) {
-					adapter.setLabelProvider(propsalLabelProvider);
-				}
-				adapter.setProposalAcceptanceStyle(ContentProposalAdapter.PROPOSAL_REPLACE);
-			}
-			GridDataFactory.fillDefaults().grab(true, false).applyTo(textField);
-			if (haveRealName) {
-				textField.setText(textField.getText() + " <"
-						+ taskData.getAttributeValue(BugzillaAttribute.QA_CONTACT.getKey()) + ">");
-			}
-		}
-
-		super.addSelfToCC(composite);
-
-	}
-
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/BugzillaTaskEditorFactory.java b/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/BugzillaTaskEditorFactory.java
deleted file mode 100644
index 9be0cda..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/BugzillaTaskEditorFactory.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004, 2008 Tasktop Technologies and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     Tasktop Technologies - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.mylyn.bugzilla.deprecated;
-
-import org.eclipse.mylyn.internal.bugzilla.core.BugzillaCorePlugin;
-import org.eclipse.mylyn.internal.tasks.ui.deprecated.AbstractRepositoryTaskEditor;
-import org.eclipse.mylyn.internal.tasks.ui.deprecated.AbstractTaskEditorFactory;
-import org.eclipse.mylyn.internal.tasks.ui.deprecated.RepositoryTaskEditorInput;
-import org.eclipse.mylyn.tasks.core.ITask;
-import org.eclipse.mylyn.tasks.core.TaskRepository;
-import org.eclipse.mylyn.tasks.ui.TasksUi;
-import org.eclipse.mylyn.tasks.ui.editors.TaskEditor;
-import org.eclipse.mylyn.tasks.ui.editors.TaskEditorInput;
-import org.eclipse.ui.IEditorInput;
-import org.eclipse.ui.part.EditorPart;
-
-/**
- * @author Mik Kersten
- * @author Rob Elves
- */
-public class BugzillaTaskEditorFactory extends AbstractTaskEditorFactory {
-
-	private static final String TITLE = "Bugzilla";
-
-	@Override
-	public EditorPart createEditor(TaskEditor parentEditor, IEditorInput editorInput) {
-		AbstractRepositoryTaskEditor editor = null;
-		if (editorInput instanceof RepositoryTaskEditorInput) {
-			RepositoryTaskEditorInput taskInput = (RepositoryTaskEditorInput) editorInput;
-			if (taskInput.getTaskData().isNew()) {
-				editor = new NewBugzillaTaskEditor(parentEditor);
-			} else {
-				editor = new BugzillaTaskEditor(parentEditor);
-			}
-		} else if (editorInput instanceof TaskEditorInput) {
-			editor = new BugzillaTaskEditor(parentEditor);
-		}
-		return editor;
-	}
-
-	@Override
-	public IEditorInput createEditorInput(ITask task) {
-		if (task instanceof BugzillaTask) {
-			BugzillaTask bugzillaTask = (BugzillaTask) task;
-			final TaskRepository repository = TasksUi.getRepositoryManager().getRepository(
-					BugzillaCorePlugin.CONNECTOR_KIND, bugzillaTask.getRepositoryUrl());
-			BugzillaTaskEditorInput input = new BugzillaTaskEditorInput(repository, bugzillaTask, true);
-			return input;
-		}
-		return null;
-	}
-
-	@Override
-	public String getTitle() {
-		return TITLE;
-	}
-
-	@Override
-	public boolean canCreateEditorFor(ITask task) {
-		return task instanceof BugzillaTask;
-	}
-
-	@Override
-	public boolean providesOutline() {
-		return true;
-	}
-
-	@Override
-	public boolean canCreateEditorFor(IEditorInput input) {
-		if (input instanceof RepositoryTaskEditorInput) {
-			return BugzillaCorePlugin.CONNECTOR_KIND.equals(((RepositoryTaskEditorInput) input).getRepository()
-					.getConnectorKind());
-		}
-		return false;
-	}
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/BugzillaTaskEditorInput.java b/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/BugzillaTaskEditorInput.java
deleted file mode 100644
index 3567cb5..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/BugzillaTaskEditorInput.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004, 2008 Tasktop Technologies and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     Tasktop Technologies - initial API and implementation
- *     Eric Booth - contribution
- *******************************************************************************/
-
-package org.eclipse.mylyn.bugzilla.deprecated;
-
-import org.eclipse.mylyn.internal.tasks.ui.deprecated.RepositoryTaskEditorInput;
-import org.eclipse.mylyn.tasks.core.TaskRepository;
-import org.eclipse.ui.IPersistableElement;
-
-/**
- * @author Eric Booth
- * @author Mik Kersten
- * @author Rob Elves
- */
-public class BugzillaTaskEditorInput extends RepositoryTaskEditorInput {
-
-	private String bugTitle = "";
-
-	private final BugzillaTask bugTask;
-
-	public BugzillaTaskEditorInput(TaskRepository repository, BugzillaTask bugzillaTask, boolean offline) {
-		super(repository, bugzillaTask.getTaskId(), bugzillaTask.getUrl());
-		this.bugTask = bugzillaTask;
-//		updateOptions(getTaskData());
-//		updateOptions(getOldTaskData());
-	}
-
-	protected void setBugTitle(String str) {
-		// 03-20-03 Allows editor to store title (once it is known)
-		bugTitle = str;
-	}
-
-	@Override
-	public boolean exists() {
-		return true;
-	}
-
-	@Override
-	public IPersistableElement getPersistable() {
-		return null;
-	}
-
-	@Override
-	public String getToolTipText() {
-		return bugTitle;
-	}
-
-	@SuppressWarnings("unchecked")
-	@Override
-	public Object getAdapter(Class adapter) {
-		return null;
-	}
-
-	/**
-	 * @return Returns the <code>BugzillaTask</code>
-	 */
-	public BugzillaTask getBugTask() {
-		return bugTask;
-	}
-
-//	private void updateOptions(TaskData taskData) {
-//		try {
-//			if (taskData != null) {
-//				RepositoryConfiguration config = BugzillaCorePlugin.getRepositoryConfiguration(repository, false,
-//						new NullProgressMonitor());
-//				config.updateAttributeOptions(taskData);
-//			}
-//		} catch (Exception e) {
-//			// ignore
-//		}
-//	}
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/BugzillaTaskHyperlinkDetector.java b/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/BugzillaTaskHyperlinkDetector.java
deleted file mode 100644
index 723f03d..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/BugzillaTaskHyperlinkDetector.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004 - 2006 University Of British Columbia and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     University Of British Columbia - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.mylyn.internal.bugzilla.ui;
-
-import java.util.ArrayList;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import org.eclipse.jface.text.IRegion;
-import org.eclipse.jface.text.Region;
-import org.eclipse.jface.text.hyperlink.IHyperlink;
-import org.eclipse.mylyn.internal.bugzilla.core.BugzillaCorePlugin;
-import org.eclipse.mylyn.tasks.core.TaskRepository;
-import org.eclipse.mylyn.tasks.ui.TaskHyperlink;
-import org.eclipse.mylyn.tasks.ui.editors.AbstractTaskHyperlinkDetector;
-import org.eclipse.mylyn.tasks.ui.editors.TaskHyperlinkDetector;
-
-/**
- * @author Rob Elves
- */
-public class BugzillaTaskHyperlinkDetector extends TaskHyperlinkDetector {
-
-	private static final int TASK_NUM_GROUP = 3;
-
-	private static final String regexp = "(duplicate of|bug|task)(\\s#|#|#\\s|\\s|)(\\s\\d+|\\d+)";
-
-	private static final Pattern PATTERN = Pattern.compile(regexp, Pattern.CASE_INSENSITIVE);
-
-	@Override
-	protected IHyperlink[] findHyperlinks(TaskRepository repository, String text, int lineOffset, int regionOffset) {
-		ArrayList<IHyperlink> hyperlinksFound = new ArrayList<IHyperlink>();
-
-		Matcher m = PATTERN.matcher(text);
-		while (m.find()) {
-			if (lineOffset >= m.start() && lineOffset <= m.end()) {
-				IHyperlink link = extractHyperlink(repository, regionOffset, m);
-				if (link != null)
-					hyperlinksFound.add(link);
-			}
-		}
-
-		if (hyperlinksFound.size() > 0) {
-			return hyperlinksFound.toArray(new IHyperlink[1]);
-		}
-		return null;
-	}
-
-	private static IHyperlink extractHyperlink(TaskRepository repository, int regionOffset, Matcher m) {
-
-		int start = -1;
-
-		if (m.group().startsWith("duplicate")) {
-			start = m.start() + m.group().indexOf(m.group(TASK_NUM_GROUP));
-		} else {
-			start = m.start();
-		}
-
-		int end = m.end();
-
-		if (end == -1)
-			end = m.group().length();
-
-		try {
-
-			String bugId = m.group(TASK_NUM_GROUP).trim();
-			start += regionOffset;
-			end += regionOffset;
-
-			IRegion sregion = new Region(start, end - start);
-			return new TaskHyperlink(sregion, repository, bugId);
-
-		} catch (NumberFormatException e) {
-			return null;
-		}
-	}
-
-	@Override
-	protected String getTargetID() {
-		return BugzillaCorePlugin.REPOSITORY_KIND;
-	}
-
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/BugzillaTaskListFactory.java b/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/BugzillaTaskListFactory.java
deleted file mode 100644
index 4d3d72f..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/BugzillaTaskListFactory.java
+++ /dev/null
@@ -1,104 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004, 2008 Tasktop Technologies and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     Tasktop Technologies - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.mylyn.bugzilla.deprecated;
-
-import java.util.HashSet;
-import java.util.Set;
-
-import org.eclipse.mylyn.internal.tasks.core.AbstractTask;
-import org.eclipse.mylyn.internal.tasks.core.RepositoryQuery;
-import org.eclipse.mylyn.internal.tasks.core.deprecated.AbstractTaskListFactory;
-import org.eclipse.mylyn.tasks.core.IRepositoryQuery;
-import org.eclipse.mylyn.tasks.core.ITask;
-import org.w3c.dom.Element;
-
-/**
- * @author Mik Kersten
- * @deprecated see BugzillaTaskListMigrator
- */
-@Deprecated
-public class BugzillaTaskListFactory extends AbstractTaskListFactory {
-
-	private static final String KEY_SEVERITY = "bugzilla.severity";
-
-	private static final String KEY_PRODUCT = "bugzilla.product";
-
-	private static final String TAG_BUGZILLA = "Bugzilla";
-
-	private static final String TAG_BUGZILLA_QUERY = TAG_BUGZILLA + KEY_QUERY;
-
-	private static final String TAG_BUGZILLA_CUSTOM_QUERY = "BugzillaCustom" + KEY_QUERY;
-
-	private static final String TAG_BUGZILLA_REPORT = "BugzillaReport";
-
-	@Override
-	public String getTaskElementName() {
-		return TAG_BUGZILLA_REPORT;
-	}
-
-	@Override
-	public Set<String> getQueryElementNames() {
-		Set<String> names = new HashSet<String>();
-		names.add(TAG_BUGZILLA_QUERY);
-		names.add(TAG_BUGZILLA_CUSTOM_QUERY);
-		return names;
-	}
-
-	@Override
-	public boolean canCreate(IRepositoryQuery category) {
-		return category instanceof BugzillaRepositoryQuery;
-	}
-
-	@Override
-	public boolean canCreate(ITask task) {
-		return task instanceof BugzillaTask;
-	}
-
-	@Override
-	public String getQueryElementName(IRepositoryQuery query) {
-		if (query instanceof BugzillaRepositoryQuery) {
-			if (((BugzillaRepositoryQuery) query).isCustomQuery()) {
-				return TAG_BUGZILLA_CUSTOM_QUERY;
-			} else {
-				return TAG_BUGZILLA_QUERY;
-			}
-		}
-		return null;
-	}
-
-	@Override
-	public RepositoryQuery createQuery(String repositoryUrl, String queryString, String label, Element element) {
-		BugzillaRepositoryQuery query = new BugzillaRepositoryQuery(repositoryUrl, queryString, label);
-		if (element.getNodeName().equals(TAG_BUGZILLA_CUSTOM_QUERY)) {
-			query.setCustomQuery(true);
-		}
-		return query;
-	}
-
-	@Override
-	public void setAdditionalAttributes(ITask task, Element element) {
-		element.setAttribute(KEY_SEVERITY, ((BugzillaTask) task).getSeverity());
-		element.setAttribute(KEY_PRODUCT, ((BugzillaTask) task).getProduct());
-	}
-
-	@Override
-	public AbstractTask createTask(String repositoryUrl, String taskId, String summary, Element element) {
-		BugzillaTask task = new BugzillaTask(repositoryUrl, taskId, summary);
-		if (element.hasAttribute(KEY_SEVERITY)) {
-			task.setSeverity(element.getAttribute(KEY_SEVERITY));
-		}
-		if (element.hasAttribute(KEY_PRODUCT)) {
-			task.setProduct(element.getAttribute(KEY_PRODUCT));
-		}
-		return task;
-	}
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/CreateBugzillaTaskAction.java b/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/CreateBugzillaTaskAction.java
deleted file mode 100644
index a60e6f4..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/CreateBugzillaTaskAction.java
+++ /dev/null
@@ -1,113 +0,0 @@
-///*******************************************************************************
-// * Copyright (c) 2004 - 2005 University Of British Columbia and others.
-// * All rights reserved. This program and the accompanying materials
-// * are made available under the terms of the Eclipse Public License v1.0
-// * which accompanies this distribution, and is available at
-// * http://www.eclipse.org/legal/epl-v10.html
-// *
-// * Contributors:
-// *     University Of British Columbia - initial API and implementation
-// *******************************************************************************/
-//
-//package org.eclipse.mylyn.bugzilla.ui.actions;
-//
-//import org.eclipse.jface.action.Action;
-//import org.eclipse.jface.action.IAction;
-//import org.eclipse.jface.viewers.ISelection;
-//import org.eclipse.jface.viewers.IStructuredSelection;
-//import org.eclipse.jface.viewers.StructuredSelection;
-//import org.eclipse.mylyn.bugzilla.core.BugzillaPlugin;
-//import org.eclipse.mylyn.bugzilla.ui.BugzillaImages;
-//import org.eclipse.mylyn.bugzilla.ui.BugzillaUiPlugin;
-//import org.eclipse.mylyn.bugzilla.ui.tasklist.BugzillaTask;
-//import org.eclipse.mylyn.tasklist.ITask;
-//import org.eclipse.mylyn.tasklist.ITaskHandler;
-//import org.eclipse.mylyn.tasklist.MylarTaskListPlugin;
-//import org.eclipse.mylyn.tasklist.TaskRepository;
-//import org.eclipse.mylyn.tasklist.internal.TaskCategory;
-//import org.eclipse.mylyn.tasklist.internal.TaskRepositoryManager;
-//import org.eclipse.mylyn.tasklist.ui.views.TaskListView;
-//import org.eclipse.ui.IViewActionDelegate;
-//import org.eclipse.ui.IViewPart;
-//
-///**
-// * @author Mik Kersten
-// * @author Ken Sueda
-// */
-//public class CreateBugzillaTaskAction extends Action implements IViewActionDelegate {
-//	
-//	private static final String LABEL = "Add Existing Bugzilla Report";
-//
-//	public static final String ID = "org.eclipse.mylyn.tasklist.actions.create.bug";
-//		
-//	public CreateBugzillaTaskAction() {
-//		setText(LABEL);
-//        setToolTipText(LABEL);
-//        setId(ID); 
-//        setImageDescriptor(BugzillaImages.TASK_BUGZILLA);
-//	} 
-//	
-//	@Override
-//	public void run() {
-//		if(TaskListView.getDefault() == null)
-//			return;
-//
-//	    String bugIdString = TaskListView.getDefault().getBugIdFromUser();
-//	    int bugId = -1;
-//	    try {
-//	    	if (bugIdString != null) {
-//	    		bugId = Integer.parseInt(bugIdString);
-//	    	} else {
-//	    		return;
-//	    	}
-//	    } catch (NumberFormatException nfe) {
-//	        TaskListView.getDefault().showMessage("Please enter a valid report number");
-//	        return;
-//	    }
-//	
-//	    TaskRepository repository = MylarTaskListPlugin.getRepositoryManager().getDefaultRepository(BugzillaPlugin.REPOSITORY_KIND);
-//	    ITask newTask = new BugzillaTask(
-//	    		TaskRepositoryManager.getHandle(repository.getUrl().toExternalForm(), bugId), 
-//	    		"<bugzilla info>", true, true);				
-//	    Object selectedObject = ((IStructuredSelection)TaskListView.getDefault().getViewer().getSelection()).getFirstElement();
-//    	
-//	    ITaskHandler taskHandler = MylarTaskListPlugin.getDefault().getHandlerForElement(newTask);
-//	    if(taskHandler != null){
-//	    	ITask addedTask = taskHandler.taskAdded(newTask);
-//	    	if(addedTask instanceof BugzillaTask){
-//		    	BugzillaTask newTask2 = (BugzillaTask)addedTask;
-//	    		if(newTask2 == newTask){
-//	    			((BugzillaTask)newTask).scheduleDownloadReport();
-//	    		} else {
-//	    			newTask = newTask2;
-//	    			((BugzillaTask)newTask).updateTaskDetails();
-//	    		}
-//	    	}
-//    	} else {
-//    		((BugzillaTask)newTask).scheduleDownloadReport();
-//    	}
-//	    if (selectedObject instanceof TaskCategory) {
-//	    	MylarTaskListPlugin.getTaskListManager().moveToCategory(((TaskCategory)selectedObject), newTask);
-//	    } else { 
-//	        MylarTaskListPlugin.getTaskListManager().moveToRoot(newTask);
-//	    }
-//	    BugzillaUiPlugin.getDefault().getBugzillaTaskListManager().addToBugzillaTaskRegistry((BugzillaTask)newTask);
-//
-//	    if(TaskListView.getDefault() != null) {
-//			// Make this new task the current selection in the view
-//			TaskListView.getDefault().getViewer().setSelection(new StructuredSelection(newTask));
-//			TaskListView.getDefault().getViewer().refresh();
-//	    }
-//	}
-//
-//	public void init(IViewPart view) {
-//	}
-//
-//	public void run(IAction action) {
-//		run();
-//	}
-//
-//	public void selectionChanged(IAction action, ISelection selection) {
-//		
-//	}
-//}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/DeleteFavoriteAction.java b/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/DeleteFavoriteAction.java
deleted file mode 100644
index 7ff5995..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/DeleteFavoriteAction.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004 - 2006 University Of British Columbia and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     University Of British Columbia - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.mylyn.internal.bugzilla.ui.actions;
-
-import org.eclipse.mylyn.internal.bugzilla.ui.BugzillaImages;
-import org.eclipse.mylyn.internal.bugzilla.ui.FavoritesView;
-
-/**
- * Action of removing a bookmark
- */
-public class DeleteFavoriteAction extends AbstractFavoritesAction {
-	/** The instance of the favorites view */
-	private FavoritesView view;
-
-	/** True if all of the bookmarks are to be deleted */
-	private boolean deleteAll;
-
-	/**
-	 * Constructor
-	 * 
-	 * @param favoritesView
-	 *            The favorites view being used
-	 * @param deleteAllFavorites
-	 *            <code>true</code> if all of the favorites should be deleted,
-	 *            else <code>false</code>
-	 */
-	public DeleteFavoriteAction(FavoritesView favoritesView, boolean deleteAllFavorites) {
-		deleteAll = deleteAllFavorites;
-
-		// set the appropriate icons and tool tips for the action depending
-		// on whether it will delete all items or not
-		if (deleteAll) {
-			setToolTipText("Remove All Favorites");
-			setText("Remove All");
-			setImageDescriptor(BugzillaImages.REMOVE_ALL);
-		} else {
-			setToolTipText("Remove Selected Favorites");
-			setText("Remove");
-			setImageDescriptor(BugzillaImages.REMOVE);
-		}
-
-		view = favoritesView;
-	}
-
-	/**
-	 * Delete the appropriate favorites
-	 * 
-	 * @see org.eclipse.jface.action.IAction#run()
-	 */
-	@Override
-	public void run() {
-		FavoritesView.checkWindow();
-
-		// call the appropriate delete function
-		if (deleteAll)
-			view.deleteAllFavorites();
-		else
-			view.deleteSelectedFavorites();
-		FavoritesView.updateActionEnablement();
-	}
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/DummySearchHitProvider.java b/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/DummySearchHitProvider.java
deleted file mode 100644
index 46e2aed..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/DummySearchHitProvider.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004, 2008 Tasktop Technologies and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     Tasktop Technologies - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.mylyn.bugzilla.deprecated;
-
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.mylyn.internal.tasks.core.AbstractTask;
-import org.eclipse.mylyn.internal.tasks.core.ITaskList;
-import org.eclipse.mylyn.internal.tasks.core.deprecated.ITaskFactory;
-import org.eclipse.mylyn.internal.tasks.core.deprecated.QueryHitCollector;
-import org.eclipse.mylyn.internal.tasks.core.deprecated.RepositoryTaskData;
-
-public class DummySearchHitProvider extends QueryHitCollector {
-
-	public DummySearchHitProvider(ITaskList tasklist) {
-		super(new ITaskFactory() {
-
-			public AbstractTask createTask(RepositoryTaskData taskData, IProgressMonitor monitor) throws CoreException {
-				return null;
-			}
-		});
-	}
-
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/Favorite.java b/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/Favorite.java
deleted file mode 100644
index 1e1f2db..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/Favorite.java
+++ /dev/null
@@ -1,113 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2003 - 2006 University Of British Columbia and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     University Of British Columbia - initial API and implementation
- *******************************************************************************/
-package org.eclipse.mylyn.internal.bugzilla.core.internal;
-
-import java.io.Serializable;
-import java.util.Date;
-import java.util.Map;
-
-import org.eclipse.mylyn.bugzilla.core.BugzillaReport;
-import org.eclipse.mylyn.internal.bugzilla.core.search.BugzillaSearchResultCollector;
-
-/**
- * Class representing an item in the favorites view
- */
-public class Favorite implements Serializable {
-
-	/** Automatically generated serialVersionUID */
-	private static final long serialVersionUID = 3258129158977632310L;
-
-	/** Bug id */
-	private int id;
-
-	/** Bug description */
-	private String description;
-
-	/** Query that created the match */
-	private String query;
-
-	/** Bug's attributes (severity, priority, etc.) */
-	private Map<String, Object> attributes;
-
-	/** Date when the favorite was recommended. */
-	private Date date;
-
-	private String server;
-
-	/**
-	 * Constructor.
-	 * 
-	 * @param bug
-	 *            The bug this favorite represents.
-	 */
-	public Favorite(BugzillaReport bug) {
-		this(bug.getRepositoryUrl(), bug.getId(), bug.getSummary(), "", BugzillaSearchResultCollector.getAttributeMap(bug));
-	}
-
-	/**
-	 * Constructor.
-	 */
-	public Favorite(String server, int id, String description, String query, Map<String, Object> attributes) {
-		this.server = server;
-		this.id = id;
-		this.description = description;
-		this.query = query;
-		this.attributes = attributes;
-		date = new Date();
-	}
-
-	/**
-	 * returns the server for the bug
-	 */
-	public String getServer() {
-		return server;
-	}
-
-	/**
-	 * Returns bug's id.
-	 */
-	public int getId() {
-		return id;
-	}
-
-	/**
-	 * Returns bug's description.
-	 */
-	public String getDescription() {
-		return description;
-	}
-
-	/**
-	 * Returns bug attributes.
-	 */
-	public Map<String, Object> getAttributes() {
-		return attributes;
-	}
-
-	/**
-	 * Returns the query that created the match.
-	 */
-	public String getQuery() {
-		return query;
-	}
-
-	/**
-	 * Returns date when the favorite was added to the view.
-	 */
-	public Date getDate() {
-		return date;
-	}
-
-	@Override
-	public String toString() {
-		return id + " - " + description;
-	}
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/FavoritesFile.java b/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/FavoritesFile.java
deleted file mode 100644
index b33df4f..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/FavoritesFile.java
+++ /dev/null
@@ -1,316 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2003 - 2006 University Of British Columbia and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     University Of British Columbia - initial API and implementation
- *******************************************************************************/
-package org.eclipse.mylyn.internal.bugzilla.core.internal;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Comparator;
-import java.util.List;
-
-import org.eclipse.jface.dialogs.MessageDialog;
-import org.eclipse.mylyn.internal.bugzilla.core.BugzillaPlugin;
-import org.eclipse.mylyn.internal.bugzilla.core.IBugzillaConstants;
-
-/**
- * Class to persist the data for the favorites list
- */
-public class FavoritesFile {
-	/** The file that the favorites are written to */
-	private File file;
-
-	/** The directory to where the file is located */
-	/** A list of favorites */
-	private ArrayList<Favorite> list = new ArrayList<Favorite>();
-
-	/** Sort by bug ID */
-	public static final int ID_SORT = 0;
-
-	/** Sort by bug priority */
-	public static final int PRIORITY_SORT = 1;
-
-	/** Sort by bug priority */
-	public static final int SEVERITY_SORT = 2;
-
-	/** Sort by bug state */
-	public static final int STATE_SORT = 3;
-
-	/** Default sort by bug ID */
-	public static int lastSel = 0;
-
-	/**
-	 * Constructor that reads the favorites data persisted in the plugin's state
-	 * directory, if it exists.
-	 * 
-	 * @param file
-	 *            The file where the favorites are persisted
-	 * @throws IOException
-	 *             Error opening or closing the favorites file
-	 * @throws ClassNotFoundException
-	 *             Error deserializing objects from the favorites file
-	 */
-	public FavoritesFile(File file) throws ClassNotFoundException, IOException {
-		this.file = file;
-		if (file.exists()) {
-			readFile();
-		}
-	}
-
-	/**
-	 * Add a favorite to the favorites list
-	 * 
-	 * @param entry
-	 *            The bug to add
-	 */
-	public void add(Favorite entry) {
-		// add the entry to the list and write the file to disk
-		list.add(entry);
-		writeFile();
-	}
-
-	/**
-	 * Find a bug in the favorites list
-	 * 
-	 * @param id
-	 *            The bug id that we are looking for
-	 * @return The index of the bug in the array if it exists, else 0
-	 */
-	public int find(int id) {
-		for (int i = 0; i < list.size(); i++) {
-			Favorite currFav = list.get(i);
-			if (currFav.getId() == id)
-				return i;
-		}
-		return 0;
-	}
-
-	/**
-	 * Get the list of favorites
-	 * 
-	 * @return The list of favorites
-	 */
-	public ArrayList<Favorite> elements() {
-		return list;
-	}
-
-	/**
-	 * Write the favorites to disk
-	 */
-	private void writeFile() {
-		try {
-			ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(file));
-
-			// Write the size of the list so that we can read it back in easier
-			out.writeInt(list.size());
-
-			// write each element in the array list
-			for (int i = 0; i < list.size(); i++) {
-				Object item = list.get(i);
-				out.writeObject(item);
-			}
-			out.close();
-		} catch (IOException e) {
-			// put up a message and log the error if there is a problem writing
-			// to the file
-			MessageDialog.openError(null, "I/O Error", "Bugzilla could not write to favorites file.");
-			BugzillaPlugin.log(e);
-		}
-	}
-
-	/**
-	 * Read the favorites in from the file on disk
-	 * 
-	 * @throws IOException
-	 *             Error opening or closing the favorites file
-	 * @throws ClassNotFoundException
-	 *             Error deserializing objects from the favorites file
-	 */
-	private void readFile() throws ClassNotFoundException, IOException {
-		ObjectInputStream in = new ObjectInputStream(new FileInputStream(file));
-
-		// get the number of favorites in the file
-		int size = in.readInt();
-
-		// read in each of the favorites in the file
-		for (int nX = 0; nX < size; nX++) {
-			Favorite item = (Favorite) in.readObject();
-			// add the favorite to the favorites list
-			list.add(item);
-		}
-		in.close();
-
-		sort(lastSel);
-	}
-
-	/**
-	 * Remove some bugs from the favorites list
-	 * 
-	 * @param indicesToRemove
-	 *            An array of the indicies of the bugs to be removed
-	 */
-	public void remove(List<Favorite> sel) {
-		list.removeAll(sel);
-
-		// rewrite the file so that the data is persistant
-		writeFile();
-	}
-
-	/**
-	 * Remove all of the items in the favortes menu
-	 */
-	public void removeAll() {
-		list.clear();
-
-		// rewrite the file so that the data is persistant
-		writeFile();
-	}
-
-	/**
-	 * Function to sort the favorites list
-	 * 
-	 * @param sortOrder
-	 *            The way to sort the bugs in the favorites list
-	 */
-	public void sort(int sortOrder) {
-		Favorite[] a = list.toArray(new Favorite[list.size()]);
-
-		// decide which sorting method to use and sort the favorites
-		switch (sortOrder) {
-		case ID_SORT:
-			Arrays.sort(a, new SortID());
-			lastSel = ID_SORT;
-			break;
-		case PRIORITY_SORT:
-			Arrays.sort(a, new SortPriority());
-			lastSel = PRIORITY_SORT;
-			break;
-
-		case SEVERITY_SORT:
-			Arrays.sort(a, new SortSeverity());
-			lastSel = SEVERITY_SORT;
-			break;
-
-		case STATE_SORT:
-			Arrays.sort(a, new SortState());
-			lastSel = STATE_SORT;
-			break;
-		}
-
-		// remove all of the elements from the list so that we can re-add
-		// them in a sorted order
-		list.clear();
-
-		// add the sorted elements to the list and the table
-		for (int j = 0; j < a.length; j++) {
-			add(a[j]);
-		}
-	}
-
-	/**
-	 * Inner class to sort by bug id
-	 */
-	private class SortID implements Comparator<Favorite> {
-		/**
-		 * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
-		 */
-		public int compare(Favorite f1, Favorite f2) {
-			Integer id1 = (Integer) f1.getAttributes().get(IBugzillaConstants.HIT_MARKER_ATTR_ID);
-			Integer id2 = (Integer) f2.getAttributes().get(IBugzillaConstants.HIT_MARKER_ATTR_ID);
-
-			if (id1 != null && id2 != null)
-				return id1.compareTo(id2);
-			else if (id1 == null && id2 != null)
-				return -1;
-			else if (id1 != null && id2 == null)
-				return 1;
-			else
-				return 0;
-		}
-	}
-
-	/**
-	 * Inner class to sort by priority
-	 */
-	private class SortPriority implements Comparator<Favorite> {
-		/*
-		 * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
-		 */
-		public int compare(Favorite f1, Favorite f2) {
-			Integer pri1 = (Integer) f1.getAttributes().get(IBugzillaConstants.HIT_MARKER_ATTR_PRIORITY);
-			Integer pri2 = (Integer) f2.getAttributes().get(IBugzillaConstants.HIT_MARKER_ATTR_PRIORITY);
-
-			if (pri1 != null && pri2 != null)
-				return pri1.compareTo(pri2);
-			else if (pri1 == null && pri2 != null)
-				return -1;
-			else if (pri1 != null && pri2 == null)
-				return 1;
-			else
-				return 0;
-		}
-	}
-
-	/**
-	 * Inner class to sort by severity
-	 */
-	private class SortSeverity implements Comparator<Favorite> {
-		/*
-		 * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
-		 */
-		public int compare(Favorite f1, Favorite f2) {
-			Integer sev1 = (Integer) f1.getAttributes().get(IBugzillaConstants.HIT_MARKER_ATTR_SEVERITY);
-			Integer sev2 = (Integer) f2.getAttributes().get(IBugzillaConstants.HIT_MARKER_ATTR_SEVERITY);
-
-			if (sev1 != null && sev2 != null)
-				return sev1.compareTo(sev2);
-			else if (sev1 == null && sev2 != null)
-				return -1;
-			else if (sev1 != null && sev2 == null)
-				return 1;
-			else
-				return 0;
-		}
-	}
-
-	/**
-	 * Inner class to sort by state
-	 */
-	private class SortState implements Comparator<Favorite> {
-		/*
-		 * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
-		 */
-		public int compare(Favorite f1, Favorite f2) {
-			Integer sta1 = (Integer) f1.getAttributes().get(IBugzillaConstants.HIT_MARKER_ATTR_STATE);
-			Integer sta2 = (Integer) f2.getAttributes().get(IBugzillaConstants.HIT_MARKER_ATTR_STATE);
-
-			if (sta1 != null && sta2 != null) {
-				int rc = sta1.compareTo(sta2);
-				if (rc == 0) {
-					Integer res1 = (Integer) f1.getAttributes().get(IBugzillaConstants.HIT_MARKER_ATTR_RESULT);
-					Integer res2 = (Integer) f2.getAttributes().get(IBugzillaConstants.HIT_MARKER_ATTR_RESULT);
-
-					return res1.compareTo(res2);
-				} else
-					return rc;
-			} else if (sta1 == null && sta2 != null)
-				return -1;
-			else if (sta1 != null && sta2 == null)
-				return 1;
-			else
-				return 0;
-		}
-	}
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/FavoritesView.java b/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/FavoritesView.java
deleted file mode 100644
index f4fa1a5..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/FavoritesView.java
+++ /dev/null
@@ -1,574 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2003 - 2006 University Of British Columbia and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     University Of British Columbia - initial API and implementation
- *******************************************************************************/
-package org.eclipse.mylyn.internal.bugzilla.ui;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-import org.eclipse.jface.action.Action;
-import org.eclipse.jface.action.GroupMarker;
-import org.eclipse.jface.action.IMenuListener;
-import org.eclipse.jface.action.IMenuManager;
-import org.eclipse.jface.action.IStatusLineManager;
-import org.eclipse.jface.action.IToolBarManager;
-import org.eclipse.jface.action.MenuManager;
-import org.eclipse.jface.action.Separator;
-import org.eclipse.jface.viewers.ColumnLayoutData;
-import org.eclipse.jface.viewers.ColumnWeightData;
-import org.eclipse.jface.viewers.ISelectionChangedListener;
-import org.eclipse.jface.viewers.IStructuredContentProvider;
-import org.eclipse.jface.viewers.IStructuredSelection;
-import org.eclipse.jface.viewers.ITableLabelProvider;
-import org.eclipse.jface.viewers.LabelProvider;
-import org.eclipse.jface.viewers.SelectionChangedEvent;
-import org.eclipse.jface.viewers.TableLayout;
-import org.eclipse.jface.viewers.TableViewer;
-import org.eclipse.jface.viewers.Viewer;
-import org.eclipse.mylyn.internal.bugzilla.core.BugzillaPlugin;
-import org.eclipse.mylyn.internal.bugzilla.core.IBugzillaConstants;
-import org.eclipse.mylyn.internal.bugzilla.core.internal.Favorite;
-import org.eclipse.mylyn.internal.bugzilla.core.internal.FavoritesFile;
-import org.eclipse.mylyn.internal.bugzilla.ui.actions.AbstractFavoritesAction;
-import org.eclipse.mylyn.internal.bugzilla.ui.actions.DeleteFavoriteAction;
-import org.eclipse.mylyn.internal.bugzilla.ui.actions.ViewFavoriteAction;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.KeyAdapter;
-import org.eclipse.swt.events.KeyEvent;
-import org.eclipse.swt.events.MouseAdapter;
-import org.eclipse.swt.events.MouseEvent;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.events.SelectionListener;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Menu;
-import org.eclipse.swt.widgets.Table;
-import org.eclipse.swt.widgets.TableColumn;
-import org.eclipse.swt.widgets.TableItem;
-import org.eclipse.ui.IActionBars;
-import org.eclipse.ui.IMemento;
-import org.eclipse.ui.IViewSite;
-import org.eclipse.ui.IWorkbenchActionConstants;
-import org.eclipse.ui.IWorkbenchPage;
-import org.eclipse.ui.IWorkbenchWindow;
-import org.eclipse.ui.PartInitException;
-import org.eclipse.ui.actions.ActionFactory;
-import org.eclipse.ui.part.ViewPart;
-
-/**
- * A view that shows any bug marked as favorites.
- */
-public class FavoritesView extends ViewPart {
-
-	private static Composite savedParent;
-
-	private IMemento savedMemento;
-
-	private static DeleteFavoriteAction remove;
-
-	public static DeleteFavoriteAction removeAll;
-
-	public static SelectAllAction selectAll;
-
-	private static ViewFavoriteAction open;
-
-	private Table table;
-
-	private MenuManager contextMenu;
-
-	private static TableViewer viewer;
-
-	private String[] columnHeaders = { "Bug", "Query", "Date" };
-
-	private ColumnLayoutData columnLayouts[] = { new ColumnWeightData(10), new ColumnWeightData(3),
-			new ColumnWeightData(5) };
-
-	/**
-	 * Constructor initializes favorites' source file initializes actions
-	 */
-	public FavoritesView() {
-		super();
-		open = new ViewFavoriteAction(this);
-		selectAll = new SelectAllAction();
-		remove = new DeleteFavoriteAction(this, false);
-		removeAll = new DeleteFavoriteAction(this, true);
-	}
-
-	@Override
-	public void init(IViewSite site) throws PartInitException {
-		super.init(site);
-	}
-
-	/**
-	 * Initializes this view with the given view site. A memento is passed to
-	 * the view which contains a snapshot of the views state from a previous
-	 * session.
-	 */
-	@Override
-	public void init(IViewSite site, IMemento memento) throws PartInitException {
-		init(site);
-		this.savedMemento = memento;
-	}
-
-	@Override
-	public void createPartControl(Composite parent) {
-		FavoritesView.savedParent = parent;
-		setPartName("Bugzilla Favorites");
-		createTable();
-
-		viewer = new TableViewer(table);
-		viewer.setUseHashlookup(true);
-		createColumns();
-
-		GridData gd = new GridData(GridData.FILL_BOTH);
-		gd.verticalSpan = 20;
-		viewer.getTable().setLayoutData(gd);
-
-		viewer.setContentProvider(new FavoritesViewContentProvider(this));
-		viewer.setLabelProvider(new FavoritesViewLabelProvider());
-		viewer.setInput(BugzillaPlugin.getDefault().getFavorites().elements());
-
-		viewer.addSelectionChangedListener(new ISelectionChangedListener() {
-			public void selectionChanged(SelectionChangedEvent event) {
-				FavoritesView.this.widgetSelected(event);
-			}
-		});
-
-		fillToolbar();
-		createContextMenu();
-
-		Menu menu = contextMenu.createContextMenu(table);
-		table.setMenu(menu);
-
-		hookGlobalActions();
-		parent.layout();
-
-		// Restore state from the previous session.
-		restoreState();
-	}
-
-	@Override
-	public void setFocus() {
-		// don't need to do anything when the focus is set
-	}
-
-	private void createColumns() {
-		TableLayout layout = new TableLayout();
-		table.setLayout(layout);
-		table.setHeaderVisible(true);
-
-		for (int i = 0; i < columnHeaders.length; i++) {
-			TableColumn tc = new TableColumn(table, SWT.NONE, i);
-
-			tc.setText(columnHeaders[i]);
-			tc.pack();
-			tc.setResizable(columnLayouts[i].resizable);
-			layout.addColumnData(columnLayouts[i]);
-		}
-	}
-
-	private void createTable() {
-
-		table = new Table(savedParent, SWT.H_SCROLL | SWT.V_SCROLL | SWT.MULTI | SWT.FULL_SELECTION);
-		table.setLinesVisible(true);
-
-		// Add action support for a double-click
-		table.addMouseListener(new MouseAdapter() {
-
-			@Override
-			public void mouseDoubleClick(MouseEvent e) {
-				open.run();
-			}
-		});
-	}
-
-	private void fillToolbar() {
-		IActionBars actionBars = getViewSite().getActionBars();
-		IToolBarManager toolbar = actionBars.getToolBarManager();
-
-		remove.setEnabled(false);
-		toolbar.add(remove);
-		toolbar.add(removeAll);
-		toolbar.add(new Separator());
-		toolbar.add(selectAll);
-
-		// create actions to handle the sorting of the favorites
-		sortByIDAction = new SortByAction(FavoritesFile.ID_SORT);
-		sortByIDAction.setText("by &Bug ID");
-		sortByIDAction.setToolTipText("Sorts by bug number");
-
-		sortByPriorityAction = new SortByAction(FavoritesFile.PRIORITY_SORT);
-		sortByPriorityAction.setText("by &Priority");
-		sortByPriorityAction.setToolTipText("Sorts by riority of the bug");
-
-		sortBySeverityAction = new SortByAction(FavoritesFile.SEVERITY_SORT);
-		sortBySeverityAction.setText("by &Severity");
-		sortBySeverityAction.setToolTipText("Sorts by severity of the bug");
-
-		sortByStatusAction = new SortByAction(FavoritesFile.STATE_SORT);
-		sortByStatusAction.setText("by S&tatus");
-		sortByStatusAction.setToolTipText("Sorts by status of the bug");
-
-		// get the menu manager and create a submenu to contain sorting
-		IMenuManager menu = actionBars.getMenuManager();
-		IMenuManager submenu = new MenuManager("&Sort");
-
-		// add the sorting actions to the menu bar
-		menu.add(submenu);
-		submenu.add(sortByIDAction);
-		submenu.add(sortBySeverityAction);
-		submenu.add(sortByPriorityAction);
-		submenu.add(sortByStatusAction);
-
-		updateSortingState();
-	}
-
-	/**
-	 * Function to make sure that the appropriate sort is checked
-	 */
-	void updateSortingState() {
-		int curCriterion = FavoritesFile.lastSel;
-
-		sortByIDAction.setChecked(curCriterion == FavoritesFile.ID_SORT);
-		sortBySeverityAction.setChecked(curCriterion == FavoritesFile.SEVERITY_SORT);
-		sortByPriorityAction.setChecked(curCriterion == FavoritesFile.PRIORITY_SORT);
-		sortByStatusAction.setChecked(curCriterion == FavoritesFile.STATE_SORT);
-		viewer.setInput(viewer.getInput());
-	}
-
-	// Sorting actions for the favorites view
-	SortByAction sortByIDAction, sortBySeverityAction, sortByPriorityAction, sortByStatusAction;
-
-	/**
-	 * Inner class to handle sorting
-	 * 
-	 * @author Shawn Minto
-	 */
-	class SortByAction extends Action {
-		/** The criteria to sort the favorites menu based on */
-		private int criterion;
-
-		/**
-		 * Constructor
-		 * 
-		 * @param criteria
-		 *            The criteria to sort the favorites menu based on
-		 */
-		public SortByAction(int criteria) {
-			this.criterion = criteria;
-		}
-
-		/**
-		 * Perform the sort
-		 */
-		@Override
-		public void run() {
-			BugzillaPlugin.getDefault().getFavorites().sort(criterion);
-			updateSortingState();
-		}
-	}
-
-	/**
-	 * Create context menu.
-	 */
-	private void createContextMenu() {
-		contextMenu = new MenuManager("#FavoritesView");
-		contextMenu.setRemoveAllWhenShown(true);
-		contextMenu.addMenuListener(new IMenuListener() {
-			public void menuAboutToShow(IMenuManager manager) {
-				fillContextMenu(manager);
-				updateActionEnablement();
-			}
-		});
-
-		// Register menu for extension.
-		getSite().registerContextMenu("#FavoritesView", contextMenu, viewer);
-	}
-
-	/**
-	 * Hook global actions
-	 */
-	private void hookGlobalActions() {
-		IActionBars bars = getViewSite().getActionBars();
-		bars.setGlobalActionHandler(ActionFactory.SELECT_ALL.getId(), selectAll);
-		bars.setGlobalActionHandler(ActionFactory.DELETE.getId(), remove);
-		table.addKeyListener(new KeyAdapter() {
-
-			@Override
-			public void keyPressed(KeyEvent event) {
-				if (event.character == SWT.DEL && event.stateMask == 0 && remove.isEnabled()) {
-					remove.run();
-				}
-			}
-		});
-	}
-
-	/**
-	 * Populate context menu
-	 */
-	private void fillContextMenu(IMenuManager mgr) {
-		mgr.add(open);
-		mgr.add(new Separator());
-		mgr.add(new GroupMarker(IWorkbenchActionConstants.MB_ADDITIONS));
-		mgr.add(new Separator());
-		mgr.add(remove);
-		mgr.add(new DeleteFavoriteAction(this, true));
-		mgr.add(new SelectAllAction());
-	}
-
-	/**
-	 * Update action enablement depending on whether or not any items are
-	 * selected. Displays name of current item in status bar.
-	 */
-	public static void updateActionEnablement() {
-
-		boolean hasSelected = viewer.getTable().getSelectionCount() > 0;
-		remove.setEnabled(hasSelected);
-		open.setEnabled(hasSelected);
-
-		boolean hasItems = viewer.getTable().getItemCount() > 0;
-		removeAll.setEnabled(hasItems);
-		selectAll.setEnabled(hasItems);
-	}
-
-	@Override
-	public void saveState(IMemento memento) {
-		TableItem[] sel = table.getSelection();
-		if (sel.length == 0)
-			return;
-		memento = memento.createChild("selection");
-		for (int i = 0; i < sel.length; i++) {
-			memento.createChild("descriptor", new Integer(table.indexOf(sel[i])).toString());
-		}
-	}
-
-	private void restoreState() {
-		if (savedMemento == null)
-			return;
-		savedMemento = savedMemento.getChild("selection");
-		if (savedMemento != null) {
-			IMemento descriptors[] = savedMemento.getChildren("descriptor");
-			if (descriptors.length > 0) {
-				int[] objList = new int[descriptors.length];
-				for (int nX = 0; nX < descriptors.length; nX++) {
-					String id = descriptors[nX].getID();
-					objList[nX] = BugzillaPlugin.getDefault().getFavorites().find(Integer.valueOf(id).intValue());
-				}
-				table.setSelection(objList);
-			}
-		}
-		viewer.setSelection(viewer.getSelection(), true);
-		savedMemento = null;
-		updateActionEnablement();
-	}
-
-	/**
-	 * Returns list of names of selected items.
-	 */
-	public List<BugzillaOpenStructure> getBugIdsOfSelected() {
-		IStructuredSelection selection = (IStructuredSelection) viewer.getSelection();// TableItem[]
-																						// sel
-																						// =
-																						// table.getSelection();
-		List<?> sel = selection.toList();
-		List<BugzillaOpenStructure> Ids = new ArrayList<BugzillaOpenStructure>();
-
-		Iterator<?> itr = sel.iterator();
-		while (itr.hasNext()) {
-			Object o = itr.next();
-			if (o instanceof Favorite) {
-				Favorite entry = (Favorite) o;
-				Integer id = (Integer) entry.getAttributes().get(IBugzillaConstants.HIT_MARKER_ATTR_ID);
-				Ids.add(new BugzillaOpenStructure(entry.getServer(), id, -1));
-			}
-		}
-
-		return Ids;
-	}
-
-	/**
-	 * Calls remove function in FavoritesFile
-	 */
-	@SuppressWarnings("unchecked")
-	public void deleteSelectedFavorites() {
-		List<Favorite> selection = ((IStructuredSelection) viewer.getSelection()).toList();
-		BugzillaPlugin.getDefault().getFavorites().remove(selection);
-		viewer.setInput(viewer.getInput());
-	}
-
-	/**
-	 * Removes all of the favorites in the FavoritesFile.
-	 */
-	public void deleteAllFavorites() {
-		BugzillaPlugin.getDefault().getFavorites().removeAll();
-		viewer.setInput(viewer.getInput());
-	}
-
-	/**
-	 * Refreshes the view.
-	 */
-	public static void add() {
-		if (viewer != null)
-			viewer.setInput(viewer.getInput());
-	}
-
-	/**
-	 * @see SelectionListener#widgetSelected(SelectionEvent)
-	 */
-	@SuppressWarnings("unchecked")
-	public void widgetSelected(SelectionChangedEvent e) {
-
-		IStructuredSelection selection = (IStructuredSelection) e.getSelection();
-
-		boolean enable = selection.size() > 0;
-		selectAll.setEnabled(enable);
-		remove.setEnabled(enable);
-		open.setEnabled(enable);
-
-		IStructuredSelection viewerSelection = (IStructuredSelection) viewer.getSelection();// TableItem[]
-																							// sel
-																							// =
-																							// table.getSelection();
-		List<Favorite> sel = viewerSelection.toList();
-		if (sel.size() > 0) {
-			IStatusLineManager manager = this.getViewSite().getActionBars().getStatusLineManager();
-			manager.setMessage(sel.get(0).toString());// table.getItem(selected).getText(0));
-		}
-
-		updateActionEnablement();
-	}
-
-	/**
-	 * Attempts to display this view on the workbench.
-	 */
-	public static void checkWindow() {
-		if (savedParent == null || savedParent.isDisposed()) {
-			IWorkbenchWindow w = BugzillaPlugin.getDefault().getWorkbench().getActiveWorkbenchWindow();
-			if (w != null) {
-				IWorkbenchPage page = w.getActivePage();
-				if (page != null) {
-					try {
-						page.showView(IBugzillaConstants.PLUGIN_ID + ".ui.favoritesView");
-					} catch (PartInitException pie) {
-						BugzillaPlugin.log(pie.getStatus());
-					}
-				}
-			}
-		}
-	}
-
-	/**
-	 * Action class - "Select All"
-	 */
-	public class SelectAllAction extends AbstractFavoritesAction {
-
-		public SelectAllAction() {
-			setToolTipText("Select all favorites");
-			setText("Select all");
-			setImageDescriptor(BugzillaImages.SELECT_ALL);
-		}
-
-		@Override
-		public void run() {
-			checkWindow();
-			table.selectAll();
-			viewer.setSelection(viewer.getSelection(), true);
-			updateActionEnablement();
-		}
-	}
-
-	private class FavoritesViewLabelProvider extends LabelProvider implements ITableLabelProvider {
-
-		/**
-		 * Returns the label text for the given column of a recommendation in
-		 * the table.
-		 */
-		public String getColumnText(Object element, int columnIndex) {
-			if (element instanceof Favorite) {
-				Favorite f = (Favorite) element;
-				switch (columnIndex) {
-				case 0:
-					return f.toString();
-				case 1:
-					return f.getQuery();
-				case 2:
-					return f.getDate().toString();
-				default:
-					return "Undefined column text";
-				}
-			}
-			return ""; //$NON-NLS-1$
-		}
-
-		/*
-		 * @see org.eclipse.jface.viewers.ITableLabelProvider#getColumnImage(java.lang.Object,
-		 *      int)
-		 */
-		public Image getColumnImage(Object arg0, int arg1) {
-			return null;
-		}
-	}
-
-	public void refresh() {
-		// don't need to do anything to refresh
-	}
-
-	private class FavoritesViewContentProvider implements IStructuredContentProvider {
-
-		private List results;
-
-		/**
-		 * The constructor.
-		 */
-		public FavoritesViewContentProvider(FavoritesView taskList) {
-			// no setup to do
-		}
-
-		/**
-		 * Returns the elements to display in the viewer when its input is set
-		 * to the given element. These elements can be presented as rows in a
-		 * table, items in a list, etc. The result is not modified by the
-		 * viewer.
-		 * 
-		 * @param inputElement
-		 *            the input element
-		 * @return the array of elements to display in the viewer
-		 */
-		public Object[] getElements(Object inputElement) {
-			if (results != null) {
-				return results.toArray();
-			} else
-				return null;
-		}
-
-		/**
-		 * Notifies this content provider that a given viewer's input has been
-		 * changed.
-		 */
-		public void inputChanged(Viewer viewerChanged, Object oldInput, Object newInput) {
-			this.results = (List) newInput;
-
-			if (viewerChanged.getInput() != null) {
-				viewerChanged.getControl().getDisplay().syncExec(new Runnable() {
-					public void run() {
-						FavoritesView.this.refresh();
-					}
-				});
-			}
-		}
-
-		public void dispose() {
-			if (results != null)
-				results = null;
-		}
-	}
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/GetQueryDialog.java b/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/GetQueryDialog.java
deleted file mode 100644
index 456185b..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/GetQueryDialog.java
+++ /dev/null
@@ -1,201 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004 - 2006 University Of British Columbia and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     University Of British Columbia - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.mylyn.internal.bugzilla.ui.search;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-
-import org.eclipse.jface.action.Action;
-import org.eclipse.jface.action.MenuManager;
-import org.eclipse.jface.action.Separator;
-import org.eclipse.jface.dialogs.Dialog;
-import org.eclipse.jface.dialogs.IDialogConstants;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.MouseAdapter;
-import org.eclipse.swt.events.MouseEvent;
-import org.eclipse.swt.events.SelectionAdapter;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.widgets.Button;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.List;
-import org.eclipse.swt.widgets.Menu;
-import org.eclipse.swt.widgets.Shell;
-
-/**
- * Dialog to display, manage and run stored queries.
- */
-public class GetQueryDialog extends Dialog {
-
-	/** The Ok button. */
-	private Button okButton;
-
-	/** The title of the dialog. */
-	private String title;
-
-	private SavedQueryFile input;
-
-	public GetQueryDialog(Shell parentShell, String dialogTitle, SavedQueryFile in) {
-		super(parentShell);
-		this.title = dialogTitle;
-		input = in;
-		setShellStyle(SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL);
-	}
-
-	@Override
-	protected void configureShell(Shell shell) {
-		super.configureShell(shell);
-		shell.setText(title);
-	}
-
-	@Override
-	protected void createButtonsForButtonBar(Composite parent) {
-		// create OK and Details buttons
-		okButton = createButton(parent, IDialogConstants.OK_ID, "Run", true);
-		okButton.setEnabled(false);
-		createButton(parent, IDialogConstants.CANCEL_ID, "Close", false);
-	}
-
-	/**
-	 * Creates the list widget to display stored queries.
-	 */
-	@Override
-	final protected Control createDialogArea(Composite parent) {
-		Composite composite = (Composite) super.createDialogArea(parent);
-
-		createMainDialogArea(composite);
-
-		return composite;
-	}
-
-	protected void createMainDialogArea(Composite parent) {
-		Label label = new Label(parent, SWT.LEFT);
-		label.setText("Select a saved query:");
-		rememberPattern = new List(parent, SWT.SINGLE | SWT.V_SCROLL | SWT.BORDER);
-		ArrayList<String> names = input.getNames();
-		int pos = 0;
-
-		for (Iterator<String> it = names.iterator(); it.hasNext();) {
-			rememberPattern.add(it.next(), pos);
-			pos++;
-		}
-
-		GridData gd = new GridData(GridData.FILL_HORIZONTAL);
-		gd.horizontalSpan = 5;
-		gd.heightHint = 60;
-
-		rememberPattern.setLayoutData(gd);
-		rememberPattern.addSelectionListener(new SelectionAdapter() {
-			@Override
-			public void widgetSelected(SelectionEvent event) {
-				selIndex = rememberPattern.getSelectionIndex();
-				okButton.setEnabled(selIndex >= 0);
-			}
-		});
-		rememberPattern.addMouseListener(new MouseAdapter() {
-			@Override
-			public void mouseDoubleClick(MouseEvent e) {
-				okPressed();
-			}
-		});
-
-		// Configure the context menu
-		MenuManager menuMgr = new MenuManager("#PopupMenu"); //$NON-NLS-1$
-		menuMgr.add(new RunQueryAction("&Run query"));
-		menuMgr.add(new Separator());
-		menuMgr.add(new RemoveAction("Remo&ve"));
-		menuMgr.add(new RemoveAllAction("Remove &all"));
-		Menu menu = menuMgr.createContextMenu(rememberPattern);
-		rememberPattern.setMenu(menu);
-
-	}
-
-	final protected void setPageComplete(boolean complete) {
-		if (okButton != null) {
-			okButton.setEnabled(complete);
-		}
-	}
-
-	private String queryNameText;
-
-	private List rememberPattern;
-
-	public String getText() {
-		return queryNameText;
-	}
-
-	/**
-	 * Deletes a selected named query.
-	 */
-	private void remove() {
-		int index = rememberPattern.getSelectionIndex();
-		if (index != -1)
-			BugzillaSearchPage.getInput().remove(new int[] { index });
-		rememberPattern.remove(index);
-		rememberPattern.setSelection(-1);
-		selIndex = -1;
-		okButton.setEnabled(false);
-	}
-
-	private void removeAll() {
-		BugzillaSearchPage.getInput().removeAll();
-		rememberPattern.removeAll();
-		rememberPattern.setSelection(-1);
-		selIndex = -1;
-		okButton.setEnabled(false);
-	}
-
-	/** Index of the selected query, or -1 if none. */
-	int selIndex = -1;
-
-	/**
-	 * Returns index of the selected query or -1 if none are selected.
-	 */
-	public int getSelected() {
-		return selIndex;
-	}
-
-	private class RunQueryAction extends Action {
-		RunQueryAction(String text) {
-			super(text);
-		}
-
-		@Override
-		public void run() {
-			GetQueryDialog.this.okPressed();
-		}
-	}
-
-	private class RemoveAction extends Action {
-		RemoveAction(String text) {
-			super(text);
-		}
-
-		@Override
-		public void run() {
-			GetQueryDialog.this.remove();
-		}
-	}
-
-	private class RemoveAllAction extends Action {
-		RemoveAllAction(String text) {
-			super(text);
-		}
-
-		@Override
-		public void run() {
-			GetQueryDialog.this.removeAll();
-		}
-	}
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/IBugzillaSearchResultCollector.java b/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/IBugzillaSearchResultCollector.java
deleted file mode 100644
index 358a974..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/IBugzillaSearchResultCollector.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004 - 2006 University Of British Columbia and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     University Of British Columbia - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.mylyn.internal.bugzilla.ui.search;
-
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IProgressMonitor;
-
-/**
- * Interface for the bugzilla search result collector.
- * 
- * @author Shawn Minto
- */
-interface IBugzillaSearchResultCollector {
-
-	/**
-	 * Called before the actual search starts
-	 * 
-	 * @param startCount -
-	 *            The starting count for the number of matches
-	 * @throws CoreException
-	 */
-	public void aboutToStart(int startCount) throws CoreException;
-
-	/**
-	 * Accept a search hit and add it as a match and set the markers
-	 * 
-	 * @param hit
-	 *            The search hit that was a match
-	 * @throws CoreException
-	 */
-	public void accept(BugzillaSearchHit hit) throws CoreException;
-
-	/**
-	 * Called when the search has ended.
-	 */
-	public void done();
-
-	/**
-	 * Get the progress monitor for the search
-	 * 
-	 * @return The progress monitor
-	 */
-	public IProgressMonitor getProgressMonitor();
-
-	/**
-	 * Set the progress monitor
-	 * 
-	 * @param monitor
-	 *            The progress monitor the search should use
-	 */
-	public void setProgressMonitor(IProgressMonitor monitor);
-
-	/**
-	 * Set the current search operation
-	 * 
-	 * @param operation
-	 *            The operation to set the search to
-	 */
-	public void setOperation(IBugzillaSearchOperation operation);
-
-	/**
-	 * Get the current operation
-	 * 
-	 * @return The current search operation
-	 */
-	public IBugzillaSearchOperation getOperation();
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/KeywordParser.java b/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/KeywordParser.java
deleted file mode 100644
index 6dd6446..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/KeywordParser.java
+++ /dev/null
@@ -1,155 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2003 - 2006 University Of British Columbia and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     University Of British Columbia - initial API and implementation
- *******************************************************************************/
-package org.eclipse.mylyn.internal.bugzilla.core;
-
-import java.io.IOException;
-import java.io.Reader;
-import java.text.ParseException;
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.security.auth.login.LoginException;
-
-import org.eclipse.mylyn.tasks.core.web.HtmlStreamTokenizer;
-import org.eclipse.mylyn.tasks.core.web.HtmlTag;
-import org.eclipse.mylyn.tasks.core.web.HtmlStreamTokenizer.Token;
-
-/**
- * Parses Bugzilla keywords page to determine keywords valid in this
- * installation
- * 
- * @author Shawn Minto
- */
-public class KeywordParser {
-	/** Tokenizer used on the stream */
-	private static HtmlStreamTokenizer tokenizer;
-
-	/**
-	 * Constructor.
-	 * 
-	 * @param in
-	 *            The input stream for the keywords page.
-	 */
-	public KeywordParser(Reader in) {
-		tokenizer = new HtmlStreamTokenizer(in, null);
-	}
-
-	public String getEncoding() {
-		return "";
-	}
-
-	/**
-	 * Parse the keyword page for the valid products that a bug can be logged
-	 * for
-	 * 
-	 * @return A list of the keywordds that we can enter bugs for
-	 * @throws IOException
-	 * @throws ParseException
-	 */
-	public List<String> getKeywords() throws IOException, ParseException, LoginException {
-		ArrayList<String> keywords = new ArrayList<String>();
-
-		boolean isTitle = false;
-		boolean possibleBadLogin = false;
-		String title = "";
-
-		for (Token token = tokenizer.nextToken(); token.getType() != Token.EOF; token = tokenizer.nextToken()) {
-
-			// make sure that bugzilla doesn't want us to login
-			if (token.getType() == Token.TAG && ((HtmlTag) (token.getValue())).getTagType() == HtmlTag.Type.TITLE
-					&& !((HtmlTag) (token.getValue())).isEndTag()) {
-				isTitle = true;
-				continue;
-			}
-
-			if (isTitle) {
-				// get all of the data from inside of the title tag
-				if (token.getType() != Token.TAG) {
-					title += ((StringBuffer) token.getValue()).toString().toLowerCase() + " ";
-					continue;
-				} else if (token.getType() == Token.TAG
-						&& ((HtmlTag) token.getValue()).getTagType() == HtmlTag.Type.TITLE
-						&& ((HtmlTag) token.getValue()).isEndTag()) {
-					// check if we may have a problem with login by looking at
-					// the title of the page
-					if ((title.indexOf("login") != -1
-							|| (title.indexOf("invalid") != -1 && title.indexOf("password") != -1)
-							|| title.indexOf("check e-mail") != -1 || title.indexOf("error") != -1))
-						possibleBadLogin = true;
-					isTitle = false;
-					title = "";
-				}
-				continue;
-			}
-
-			if (token.getType() == Token.TAG) {
-				HtmlTag tag = (HtmlTag) token.getValue();
-				if (tag.getTagType() == HtmlTag.Type.TR && !tag.isEndTag()) {
-					token = tokenizer.nextToken();
-					if (token.getType() != Token.EOF && token.getType() == Token.TAG) {
-						tag = (HtmlTag) token.getValue();
-						if (tag.getTagType() != HtmlTag.Type.TH)
-							continue;
-						else {
-							if (tag.getAttribute("align") == null
-									|| !"left".equalsIgnoreCase(tag.getAttribute("align")))
-								parseKeywords(keywords);
-
-						}
-					}
-					continue;
-				}
-			}
-		}
-
-		// if we don't have any keywords and suspect that there was a login
-		// problem, assume we had a login problem
-		if (keywords == null && possibleBadLogin)
-			throw new LoginException(IBugzillaConstants.MESSAGE_LOGIN_FAILURE);
-		return keywords;
-	}
-
-	/**
-	 * Parse the keywords that we can enter bugs for
-	 * 
-	 * @param keywords
-	 *            The list of keywords to add this new product to
-	 * @return
-	 */
-	private void parseKeywords(List<String> keywords) throws IOException, ParseException {
-		StringBuffer sb = new StringBuffer();
-
-		for (Token token = tokenizer.nextToken(); token.getType() != Token.EOF; token = tokenizer.nextToken()) {
-			if (token.getType() == Token.TAG) {
-				HtmlTag tag = (HtmlTag) token.getValue();
-				if (tag.getTagType() == HtmlTag.Type.TH
-						&& (tag.isEndTag() || !"left".equalsIgnoreCase(tag.getAttribute("align"))))
-					break;
-			} else if (token.getType() == Token.TEXT)
-				sb.append(token.toString());
-		}
-
-		String prod = HtmlStreamTokenizer.unescape(sb).toString();
-		if (prod.endsWith(":"))
-			prod = prod.substring(0, prod.length() - 1);
-		keywords.add(prod);
-
-		for (Token token = tokenizer.nextToken(); token.getType() != Token.EOF; token = tokenizer.nextToken()) {
-			if (token.getType() == Token.TAG) {
-				HtmlTag tag = (HtmlTag) token.getValue();
-				if (tag.getTagType() == HtmlTag.Type.TR && tag.isEndTag())
-					break;
-
-			}
-		}
-	}
-
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/NewBugParser.java b/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/NewBugParser.java
deleted file mode 100644
index 68ff456..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/NewBugParser.java
+++ /dev/null
@@ -1,427 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004 - 2006 University Of British Columbia and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     University Of British Columbia - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.mylyn.internal.bugzilla.core.internal;
-
-import java.io.IOException;
-import java.io.Reader;
-import java.text.ParseException;
-
-import javax.security.auth.login.LoginException;
-
-import org.eclipse.mylyn.bugzilla.core.AbstractRepositoryReportAttribute;
-import org.eclipse.mylyn.internal.bugzilla.core.IBugzillaConstants;
-import org.eclipse.mylyn.internal.bugzilla.core.NewBugzillaReport;
-import org.eclipse.mylyn.internal.bugzilla.core.internal.HtmlStreamTokenizer.Token;
-
-/**
- * @author Shawn Minto
- * 
- * This class parses the valid attribute values for a new bug
- */
-class NewBugParser {
-	/** Tokenizer used on the stream */
-	private HtmlStreamTokenizer tokenizer;
-
-	/** Flag for whether we need to try to get the product or not */
-	private static boolean getProd = false;
-
-	public NewBugParser(Reader in) {
-		tokenizer = new HtmlStreamTokenizer(in, null);
-	}
-
-	/**
-	 * Parse the new bugs valid attributes
-	 * 
-	 * @param nbm
-	 *            A reference to a NewBugModel where all of the information is
-	 *            stored
-	 * @throws IOException
-	 * @throws ParseException
-	 * @throws LoginException
-	 */
-	public void parseBugAttributes(NewBugzillaReport nbm, boolean retrieveProducts) throws IOException, ParseException,
-			LoginException {
-		nbm.attributes.clear(); // clear any attriubtes in bug model from a
-		// previous product
-
-		NewBugParser.getProd = retrieveProducts;
-
-		// create a new bug report and set the parser state to the start state
-		ParserState state = ParserState.START;
-		String attribute = null;
-
-		boolean isTitle = false;
-		boolean possibleBadLogin = false;
-		boolean isErrorState = false;
-		String title = "";
-		// Default error message
-		String errorMsg = "Bugzilla could not get the needed bug attribute since your login name or password is incorrect.  Please check your settings in the bugzilla preferences.";
-
-		for (Token token = tokenizer.nextToken(); token.getType() != Token.EOF; token = tokenizer.nextToken()) {
-			// make sure that bugzilla doesn't want us to login
-			if (token.getType() == Token.TAG && ((HtmlTag) (token.getValue())).getTagType() == HtmlTag.Type.TITLE
-					&& !((HtmlTag) (token.getValue())).isEndTag()) {
-				isTitle = true;
-				continue;
-			}
-
-			if (isTitle) {
-				// get all of the data in the title tag to compare with
-				if (token.getType() != Token.TAG) {
-					title += ((StringBuffer) token.getValue()).toString().toLowerCase() + " ";
-					continue;
-				} else if (token.getType() == Token.TAG
-						&& ((HtmlTag) token.getValue()).getTagType() == HtmlTag.Type.TITLE
-						&& ((HtmlTag) token.getValue()).isEndTag()) {
-					// check if the title looks like we may have a problem with
-					// login
-					if (title.indexOf("login") != -1) {
-						possibleBadLogin = true; // generic / default msg
-						// passed to constructor re:
-						// bad login
-					}
-					if ((title.indexOf("invalid") != -1 && title.indexOf("password") != -1)
-							|| title.indexOf("check e-mail") != -1 || title.indexOf("error") != -1) {
-						possibleBadLogin = true;
-						isErrorState = true; // set flag so appropriate msg
-						// is provide for the exception
-						errorMsg = ""; // error message will be parsed from
-						// error page
-					}
-
-					isTitle = false;
-					title = "";
-				}
-				continue;
-			}
-
-			// we have found the start of an attribute name
-			if ((state == ParserState.ATT_NAME || state == ParserState.START) && token.getType() == Token.TAG) {
-				HtmlTag tag = (HtmlTag) token.getValue();				
-				if (tag.getTagType() == HtmlTag.Type.TD && "right".equalsIgnoreCase(tag.getAttribute("align"))) {
-					// parse the attribute's name
-					attribute = parseAttributeName();
-					if(attribute != null && attribute.contains(IBugzillaConstants.INVALID_2201_ATTRIBUTE_IGNORED)) {
-						continue;
-					}					
-					if (attribute == null)
-						continue;
-					state = ParserState.ATT_VALUE;
-					continue;
-				}
-
-				if (tag.getTagType() == HtmlTag.Type.TD && "#ff0000".equalsIgnoreCase(tag.getAttribute("bgcolor"))) {
-					state = ParserState.ERROR;
-					continue;
-				}
-			}
-
-			// we have found the start of attribute values
-			if (state == ParserState.ATT_VALUE && token.getType() == Token.TAG) {
-				HtmlTag tag = (HtmlTag) token.getValue();
-				if (tag.getTagType() == HtmlTag.Type.TD) {
-					// parse the attribute values
-					parseAttributeValue(nbm, attribute);
-
-					state = ParserState.ATT_NAME;
-					attribute = null;
-					continue;
-				}
-			}
-			// page being parsed contains an Error message
-			// parse error message so it can be given to the constructor of the
-			// exception
-			// so an appropriate error message is displayed
-			if (state == ParserState.ERROR && isErrorState) {
-				// tag should be text token, not a tag
-				// get the error message
-				if (token.getType() == Token.TEXT) {
-					// get string value of next token to add to error messgage
-					// unescape the string so any escape sequences parsed appear
-					// unescaped in the details pane
-					errorMsg += HtmlStreamTokenizer.unescape(((StringBuffer) token.getValue()).toString()) + " ";
-				}
-				// expect </font> tag to indicate end of error end msg
-				// set next state to continue parsing remainder of page
-				else if (token.getType() == Token.TAG
-						&& ((HtmlTag) (token.getValue())).getTagType() == HtmlTag.Type.FONT
-						&& ((HtmlTag) (token.getValue())).isEndTag()) {
-					state = ParserState.ATT_NAME;
-				}
-				continue;
-			}
-
-			if ((state == ParserState.ATT_NAME || state == ParserState.START) && token.getType() == Token.TAG) {
-				HtmlTag tag = (HtmlTag) token.getValue();
-				if (tag.getTagType() == HtmlTag.Type.INPUT && tag.getAttribute("type") != null
-						&& "hidden".equalsIgnoreCase(tag.getAttribute("type").trim())) {
-					AbstractRepositoryReportAttribute a = new AbstractRepositoryReportAttribute(tag.getAttribute("name"));
-					a.setID(tag.getAttribute("name"));
-					a.setValue(tag.getAttribute("value"));
-					a.setHidden(true);
-					nbm.attributes.put(a.getName(), a);
-					continue;
-				}
-			}
-		}
-
-		if (possibleBadLogin && (nbm.getAttributes() == null || nbm.getAttributes().size() == 0)) {
-			throw new LoginException(errorMsg);
-		}
-	}
-
-	/**
-	 * Parse the case where we have found an attribute name
-	 * 
-	 * @param tokenizer
-	 *            The tokenizer to use to find the name
-	 * @return The name of the attribute
-	 * @throws IOException
-	 * @throws ParseException
-	 */
-	private String parseAttributeName() throws IOException, ParseException {
-		StringBuffer sb = new StringBuffer();
-
-		parseTableCell(sb);
-		HtmlStreamTokenizer.unescape(sb);
-		// remove the colon if there is one
-		if (sb.length() == 0)
-			return null;
-		if (sb.charAt(sb.length() - 1) == ':') {
-			sb.deleteCharAt(sb.length() - 1);
-		}
-		return sb.toString();
-	}
-
-	/**
-	 * Reads text into a StringBuffer until it encounters a close table cell tag
-	 * (&lt;/TD&gt;) or start of another cell. The text is appended to the
-	 * existing value of the buffer. <b>NOTE:</b> Does not handle nested cells!
-	 * 
-	 * @param tokenizer
-	 * @param sb
-	 * @throws IOException
-	 * @throws ParseException
-	 */
-	private void parseTableCell(StringBuffer sb) throws IOException, ParseException {
-		boolean noWhitespace = false;
-		for (HtmlStreamTokenizer.Token token = tokenizer.nextToken(); token.getType() != Token.EOF; token = tokenizer
-				.nextToken()) {
-			if (token.getType() == Token.TAG) {
-				HtmlTag tag = (HtmlTag) token.getValue();
-				if (tag.getTagType() == HtmlTag.Type.TD) {
-					if (!tag.isEndTag()) {
-						tokenizer.pushback(token);
-					}
-					break;
-				}
-				noWhitespace = token.getWhitespace().length() == 0;
-			} else if (token.getType() == Token.TEXT) {
-				// if there was no whitespace between the tag and the
-				// preceding text, don't insert whitespace before this text
-				// unless it is there in the source
-				if (!noWhitespace && token.getWhitespace().length() > 0 && sb.length() > 0) {
-					sb.append(' ');
-				}
-				sb.append((StringBuffer) token.getValue());
-			}
-		}
-	}
-
-	/**
-	 * Parse the case where we have found attribute values
-	 * 
-	 * @param nbm
-	 *            The NewBugModel that is to contain information about a new bug
-	 * @param attributeName
-	 *            The name of the attribute that we are parsing
-	 * @param tokenizer
-	 *            The tokenizer to use for parsing
-	 * @throws IOException
-	 * @throws ParseException
-	 */
-	private void parseAttributeValue(NewBugzillaReport nbm, String attributeName) throws IOException, ParseException {
-
-		HtmlStreamTokenizer.Token token = tokenizer.nextToken();
-		if (token.getType() == Token.TAG) {
-			HtmlTag tag = (HtmlTag) token.getValue();
-			if (tag.getTagType() == HtmlTag.Type.SELECT && !tag.isEndTag()) {
-				String parameterName = tag.getAttribute("name");
-				parseSelect(nbm, attributeName, parameterName);
-			} else if (tag.getTagType() == HtmlTag.Type.INPUT && !tag.isEndTag()) {
-				parseInput(nbm, attributeName, tag);
-			} else if (!tag.isEndTag()) {
-				parseAttributeValueCell(nbm, attributeName);
-			}
-		} else {
-			StringBuffer sb = new StringBuffer();
-			if (token.getType() == Token.TEXT) {
-				sb.append((StringBuffer) token.getValue());
-				parseAttributeValueCell(nbm, attributeName, sb);
-			}
-		}
-	}
-
-	/**
-	 * Parse the case where the attribute value is just text in a table cell
-	 * 
-	 * @param attributeName
-	 *            The name of the attribute we are parsing
-	 * @param tokenizer
-	 *            The tokenizer to use for parsing
-	 * @throws IOException
-	 * @throws ParseException
-	 */
-	private void parseAttributeValueCell(NewBugzillaReport nbm, String attributeName) throws IOException, ParseException {
-		StringBuffer sb = new StringBuffer();
-
-		parseAttributeValueCell(nbm, attributeName, sb);
-	}
-
-	private void parseAttributeValueCell(NewBugzillaReport nbm, String attributeName, StringBuffer sb) throws IOException,
-			ParseException {
-
-		parseTableCell(sb);
-		HtmlStreamTokenizer.unescape(sb);
-
-		// if we need the product we will get it
-		if (getProd && attributeName.equalsIgnoreCase("product")) {
-			nbm.setProduct(sb.toString());
-		}
-	}
-
-	/**
-	 * Parse the case where the attribute value is an input
-	 * 
-	 * @param nbm
-	 *            The new bug model to add information that we get to
-	 * @param attributeName
-	 *            The name of the attribute that we are parsing
-	 * @param tag
-	 *            The HTML tag that we are currently on
-	 * @throws IOException
-	 */
-	private static void parseInput(NewBugzillaReport nbm, String attributeName, HtmlTag tag) throws IOException {
-
-		AbstractRepositoryReportAttribute a = new AbstractRepositoryReportAttribute(attributeName);
-		a.setID(tag.getAttribute("name"));
-		String value = tag.getAttribute("value");
-		if (value == null)
-			value = "";
-
-		// if we found the summary, add it to the bug report
-		if (attributeName.equalsIgnoreCase("summary")) {
-			nbm.setSummary(value);
-		} else if (attributeName.equalsIgnoreCase("Attachments")) {
-			// do nothing - not a problem after 2.14
-		} else if (attributeName.equalsIgnoreCase("add cc")) {
-			// do nothing
-		} else if (attributeName.toLowerCase().startsWith("cc")) {
-			// do nothing cc's are options not inputs
-		} else {
-			// otherwise just add the attribute
-			a.setValue(value);
-			nbm.attributes.put(attributeName, a);
-		}
-	}
-
-	/**
-	 * Parse the case where the attribute value is an option
-	 * 
-	 * @param nbm
-	 *            The NewBugModel that we are storing information in
-	 * @param attributeName
-	 *            The name of the attribute that we are parsing
-	 * @param parameterName
-	 *            The SELECT tag's name
-	 * @param tokenizer
-	 *            The tokenizer that we are using for parsing
-	 * @throws IOException
-	 * @throws ParseException
-	 */
-	private void parseSelect(NewBugzillaReport nbm, String attributeName, String parameterName) throws IOException,
-			ParseException {
-
-		boolean first = false;
-		AbstractRepositoryReportAttribute a = new AbstractRepositoryReportAttribute(attributeName);
-		a.setID(parameterName);
-
-		HtmlStreamTokenizer.Token token = tokenizer.nextToken();
-		while (token.getType() != Token.EOF) {
-			if (token.getType() == Token.TAG) {
-				HtmlTag tag = (HtmlTag) token.getValue();
-				if (tag.getTagType() == HtmlTag.Type.SELECT && tag.isEndTag())
-					break;
-				if (tag.getTagType() == HtmlTag.Type.OPTION && !tag.isEndTag()) {
-					String optionName = tag.getAttribute("value");
-					boolean selected = tag.hasAttribute("selected");
-					StringBuffer optionText = new StringBuffer();
-					for (token = tokenizer.nextToken(); token.getType() == Token.TEXT; token = tokenizer.nextToken()) {
-						if (optionText.length() > 0) {
-							optionText.append(' ');
-						}
-						optionText.append((StringBuffer) token.getValue());
-					}
-					a.addOptionValue(optionText.toString(), optionName);
-
-					if (selected || first) {
-						a.setValue(optionText.toString());
-						first = false;
-					}
-				} else {
-					token = tokenizer.nextToken();
-				}
-			} else {
-				token = tokenizer.nextToken();
-			}
-		}
-
-		if (!(nbm.attributes).containsKey(attributeName)) {
-			(nbm.attributes).put(attributeName, a);
-		}
-	}
-
-	/**
-	 * Enum class for describing current state of Bugzilla report parser.
-	 */
-	private static class ParserState {
-		/** An instance of the start state */
-		protected static final ParserState START = new ParserState("start");
-
-		/** An instance of the state when the parser found an attribute name */
-		protected static final ParserState ATT_NAME = new ParserState("att_name");
-
-		/** An instance of the state when the parser found an attribute value */
-		protected static final ParserState ATT_VALUE = new ParserState("att_value");
-
-		/** An instance of the state when an error page is found */
-		protected static final ParserState ERROR = new ParserState("error");
-
-		/** State's human-readable name */
-		private String name;
-
-		/**
-		 * Constructor
-		 * 
-		 * @param description -
-		 *            The states human readable name
-		 */
-		private ParserState(String description) {
-			this.name = description;
-		}
-
-		@Override
-		public String toString() {
-			return name;
-		}
-	}
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/NewBugWizardTest.java b/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/NewBugWizardTest.java
deleted file mode 100644
index 88506c4..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/NewBugWizardTest.java
+++ /dev/null
@@ -1,98 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004, 2008 Tasktop Technologies and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     Tasktop Technologies - initial API and implementation
- *     Ian Bull - improvements
- *******************************************************************************/
-
-package org.eclipse.mylyn.bugzilla.deprecated;
-
-import junit.framework.TestCase;
-
-import org.eclipse.core.runtime.Platform;
-import org.eclipse.mylyn.internal.bugzilla.core.BugzillaAttribute;
-import org.eclipse.mylyn.internal.bugzilla.core.BugzillaCorePlugin;
-import org.eclipse.mylyn.internal.bugzilla.core.IBugzillaConstants;
-import org.eclipse.mylyn.internal.tasks.ui.TasksUiPlugin;
-import org.eclipse.mylyn.tasks.core.AbstractRepositoryConnector;
-import org.eclipse.mylyn.tasks.core.TaskRepository;
-import org.eclipse.mylyn.tasks.core.data.AbstractTaskDataHandler;
-import org.eclipse.mylyn.tasks.core.data.TaskAttributeMapper;
-import org.eclipse.mylyn.tasks.core.data.TaskData;
-
-/**
- * @author Mik Kersten
- * @author Ian Bull
- */
-public class NewBugWizardTest extends TestCase {
-
-	public void testPlatformOptions() throws Exception {
-
-		TaskRepository repository = new TaskRepository(BugzillaCorePlugin.CONNECTOR_KIND,
-				IBugzillaConstants.TEST_BUGZILLA_220_URL);
-		AbstractRepositoryConnector connector = TasksUiPlugin.getRepositoryManager().getRepositoryConnector(
-				repository.getConnectorKind());
-
-		final TaskAttributeMapper attributeMapper = connector.getTaskDataHandler().getAttributeMapper(repository);
-
-		final TaskData taskData = new TaskData(attributeMapper, BugzillaCorePlugin.CONNECTOR_KIND,
-				repository.getRepositoryUrl(), "1");
-
-		assertNotNull(connector);
-		AbstractTaskDataHandler taskDataHandler = connector.getTaskDataHandler();
-		assertNotNull(taskDataHandler);
-
-		BugzillaCorePlugin.getDefault().setPlatformOptions(taskData);
-
-		String os = Platform.getOS();
-		if (os.equals("win32")) {
-			assertEquals("Windows", taskData.getRoot().getAttribute(BugzillaAttribute.OP_SYS.getKey()).getValue());
-		} else if (os.equals("solaris")) {
-			assertEquals("Solaris", taskData.getRoot().getAttribute(BugzillaAttribute.OP_SYS.getKey()).getValue());
-		} else if (os.equals("qnx")) {
-			assertEquals("QNX-Photon", taskData.getRoot().getAttribute(BugzillaAttribute.OP_SYS.getKey()).getValue());
-		} else if (os.equals("macosx")) {
-			assertEquals("Mac OS", taskData.getRoot().getAttribute(BugzillaAttribute.OP_SYS.getKey()).getValue());
-		} else if (os.equals("linux")) {
-			assertEquals("Linux", taskData.getRoot().getAttribute(BugzillaAttribute.OP_SYS.getKey()).getValue());
-		} else if (os.equals("hpux")) {
-			assertEquals("HP-UX", taskData.getRoot().getAttribute(BugzillaAttribute.OP_SYS.getKey()).getValue());
-		} else if (os.equals("aix")) {
-			assertEquals("AIX", taskData.getRoot().getAttribute(BugzillaAttribute.OP_SYS.getKey()).getValue());
-		}
-
-		String platform = Platform.getOSArch();
-		if (platform.equals("x86")) {
-			if (os.equals("macosx")) {
-				assertEquals("Macintosh", taskData.getRoot()
-						.getAttribute(BugzillaAttribute.REP_PLATFORM.getKey())
-						.getValue());
-			} else {
-				assertEquals("PC", taskData.getRoot().getAttribute(BugzillaAttribute.REP_PLATFORM.getKey()).getValue());
-			}
-		} else if (platform.equals("x86_64")) {
-			assertEquals("PC", taskData.getRoot().getAttribute(BugzillaAttribute.REP_PLATFORM.getKey()).getValue());
-		} else if (platform.equals("ia64")) {
-			assertEquals("PC", taskData.getRoot().getAttribute(BugzillaAttribute.REP_PLATFORM.getKey()).getValue());
-		} else if (platform.equals("ia64_32")) {
-			assertEquals("PC", taskData.getRoot().getAttribute(BugzillaAttribute.REP_PLATFORM.getKey()).getValue());
-		} else if (platform.equals("sparc")) {
-			assertEquals("Sun", taskData.getRoot().getAttribute(BugzillaAttribute.REP_PLATFORM.getKey()).getValue());
-		} else if (platform.equals("ppc")) {
-			if (os.equals("macosx")) {
-				assertEquals("Macintosh", taskData.getRoot()
-						.getAttribute(BugzillaAttribute.REP_PLATFORM.getKey())
-						.getValue());
-			} else {
-				assertEquals("Power", taskData.getRoot()
-						.getAttribute(BugzillaAttribute.REP_PLATFORM.getKey())
-						.getValue());
-			}
-		}
-	}
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/NewBugzillaTaskData.java b/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/NewBugzillaTaskData.java
deleted file mode 100644
index adcd24d..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/NewBugzillaTaskData.java
+++ /dev/null
@@ -1,183 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2003 - 2006 University Of British Columbia and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     University Of British Columbia - initial API and implementation
- *******************************************************************************/
-package org.eclipse.mylyn.internal.bugzilla.core;
-
-import java.io.Serializable;
-
-import org.eclipse.mylyn.tasks.core.RepositoryTaskData;
-
-
-/**
- * This class is used to store data about the new bug that is being created
- * while the wizard is being used
- * 
- * @author Eric Booth
- * @author Rob Elves
- */
-public class NewBugzillaTaskData extends RepositoryTaskData implements Serializable { 
-
-	/** Automatically generated serialVersionUID */
-	private static final long serialVersionUID = 3977859587934335283L;
-
-	/** Whether the attributes have been parsed yet or not */
-	protected boolean hasParsedAttributes = false;
-
-	/** Whether the products have been parsed yet or not */
-	protected boolean hasParsedProducts = false;
-
-	/** The product that the bug is for */
-	protected String product;
-
-	/** The summary for the bug */
-	protected String summary = "";
-
-	/**
-	 * Flag to indicate status of connection to Bugzilla server to identify
-	 * whether ProductConfiguration should be used instead
-	 */
-	protected boolean connected = true;
-
-	/** Whether or not this bug report is saved offline. */
-	protected boolean savedOffline = false;
-
-	/**
-	 * Creates a new <code>NewBugModel</code>. The id chosen for this bug is
-	 * based on the id of the last <code>NewBugModel</code> that was created.
-	 */
-	public NewBugzillaTaskData(String repositoryURL, String offlineId) {
-		super(new BugzillaAttributeFactory(), BugzillaCorePlugin.REPOSITORY_KIND, repositoryURL, offlineId);
-	}
-
-	@Override
-	public String getLabel() {
-		return "<unsubmitted> "+ this.getRepositoryUrl();
-	}
-
-	@Override
-	public String getDescription() {
-		return description;
-	}
-
-	@Override
-	public void setDescription(String newDescription) {
-		description = newDescription;
-	}
-
-	@Override
-	public String getSummary() {
-		return summary;
-	}
-
-	@Override
-	public void setSummary(String newSummary) {
-		summary = newSummary;
-	}
-
-	/**
-	 * @return The product that the bug is for.
-	 */
-	@Override
-	public String getProduct() {
-		return product;
-	}
-
-	/**
-	 * Sets the product that the bug is for.
-	 * 
-	 * @param product
-	 *            The product.
-	 */
-	public void setProduct(String product) {
-		this.product = product;
-	}
-
-	/**
-	 * @return Flag to indicate status of connection to Bugzilla server (to
-	 *         identify whether ProductConfiguration should be used instead)
-	 */
-	public boolean isConnected() {
-		return connected;
-	}
-
-	/**
-	 * Sets the value of the flag to indicate status of connection to Bugzilla
-	 * server (to identify whether ProductConfiguration should be used instead)
-	 * 
-	 * @param newConnectionStatus
-	 *            <code>true</code> if the bug is connected.
-	 */
-	public void setConnected(boolean newConnectionStatus) {
-		connected = newConnectionStatus;
-	}
-
-	/**
-	 * @return Returns whether the attributes have been parsed yet or not.
-	 */
-	public boolean hasParsedAttributes() {
-		return hasParsedAttributes;
-	}
-
-	/**
-	 * Sets whether the attributes have been parsed yet or not.
-	 * 
-	 * @param hasParsedAttributes
-	 *            <code>true</code> if the attributes have been parsed.
-	 */
-	public void setParsedAttributesStatus(boolean hasParsedAttributes) {
-		this.hasParsedAttributes = hasParsedAttributes;
-	}
-
-	/**
-	 * @return Returns whether the products have been parsed yet or not.
-	 */
-	public boolean hasParsedProducts() {
-		return hasParsedProducts;
-	}
-
-	/**
-	 * Sets whether the products have been parsed yet or not.
-	 * 
-	 * @param hasParsedProducts
-	 *            <code>true</code> if the products have been parsed.
-	 */
-	public void setParsedProductsStatus(boolean hasParsedProducts) {
-		this.hasParsedProducts = hasParsedProducts;
-	}
-
-	public boolean isSavedOffline() {
-		return savedOffline;
-	}
-
-	@Override
-	public boolean isNew() {
-		return true;
-	}
-
-//	public void setOfflineState(boolean newOfflineState) {
-//		savedOffline = newOfflineState;
-//	}
-
-	@Override
-	public boolean hasLocalChanges() {
-		return true;
-	}
-
-	/** returns null */
-	@Override
-	public String getCreated() {
-		return null;
-	}
-
-	@Override
-	public String getLastModified() {
-		return null;
-	}
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/NewBugzillaTaskEditor.java b/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/NewBugzillaTaskEditor.java
deleted file mode 100644
index e716927..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/NewBugzillaTaskEditor.java
+++ /dev/null
@@ -1,252 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004, 2008 Tasktop Technologies and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     Tasktop Technologies - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.mylyn.bugzilla.deprecated;
-
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.NullProgressMonitor;
-import org.eclipse.jface.dialogs.MessageDialog;
-import org.eclipse.jface.fieldassist.ContentProposalAdapter;
-import org.eclipse.jface.layout.GridDataFactory;
-import org.eclipse.jface.viewers.ILabelProvider;
-import org.eclipse.mylyn.internal.bugzilla.core.BugzillaAttribute;
-import org.eclipse.mylyn.internal.bugzilla.core.BugzillaCorePlugin;
-import org.eclipse.mylyn.internal.bugzilla.ui.BugzillaUiPlugin;
-import org.eclipse.mylyn.internal.tasks.core.deprecated.RepositoryTaskAttribute;
-import org.eclipse.mylyn.internal.tasks.ui.deprecated.AbstractNewRepositoryTaskEditor;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.ModifyEvent;
-import org.eclipse.swt.events.ModifyListener;
-import org.eclipse.swt.events.SelectionAdapter;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Button;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Text;
-import org.eclipse.ui.IEditorInput;
-import org.eclipse.ui.IEditorSite;
-import org.eclipse.ui.fieldassist.ContentAssistCommandAdapter;
-import org.eclipse.ui.forms.editor.FormEditor;
-import org.eclipse.ui.forms.widgets.FormToolkit;
-import org.eclipse.ui.forms.widgets.Section;
-
-/**
- * An editor used to view a locally created bug that does not yet exist on a repository.
- * 
- * @author Rob Elves
- */
-public class NewBugzillaTaskEditor extends AbstractNewRepositoryTaskEditor {
-
-	protected Text assignedTo;
-
-	public NewBugzillaTaskEditor(FormEditor editor) {
-		super(editor);
-	}
-
-	@Override
-	public void init(IEditorSite site, IEditorInput input) {
-		super.init(site, input);
-
-		setExpandAttributeSection(true);
-	}
-
-	@Override
-	protected void saveTaskOffline(IProgressMonitor progressMonitor) {
-		String text = descriptionTextViewer.getTextWidget().getText();
-		if (repository.getVersion().startsWith("2.18")) {
-			text = BugzillaUiPlugin.formatTextToLineWrap(text, true);
-			descriptionTextViewer.getTextWidget().setText(text);
-		}
-		super.saveTaskOffline(progressMonitor);
-	}
-
-	@Override
-	protected void createPeopleLayout(Composite composite) {
-		FormToolkit toolkit = getManagedForm().getToolkit();
-		Section peopleSection = createSection(composite, getSectionLabel(SECTION_NAME.PEOPLE_SECTION));
-		GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL).grab(true, true).applyTo(peopleSection);
-		Composite peopleComposite = toolkit.createComposite(peopleSection);
-		GridLayout layout = new GridLayout(2, false);
-		layout.marginRight = 5;
-		peopleComposite.setLayout(layout);
-		GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL).grab(true, true).applyTo(peopleComposite);
-
-		addAssignedTo(peopleComposite);
-		//addSelfToCC(peopleComposite);
-		addCCList(peopleComposite);
-		getManagedForm().getToolkit().paintBordersFor(peopleComposite);
-		peopleSection.setClient(peopleComposite);
-		peopleSection.setEnabled(true);
-	}
-
-	@Override
-	public void submitToRepository() {
-		if (summaryText.getText().equals("")) {
-			MessageDialog.openInformation(this.getSite().getShell(), "Submit Error",
-					"Please provide a brief summary with new reports.");
-			summaryText.setFocus();
-			return;
-		} else if (descriptionTextViewer.getTextWidget().getText().equals("")) {
-			MessageDialog.openInformation(this.getSite().getShell(), "Submit Error",
-					"Please proved a detailed description with new reports");
-			descriptionTextViewer.getTextWidget().setFocus();
-			return;
-		}
-		RepositoryTaskAttribute attribute = taskData.getAttribute(BugzillaAttribute.COMPONENT.getKey());
-		String componentValue = attribute.getValue();
-		if (componentValue.equals("")) {
-			MessageDialog.openInformation(this.getSite().getShell(), "Submit Error",
-					"Please select a component with new reports");
-			descriptionTextViewer.getTextWidget().setFocus();
-			return;
-		}
-		super.submitToRepository();
-	}
-
-	@Override
-	protected void createCustomAttributeLayout(Composite composite) {
-
-		RepositoryTaskAttribute attribute = this.taskData.getAttribute(BugzillaAttribute.DEPENDSON.getKey());
-		if (attribute != null && !attribute.isReadOnly()) {
-			Label label = createLabel(composite, attribute);
-			GridDataFactory.fillDefaults().align(SWT.RIGHT, SWT.CENTER).applyTo(label);
-			Composite textFieldComposite = getManagedForm().getToolkit().createComposite(composite);
-			GridLayout textLayout = new GridLayout();
-			textLayout.marginWidth = 1;
-			textLayout.marginHeight = 3;
-			textLayout.verticalSpacing = 3;
-			textFieldComposite.setLayout(textLayout);
-			GridData textData = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
-			textData.horizontalSpan = 1;
-			textData.widthHint = 135;
-
-			final Text text = createTextField(textFieldComposite, attribute, SWT.FLAT);
-			text.setLayoutData(textData);
-			getManagedForm().getToolkit().paintBordersFor(textFieldComposite);
-		}
-
-		attribute = this.taskData.getAttribute(BugzillaAttribute.BLOCKED.getKey());
-		if (attribute != null && !attribute.isReadOnly()) {
-			Label label = createLabel(composite, attribute);
-			GridDataFactory.fillDefaults().align(SWT.RIGHT, SWT.CENTER).applyTo(label);
-			Composite textFieldComposite = getManagedForm().getToolkit().createComposite(composite);
-			GridLayout textLayout = new GridLayout();
-			textLayout.marginWidth = 1;
-			textLayout.marginHeight = 3;
-			textLayout.verticalSpacing = 3;
-			textFieldComposite.setLayout(textLayout);
-			GridData textData = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
-			textData.horizontalSpan = 1;
-			textData.widthHint = 135;
-			final Text text = createTextField(textFieldComposite, attribute, SWT.FLAT);
-			text.setLayoutData(textData);
-			getManagedForm().getToolkit().paintBordersFor(textFieldComposite);
-		}
-	}
-
-	@Override
-	protected boolean hasContentAssist(RepositoryTaskAttribute attribute) {
-		return BugzillaAttribute.NEWCC.getKey().equals(attribute.getId());
-	}
-
-	/**
-	 * FIXME: A lot of duplicated code here between this and BugzillaTaskEditor
-	 */
-	@Override
-	protected void addAssignedTo(Composite peopleComposite) {
-		RepositoryTaskAttribute assignedAttribute = taskData.getAttribute(RepositoryTaskAttribute.USER_ASSIGNED);
-		if (assignedAttribute != null) {
-			String bugzillaVersion;
-			try {
-				bugzillaVersion = BugzillaCorePlugin.getRepositoryConfiguration(repository, false,
-						new NullProgressMonitor()).getInstallVersion();
-			} catch (CoreException e1) {
-				// ignore
-				bugzillaVersion = "2.18";
-			}
-			if (bugzillaVersion.compareTo("3.1") < 0) {
-				// old bugzilla workflow is used
-				super.addAssignedTo(peopleComposite);
-				return;
-			}
-			Label label = createLabel(peopleComposite, assignedAttribute);
-			GridDataFactory.fillDefaults().align(SWT.RIGHT, SWT.CENTER).applyTo(label);
-			if (assignedAttribute.isReadOnly()) {
-				assignedTo = createTextField(peopleComposite, assignedAttribute, SWT.FLAT | SWT.READ_ONLY);
-			} else {
-				assignedTo = createTextField(peopleComposite, assignedAttribute, SWT.FLAT);
-			}
-			GridDataFactory.fillDefaults().hint(150, SWT.DEFAULT).applyTo(assignedTo);
-			assignedTo.addModifyListener(new ModifyListener() {
-				public void modifyText(ModifyEvent e) {
-					String sel = assignedTo.getText();
-					RepositoryTaskAttribute a = taskData.getAttribute(RepositoryTaskAttribute.USER_ASSIGNED);
-					if (!(a.getValue().equals(sel))) {
-						a.setValue(sel);
-						markDirty(true);
-					}
-				}
-			});
-			ContentAssistCommandAdapter adapter = applyContentAssist(assignedTo,
-					createContentProposalProvider(assignedAttribute));
-			ILabelProvider propsalLabelProvider = createProposalLabelProvider(assignedAttribute);
-			if (propsalLabelProvider != null) {
-				adapter.setLabelProvider(propsalLabelProvider);
-			}
-			adapter.setProposalAcceptanceStyle(ContentProposalAdapter.PROPOSAL_REPLACE);
-
-			FormToolkit toolkit = getManagedForm().getToolkit();
-			Label dummylabel = toolkit.createLabel(peopleComposite, "");
-			GridDataFactory.fillDefaults().align(SWT.RIGHT, SWT.CENTER).applyTo(dummylabel);
-			RepositoryTaskAttribute attribute = taskData.getAttribute(BugzillaAttribute.SET_DEFAULT_ASSIGNEE.getKey());
-			if (attribute == null) {
-				taskData.setAttributeValue(BugzillaAttribute.SET_DEFAULT_ASSIGNEE.getKey(), "0");
-				attribute = taskData.getAttribute(BugzillaAttribute.SET_DEFAULT_ASSIGNEE.getKey());
-			}
-			addButtonField(peopleComposite, attribute, SWT.CHECK);
-		}
-	}
-
-	private Button addButtonField(Composite rolesComposite, RepositoryTaskAttribute attribute, int style) {
-		if (attribute == null) {
-			return null;
-		}
-		String name = attribute.getName();
-		if (hasOutgoingChange(attribute)) {
-			name += "*";
-		}
-
-		final Button button = getManagedForm().getToolkit().createButton(rolesComposite, name, style);
-		if (!attribute.isReadOnly()) {
-			button.setData(attribute);
-			button.setSelection(attribute.getValue().equals("1"));
-			button.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));
-			button.addSelectionListener(new SelectionAdapter() {
-
-				@Override
-				public void widgetSelected(SelectionEvent e) {
-					String sel = "1";
-					if (!button.getSelection()) {
-						sel = "0";
-					}
-					RepositoryTaskAttribute a = (RepositoryTaskAttribute) button.getData();
-					a.setValue(sel);
-					attributeChanged(a);
-				}
-			});
-		}
-		return button;
-	}
-
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/OpenBugzillaReportJob.java b/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/OpenBugzillaReportJob.java
deleted file mode 100644
index dcec6bd..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/OpenBugzillaReportJob.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004 - 2006 University Of British Columbia and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     University Of British Columbia - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.mylyn.internal.bugs;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.jface.operation.IRunnableWithProgress;
-import org.eclipse.mylyn.internal.bugzilla.ui.BugzillaOpenStructure;
-import org.eclipse.mylyn.internal.bugzilla.ui.ViewBugzillaAction;
-import org.eclipse.mylyn.internal.core.util.MylarStatusHandler;
-
-/**
- * @author Mik Kersten
- */
-public class OpenBugzillaReportJob implements IRunnableWithProgress {
-
-	private int id;
-
-	private String serverUrl;
-
-	public OpenBugzillaReportJob(String serverUrl, int id) {
-		this.id = id;
-		this.serverUrl = serverUrl;
-	}
-
-	public void run(IProgressMonitor monitor) {
-		try {
-			monitor.beginTask("Opening Bugzilla Report", 10);
-			List<BugzillaOpenStructure> list = new ArrayList<BugzillaOpenStructure>(1);
-			list.add(new BugzillaOpenStructure(serverUrl, id, -1));
-			new ViewBugzillaAction("Open Bug " + id, list).run(monitor);
-			monitor.done();
-		} catch (Exception e) {
-			MylarStatusHandler.fail(e, "Unable to open Bug report: " + id, true);
-		}
-	}
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/RegularExpressionMatchTest.java b/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/RegularExpressionMatchTest.java
deleted file mode 100644
index f756208..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/RegularExpressionMatchTest.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004 - 2006 University Of British Columbia and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     University Of British Columbia - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.mylyn.bugzilla.tests;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.StringReader;
-
-import junit.framework.TestCase;
-
-import org.eclipse.core.runtime.NullProgressMonitor;
-import org.eclipse.mylyn.internal.bugzilla.core.BugzillaQueryHit;
-import org.eclipse.mylyn.internal.bugzilla.core.IBugzillaConstants;
-import org.eclipse.mylyn.internal.sandbox.bridge.bugs.BugzillaSearchEngine;
-
-public class RegularExpressionMatchTest extends TestCase {
-
-	public void testMatchV218() throws IOException {
-		BufferedReader in = new BufferedReader(new StringReader(BUGZILLA_218));
-		BugzillaQueryHit hit = BugzillaSearchEngine.createHit(BugzillaSearchEngine.reValue, new NullProgressMonitor(),
-				in, IBugzillaConstants.ECLIPSE_BUGZILLA_URL, 123);
-		//assertEquals("nor", hit.getSeverity());
-		assertEquals("P2", hit.getPriority());
-	}
-
-	public void testMatchV220() throws IOException {
-		BufferedReader in = new BufferedReader(new StringReader(BUGZILLA_220));
-		BugzillaQueryHit hit = BugzillaSearchEngine.createHit(BugzillaSearchEngine.reValueBugzilla220,
-				new NullProgressMonitor(), in, IBugzillaConstants.ECLIPSE_BUGZILLA_URL, 123);
-		//assertEquals("nor", hit.getSeverity());
-		assertEquals("P2", hit.getPriority());
-	}
-
-	private static final String BUGZILLA_218 = "  <tr class=\"bz_normal             bz_P2             bz_ASSIGNED                                       bz_even             \">\n"
-			+ "             \n"
-			+ "\n"
-			+ "    <td class=\"first-child\">\n"
-			+ "      <a href=\"show_bug.cgi?id=111870\">111870</a>\n"
-			+ "      <span style=\"display: none\"></span>\n"
-			+ "    </td>\n"
-			+ "\n"
-			+ "    <td><nobr>nor</nobr>\n"
-			+ "    </td>\n"
-			+ "    <td><nobr>P2</nobr>\n"
-			+ "    </td>\n"
-			+ "    <td><nobr>Oth</nobr>\n"
-			+ "    </td>\n"
-			+ "    <td><nobr>wes.coelho&#64;gmail.com</nobr>\n"
-			+ "    </td>\n"
-			+ "    <td><nobr>ASSI</nobr>\n"
-			+ "    </td>\n"
-			+ "    <td><nobr></nobr>\n"
-			+ "    </td>\n"
-			+ "    <td>hour estimates are wrong\n"
-			+ "    </td>\n" + "\n" + "  </tr>\n";
-
-	private static final String BUGZILLA_220 = "  <tr class=\"bz_enhancement             bz_P2             bz_ASSIGNED                                                    bz_row_odd             \">\n"
-			+ "             \n"
-			+ "\n"
-			+ "    <td class=\"first-child\">\n"
-			+ "      <a href=\"show_bug.cgi?id=114172\">114172</a>\n"
-			+ "      <span style=\"display: none\"></span>\n"
-			+ "    </td>\n"
-			+ "\n"
-			+ "    <td style=\"white-space: nowrap\">nor\n"
-			+ "    </td>\n"
-			+ "    <td style=\"white-space: nowrap\">P2\n"
-			+ "    </td>\n"
-			+ "    <td style=\"white-space: nowrap\">PC\n"
-			+ "    </td>\n"
-			+ "    <td style=\"white-space: nowrap\">wes.coelho&#64;gmail.com\n"
-			+ "    </td>\n"
-			+ "    <td style=\"white-space: nowrap\">ASSI\n"
-			+ "    </td>\n"
-			+ "    <td style=\"white-space: nowrap\">\n"
-			+ "    </td>\n"
-			+ "    <td >Switch task data directory option on the task list\n" + "    </td>\n" + "\n" + "  </tr>\n";
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/RepositoryConfiguration.java b/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/RepositoryConfiguration.java
deleted file mode 100644
index 99cd532..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/RepositoryConfiguration.java
+++ /dev/null
@@ -1,407 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004 - 2006 University Of British Columbia and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     University Of British Columbia - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.mylyn.internal.tasks.core;
-
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.eclipse.mylyn.tasks.core.AbstractAttributeFactory;
-import org.eclipse.mylyn.tasks.core.AttributeContainer;
-
-/**
- * Class describing the configuration of products and components for a given
- * Bugzilla installation.
- * 
- * @author Rob Elves
- */
-public class CopyOfRepositoryConfiguration extends AttributeContainer implements Serializable {
-
-	/**
-	 * Container for product information: name, components.
-	 */
-	private static class ProductEntry implements Serializable {
-
-		private static final long serialVersionUID = 4120139521246741120L;
-
-		List<String> components = new ArrayList<String>();
-
-		List<String> milestones = new ArrayList<String>();
-
-		String productName;
-
-		List<String> versions = new ArrayList<String>();
-
-		ProductEntry(String name) {
-			this.productName = name;
-		}
-
-		void addComponent(String componentName) {
-			if (!components.contains(componentName)) {
-				components.add(componentName);
-			}
-		}
-
-		void addTargetMilestone(String target) {
-			milestones.add(target);
-		}
-
-		void addVersion(String name) {
-			if (!versions.contains(name)) {
-				versions.add(name);
-			}
-		}
-
-		List<String> getComponents() {
-			return components;
-		}
-
-		List<String> getTargetMilestones() {
-			return milestones;
-		}
-
-		List<String> getVersions() {
-			return versions;
-		}
-	}
-
-	public static final String CONFIG_COMPONENT = "repository.configuration.component";
-
-	public static final String CONFIG_KEYWORDS = "repository.configuration.keywords";
-
-	public static final String CONFIG_MILESTONE = "repository.configuration.milestone";
-
-	public static final String CONFIG_OPSYS = "repository.configuration.opsys";
-
-	public static final String CONFIG_PLATFORM = "repository.configuration.platform";
-
-	public static final String CONFIG_PRIORITY = "repository.configuration.priority";
-
-	public static final String CONFIG_PRODUCT = "repository.configuration.product";
-
-	public static final String CONFIG_RESOLUTION = "repository.configuration.resolution";
-
-	public static final String CONFIG_SEVERITY = "repository.configuration.severity";
-
-	public static final String CONFIG_STATUS = "repository.configuration.status";
-
-	public static final String CONFIG_VERSION = "repository.configuration.version";
-
-	private static final long serialVersionUID = -3623617786905114255L;
-
-	private static final String VERSION_UNKNOWN = "unknown";
-
-	private List<String> bugStatus = new ArrayList<String>();
-
-	private List<String> components = new ArrayList<String>();
-
-	private List<String> keywords = new ArrayList<String>();
-
-	private List<String> milestones = new ArrayList<String>();
-
-	private List<String> openStatusValues = new ArrayList<String>();
-
-	private List<String> operatingSystems = new ArrayList<String>();
-
-	private List<String> platforms = new ArrayList<String>();
-
-	private List<String> priorities = new ArrayList<String>();
-
-	private Map<String, ProductEntry> products = new HashMap<String, ProductEntry>();
-
-	// master lists
-
-	private String repositoryUrl = "<unknown>";
-
-	private List<String> resolutionValues = new ArrayList<String>();
-
-	private List<String> severities = new ArrayList<String>();
-
-	private String version = VERSION_UNKNOWN;
-
-	private List<String> versions = new ArrayList<String>();
-
-	public CopyOfRepositoryConfiguration(AbstractAttributeFactory factory) {
-		super(factory);
-		// ignore
-	}
-
-//	/**
-//	 * Adds a component to the given product.
-//	 */
-//	public void addComponent(String product, String component) {
-//		if (!components.contains(component))
-//			components.add(component);
-//		ProductEntry entry = products.get(product);
-//		if (entry == null) {
-//			entry = new ProductEntry(product);
-//			products.put(product, entry);
-//		}
-//		entry.addComponent(component);
-//	}
-//
-//	public void addKeyword(String keyword) {
-//		keywords.add(keyword);
-//	}
-//
-//	public void addOpenStatusValue(String value) {
-//		openStatusValues.add(value);
-//	}
-//
-//	public void addOS(String os) {
-//		operatingSystems.add(os);
-//	}
-//
-//	public void addPlatform(String platform) {
-//		platforms.add(platform);
-//	}
-//
-//	public void addPriority(String priority) {
-//		priorities.add(priority);
-//	}
-//
-//	/**
-//	 * Adds a product to the configuration.
-//	 */
-//	public void addProduct(String name) {
-//		if (!products.containsKey(name)) {
-//			ProductEntry product = new ProductEntry(name);
-//			products.put(name, product);
-//		}
-//	}
-//
-//	public void addResolution(String res) {
-//		resolutionValues.add(res);
-//	}
-//
-//	public void addSeverity(String severity) {
-//		severities.add(severity);
-//
-//	}
-//
-//	public void addStatus(String status) {
-//		bugStatus.add(status);
-//	}
-//
-//	public void addTargetMilestone(String product, String target) {
-//		if (!milestones.contains(target))
-//			milestones.add(target);
-//		ProductEntry entry = products.get(product);
-//		if (entry == null) {
-//			entry = new ProductEntry(product);
-//			products.put(product, entry);
-//		}
-//
-//		entry.addTargetMilestone(target);
-//
-//	}
-//
-//	public void addVersion(String product, String version) {
-//		if (!versions.contains(version))
-//			versions.add(version);
-//		ProductEntry entry = products.get(product);
-//		if (entry == null) {
-//			entry = new ProductEntry(product);
-//			products.put(product, entry);
-//		}
-//		entry.addVersion(version);
-//	}
-//
-//	public List<String> getComponents() {
-//		return components;
-//	}
-//
-//	// /**
-//	// * Adds a list of components to the given product.
-//	// */
-//	// public void addComponents(String product, List<String> components) {
-//	// ProductEntry entry = products.get(product);
-//	// if (entry == null) {
-//	// entry = new ProductEntry(product);
-//	// products.put(product, entry);
-//	// }
-//	// for (String component : components) {
-//	// entry.addComponent(component);
-//	// }
-//	// }
-//	// /**
-//	// * Adds a list of components to the given product.
-//	// */
-//	// public void addComponents(String product, List<String> components) {
-//	// ProductEntry entry = products.get(product);
-//	// if (entry == null) {
-//	// entry = new ProductEntry(product);
-//	// products.put(product, entry);
-//	// }
-//	// for (String component : components) {
-//	// entry.addComponent(component);
-//	// }
-//	// }
-//
-//	/**
-//	 * Returns an array of names of component that exist for a given product or
-//	 * <code>null</code> if the product does not exist.
-//	 */
-//	public List<String> getComponents(String product) {
-//		ProductEntry entry = products.get(product);
-//		if (entry != null) {
-//			return entry.getComponents();
-//		} else
-//			return Collections.emptyList();
-//	}
-//
-//	// /**
-//	// * Adds a list of components to the given product.
-//	// */
-//	// public void addVersions(String product, List<String> versions) {
-//	// ProductEntry entry = products.get(product);
-//	// if (entry == null) {
-//	// entry = new ProductEntry(product);
-//	// products.put(product, entry);
-//	// }
-//	// for (String version : versions) {
-//	// entry.addVersion(version);
-//	// }
-//	// }
-//
-//	public String getInstallVersion() {
-//		return version;
-//	}
-//
-//	public List<String> getKeywords() {
-//		return keywords;
-//	}
-//
-//	public List<String> getOpenStatusValues() {
-//		return openStatusValues;
-//	}
-//
-//	/*
-//	 * Intermediate step until configuration is made generic.
-//	 */
-//	public List<String> getOptionValues(String attributeKey, String product) {		
-//		if (attributeKey.equals(CONFIG_PRODUCT))
-//			return getProducts();
-//		if (attributeKey.equals(CONFIG_MILESTONE))
-//			return getTargetMilestones(product);
-//		if (attributeKey.equals(CONFIG_STATUS))
-//			return getStatusValues();
-//		if (attributeKey.equals(CONFIG_VERSION))
-//			return getVersions(product);
-//		if (attributeKey.equals(CONFIG_COMPONENT))
-//			return getComponents(product);
-//		if (attributeKey.equals(CONFIG_PLATFORM))
-//			return getPlatforms();
-//		if (attributeKey.equals(CONFIG_OPSYS))
-//			return getOSs();
-//		if (attributeKey.equals(CONFIG_PRIORITY))
-//			return getPriorities();
-//		if (attributeKey.equals(CONFIG_SEVERITY))
-//			return getSeverities();
-//		if (attributeKey.equals(CONFIG_KEYWORDS))
-//			return getKeywords();
-//		if (attributeKey.equals(CONFIG_RESOLUTION))
-//			return getResolutions();
-//
-//		return new ArrayList<String>();
-//	}
-//
-//	/**
-//	 * Returns an array of names of valid OS values.
-//	 */
-//	public List<String> getOSs() {
-//		//return operatingSystems;
-//		return getAttributeValues("op_sys");
-//	}
-//
-//	/**
-//	 * Returns an array of names of valid platform values.
-//	 */
-//	public List<String> getPlatforms() {
-//		return platforms;
-//	}
-//
-//	/**
-//	 * Returns an array of names of valid platform values.
-//	 */
-//	public List<String> getPriorities() {
-//		return priorities;
-//	}
-//
-//	/**
-//	 * Returns an array of names of current products.
-//	 */
-//	public List<String> getProducts() {
-//		ArrayList<String> productList = new ArrayList<String>(products.keySet());
-//		Collections.sort(productList);
-//		return productList;
-//	}
-//
-//	public List<String> getResolutions() {
-//		return resolutionValues;
-//	}
-//
-//	/**
-//	 * Returns an array of names of valid severity values.
-//	 */
-//	public List<String> getSeverities() {
-//		return severities;
-//	}
-//
-//	public List<String> getStatusValues() {
-//		return bugStatus;
-//	}
-//
-//	public List<String> getTargetMilestones() {
-//		return milestones;
-//	}
-//
-//	public List<String> getTargetMilestones(String product) {
-//		ProductEntry entry = products.get(product);
-//		if (entry != null) {
-//			return entry.getTargetMilestones();
-//		} else
-//			return Collections.emptyList();
-//	}
-//
-//	public List<String> getVersions() {
-//		return versions;
-//	}
-//
-//	/**
-//	 * Returns an array of names of versions that exist for a given product or
-//	 * <code>null</code> if the product does not exist.
-//	 */
-//	public List<String> getVersions(String product) {
-//		ProductEntry entry = products.get(product);
-//		if (entry != null) {
-//			return entry.getVersions();
-//		} else
-//			return Collections.emptyList();
-//	}
-//
-//	public void setInstallVersion(String version) {
-//		this.version = version;
-//	}
-
-	public String getRepositoryUrl() {
-		return repositoryUrl;
-	}
-	
-	public void setRepositoryUrl(String repositoryUrl) {
-		this.repositoryUrl = repositoryUrl;
-	}
-
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/RepositoryReportFactory.java b/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/RepositoryReportFactory.java
deleted file mode 100644
index 1aa297f..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/RepositoryReportFactory.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004, 2007 Mylyn project committers and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *******************************************************************************/
-
-package org.eclipse.mylyn.internal.bugzilla.core;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.Locale;
-
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.mylyn.tasks.core.RepositoryStatus;
-import org.eclipse.mylyn.tasks.core.RepositoryTaskData;
-
-/**
- * Reads bug reports from repository.
- * 
- * @author Rob Elves
- */
-public class RepositoryReportFactory extends AbstractReportFactory {
-
-	public RepositoryReportFactory(InputStream inStream, String encoding) {
-		super(inStream, encoding);
-	}
-
-	private static BugzillaAttributeFactory bugzillaAttributeFactory = new BugzillaAttributeFactory();
-
-	public void populateReport(RepositoryTaskData bugReport) throws IOException, CoreException {
-
-		SaxBugReportContentHandler contentHandler = new SaxBugReportContentHandler(bugzillaAttributeFactory, bugReport);
-		collectResults(contentHandler, false);
-
-		if (contentHandler.errorOccurred()) {
-			String errorResponse = contentHandler.getErrorMessage().toLowerCase(Locale.ENGLISH);
-			if (errorResponse.equals(IBugzillaConstants.XML_ERROR_NOTFOUND)
-					|| errorResponse.equals(IBugzillaConstants.XML_ERROR_INVALIDBUGID)) {
-				throw new CoreException(new BugzillaStatus(IStatus.WARNING, BugzillaCorePlugin.PLUGIN_ID,
-						RepositoryStatus.ERROR_REPOSITORY, bugReport.getRepositoryUrl(),
-						IBugzillaConstants.ERROR_MSG_INVALID_BUG_ID));
-			}
-			if (errorResponse.equals(IBugzillaConstants.XML_ERROR_NOTPERMITTED)) {
-				throw new CoreException(new BugzillaStatus(IStatus.WARNING, BugzillaCorePlugin.PLUGIN_ID,
-						RepositoryStatus.ERROR_REPOSITORY, bugReport.getRepositoryUrl(),
-						IBugzillaConstants.ERROR_MSG_OP_NOT_PERMITTED));
-			}
-		}
-	}
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/SaveQueryDialog.java b/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/SaveQueryDialog.java
deleted file mode 100644
index deb1d15..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/SaveQueryDialog.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004 - 2006 University Of British Columbia and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     University Of British Columbia - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.mylyn.internal.bugzilla.ui.search;
-
-import org.eclipse.jface.dialogs.Dialog;
-import org.eclipse.jface.dialogs.IDialogConstants;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.ModifyEvent;
-import org.eclipse.swt.events.ModifyListener;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.widgets.Button;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Shell;
-import org.eclipse.swt.widgets.Text;
-
-/**
- * Dialog for naming a saved query.
- */
-public class SaveQueryDialog extends Dialog {
-	private Text queryName;
-
-	/**
-	 * The Ok button.
-	 */
-	private Button okButton;
-
-	/**
-	 * The title of the dialog.
-	 */
-	private String title;
-
-	public SaveQueryDialog(Shell parentShell, String dialogTitle) {
-		super(parentShell);
-		this.title = dialogTitle;
-		setShellStyle(SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL);
-	}
-
-	@Override
-	protected void configureShell(Shell shell) {
-		super.configureShell(shell);
-		shell.setText(title);
-	}
-
-	@Override
-	protected void createButtonsForButtonBar(Composite parent) {
-		// create OK and cancel buttons
-		okButton = createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL, true);
-		createButton(parent, IDialogConstants.CANCEL_ID, IDialogConstants.CANCEL_LABEL, false);
-		okButton.setEnabled(false);
-	}
-
-	@Override
-	protected Control createDialogArea(Composite parent) {
-		// create composite
-		Composite composite = (Composite) super.createDialogArea(parent);
-
-		createMainDialogArea(composite);
-		return composite;
-	}
-
-	protected void createMainDialogArea(Composite parent) {
-		queryName = new Text(parent, SWT.SINGLE | SWT.BORDER);
-		queryName.setLayoutData(new GridData(GridData.BEGINNING | GridData.FILL_HORIZONTAL | GridData.GRAB_HORIZONTAL));
-		queryName.addModifyListener(new ModifyListener() {
-			public void modifyText(ModifyEvent e) {
-				if (queryName.getText().compareTo("") != 0 && queryName.getText() != null)
-					okButton.setEnabled(true);
-				else
-					okButton.setEnabled(false);
-				queryNameText = queryName.getText();
-			}
-		});
-	}
-
-	String queryNameText;
-
-	public String getText() {
-		return queryNameText;
-	}
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/SavedQueryFile.java b/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/SavedQueryFile.java
deleted file mode 100644
index 71cf719..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/SavedQueryFile.java
+++ /dev/null
@@ -1,256 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004 - 2006 University Of British Columbia and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     University Of British Columbia - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.mylyn.internal.bugzilla.ui.search;
-
-import java.io.DataInputStream;
-import java.io.DataOutputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.util.ArrayList;
-
-import org.eclipse.jface.dialogs.MessageDialog;
-import org.eclipse.mylyn.internal.bugzilla.core.BugzillaPlugin;
-import org.eclipse.ui.PlatformUI;
-
-/**
- * This class manages accessing and persisting named Bugzilla queries.
- */
-public class SavedQueryFile {
-	/** The file that the queries are written to */
-	private File file;
-
-	/** The directory to where the file is located */
-	private File directory;
-
-	/** A list of remembered queries */
-	private ArrayList<String> list = new ArrayList<String>();
-
-	private ArrayList<String> nameList = new ArrayList<String>();
-
-	private ArrayList<String> sumList = new ArrayList<String>();
-
-	/**
-	 * Constructor
-	 * 
-	 * @param dirPath
-	 *            The path to the directory where the favorites file should be
-	 *            written to
-	 * @param fileName
-	 *            The file that the favorites should be written to
-	 */
-	public SavedQueryFile(String dirPath, String fileName) {
-		// create a new file and if it exists, read the data from the file
-		// else create the file and directories if they dont exist
-		file = new File(dirPath + fileName);
-		if (file.exists()) {
-			readFile();
-		} else {
-			directory = new File(dirPath);
-			if (!directory.exists())
-				directory.mkdirs();
-			writeFile();
-		}
-	}
-
-	/**
-	 * Add a query to the list
-	 * 
-	 * @param entry
-	 *            The query to add
-	 */
-	public int add(String entry, String name, String sum) {
-		// add the entry to the list and write the file to disk
-		int index = find(name);
-		if (index == -1) {
-			list.add(entry);
-			nameList.add(name);
-			sumList.add(sum);
-			writeFile();
-		} else {
-			boolean isDuplicate = MessageDialog.openConfirm(PlatformUI.getWorkbench()
-					.getActiveWorkbenchWindow().getShell(), "Save Bugzilla Query", name
-					+ " already exists. Do you want to replace it?");
-			if (isDuplicate) {
-				list.add(index, entry);
-				nameList.add(index, name);
-				sumList.add(index, sum);
-				list.remove(index + 1);
-				nameList.remove(index + 1);
-				sumList.remove(index + 1);
-				writeFile();
-			}
-		}
-
-		index = find(entry);
-		return index;
-	}
-
-	/**
-	 * Find a bug in the query list
-	 * 
-	 * @param name
-	 *            The name of the query that we are looking for
-	 * @return The index of the query in the array if it exists, else -1
-	 */
-	public int find(String name) {
-		for (int i = 0; i < list.size(); i++) {
-			String str = nameList.get(i);
-			if (name.compareTo(str) == 0)
-				return i;
-		}
-		return -1;
-	}
-
-	/**
-	 * Get the list of queries
-	 * 
-	 * @return The list of queries
-	 */
-	public ArrayList<String> elements() {
-		return list;
-	}
-
-	/**
-	 * Write the queries to disk
-	 */
-	private void writeFile() {
-		try {
-			OutputStream os = new FileOutputStream(file);
-			DataOutputStream data = new DataOutputStream(os);
-
-			// Write the size of the list so that we can read it back in easier
-			data.writeInt(list.size());
-
-			// write each element in the array list
-			for (int i = 0; i < list.size(); i++) {
-				String item = list.get(i);
-				String itemName = nameList.get(i);
-				String summary = sumList.get(i);
-
-				// write the string in a machine independant manner
-				data.writeUTF(item);
-				data.writeUTF(itemName);
-				data.writeUTF(summary);
-			}
-
-			// close the file
-			data.close();
-		} catch (IOException e) {
-			// put up a message and log the error if there is a problem writing
-			// to the file
-			BugzillaPlugin.getDefault().logAndShowExceptionDetailsDialog(e,
-					"occurred while saving your Bugzilla queries", "I/O Error");
-		}
-	}
-
-	/**
-	 * Read the queries in from the file on disk
-	 */
-	private void readFile() {
-		try {
-			InputStream is = new FileInputStream(file);
-			DataInputStream data = new DataInputStream(is);
-
-			// get the number of favorites in the file
-			int size = data.readInt();
-
-			// read in each of the favorites in the file
-			for (int nX = 0; nX < size; nX++) {
-				String item, name, summary;
-
-				// get the data from disk in a machine independant way
-				item = data.readUTF();
-				name = data.readUTF();
-				summary = data.readUTF();
-
-				// add the favorite to the favorites list
-				list.add(item);
-				nameList.add(name);
-				sumList.add(summary);
-			}
-
-			// close the input stream
-			data.close();
-		} catch (IOException e) {
-			// put up a message and log the error if there is a problem reading
-			// from the file
-			BugzillaPlugin.getDefault().logAndShowExceptionDetailsDialog(e,
-					"occurred while restoring saved Bugzilla queries.", "I/O Error");
-		}
-	}
-
-	/**
-	 * Remove some queries from the list
-	 * 
-	 * @param indicesToRemove
-	 *            An array of the indicies of the queries to be removed
-	 */
-	public void remove(int[] indicesToRemove) {
-		int timesShifted = 0;
-
-		// remove each of the indicated items from the array
-		for (int i = 0; i < indicesToRemove.length; i++) {
-			list.remove(indicesToRemove[i] - timesShifted);
-			nameList.remove(indicesToRemove[i] - timesShifted);
-			sumList.remove(indicesToRemove[i] - timesShifted);
-			timesShifted++;
-		}
-
-		// rewrite the file so that the data is persistant
-		writeFile();
-
-		// remove the items from the combo box
-		timesShifted = 0;
-	}
-
-	/**
-	 * Remove all of the items in the favortes menu
-	 */
-	public void removeAll() {
-		// remove every element from the favorites list
-		while (list.size() > 0) {
-			list.remove(0);
-			nameList.remove(0);
-			sumList.remove(0);
-		}
-
-		// rewrite the file so that the data is persistant
-		writeFile();
-	}
-
-	/**
-	 * Get the query parameters of the currently selected remembered query
-	 * 
-	 * @return The query url
-	 */
-	public String getQueryParameters(int index) {
-		return list.get(index);
-	}
-
-	/**
-	 * Get the summary text of the currently selected remembered query
-	 * 
-	 * @return The summary text
-	 */
-	public String getSummaryText(int index) {
-		return sumList.get(index);
-
-	}
-
-	public ArrayList<String> getNames() {
-		return nameList;
-	}
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/SaxBugReportContentHandler.java b/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/SaxBugReportContentHandler.java
deleted file mode 100644
index 0204b95..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/SaxBugReportContentHandler.java
+++ /dev/null
@@ -1,291 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004, 2007 Mylyn project committers and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *******************************************************************************/
-
-package org.eclipse.mylyn.internal.bugzilla.core;
-
-import java.util.HashMap;
-import java.util.Locale;
-import java.util.Map;
-
-import org.eclipse.mylyn.monitor.core.StatusHandler;
-import org.eclipse.mylyn.tasks.core.AbstractAttributeFactory;
-import org.eclipse.mylyn.tasks.core.RepositoryAttachment;
-import org.eclipse.mylyn.tasks.core.RepositoryTaskAttribute;
-import org.eclipse.mylyn.tasks.core.RepositoryTaskData;
-import org.eclipse.mylyn.tasks.core.TaskComment;
-import org.eclipse.mylyn.web.core.HtmlStreamTokenizer;
-import org.xml.sax.Attributes;
-import org.xml.sax.SAXException;
-import org.xml.sax.helpers.DefaultHandler;
-
-/**
- * Parser for xml bugzilla reports.
- * 
- * @author Rob Elves
- */
-public class SaxBugReportContentHandler extends DefaultHandler {
-
-	private static final String COMMENT_ATTACHMENT_STRING = "Created an attachment (id=";
-
-	private StringBuffer characters;
-
-	private TaskComment taskComment;
-
-	private final Map<String, TaskComment> attachIdToComment = new HashMap<String, TaskComment>();
-
-	private int commentNum = 0;
-
-	private RepositoryAttachment attachment;
-
-	private RepositoryTaskData repositoryTaskData;
-
-	private String errorMessage = null;
-
-	private AbstractAttributeFactory attributeFactory;
-
-	public SaxBugReportContentHandler(AbstractAttributeFactory factory, RepositoryTaskData taskData) {
-		this.attributeFactory = factory;
-		this.repositoryTaskData = taskData;
-	}
-
-	public boolean errorOccurred() {
-		return errorMessage != null;
-	}
-
-	public String getErrorMessage() {
-		return errorMessage;
-	}
-
-	public RepositoryTaskData getReport() {
-		return repositoryTaskData;
-	}
-
-	@Override
-	public void characters(char[] ch, int start, int length) throws SAXException {
-		characters.append(ch, start, length);
-		// if (monitor.isCanceled()) {
-		// throw new OperationCanceledException("Search cancelled");
-		// }
-	}
-
-	@Override
-	public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
-		characters = new StringBuffer();
-		BugzillaReportElement tag = BugzillaReportElement.UNKNOWN;
-		try {
-			tag = BugzillaReportElement.valueOf(localName.trim().toUpperCase(Locale.ENGLISH));
-		} catch (RuntimeException e) {
-			if (e instanceof IllegalArgumentException) {
-				// ignore unrecognized tags
-				return;
-			}
-			throw e;
-		}
-		switch (tag) {
-		case BUGZILLA:
-			// Note: here we can get the bugzilla version if necessary
-			break;
-		case BUG:
-			if (attributes != null && (attributes.getValue("error") != null)) {
-				errorMessage = attributes.getValue("error");
-			}
-			break;
-		case LONG_DESC:
-			taskComment = new TaskComment(attributeFactory, commentNum++);
-			break;
-		case ATTACHMENT:
-			attachment = new RepositoryAttachment(attributeFactory);
-			if (attributes != null) {
-				if ("1".equals(attributes.getValue(BugzillaReportElement.IS_OBSOLETE.getKeyString()))) {
-					attachment.addAttribute(BugzillaReportElement.IS_OBSOLETE.getKeyString(),
-							attributeFactory.createAttribute(BugzillaReportElement.IS_OBSOLETE.getKeyString()));
-					attachment.setObsolete(true);
-				}
-				if ("1".equals(attributes.getValue(BugzillaReportElement.IS_PATCH.getKeyString()))) {
-					attachment.setPatch(true);
-				}
-			}
-			break;
-		}
-
-	}
-
-	@Override
-	public void endElement(String uri, String localName, String qName) throws SAXException {
-
-		String parsedText = HtmlStreamTokenizer.unescape(characters.toString());
-
-		BugzillaReportElement tag = BugzillaReportElement.UNKNOWN;
-		try {
-			tag = BugzillaReportElement.valueOf(localName.trim().toUpperCase(Locale.ENGLISH));
-		} catch (RuntimeException e) {
-			if (e instanceof IllegalArgumentException) {
-				// ignore unrecognized tags
-				return;
-			}
-			throw e;
-		}
-		switch (tag) {
-		case BUG_ID: {
-			try {
-				if (!repositoryTaskData.getId().equals(parsedText)) {
-					errorMessage = "Requested report number does not match returned report number.";
-				}
-			} catch (Exception e) {
-				errorMessage = "Bug id from server did not match requested id.";
-			}
-
-			RepositoryTaskAttribute attr = repositoryTaskData.getAttribute(tag.getKeyString());
-			if (attr == null) {
-				attr = attributeFactory.createAttribute(tag.getKeyString());
-				repositoryTaskData.addAttribute(tag.getKeyString(), attr);
-			}
-			attr.setValue(parsedText);
-			break;
-		}
-
-			// Comment attributes
-		case WHO:
-		case BUG_WHEN:
-			if (taskComment != null) {
-				RepositoryTaskAttribute attr = attributeFactory.createAttribute(tag.getKeyString());
-				attr.setValue(parsedText);
-				taskComment.addAttribute(tag.getKeyString(), attr);
-			}
-			break;
-		case THETEXT:
-			if (taskComment != null) {
-				RepositoryTaskAttribute attr = attributeFactory.createAttribute(tag.getKeyString());
-				attr.setValue(parsedText);
-				taskComment.addAttribute(tag.getKeyString(), attr);
-
-				// Check for attachment
-				parseAttachment(taskComment, parsedText);
-			}
-			break;
-		case LONG_DESC:
-			if (taskComment != null) {
-				if (taskComment.getNumber() == 0) {
-					repositoryTaskData.setAttributeValue(RepositoryTaskAttribute.DESCRIPTION, taskComment.getText());
-					break;
-				}
-				repositoryTaskData.addComment(taskComment);
-			}
-			break;
-
-		// Attachment attributes
-		case ATTACHID:
-		case DATE:
-		case DESC:
-		case FILENAME:
-		case CTYPE:
-		case TYPE:
-			if (attachment != null) {
-				RepositoryTaskAttribute attr = attributeFactory.createAttribute(tag.getKeyString());
-				attr.setValue(parsedText);
-				attachment.addAttribute(tag.getKeyString(), attr);
-			}
-			break;
-		case DATA:
-			break;
-		case ATTACHMENT:
-			if (attachment != null) {
-				repositoryTaskData.addAttachment(attachment);
-			}
-			break;
-
-		// IGNORED ELEMENTS
-		// case REPORTER_ACCESSIBLE:
-		// case CLASSIFICATION_ID:
-		// case CLASSIFICATION:
-		// case CCLIST_ACCESSIBLE:
-		// case EVERCONFIRMED:
-		case BUGZILLA:
-			break;
-		case BUG:
-			// Reached end of bug. Need to set LONGDESCLENGTH to number of
-			// comments
-			RepositoryTaskAttribute numCommentsAttribute = repositoryTaskData.getAttribute(BugzillaReportElement.LONGDESCLENGTH.getKeyString());
-			if (numCommentsAttribute == null) {
-				numCommentsAttribute = attributeFactory.createAttribute(BugzillaReportElement.LONGDESCLENGTH.getKeyString());
-				numCommentsAttribute.setValue("" + repositoryTaskData.getComments().size());
-				repositoryTaskData.addAttribute(BugzillaReportElement.LONGDESCLENGTH.getKeyString(),
-						numCommentsAttribute);
-			} else {
-				numCommentsAttribute.setValue("" + repositoryTaskData.getComments().size());
-			}
-
-			// Set the creator name on all attachments
-			for (RepositoryAttachment attachment : repositoryTaskData.getAttachments()) {
-				TaskComment taskComment = attachIdToComment.get(attachment.getId());
-				if (taskComment != null) {
-					attachment.setCreator(taskComment.getAuthor());
-				}
-				attachment.setAttributeValue(RepositoryTaskAttribute.ATTACHMENT_URL,
-						repositoryTaskData.getRepositoryUrl() + IBugzillaConstants.URL_GET_ATTACHMENT_SUFFIX
-								+ attachment.getId());
-				attachment.setRepositoryKind(repositoryTaskData.getRepositoryKind());
-				attachment.setRepositoryUrl(repositoryTaskData.getRepositoryUrl());
-				attachment.setTaskId(repositoryTaskData.getId());
-			}
-			break;
-
-		case BLOCKED:
-		case DEPENDSON:
-			RepositoryTaskAttribute dependancyAttribute = repositoryTaskData.getAttribute(tag.getKeyString());
-			if (dependancyAttribute == null) {
-				dependancyAttribute = attributeFactory.createAttribute(tag.getKeyString());
-				dependancyAttribute.setValue(parsedText);
-				repositoryTaskData.addAttribute(tag.getKeyString(), dependancyAttribute);
-			} else {
-				if (dependancyAttribute.getValue().equals("")) {
-					dependancyAttribute.setValue(parsedText);
-				} else {
-					dependancyAttribute.setValue(dependancyAttribute.getValue() + ", " + parsedText);
-				}
-			}
-			break;
-		case DELTA_TS:
-			RepositoryTaskAttribute delta_ts_attribute = repositoryTaskData.getAttribute(tag.getKeyString());
-			if (delta_ts_attribute == null) {
-				delta_ts_attribute = attributeFactory.createAttribute(tag.getKeyString());
-				repositoryTaskData.addAttribute(tag.getKeyString(), delta_ts_attribute);
-			}
-			delta_ts_attribute.setValue(BugzillaClient.stripTimeZone(parsedText));
-			break;
-		default:
-			RepositoryTaskAttribute attribute = repositoryTaskData.getAttribute(tag.getKeyString());
-			if (attribute == null) {
-				attribute = attributeFactory.createAttribute(tag.getKeyString());
-				repositoryTaskData.addAttribute(tag.getKeyString(), attribute);
-			}
-			attribute.addValue(parsedText);
-			break;
-		}
-
-	}
-
-	/** determines attachment id from comment */
-	private void parseAttachment(TaskComment taskComment, String commentText) {
-
-		String attachmentID = "";
-
-		if (commentText.startsWith(COMMENT_ATTACHMENT_STRING)) {
-			int endIndex = commentText.indexOf(")");
-			if (endIndex > 0 && endIndex < commentText.length()) {
-				attachmentID = commentText.substring(COMMENT_ATTACHMENT_STRING.length(), endIndex);
-				if (!attachmentID.equals("")) {
-					taskComment.setHasAttachment(true);
-					taskComment.setAttachmentId(attachmentID);
-					attachIdToComment.put(attachmentID, taskComment);
-				}
-			}
-		}
-	}
-
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/SaxConfigurationContentHandler.java b/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/SaxConfigurationContentHandler.java
deleted file mode 100644
index 5f5b050..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/SaxConfigurationContentHandler.java
+++ /dev/null
@@ -1,437 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004 - 2006 University Of British Columbia and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     University Of British Columbia - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.mylyn.internal.bugzilla.core;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.xml.sax.Attributes;
-import org.xml.sax.SAXException;
-import org.xml.sax.helpers.DefaultHandler;
-
-/**
- * Quick config rdf parser.
- * 
- * <pre>
- *     config.cgi?ctype=rdf
- * </pre>
- * 
- * Populates a <link>ProductConfiguration</link> data structure.
- * 
- * @author Rob Elves
- */
-public class SaxConfigurationContentHandler extends DefaultHandler {
-
-	private static final String ELEMENT_RESOLUTION = "resolution";
-
-	private static final String ELEMENT_STATUS_OPEN = "status_open";
-
-	private static final String ELEMENT_TARGET_MILESTONE = "target_milestone";
-
-	private static final String ELEMENT_TARGET_MILESTONES = "target_milestones";
-
-	private static final String ELEMENT_INSTALL_VERSION = "install_version";
-
-	private static final String ATTRIBUTE_RDF_ABOUT = "rdf:about";
-
-	private static final String ATTRIBUTE_RESOURCE = "resource";
-
-	private static final String ELEMENT_VERSION = "version";
-
-	private static final String ELEMENT_VERSIONS = "versions";
-
-	private static final String ELEMENT_COMPONENT = "component";
-
-	private static final String ELEMENT_COMPONENTS = "components";
-
-	private static final String ELEMENT_NAME = "name";
-
-	private static final String ELEMENT_PRODUCTS = "products";
-
-	private static final String ELEMENT_SEVERITY = "severity";
-
-	private static final String ELEMENT_PRIORITY = "priority";
-
-	private static final String ELEMENT_KEYWORD = "keyword";
-
-	private static final String ELEMENT_OP_SYS = "op_sys";
-
-	private static final String ELEMENT_PLATFORM = "platform";
-
-	private static final String ELEMENT_LI = "li";
-
-	private static final String ELEMENT_STATUS = "status";
-
-	private static final int EXPECTING_ROOT = 0;
-
-	private static final int IN_INSTALL_VERSION = 1 << 1;
-
-	private static final int IN_STATUS = 1 << 2;
-
-	private static final int IN_PLATFORM = 1 << 3;
-
-	private static final int IN_OP_SYS = 1 << 4;
-
-	private static final int IN_PRIORITY = 1 << 5;
-
-	private static final int IN_SEVERITY = 1 << 6;
-
-	private static final int IN_PRODUCTS = 1 << 7;
-
-	private static final int IN_COMPONENTS = 1 << 8;
-
-	private static final int IN_VERSIONS = 1 << 9;
-
-	private static final int IN_LI = 1 << 10;
-
-	private static final int IN_LI_LI = 1 << 11;
-
-	private static final int IN_NAME = 1 << 12;
-
-	private static final int IN_COMPONENT = 1 << 13;
-
-	private static final int IN_VERSION = 1 << 14;
-
-	private static final int IN_TARGET_MILESTONES = 1 << 15;
-
-	private static final int IN_TARGET_MILESTONE = 1 << 16;
-
-	private static final int IN_STATUS_OPEN = 1 << 17;
-
-	private static final int IN_RESOLUTION = 1 << 18;
-
-	private static final int IN_KEYWORD = 1 << 19;
-
-	private static final int IN_STATUS_CLOSED = 1 << 20;
-
-	private int state = EXPECTING_ROOT;
-
-	private StringBuffer currentProduct = new StringBuffer();
-
-	private StringBuffer parsedValue = new StringBuffer();
-
-	private String about;
-
-	private RepositoryConfiguration configuration = new RepositoryConfiguration();
-
-	private Map<String, List<String>> components = new HashMap<String, List<String>>();
-
-	private Map<String, List<String>> versions = new HashMap<String, List<String>>();
-
-	private Map<String, List<String>> milestones = new HashMap<String, List<String>>();
-
-	private Map<String, StringBuffer> componentNames = new HashMap<String, StringBuffer>();
-
-	private Map<String, StringBuffer> versionNames = new HashMap<String, StringBuffer>();
-
-	private Map<String, StringBuffer> milestoneNames = new HashMap<String, StringBuffer>();
-
-	public RepositoryConfiguration getConfiguration() {
-		return configuration;
-	}
-
-	@Override
-	public void characters(char[] ch, int start, int length) throws SAXException {
-		switch (state) {
-
-		case IN_PRODUCTS | IN_LI | IN_NAME:
-			currentProduct.append(String.copyValueOf(ch, start, length));
-			break;
-		case IN_COMPONENTS | IN_LI | IN_COMPONENT | IN_NAME:
-			String comp = String.copyValueOf(ch, start, length);
-			if (about != null) {
-				StringBuffer name = componentNames.get(about);
-				if (name == null) {
-					name = new StringBuffer();
-					componentNames.put(about, name);
-				}
-				name.append(comp);
-			}
-			break;
-		case IN_VERSIONS | IN_LI | IN_VERSION | IN_NAME:
-			String ver = String.copyValueOf(ch, start, length);
-			if (about != null) {
-				StringBuffer name = versionNames.get(about);
-				if (name == null) {
-					name = new StringBuffer();
-					versionNames.put(about, name);
-				}
-				name.append(ver);
-			}
-			break;
-		case IN_TARGET_MILESTONES | IN_LI | IN_TARGET_MILESTONE | IN_NAME:
-			String target = String.copyValueOf(ch, start, length);
-			if (about != null) {
-				StringBuffer name = milestoneNames.get(about);
-				if (name == null) {
-					name = new StringBuffer();
-					milestoneNames.put(about, name);
-				}
-				name.append(target);
-			}
-			break;
-		case IN_PLATFORM | IN_LI:
-			parsedValue.append(String.copyValueOf(ch, start, length));
-			break;
-		case IN_OP_SYS | IN_LI:
-			parsedValue.append(String.copyValueOf(ch, start, length));
-			break;
-		case IN_PRIORITY | IN_LI:
-			parsedValue.append(String.copyValueOf(ch, start, length));
-			break;
-		case IN_SEVERITY | IN_LI:
-			parsedValue.append(String.copyValueOf(ch, start, length));
-			break;
-		case IN_INSTALL_VERSION:
-			parsedValue.append(String.copyValueOf(ch, start, length));
-			break;
-		case IN_STATUS | IN_LI:
-			parsedValue.append(String.copyValueOf(ch, start, length));
-			break;
-		case IN_RESOLUTION | IN_LI:
-			parsedValue.append(String.copyValueOf(ch, start, length));
-			break;
-		case IN_KEYWORD | IN_LI:
-			parsedValue.append(String.copyValueOf(ch, start, length));
-			break;
-		case IN_STATUS_OPEN | IN_LI:
-			parsedValue.append(String.copyValueOf(ch, start, length));
-			break;
-		}
-	}
-
-	@Override
-	public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
-
-		if (localName.equals(ELEMENT_STATUS)) {
-			state = state | IN_STATUS;
-		} else if (localName.equals(ELEMENT_LI) && ((state & IN_LI) == IN_LI)) {
-			state = state | IN_LI_LI;
-			parseResource(attributes);
-		} else if (localName.equals(ELEMENT_LI) && ((state & IN_LI) != IN_LI)) {
-			state = state | IN_LI;
-		} else if (localName.equals(ELEMENT_PLATFORM)) {
-			state = state | IN_PLATFORM;
-		} else if (localName.equals(ELEMENT_OP_SYS)) {
-			state = state | IN_OP_SYS;
-		} else if (localName.equals(ELEMENT_PRIORITY)) {
-			state = state | IN_PRIORITY;
-		} else if (localName.equals(ELEMENT_SEVERITY)) {
-			state = state | IN_SEVERITY;
-		} else if (localName.equals(ELEMENT_PRODUCTS)) {
-			state = state | IN_PRODUCTS;
-		} else if (localName.equals(ELEMENT_OP_SYS)) {
-			state = state | IN_OP_SYS;
-		} else if (localName.equals(ELEMENT_NAME)) {
-			state = state | IN_NAME;
-			currentProduct = new StringBuffer();
-		} else if (localName.equals(ELEMENT_COMPONENTS)) {
-			state = state | IN_COMPONENTS;
-		} else if (localName.equals(ELEMENT_COMPONENT)) {
-			state = state | IN_COMPONENT;
-			parseResource(attributes);
-		} else if (localName.equals(ELEMENT_VERSIONS)) {
-			state = state | IN_VERSIONS;
-		} else if (localName.equals(ELEMENT_VERSION)) {
-			state = state | IN_VERSION;
-			parseResource(attributes);
-		} else if (localName.equals(ELEMENT_INSTALL_VERSION)) {
-			state = state | IN_INSTALL_VERSION;
-		} else if (localName.equals(ELEMENT_TARGET_MILESTONES)) {
-			state = state | IN_TARGET_MILESTONES;
-		} else if (localName.equals(ELEMENT_TARGET_MILESTONE)) {
-			state = state | IN_TARGET_MILESTONE;
-			parseResource(attributes);
-		} else if (localName.equals(ELEMENT_STATUS_OPEN)) {
-			state = state | IN_STATUS_OPEN;
-		} else if (localName.equals(ELEMENT_RESOLUTION)) {
-			state = state | IN_RESOLUTION;
-		} else if (localName.equals(ELEMENT_KEYWORD)) {
-			state = state | IN_KEYWORD;
-		}
-		parsedValue = new StringBuffer();
-	}
-
-	private void parseResource(Attributes attributes) {
-
-		switch (state) {
-		case IN_PRODUCTS | IN_LI | IN_COMPONENTS | IN_LI_LI:
-			if (attributes != null) {
-				String compURI = attributes.getValue(ATTRIBUTE_RESOURCE);
-				if (compURI != null && currentProduct.length() > 0) {
-					List<String> compURIs = components.get(currentProduct.toString());
-					if (compURIs == null) {
-						compURIs = new ArrayList<String>();
-						components.put(currentProduct.toString(), compURIs);
-					}
-					compURIs.add(compURI);
-				}
-			}
-			break;
-		case IN_PRODUCTS | IN_LI | IN_VERSIONS | IN_LI_LI:
-			if (attributes != null) {
-				String resourceURI = attributes.getValue(ATTRIBUTE_RESOURCE);
-				if (resourceURI != null && currentProduct.length() > 0) {
-					List<String> versionUris = versions.get(currentProduct.toString());
-					if (versionUris == null) {
-						versionUris = new ArrayList<String>();
-						versions.put(currentProduct.toString(), versionUris);
-					}
-					versionUris.add(resourceURI);
-				}
-			}
-			break;
-		case IN_PRODUCTS | IN_LI | IN_TARGET_MILESTONES | IN_LI_LI:
-			if (attributes != null) {
-				String resourceURI = attributes.getValue(ATTRIBUTE_RESOURCE);
-				if (resourceURI != null) {
-					List<String> milestoneUris = milestones.get(currentProduct.toString());
-					if (milestoneUris == null) {
-						milestoneUris = new ArrayList<String>();
-						milestones.put(currentProduct.toString(), milestoneUris);
-					}
-					milestoneUris.add(resourceURI);
-				}
-			}
-			break;
-		case IN_COMPONENTS | IN_LI | IN_COMPONENT:
-			if (attributes != null) {
-				about = attributes.getValue(ATTRIBUTE_RDF_ABOUT);
-			}
-			break;
-		case IN_VERSIONS | IN_LI | IN_VERSION:
-			if (attributes != null) {
-				about = attributes.getValue(ATTRIBUTE_RDF_ABOUT);
-			}
-			break;
-
-		case IN_TARGET_MILESTONES | IN_LI | IN_TARGET_MILESTONE:
-			if (attributes != null) {
-				about = attributes.getValue(ATTRIBUTE_RDF_ABOUT);
-			}
-			break;
-
-		}
-	}
-
-	@Override
-	public void endElement(String uri, String localName, String qName) throws SAXException {
-
-		// KEEP: && ((state & IN_LI) == IN_LI)
-
-		if (localName.equals(ELEMENT_STATUS)) {
-			state = state & ~IN_STATUS;
-		} else if (localName.equals(ELEMENT_LI) && ((state & IN_LI_LI) == IN_LI_LI)) {
-			state = state & ~IN_LI_LI;
-		} else if (localName.equals(ELEMENT_LI) && ((state & IN_LI_LI) != IN_LI_LI)) {
-			state = state & ~IN_LI;
-			if (parsedValue.length() == 0)
-				return;
-			if (state == (IN_STATUS)) {
-				configuration.addStatus(parsedValue.toString());
-			} else if (state == (IN_STATUS_OPEN)) {
-				configuration.addOpenStatusValue(parsedValue.toString());
-			} else if (state == (IN_STATUS_CLOSED)) {
-				// TODO: Add closed status values to configuration
-			} else if (state == (IN_RESOLUTION)) {
-				configuration.addResolution(parsedValue.toString());
-			} else if (state == (IN_KEYWORD)) {
-				configuration.addKeyword(parsedValue.toString());
-			} else if (state == (IN_PLATFORM)) {
-				configuration.addPlatform(parsedValue.toString());
-			} else if (state == (IN_OP_SYS)) {
-				configuration.addOS(parsedValue.toString());
-			} else if (state == (IN_PRIORITY)) {
-				configuration.addPriority(parsedValue.toString());
-			} else if (state == (IN_SEVERITY)) {
-				configuration.addSeverity(parsedValue.toString());
-			}
-		} else if (localName.equals(ELEMENT_PLATFORM)) {
-			state = state & ~IN_PLATFORM;
-		} else if (localName.equals(ELEMENT_OP_SYS)) {
-			state = state & ~IN_OP_SYS;
-		} else if (localName.equals(ELEMENT_PRIORITY)) {
-			state = state & ~IN_PRIORITY;
-		} else if (localName.equals(ELEMENT_SEVERITY)) {
-			state = state & ~IN_SEVERITY;
-		} else if (localName.equals(ELEMENT_PRODUCTS)) {
-			state = state & ~IN_PRODUCTS;
-		} else if (localName.equals(ELEMENT_OP_SYS)) {
-			state = state & ~IN_OP_SYS;
-		} else if (localName.equals(ELEMENT_NAME)) {
-			state = state & ~IN_NAME;
-			if (state == (IN_PRODUCTS | IN_LI) && currentProduct.length() > 0) {
-				configuration.addProduct(currentProduct.toString());
-			}
-		} else if (localName.equals(ELEMENT_COMPONENTS)) {
-			state = state & ~IN_COMPONENTS;
-		} else if (localName.equals(ELEMENT_COMPONENT)) {
-			state = state & ~IN_COMPONENT;
-		} else if (localName.equals(ELEMENT_VERSION)) {
-			state = state & ~IN_VERSION;
-		} else if (localName.equals(ELEMENT_VERSIONS)) {
-			state = state & ~IN_VERSIONS;
-		} else if (localName.equals(ELEMENT_INSTALL_VERSION)) {
-			state = state & ~IN_INSTALL_VERSION;
-			configuration.setInstallVersion(parsedValue.toString());
-		} else if (localName.equals(ELEMENT_TARGET_MILESTONE)) {
-			state = state & ~IN_TARGET_MILESTONE;
-		} else if (localName.equals(ELEMENT_TARGET_MILESTONES)) {
-			state = state & ~IN_TARGET_MILESTONES;
-		} else if (localName.equals(ELEMENT_STATUS_OPEN)) {
-			state = state & ~IN_STATUS_OPEN;
-		} else if (localName.equals(ELEMENT_RESOLUTION)) {
-			state = state & ~IN_RESOLUTION;
-		} else if (localName.equals(ELEMENT_KEYWORD)) {
-			state = state & ~IN_KEYWORD;
-		}
-	}
-
-	@Override
-	public void endDocument() throws SAXException {
-
-		for (String product : components.keySet()) {
-			List<String> componentURIs = components.get(product);
-			for (String uri : componentURIs) {
-				StringBuffer realName = componentNames.get(uri);
-				if (realName != null && product.length() > 0) {
-					configuration.addComponent(product, realName.toString());
-				}
-			}
-		}
-
-		for (String product : versions.keySet()) {
-			List<String> versionURIs = versions.get(product);
-			for (String uri : versionURIs) {
-				StringBuffer realName = versionNames.get(uri);
-				if (realName != null) {
-					configuration.addVersion(product, realName.toString());
-				}
-			}
-
-		}
-
-		for (String product : milestones.keySet()) {
-			List<String> milestoneURIs = milestones.get(product);
-			for (String uri : milestoneURIs) {
-				StringBuffer realName = milestoneNames.get(uri);
-				if (realName != null) {
-					configuration.addTargetMilestone(product, realName.toString());
-				}
-			}
-
-		}
-		super.endDocument();
-	}
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/SaxConfigurationContentHandlerOLD.java b/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/SaxConfigurationContentHandlerOLD.java
deleted file mode 100644
index 4e6871c..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/SaxConfigurationContentHandlerOLD.java
+++ /dev/null
@@ -1,399 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004 - 2006 University Of British Columbia and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     University Of British Columbia - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.mylyn.internal.bugzilla.core;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.eclipse.mylyn.internal.tasks.core.RepositoryConfiguration;
-import org.xml.sax.Attributes;
-import org.xml.sax.SAXException;
-import org.xml.sax.helpers.DefaultHandler;
-
-/**
- * Quick config rdf parser.
- * 
- * <pre>
- *  config.cgi?ctype=rdf
- * </pre>
- * 
- * Populates a <link>ProductConfiguration</link> data structure.
- * 
- * @author Rob Elves
- */
-public class SaxConfigurationContentHandler extends DefaultHandler {
-
-	private static final String ELEMENT_RESOLUTION = "resolution";
-
-	private static final String ELEMENT_STATUS_OPEN = "status_open";
-
-	private static final String ELEMENT_TARGET_MILESTONE = "target_milestone";
-
-	private static final String ELEMENT_TARGET_MILESTONES = "target_milestones";
-
-	private static final String ELEMENT_INSTALL_VERSION = "install_version";
-
-	private static final String ATTRIBUTE_RDF_ABOUT = "rdf:about";
-
-	private static final String ATTRIBUTE_RESOURCE = "resource";
-
-	private static final String ELEMENT_VERSION = "version";
-
-	private static final String ELEMENT_VERSIONS = "versions";
-
-	private static final String ELEMENT_COMPONENT = "component";
-
-	private static final String ELEMENT_COMPONENTS = "components";
-
-	private static final String ELEMENT_NAME = "name";
-
-	private static final String ELEMENT_PRODUCTS = "products";
-
-	private static final String ELEMENT_SEVERITY = "severity";
-
-	private static final String ELEMENT_PRIORITY = "priority";
-	
-	private static final String ELEMENT_KEYWORD = "keyword";
-
-	private static final String ELEMENT_OP_SYS = "op_sys";
-
-	private static final String ELEMENT_PLATFORM = "platform";
-
-	private static final String ELEMENT_LI = "li";
-
-	private static final String ELEMENT_STATUS = "status";
-
-	private static final int EXPECTING_ROOT = 0;
-
-	private static final int IN_INSTALL_VERSION = 1 << 1;
-
-	private static final int IN_STATUS = 1 << 2;
-
-	private static final int IN_PLATFORM = 1 << 3;
-
-	private static final int IN_OP_SYS = 1 << 4;
-
-	private static final int IN_PRIORITY = 1 << 5;
-
-	private static final int IN_SEVERITY = 1 << 6;
-
-	private static final int IN_PRODUCTS = 1 << 7;
-
-	private static final int IN_COMPONENTS = 1 << 8;
-
-	private static final int IN_VERSIONS = 1 << 9;
-
-	private static final int IN_LI = 1 << 10;
-
-	private static final int IN_LI_LI = 1 << 11;
-
-	private static final int IN_NAME = 1 << 12;
-
-	private static final int IN_COMPONENT = 1 << 13;
-
-	private static final int IN_VERSION = 1 << 14;
-
-	private static final int IN_TARGET_MILESTONES = 1 << 15;
-
-	private static final int IN_TARGET_MILESTONE = 1 << 16;
-
-	private static final int IN_STATUS_OPEN = 1 << 17;
-	
-	private static final int IN_RESOLUTION = 1 << 18;
-	
-	private static final int IN_KEYWORD = 1 << 19;
-
-	private int state = EXPECTING_ROOT;
-
-	private String currentProduct;
-
-	private String about;
-
-	private RepositoryConfiguration configuration = new RepositoryConfiguration(new BugzillaAttributeFactory());
-
-	private Map<String, List<String>> components = new HashMap<String, List<String>>();
-
-	private Map<String, List<String>> versions = new HashMap<String, List<String>>();
-
-	private Map<String, List<String>> milestones = new HashMap<String, List<String>>();
-
-	private Map<String, String> componentNames = new HashMap<String, String>();
-
-	private Map<String, String> versionNames = new HashMap<String, String>();
-
-	private Map<String, String> milestoneNames = new HashMap<String, String>();
-
-	public RepositoryConfiguration getConfiguration() {
-		return configuration;
-	}
-
-	@Override
-	public void characters(char[] ch, int start, int length) throws SAXException {
-		switch (state) {
-
-		case IN_PRODUCTS | IN_LI | IN_NAME:
-			configuration.addProduct(String.copyValueOf(ch, start, length));
-			currentProduct = String.copyValueOf(ch, start, length);
-			break;
-		case IN_COMPONENTS | IN_LI | IN_COMPONENT | IN_NAME:
-			if (about != null) {
-				String name = String.copyValueOf(ch, start, length);
-				componentNames.put(about, name);
-			}
-			break;
-		case IN_VERSIONS | IN_LI | IN_VERSION | IN_NAME:
-			if (about != null) {
-				String name = String.copyValueOf(ch, start, length);
-				versionNames.put(about, name);
-			}
-			break;
-		case IN_TARGET_MILESTONES | IN_LI | IN_TARGET_MILESTONE | IN_NAME:
-			if (about != null) {
-				String name = String.copyValueOf(ch, start, length);
-				milestoneNames.put(about, name);
-			}
-			break;
-		case IN_PLATFORM | IN_LI:
-			configuration.addPlatform(String.copyValueOf(ch, start, length));
-			break;
-		case IN_OP_SYS | IN_LI:
-			configuration.addAttributeValue(BugzillaReportElement.OP_SYS.getKeyString(), String.copyValueOf(ch, start, length));
-			configuration.addOS(String.copyValueOf(ch, start, length));
-			break;
-		case IN_PRIORITY | IN_LI:
-			configuration.addPriority(String.copyValueOf(ch, start, length));
-			break;
-		case IN_SEVERITY | IN_LI:
-			configuration.addSeverity(String.copyValueOf(ch, start, length));
-			break;
-		case IN_INSTALL_VERSION:
-			configuration.setInstallVersion(String.copyValueOf(ch, start, length));
-			break;
-		case IN_STATUS | IN_LI:
-			configuration.addStatus(String.copyValueOf(ch, start, length));
-			break;
-		case IN_RESOLUTION | IN_LI:
-			configuration.addResolution(String.copyValueOf(ch, start, length));
-			break;
-		case IN_KEYWORD | IN_LI:
-			configuration.addAttributeValue(BugzillaReportElement.KEYWORDS.getKeyString(), String.copyValueOf(ch, start, length));
-			configuration.addKeyword(String.copyValueOf(ch, start, length));
-			break;
-		case IN_STATUS_OPEN | IN_LI:
-			configuration.addOpenStatusValue(String.copyValueOf(ch, start, length));
-			break;
-		}
-	}
-
-	@Override
-	public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
-
-		if (localName.equals(ELEMENT_STATUS)) {
-			state = state | IN_STATUS;
-		} else if (localName.equals(ELEMENT_LI) && ((state & IN_LI) == IN_LI)) {
-			state = state | IN_LI_LI;
-			parseResource(attributes);
-		} else if (localName.equals(ELEMENT_LI) && ((state & IN_LI) != IN_LI)) {
-			state = state | IN_LI;
-		} else if (localName.equals(ELEMENT_PLATFORM)) {
-			state = state | IN_PLATFORM;
-		} else if (localName.equals(ELEMENT_OP_SYS)) {
-			state = state | IN_OP_SYS;
-		} else if (localName.equals(ELEMENT_PRIORITY)) {
-			state = state | IN_PRIORITY;
-		} else if (localName.equals(ELEMENT_SEVERITY)) {
-			state = state | IN_SEVERITY;
-		} else if (localName.equals(ELEMENT_PRODUCTS)) {
-			state = state | IN_PRODUCTS;
-		} else if (localName.equals(ELEMENT_OP_SYS)) {
-			state = state | IN_OP_SYS;
-		} else if (localName.equals(ELEMENT_NAME)) {
-			state = state | IN_NAME;
-		} else if (localName.equals(ELEMENT_COMPONENTS)) {
-			state = state | IN_COMPONENTS;
-		} else if (localName.equals(ELEMENT_COMPONENT)) {
-			state = state | IN_COMPONENT;
-			parseResource(attributes);
-		} else if (localName.equals(ELEMENT_VERSIONS)) {
-			state = state | IN_VERSIONS;
-		} else if (localName.equals(ELEMENT_VERSION)) {
-			state = state | IN_VERSION;
-			parseResource(attributes);
-		} else if (localName.equals(ELEMENT_INSTALL_VERSION)) {
-			state = state | IN_INSTALL_VERSION;
-		} else if (localName.equals(ELEMENT_TARGET_MILESTONES)) {
-			state = state | IN_TARGET_MILESTONES;
-		} else if (localName.equals(ELEMENT_TARGET_MILESTONE)) {
-			state = state | IN_TARGET_MILESTONE;
-			parseResource(attributes);
-		} else if (localName.equals(ELEMENT_STATUS_OPEN)) {
-			state = state | IN_STATUS_OPEN;
-		} else if (localName.equals(ELEMENT_RESOLUTION)) {
-			state = state | IN_RESOLUTION;
-		} else if (localName.equals(ELEMENT_KEYWORD)) {
-			state = state | IN_KEYWORD;
-		}
-
-	}
-
-	private void parseResource(Attributes attributes) {
-
-		switch (state) {
-		case IN_PRODUCTS | IN_LI | IN_COMPONENTS | IN_LI_LI:
-			if (attributes != null) {
-				String compURI = attributes.getValue(ATTRIBUTE_RESOURCE);
-				if (compURI != null) {
-
-					List<String> compURIs = components.get(currentProduct);
-					if (compURIs == null) {
-						compURIs = new ArrayList<String>();
-						components.put(currentProduct, compURIs);
-					}
-					compURIs.add(compURI);
-
-				}
-			}
-			break;
-		case IN_PRODUCTS | IN_LI | IN_VERSIONS | IN_LI_LI:
-			if (attributes != null) {
-				String resourceURI = attributes.getValue(ATTRIBUTE_RESOURCE);
-				if (resourceURI != null) {
-					List<String> versionUris = versions.get(currentProduct);
-					if (versionUris == null) {
-						versionUris = new ArrayList<String>();
-						versions.put(currentProduct, versionUris);
-					}
-					versionUris.add(resourceURI);
-				}
-			}
-			break;
-		case IN_PRODUCTS | IN_LI | IN_TARGET_MILESTONES | IN_LI_LI:
-			if (attributes != null) {
-				String resourceURI = attributes.getValue(ATTRIBUTE_RESOURCE);
-				if (resourceURI != null) {
-					List<String> milestoneUris = milestones.get(currentProduct);
-					if (milestoneUris == null) {
-						milestoneUris = new ArrayList<String>();
-						milestones.put(currentProduct, milestoneUris);
-					}
-					milestoneUris.add(resourceURI);
-				}
-			}
-			break;
-		case IN_COMPONENTS | IN_LI | IN_COMPONENT:
-			if (attributes != null) {
-				about = attributes.getValue(ATTRIBUTE_RDF_ABOUT);
-			}
-			break;
-		case IN_VERSIONS | IN_LI | IN_VERSION:
-			if (attributes != null) {
-				about = attributes.getValue(ATTRIBUTE_RDF_ABOUT);
-			}
-			break;
-
-		case IN_TARGET_MILESTONES | IN_LI | IN_TARGET_MILESTONE:
-			if (attributes != null) {
-				about = attributes.getValue(ATTRIBUTE_RDF_ABOUT);
-			}
-			break;
-
-		}
-	}
-
-	@Override
-	public void endElement(String uri, String localName, String qName) throws SAXException {
-
-		// KEEP: && ((state & IN_LI) == IN_LI)
-
-		if (localName.equals(ELEMENT_STATUS)) {
-			state = state & ~IN_STATUS;
-		} else if (localName.equals(ELEMENT_LI) && ((state & IN_LI_LI) == IN_LI_LI)) {
-			state = state & ~IN_LI_LI;
-		} else if (localName.equals(ELEMENT_LI) && ((state & IN_LI_LI) != IN_LI_LI)) {
-			state = state & ~IN_LI;
-		} else if (localName.equals(ELEMENT_PLATFORM)) {
-			state = state & ~IN_PLATFORM;
-		} else if (localName.equals(ELEMENT_OP_SYS)) {
-			state = state & ~IN_OP_SYS;
-		} else if (localName.equals(ELEMENT_PRIORITY)) {
-			state = state & ~IN_PRIORITY;
-		} else if (localName.equals(ELEMENT_SEVERITY)) {
-			state = state & ~IN_SEVERITY;
-		} else if (localName.equals(ELEMENT_PRODUCTS)) {
-			state = state & ~IN_PRODUCTS;
-		} else if (localName.equals(ELEMENT_OP_SYS)) {
-			state = state & ~IN_OP_SYS;
-		} else if (localName.equals(ELEMENT_NAME)) {
-			state = state & ~IN_NAME;
-		} else if (localName.equals(ELEMENT_COMPONENTS)) {
-			state = state & ~IN_COMPONENTS;
-		} else if (localName.equals(ELEMENT_COMPONENT)) {
-			state = state & ~IN_COMPONENT;
-		} else if (localName.equals(ELEMENT_VERSION)) {
-			state = state & ~IN_VERSION;
-		} else if (localName.equals(ELEMENT_VERSIONS)) {
-			state = state & ~IN_VERSIONS;
-		} else if (localName.equals(ELEMENT_INSTALL_VERSION)) {
-			state = state & ~IN_INSTALL_VERSION;
-		} else if (localName.equals(ELEMENT_TARGET_MILESTONE)) {
-			state = state & ~IN_TARGET_MILESTONE;
-		} else if (localName.equals(ELEMENT_TARGET_MILESTONES)) {
-			state = state & ~IN_TARGET_MILESTONES;
-		} else if (localName.equals(ELEMENT_STATUS_OPEN)) {
-			state = state & ~IN_STATUS_OPEN;
-		} else if (localName.equals(ELEMENT_RESOLUTION)) {
-			state = state & ~IN_RESOLUTION;
-		} else if (localName.equals(ELEMENT_KEYWORD)) {
-			state = state & ~IN_KEYWORD;
-		}
-
-	}
-
-	@Override
-	public void endDocument() throws SAXException {
-  
-		for (String product : components.keySet()) {
-			List<String> componentURIs = components.get(product);
-			for (String uri : componentURIs) {
-				String realName = componentNames.get(uri);
-				if (realName != null) {
-					configuration.addComponent(product, realName);
-				}
-			} 
-		} 
-
-		for (String product : versions.keySet()) {
-			List<String> versionURIs = versions.get(product);
-			for (String uri : versionURIs) {
-				String realName = versionNames.get(uri);
-				if (realName != null) {
-					configuration.addVersion(product, realName);
-				}
-			}
-
-		}
-
-		for (String product : milestones.keySet()) {
-			List<String> milestoneURIs = milestones.get(product);
-			for (String uri : milestoneURIs) {
-				String realName = milestoneNames.get(uri);
-				if (realName != null) {
-					configuration.addTargetMilestone(product, realName);
-				}
-			}
-
-		}
-		super.endDocument();
-	}
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/TaskListNotificationManagerTest.java b/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/TaskListNotificationManagerTest.java
deleted file mode 100644
index 874de69..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/TaskListNotificationManagerTest.java
+++ /dev/null
@@ -1,137 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004, 2008 Tasktop Technologies and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     Tasktop Technologies - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.mylyn.bugzilla.deprecated;
-
-import junit.framework.TestCase;
-
-import org.eclipse.mylyn.bugzilla.deprecated.BugzillaRepositoryQuery;
-import org.eclipse.mylyn.bugzilla.deprecated.BugzillaTask;
-import org.eclipse.mylyn.internal.provisional.commons.ui.AbstractNotification;
-import org.eclipse.mylyn.internal.tasks.core.AbstractTask;
-import org.eclipse.mylyn.internal.tasks.core.LocalTask;
-import org.eclipse.mylyn.internal.tasks.core.TaskActivityUtil;
-import org.eclipse.mylyn.internal.tasks.ui.TaskListNotificationManager;
-import org.eclipse.mylyn.internal.tasks.ui.TasksUiPlugin;
-import org.eclipse.mylyn.internal.tasks.ui.notifications.TaskListNotification;
-import org.eclipse.mylyn.tasks.core.TaskRepository;
-import org.eclipse.mylyn.tasks.core.ITask.SynchronizationState;
-
-/**
- * @author Rob Elves
- * @deprecated
- */
-@Deprecated
-public class TaskListNotificationManagerTest extends TestCase {
-
-	@Override
-	protected void setUp() throws Exception {
-		super.setUp();
-	}
-
-	@Override
-	protected void tearDown() throws Exception {
-		super.tearDown();
-	}
-
-	public void testTaskListNotificationReminder() throws InterruptedException {
-
-		AbstractTask task0 = new LocalTask("0", "t0 - test 0");
-		AbstractTask task1 = new LocalTask("1", "t1 - test 1");
-		AbstractTask task2 = new LocalTask("2", "t2 - test 2");
-
-		task0.setScheduledForDate(TaskActivityUtil.getCurrentWeek().getToday().previous());
-		task1.setScheduledForDate(TaskActivityUtil.getCurrentWeek().getToday().previous());
-		task2.setScheduledForDate(TaskActivityUtil.getCurrentWeek().getToday().previous());
-
-		TasksUiPlugin.getTaskList().addTask(task0);
-		TasksUiPlugin.getTaskList().addTask(task1);
-		TasksUiPlugin.getTaskList().addTask(task2);
-
-		TaskListNotificationManager notificationManager = TasksUiPlugin.getTaskListNotificationManager();
-		notificationManager.collectNotifications();
-
-		task0 = TasksUiPlugin.getTaskList().getTask("local-0");
-		assertNotNull(task0);
-		assertTrue(task0.isReminded());
-		task1 = TasksUiPlugin.getTaskList().getTask("local-1");
-		assertNotNull(task1);
-		assertTrue(task1.isReminded());
-		task2 = TasksUiPlugin.getTaskList().getTask("local-2");
-		assertNotNull(task2);
-		assertTrue(task2.isReminded());
-
-	}
-
-	public void testTaskListNotificationIncoming() {
-
-		TaskRepository repository = new TaskRepository("bugzilla", "https://bugs.eclipse.org/bugs");
-		TasksUiPlugin.getRepositoryManager().addRepository(repository);
-		AbstractTask task = new BugzillaTask("https://bugs.eclipse.org/bugs", "142891", "label");
-		assertEquals(SynchronizationState.SYNCHRONIZED, task.getSynchronizationState());
-		assertFalse(task.isNotified());
-		TasksUiPlugin.getTaskList().addTask(task);
-		TaskListNotificationManager notificationManager = TasksUiPlugin.getTaskListNotificationManager();
-		notificationManager.collectNotifications();
-		TaskListNotification notification = new TaskListNotification(task);
-		notification.setDescription("Unread task");
-		assertTrue(notificationManager.getNotifications().contains(notification));
-		task = TasksUiPlugin.getTaskList().getTask("https://bugs.eclipse.org/bugs-142891");
-		assertNotNull(task);
-		assertTrue(task.isNotified());
-	}
-
-	public void testTaskListNotificationQueryIncoming() {
-		BugzillaTask hit = new BugzillaTask("https://bugs.eclipse.org/bugs", "1", "summary");
-		assertFalse(hit.isNotified());
-		BugzillaRepositoryQuery query = new BugzillaRepositoryQuery("https://bugs.eclipse.org/bugs", "queryUrl",
-				"summary");
-		TasksUiPlugin.getTaskList().addQuery(query);
-		TasksUiPlugin.getTaskList().addTask(hit, query);
-
-		TaskListNotificationManager notificationManager = TasksUiPlugin.getTaskListNotificationManager();
-		assertFalse(hit.isNotified());
-		notificationManager.collectNotifications();
-		for (AbstractNotification notification : notificationManager.getNotifications()) {
-			notification.getLabel().equals(hit.getSummary());
-		}
-		//assertTrue(notificationManager.getNotifications().contains(new TaskListNotificationQueryIncoming(hit)));
-		assertTrue(hit.isNotified());
-	}
-
-	public void testTaskListNotificationQueryIncomingRepeats() {
-		TaskTestUtil.resetTaskList();
-		BugzillaTask hit = new BugzillaTask("https://bugs.eclipse.org/bugs", "1", "summary");
-		String hitHandle = hit.getHandleIdentifier();
-		assertFalse(hit.isNotified());
-		BugzillaRepositoryQuery query = new BugzillaRepositoryQuery("https://bugs.eclipse.org/bugs", "queryUrl",
-				"summary");
-		TasksUiPlugin.getTaskList().addQuery(query);
-		TasksUiPlugin.getTaskList().addTask(hit, query);
-		TaskListNotificationManager notificationManager = TasksUiPlugin.getTaskListNotificationManager();
-		notificationManager.collectNotifications();
-		for (AbstractNotification notification : notificationManager.getNotifications()) {
-			notification.getLabel().equals(hit.getSummary());
-		}
-		//assertTrue(notificationManager.getNotifications().iterator().next().equals(new TaskListNotificationQueryIncoming(hit)));
-		assertTrue(hit.isNotified());
-
-		TasksUiPlugin.getTaskListManager().saveTaskList();
-		TaskTestUtil.resetTaskList();
-		assertEquals(0, TasksUiPlugin.getTaskList().getQueries().size());
-		assertTrue(TasksUiPlugin.getTaskListManager().readExistingOrCreateNewList());
-		assertEquals(1, TasksUiPlugin.getTaskList().getQueries().size());
-		BugzillaTask hitLoaded = (BugzillaTask) TasksUiPlugin.getTaskList().getTask(hitHandle);
-		assertNotNull(hitLoaded);
-		assertTrue(hitLoaded.isNotified());
-	}
-
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/ViewBugzillaAction.java b/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/ViewBugzillaAction.java
deleted file mode 100644
index c5f22f0..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/ViewBugzillaAction.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2003 - 2006 University Of British Columbia and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     University Of British Columbia - initial API and implementation
- *******************************************************************************/
-package org.eclipse.mylyn.internal.bugzilla.ui;
-
-import java.io.IOException;
-import java.util.Iterator;
-import java.util.List;
-
-import javax.security.auth.login.LoginException;
-
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.Status;
-import org.eclipse.jface.dialogs.MessageDialog;
-import org.eclipse.mylyn.internal.bugzilla.core.BugzillaPlugin;
-import org.eclipse.mylyn.internal.bugzilla.ui.editor.AbstractBugEditor;
-import org.eclipse.mylyn.internal.bugzilla.ui.editor.ExistingBugEditorInput;
-import org.eclipse.mylyn.internal.core.util.MylarStatusHandler;
-import org.eclipse.mylyn.provisional.tasklist.MylarTaskListPlugin;
-import org.eclipse.mylyn.provisional.tasklist.TaskRepository;
-import org.eclipse.ui.IWorkbenchPage;
-import org.eclipse.ui.PartInitException;
-import org.eclipse.ui.PlatformUI;
-import org.eclipse.ui.progress.UIJob;
-
-/**
- * Action performed when the bugs are supposed to be displayed in the editor
- * window from the favorites list
- */
-@Deprecated
-public class ViewBugzillaAction extends UIJob {
-
-	/** List of bugs to be displayed */
-	private List<BugzillaOpenStructure> bugs;
-
-	/**
-	 * Constructor
-	 * 
-	 * @param name
-	 *            The job name
-	 * @param bugs
-	 *            List of bugs to be displayed
-	 */
-	public ViewBugzillaAction(String name, List<BugzillaOpenStructure> bugs) {
-		super(name);
-		this.bugs = bugs;
-	}
-
-	@Override
-	public IStatus runInUIThread(IProgressMonitor monitor) {
-		IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
-
-		// go through each bug and get its id
-		for (Iterator<BugzillaOpenStructure> it = bugs.iterator(); it.hasNext();) {
-			BugzillaOpenStructure bos = it.next();
-
-		}
-		return new Status(IStatus.OK, BugzillaUiPlugin.PLUGIN_ID, IStatus.OK, "", null);
-	}
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/ViewFavoriteAction.java b/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/ViewFavoriteAction.java
deleted file mode 100644
index 3ca9495..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/ViewFavoriteAction.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004 - 2006 University Of British Columbia and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     University Of British Columbia - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.mylyn.internal.bugzilla.ui.actions;
-
-import java.util.List;
-
-import org.eclipse.mylyn.internal.bugzilla.ui.BugzillaImages;
-import org.eclipse.mylyn.internal.bugzilla.ui.BugzillaOpenStructure;
-import org.eclipse.mylyn.internal.bugzilla.ui.FavoritesView;
-import org.eclipse.mylyn.internal.bugzilla.ui.ViewBugzillaAction;
-
-/**
- * View a bug from the favorites menu
- */
-public class ViewFavoriteAction extends AbstractFavoritesAction {
-
-	/** The view to get the result to launch a viewer on */
-	private FavoritesView view;
-
-	/**
-	 * Constructor
-	 * 
-	 * @param resultsView
-	 *            The view to launch a viewer on
-	 */
-	public ViewFavoriteAction(FavoritesView resultsView) {
-		setToolTipText("View Selected Favorites");
-		setText("View Selected");
-		setImageDescriptor(BugzillaImages.OPEN);
-		view = resultsView;
-	}
-
-	/**
-	 * View the selected bugs in the editor window
-	 * 
-	 * @see org.eclipse.jface.action.IAction#run()
-	 */
-	@Override
-	public void run() {
-		FavoritesView.checkWindow();
-		List<BugzillaOpenStructure> selectedBugs = view.getBugIdsOfSelected();
-
-		// if there are some selected bugs view the bugs in the editor window
-		if (!selectedBugs.isEmpty()) {
-			ViewBugzillaAction viewBugs = new ViewBugzillaAction("Display bugs in editor", selectedBugs);
-			viewBugs.schedule();
-		}
-	}
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/ViewOfflineReportAction.java b/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/ViewOfflineReportAction.java
deleted file mode 100644
index 8cfa509..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/ViewOfflineReportAction.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2003 - 2006 University Of British Columbia and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     University Of British Columbia - initial API and implementation
- *******************************************************************************/
-package org.eclipse.mylyn.internal.bugzilla.ui.actions;
-
-import java.util.Iterator;
-import java.util.List;
-
-import org.eclipse.mylyn.bugzilla.core.BugReport;
-import org.eclipse.mylyn.bugzilla.core.IBugzillaBug;
-import org.eclipse.mylyn.internal.bugzilla.core.BugzillaPlugin;
-import org.eclipse.mylyn.internal.bugzilla.core.IBugzillaConstants;
-import org.eclipse.mylyn.internal.bugzilla.core.NewBugModel;
-import org.eclipse.mylyn.internal.bugzilla.ui.BugzillaImages;
-import org.eclipse.mylyn.internal.bugzilla.ui.OfflineView;
-import org.eclipse.mylyn.internal.bugzilla.ui.editor.ExistingBugEditorInput;
-import org.eclipse.mylyn.internal.bugzilla.ui.editor.NewBugEditorInput;
-import org.eclipse.mylyn.internal.tasklist.MylarTaskListPlugin;
-import org.eclipse.mylyn.internal.tasklist.TaskRepository;
-import org.eclipse.ui.IWorkbenchPage;
-import org.eclipse.ui.PartInitException;
-
-/**
- * View a bug from the offlineReports menu
- * 
- * @author Mik Kersten (hardening of prototype)
- */
-public class ViewOfflineReportAction extends AbstractOfflineReportsAction {
-
-	/** The view to get the result to launch a viewer on */
-	private OfflineView view;
-
-	/**
-	 * Constructor
-	 * 
-	 * @param resultsView
-	 *            The view to launch a viewer on
-	 */
-	public ViewOfflineReportAction(OfflineView resultsView) {
-		setToolTipText("View Selected Offline Reports");
-		setText("View Selected");
-		setImageDescriptor(BugzillaImages.OPEN);
-		view = resultsView;
-	}
-
-	@Override
-	public void run() {
-		OfflineView.checkWindow();
-		List<IBugzillaBug> selectedBugs = view.getSelectedBugs();
-
-		// if there are some selected bugs view the bugs in the editor window
-		if (!selectedBugs.isEmpty()) {
-			IWorkbenchPage page = BugzillaPlugin.getDefault().getWorkbench().getActiveWorkbenchWindow().getActivePage();
-			for (Iterator<IBugzillaBug> it = selectedBugs.iterator(); it.hasNext();) {
-				IBugzillaBug bug = it.next();
-				if (bug instanceof BugReport) {
-					TaskRepository repository = MylarTaskListPlugin.getRepositoryManager().getRepository(
-							BugzillaPlugin.REPOSITORY_KIND, bug.getRepository());
-					if (repository != null) {
-						ExistingBugEditorInput editorInput = new ExistingBugEditorInput((BugReport) bug);
-						try {
-							page.openEditor(editorInput, IBugzillaConstants.EXISTING_BUG_EDITOR_ID);
-						} catch (PartInitException e) {
-							BugzillaPlugin.log(e);
-						}
-					}
-					continue;
-				}
-				if (bug instanceof NewBugModel) {
-					NewBugEditorInput editorInput = new NewBugEditorInput((NewBugModel) bug);
-					try {
-						page.openEditor(editorInput, IBugzillaConstants.NEW_BUG_EDITOR_ID);
-					} catch (PartInitException e) {
-						BugzillaPlugin.log(e);
-					}
-					continue;
-				}
-			}
-		}
-	}
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/WizardAttributesPage.java b/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/WizardAttributesPage.java
deleted file mode 100644
index 5c1aef9..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/bugzilla/WizardAttributesPage.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004 - 2006 University Of British Columbia and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     University Of British Columbia - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.mylyn.internal.bugzilla.ui.wizard;
-
-import org.eclipse.mylyn.internal.bugzilla.core.IBugzillaConstants;
-import org.eclipse.mylyn.internal.bugzilla.ui.BugzillaUiPlugin;
-import org.eclipse.ui.IWorkbench;
-
-/**
- * Wizard page shown when the user has chosen a product to log a bug for.
- * 
- * @author Mik Kersten
- */
-public class WizardAttributesPage extends AbstractBugzillaWizardPage {
-
-	private static final String DESCRIPTION = "Enter Bugzilla report details";
-
-	public WizardAttributesPage(IWorkbench workbench) {
-		super("Page2", IBugzillaConstants.TITLE_NEW_BUG, DESCRIPTION, workbench);
-		setImageDescriptor(BugzillaUiPlugin.imageDescriptorFromPlugin("org.eclipse.mylyn.bugzilla.ui",
-			"icons/wizban/bug-wizard.gif"));
-	}
-
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/editors/AbstractNewRepositoryTaskEditor.java b/org.eclipse.mylyn.ide.dev/developer/src-old/editors/AbstractNewRepositoryTaskEditor.java
deleted file mode 100644
index fb504c5..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/editors/AbstractNewRepositoryTaskEditor.java
+++ /dev/null
@@ -1,534 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004, 2008 Tasktop Technologies and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     Tasktop Technologies - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.mylyn.internal.tasks.ui.deprecated;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.List;
-
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.NullProgressMonitor;
-import org.eclipse.jface.dialogs.IDialogConstants;
-import org.eclipse.jface.dialogs.MessageDialog;
-import org.eclipse.jface.layout.GridDataFactory;
-import org.eclipse.jface.viewers.IStructuredSelection;
-import org.eclipse.jface.viewers.SelectionChangedEvent;
-import org.eclipse.jface.viewers.StructuredSelection;
-import org.eclipse.mylyn.internal.provisional.commons.ui.CommonImages;
-import org.eclipse.mylyn.internal.tasks.core.AbstractTask;
-import org.eclipse.mylyn.internal.tasks.core.AbstractTaskCategory;
-import org.eclipse.mylyn.internal.tasks.core.AbstractTaskContainer;
-import org.eclipse.mylyn.internal.tasks.core.DateRange;
-import org.eclipse.mylyn.internal.tasks.core.ITaskList;
-import org.eclipse.mylyn.internal.tasks.core.TaskCategory;
-import org.eclipse.mylyn.internal.tasks.ui.ScheduleDatePicker;
-import org.eclipse.mylyn.internal.tasks.ui.TasksUiPlugin;
-import org.eclipse.mylyn.internal.tasks.ui.editors.RepositoryTaskOutlineNode;
-import org.eclipse.mylyn.internal.tasks.ui.editors.RepositoryTaskSelection;
-import org.eclipse.mylyn.internal.tasks.ui.util.TasksUiInternal;
-import org.eclipse.mylyn.internal.tasks.ui.views.TaskListView;
-import org.eclipse.mylyn.tasks.core.IRepositoryElement;
-import org.eclipse.mylyn.tasks.ui.TasksUiImages;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.custom.CCombo;
-import org.eclipse.swt.custom.VerifyKeyListener;
-import org.eclipse.swt.events.ModifyEvent;
-import org.eclipse.swt.events.ModifyListener;
-import org.eclipse.swt.events.SelectionAdapter;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.events.VerifyEvent;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Button;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.swt.widgets.Event;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Listener;
-import org.eclipse.swt.widgets.Spinner;
-import org.eclipse.ui.IEditorInput;
-import org.eclipse.ui.IEditorSite;
-import org.eclipse.ui.PlatformUI;
-import org.eclipse.ui.forms.editor.FormEditor;
-import org.eclipse.ui.forms.events.HyperlinkAdapter;
-import org.eclipse.ui.forms.events.HyperlinkEvent;
-import org.eclipse.ui.forms.widgets.ExpandableComposite;
-import org.eclipse.ui.forms.widgets.FormToolkit;
-import org.eclipse.ui.forms.widgets.ImageHyperlink;
-import org.eclipse.ui.forms.widgets.Section;
-
-/**
- * @deprecated Do not use. This class is pending for removal: see bug 237552.
- */
-@Deprecated
-public abstract class AbstractNewRepositoryTaskEditor extends AbstractRepositoryTaskEditor {
-
-	private static final int DESCRIPTION_WIDTH = 79 * 7; // 500;
-
-	private static final int DESCRIPTION_HEIGHT = 10 * 14;
-
-	private static final int DEFAULT_FIELD_WIDTH = 150;
-
-	private static final int DEFAULT_ESTIMATED_TIME = 1;
-
-	private static final String LABEL_SUMBIT = "Submit";
-
-	private static final String ERROR_CREATING_BUG_REPORT = "Error creating bug report";
-
-	protected ScheduleDatePicker scheduledForDate;
-
-	protected Spinner estimatedTime;
-
-	@Deprecated
-	protected String newSummary = "";
-
-	protected Button addToCategory;
-
-	protected CCombo categoryChooser;
-
-	/**
-	 * @author Raphael Ackermann (bug 195514)
-	 */
-	protected class TabVerifyKeyListener implements VerifyKeyListener {
-
-		public void verifyKey(VerifyEvent event) {
-			// if there is a tab key, do not "execute" it and instead select the Attributes section
-			if (event.keyCode == SWT.TAB) {
-				event.doit = false;
-				focusAttributes();
-			}
-		}
-	}
-
-	public AbstractNewRepositoryTaskEditor(FormEditor editor) {
-		super(editor);
-	}
-
-	@Override
-	public void init(IEditorSite site, IEditorInput input) {
-		if (!(input instanceof NewTaskEditorInput)) {
-			return;
-		}
-
-		initTaskEditor(site, (RepositoryTaskEditorInput) input);
-
-		setTaskOutlineModel(RepositoryTaskOutlineNode.parseBugReport(taskData, false));
-		newSummary = taskData.getSummary();
-	}
-
-	@Override
-	protected void createDescriptionLayout(Composite composite) {
-		FormToolkit toolkit = this.getManagedForm().getToolkit();
-		Section section = toolkit.createSection(composite, ExpandableComposite.TITLE_BAR);
-		section.setText(getSectionLabel(SECTION_NAME.DESCRIPTION_SECTION));
-		section.setExpanded(true);
-		section.setLayout(new GridLayout());
-		section.setLayoutData(new GridData(GridData.FILL_BOTH));
-
-		Composite descriptionComposite = toolkit.createComposite(section);
-		GridLayout descriptionLayout = new GridLayout();
-
-		descriptionComposite.setLayout(descriptionLayout);
-		GridData descriptionData = new GridData(GridData.FILL_BOTH);
-		descriptionData.grabExcessVerticalSpace = true;
-		descriptionComposite.setLayoutData(descriptionData);
-		section.setClient(descriptionComposite);
-
-		descriptionTextViewer = addTextEditor(repository, descriptionComposite, taskData.getDescription(), true,
-				SWT.FLAT | SWT.MULTI | SWT.WRAP | SWT.V_SCROLL);
-		descriptionTextViewer.setEditable(true);
-		GridData gd = new GridData(GridData.FILL_BOTH);
-		gd.widthHint = DESCRIPTION_WIDTH;
-		gd.minimumHeight = DESCRIPTION_HEIGHT;
-		gd.grabExcessHorizontalSpace = true;
-		gd.grabExcessVerticalSpace = true;
-		descriptionTextViewer.getControl().setLayoutData(gd);
-		descriptionTextViewer.getControl().setData(FormToolkit.KEY_DRAW_BORDER, FormToolkit.TEXT_BORDER);
-
-		addDuplicateDetection(descriptionComposite);
-
-		toolkit.paintBordersFor(descriptionComposite);
-	}
-
-	/**
-	 * @author Raphael Ackermann (modifications) (bug 195514)
-	 * @param composite
-	 */
-	@Override
-	protected void createSummaryLayout(Composite composite) {
-		addSummaryText(composite);
-		if (summaryTextViewer != null) {
-			summaryTextViewer.prependVerifyKeyListener(new TabVerifyKeyListener());
-			// TODO: Eliminate this and newSummary field when api can be changed
-			summaryTextViewer.getTextWidget().addModifyListener(new ModifyListener() {
-				public void modifyText(ModifyEvent e) {
-					String sel = summaryText.getText();
-					if (!(newSummary.equals(sel))) {
-						newSummary = sel;
-					}
-				}
-			});
-		}
-	}
-
-	@Override
-	protected void createAttachmentLayout(Composite comp) {
-		// currently can't attach while creating new bug
-	}
-
-	@Override
-	protected void createCommentLayout(Composite comp) {
-		// ignore
-	}
-
-	@Override
-	protected void createNewCommentLayout(Composite comp) {
-		createPlanningLayout(comp);
-	}
-
-	protected void createPlanningLayout(Composite comp) {
-		Section section = createSection(comp, "Personal Planning");
-		section.setLayout(new GridLayout());
-		section.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-		section.setExpanded(true);
-
-		Composite sectionClient = getManagedForm().getToolkit().createComposite(section);
-		section.setClient(sectionClient);
-		GridLayout layout = new GridLayout();
-		layout.numColumns = 7;
-		layout.makeColumnsEqualWidth = false;
-		sectionClient.setLayout(layout);
-		GridData clientDataLayout = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
-		sectionClient.setLayoutData(clientDataLayout);
-
-		// Scheduled date
-		getManagedForm().getToolkit().createLabel(sectionClient, "Scheduled for:");
-		// label.setForeground(toolkit.getColors().getColor(FormColors.TITLE));
-		scheduledForDate = new ScheduleDatePicker(sectionClient, null, SWT.FLAT);
-		scheduledForDate.setBackground(Display.getDefault().getSystemColor(SWT.COLOR_WHITE));
-		scheduledForDate.setData(FormToolkit.KEY_DRAW_BORDER, FormToolkit.TEXT_BORDER);
-//		Calendar newTaskSchedule = TaskActivityUtil.getCalendar();
-//		int scheduledEndHour = TasksUiPlugin.getDefault().getPreferenceStore().getInt(
-//				TasksUiPreferenceConstants.PLANNING_ENDHOUR);
-		// If past scheduledEndHour set for following day
-//		if (newTaskSchedule.get(Calendar.HOUR_OF_DAY) >= scheduledEndHour) {
-//			TaskActivityUtil.snapForwardNumDays(newTaskSchedule, 1);
-//		} else {
-//			TaskActivityUtil.snapEndOfWorkDay(newTaskSchedule);
-//		}
-//		scheduledForDate.setDate(newTaskSchedule);
-//		Button removeReminder = getManagedForm().getToolkit().createButton(sectionClient, "Clear",
-//				SWT.PUSH | SWT.CENTER);
-//		removeReminder.addSelectionListener(new SelectionAdapter() {
-//			@Override
-//			public void widgetSelected(SelectionEvent e) {
-//				scheduledForDate.setDate(null);
-//			}
-//		});
-
-		ImageHyperlink clearReminder = getManagedForm().getToolkit().createImageHyperlink(sectionClient, SWT.NONE);
-		clearReminder.setImage(CommonImages.getImage(CommonImages.REMOVE));
-		clearReminder.setToolTipText("Clear");
-		clearReminder.addHyperlinkListener(new HyperlinkAdapter() {
-			@Override
-			public void linkActivated(HyperlinkEvent e) {
-				scheduledForDate.setScheduledDate(null);
-			}
-		});
-
-		// 1 Blank column after Reminder clear button
-		Label dummy = getManagedForm().getToolkit().createLabel(sectionClient, "");
-		GridData dummyLabelDataLayout = new GridData(GridData.HORIZONTAL_ALIGN_CENTER);
-		dummyLabelDataLayout.horizontalSpan = 1;
-		dummyLabelDataLayout.widthHint = 30;
-		dummy.setLayoutData(dummyLabelDataLayout);
-
-		// Estimated time
-		getManagedForm().getToolkit().createLabel(sectionClient, "Estimated hours:");
-		// label.setForeground(toolkit.getColors().getColor(FormColors.TITLE));
-		// estimatedTime = new Spinner(sectionClient, SWT.FLAT);
-		estimatedTime = new Spinner(sectionClient, SWT.FLAT);
-		estimatedTime.setDigits(0);
-		estimatedTime.setMaximum(100);
-		estimatedTime.setMinimum(0);
-		estimatedTime.setIncrement(1);
-		estimatedTime.setSelection(DEFAULT_ESTIMATED_TIME);
-		estimatedTime.setData(FormToolkit.KEY_DRAW_BORDER, FormToolkit.TEXT_BORDER);
-		GridData estimatedDataLayout = new GridData();
-		estimatedDataLayout.widthHint = 30;
-		estimatedTime.setLayoutData(estimatedDataLayout);
-		// getManagedForm().getToolkit().createLabel(sectionClient, "hours ");
-		// label.setForeground(toolkit.getColors().getColor(FormColors.TITLE));
-
-		ImageHyperlink clearEstimated = getManagedForm().getToolkit().createImageHyperlink(sectionClient, SWT.NONE);
-		clearEstimated.setImage(CommonImages.getImage(CommonImages.REMOVE));
-		clearEstimated.setToolTipText("Clear");
-		clearEstimated.addHyperlinkListener(new HyperlinkAdapter() {
-			@Override
-			public void linkActivated(HyperlinkEvent e) {
-				estimatedTime.setSelection(0);
-			}
-		});
-
-		getManagedForm().getToolkit().paintBordersFor(sectionClient);
-	}
-
-	@Override
-	protected void addRadioButtons(Composite buttonComposite) {
-		// Since NewBugModels have no special submitting actions,
-		// no radio buttons are required.
-	}
-
-	@Override
-	protected void createCustomAttributeLayout(Composite composite) {
-		// ignore
-	}
-
-	@Override
-	protected void saveTaskOffline(IProgressMonitor progressMonitor) {
-		taskData.setSummary(newSummary);
-		taskData.setDescription(descriptionTextViewer.getTextWidget().getText());
-		updateEditorTitle();
-	}
-
-	/**
-	 * A listener for selection of the summary textbox.
-	 */
-	protected class DescriptionListener implements Listener {
-		public void handleEvent(Event event) {
-			fireSelectionChanged(new SelectionChangedEvent(selectionProvider, new StructuredSelection(
-					new RepositoryTaskSelection(taskData.getTaskId(), taskData.getRepositoryUrl(),
-							taskData.getConnectorKind(), "New Description", false, taskData.getSummary()))));
-		}
-	}
-
-	@Override
-	protected void validateInput() {
-		// ignore
-	}
-
-	@Override
-	public boolean isDirty() {
-		return true;
-	}
-
-	/**
-	 * @author Raphael Ackermann (bug 198526)
-	 */
-	@Override
-	public void setFocus() {
-		if (summaryText != null) {
-			summaryText.setFocus();
-		}
-	}
-
-	@Override
-	public boolean isSaveAsAllowed() {
-		return false;
-	}
-
-	/**
-	 * Creates the button layout. This displays options and buttons at the bottom of the editor to allow actions to be
-	 * performed on the bug.
-	 */
-	@Override
-	protected void createActionsLayout(Composite formComposite) {
-		Section section = getManagedForm().getToolkit().createSection(formComposite, ExpandableComposite.TITLE_BAR);
-
-		section.setText(getSectionLabel(SECTION_NAME.ACTIONS_SECTION));
-		section.setExpanded(true);
-		section.setLayout(new GridLayout());
-		GridDataFactory.fillDefaults().align(SWT.FILL, SWT.TOP).grab(true, true).applyTo(section);
-
-		Composite buttonComposite = getManagedForm().getToolkit().createComposite(section);
-		buttonComposite.setLayout(new GridLayout(4, false));
-		buttonComposite.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));
-		section.setClient(buttonComposite);
-
-		addToCategory = getManagedForm().getToolkit().createButton(buttonComposite, "Add to Category", SWT.CHECK);
-		categoryChooser = new CCombo(buttonComposite, SWT.FLAT | SWT.READ_ONLY);
-		categoryChooser.setData(FormToolkit.KEY_DRAW_BORDER, FormToolkit.TEXT_BORDER);
-		categoryChooser.setLayoutData(GridDataFactory.swtDefaults().hint(150, SWT.DEFAULT).create());
-		getManagedForm().getToolkit().adapt(categoryChooser, true, true);
-		categoryChooser.setFont(TEXT_FONT);
-		ITaskList taskList = TasksUiInternal.getTaskList();
-		List<AbstractTaskCategory> categories = new ArrayList<AbstractTaskCategory>(taskList.getCategories());
-		Collections.sort(categories, new Comparator<AbstractTaskContainer>() {
-
-			public int compare(AbstractTaskContainer c1, AbstractTaskContainer c2) {
-				if (c1.equals(TasksUiPlugin.getTaskList().getDefaultCategory())) {
-					return -1;
-				} else if (c2.equals(TasksUiPlugin.getTaskList().getDefaultCategory())) {
-					return 1;
-				} else {
-					return c1.getSummary().compareToIgnoreCase(c2.getSummary());
-				}
-			}
-
-		});
-
-		for (IRepositoryElement category : categories) {
-			categoryChooser.add(category.getSummary());
-		}
-
-		categoryChooser.select(0);
-		categoryChooser.setEnabled(false);
-		categoryChooser.setData(categories);
-		addToCategory.addSelectionListener(new SelectionAdapter() {
-
-			@Override
-			public void widgetSelected(SelectionEvent e) {
-				categoryChooser.setEnabled(addToCategory.getSelection());
-			}
-
-		});
-
-		GridDataFactory.fillDefaults().hint(DEFAULT_FIELD_WIDTH, SWT.DEFAULT).span(3, SWT.DEFAULT).applyTo(
-				categoryChooser);
-
-		addActionButtons(buttonComposite);
-
-		getManagedForm().getToolkit().paintBordersFor(buttonComposite);
-	}
-
-	/**
-	 * Returns the {@link AbstractTaskContainer category} the new task belongs to
-	 * 
-	 * @return {@link AbstractTaskContainer category} where the new task must be added to, or null if it must not be
-	 *         added to the task list
-	 */
-	@Override
-	@SuppressWarnings("unchecked")
-	protected AbstractTaskCategory getCategory() {
-		int index = categoryChooser.getSelectionIndex();
-		if (addToCategory.getSelection() && index != -1) {
-			return ((List<AbstractTaskCategory>) categoryChooser.getData()).get(index);
-		}
-		return null;
-	}
-
-	@Override
-	protected void addActionButtons(Composite buttonComposite) {
-		FormToolkit toolkit = new FormToolkit(buttonComposite.getDisplay());
-		submitButton = toolkit.createButton(buttonComposite, LABEL_SUMBIT, SWT.NONE);
-		GridData submitButtonData = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
-		submitButtonData.widthHint = 100;
-		submitButton.setImage(CommonImages.getImage(TasksUiImages.REPOSITORY_SUBMIT));
-		submitButton.setLayoutData(submitButtonData);
-		submitButton.addListener(SWT.Selection, new Listener() {
-			public void handleEvent(Event e) {
-				submitToRepository();
-			}
-		});
-		submitButton.setToolTipText("Submit to " + this.repository.getRepositoryUrl());
-	}
-
-	protected boolean prepareSubmit() {
-		submitButton.setEnabled(false);
-		showBusy(true);
-
-		if (summaryText != null && summaryText.getText().trim().equals("")) {
-			PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {
-				public void run() {
-					MessageDialog.openInformation(AbstractNewRepositoryTaskEditor.this.getSite().getShell(),
-							ERROR_CREATING_BUG_REPORT, "A summary must be provided with new bug reports.");
-					summaryText.setFocus();
-					submitButton.setEnabled(true);
-					showBusy(false);
-				}
-			});
-			return false;
-		}
-
-		if (descriptionTextViewer != null && descriptionTextViewer.getTextWidget().getText().trim().equals("")) {
-			PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {
-				public void run() {
-					MessageDialog.openInformation(AbstractNewRepositoryTaskEditor.this.getSite().getShell(),
-							ERROR_CREATING_BUG_REPORT, "A summary must be provided with new reports.");
-					descriptionTextViewer.getTextWidget().setFocus();
-					submitButton.setEnabled(true);
-					showBusy(false);
-				}
-			});
-			return false;
-		}
-
-		return true;
-	}
-
-	@Override
-	protected void createPeopleLayout(Composite composite) {
-		// ignore, new editor doesn't have people section
-	}
-
-	@Override
-	public AbstractTask updateSubmittedTask(String id, IProgressMonitor monitor) throws CoreException {
-		final AbstractTask newTask = super.updateSubmittedTask(id, monitor);
-
-		if (newTask != null) {
-			PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {
-				public void run() {
-					DateRange selectedDate = null;
-					if (scheduledForDate != null) {
-						selectedDate = scheduledForDate.getScheduledDate();
-					}
-					if (selectedDate != null) {
-						TasksUiPlugin.getTaskActivityManager().setScheduledFor(newTask, selectedDate);
-					}
-
-					if (estimatedTime != null) {
-						newTask.setEstimatedTimeHours(estimatedTime.getSelection());
-					}
-
-					Object selectedObject = null;
-					if (TaskListView.getFromActivePerspective() != null) {
-						selectedObject = ((IStructuredSelection) TaskListView.getFromActivePerspective()
-								.getViewer()
-								.getSelection()).getFirstElement();
-					}
-
-					if (selectedObject instanceof TaskCategory) {
-						TasksUiInternal.getTaskList().addTask(newTask, ((TaskCategory) selectedObject));
-					}
-				}
-			});
-		}
-
-		return newTask;
-	}
-
-	@Override
-	public void doSave(IProgressMonitor monitor) {
-		new MessageDialog(null, "Operation not supported", null,
-				"Save of un-submitted new tasks is not currently supported.\nPlease submit all new tasks.",
-				MessageDialog.INFORMATION, new String[] { IDialogConstants.OK_LABEL }, 0).open();
-		monitor.setCanceled(true);
-		return;
-	}
-
-	@Override
-	public boolean searchForDuplicates() {
-		// called so that the description text is set on taskData before we
-		// search for duplicates
-		this.saveTaskOffline(new NullProgressMonitor());
-		return super.searchForDuplicates();
-	}
-
-	@Override
-	protected boolean supportsRefreshAttributes() {
-		// see bug 212475
-		return false;
-	}
-
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/editors/AbstractRepositoryQueryWizard.java b/org.eclipse.mylyn.ide.dev/developer/src-old/editors/AbstractRepositoryQueryWizard.java
deleted file mode 100644
index 50a75e7..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/editors/AbstractRepositoryQueryWizard.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004, 2008 Tasktop Technologies and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     Tasktop Technologies - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.mylyn.internal.tasks.ui.deprecated;
-
-import org.eclipse.jface.wizard.Wizard;
-import org.eclipse.mylyn.internal.tasks.core.RepositoryQuery;
-import org.eclipse.mylyn.internal.tasks.ui.util.TasksUiInternal;
-import org.eclipse.mylyn.tasks.core.AbstractRepositoryConnector;
-import org.eclipse.mylyn.tasks.core.IRepositoryQuery;
-import org.eclipse.mylyn.tasks.core.TaskRepository;
-import org.eclipse.mylyn.tasks.ui.TasksUi;
-import org.eclipse.mylyn.tasks.ui.TasksUiImages;
-import org.eclipse.mylyn.tasks.ui.wizards.AbstractRepositoryQueryPage;
-
-/**
- * @deprecated Do not use. This class is pending for removal: see bug 237552.
- */
-@Deprecated
-public abstract class AbstractRepositoryQueryWizard extends Wizard {
-
-	private static final String TITLE = "Edit Repository Query";
-
-	protected final TaskRepository repository;
-
-	protected IRepositoryQuery query;
-
-	protected AbstractRepositoryQueryPage page;
-
-	/**
-	 * @since 3.0
-	 */
-	public AbstractRepositoryQueryWizard(TaskRepository repository, IRepositoryQuery query) {
-		this.repository = repository;
-		this.query = query;
-		setNeedsProgressMonitor(true);
-		setWindowTitle(TITLE);
-		setDefaultPageImageDescriptor(TasksUiImages.BANNER_REPOSITORY);
-	}
-
-	@Override
-	public boolean performFinish() {
-		if (query != null) {
-			TasksUiInternal.getTaskList().deleteQuery((RepositoryQuery) query);
-		}
-		IRepositoryQuery queryToRun = page != null ? page.getQuery() : this.query;
-		if (queryToRun != null) {
-			TasksUiInternal.getTaskList().addQuery((RepositoryQuery) queryToRun);
-
-			AbstractRepositoryConnector connector = TasksUi.getRepositoryManager().getRepositoryConnector(
-					repository.getConnectorKind());
-			if (connector != null) {
-				TasksUiInternal.synchronizeQuery(connector, (RepositoryQuery) queryToRun, null, true);
-			}
-		}
-
-		return true;
-	}
-
-	public String getQuerySummary() {
-		if (query != null) {
-			return query.getSummary();
-		}
-		return null;
-	}
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/editors/AbstractRepositoryTaskEditor.java b/org.eclipse.mylyn.ide.dev/developer/src-old/editors/AbstractRepositoryTaskEditor.java
deleted file mode 100644
index 8b05e51..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/editors/AbstractRepositoryTaskEditor.java
+++ /dev/null
@@ -1,4051 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004, 2008 Tasktop Technologies and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     Tasktop Technologies - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.mylyn.internal.tasks.ui.deprecated;
-
-import java.io.File;
-import java.lang.reflect.Method;
-import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.NullProgressMonitor;
-import org.eclipse.core.runtime.OperationCanceledException;
-import org.eclipse.core.runtime.Status;
-import org.eclipse.core.runtime.SubProgressMonitor;
-import org.eclipse.core.runtime.jobs.IJobChangeEvent;
-import org.eclipse.core.runtime.jobs.IJobChangeListener;
-import org.eclipse.core.runtime.jobs.Job;
-import org.eclipse.core.runtime.jobs.JobChangeAdapter;
-import org.eclipse.jface.action.Action;
-import org.eclipse.jface.action.ControlContribution;
-import org.eclipse.jface.action.IMenuListener;
-import org.eclipse.jface.action.IMenuManager;
-import org.eclipse.jface.action.IToolBarManager;
-import org.eclipse.jface.action.MenuManager;
-import org.eclipse.jface.action.Separator;
-import org.eclipse.jface.action.ToolBarManager;
-import org.eclipse.jface.dialogs.IMessageProvider;
-import org.eclipse.jface.dialogs.MessageDialog;
-import org.eclipse.jface.fieldassist.ContentProposalAdapter;
-import org.eclipse.jface.fieldassist.ControlDecoration;
-import org.eclipse.jface.fieldassist.FieldDecoration;
-import org.eclipse.jface.fieldassist.FieldDecorationRegistry;
-import org.eclipse.jface.fieldassist.IContentProposalProvider;
-import org.eclipse.jface.fieldassist.TextContentAdapter;
-import org.eclipse.jface.layout.GridDataFactory;
-import org.eclipse.jface.resource.JFaceResources;
-import org.eclipse.jface.text.ITextListener;
-import org.eclipse.jface.text.Region;
-import org.eclipse.jface.text.TextEvent;
-import org.eclipse.jface.text.TextViewer;
-import org.eclipse.jface.text.hyperlink.IHyperlink;
-import org.eclipse.jface.util.SafeRunnable;
-import org.eclipse.jface.viewers.ColumnViewerToolTipSupport;
-import org.eclipse.jface.viewers.DoubleClickEvent;
-import org.eclipse.jface.viewers.IDoubleClickListener;
-import org.eclipse.jface.viewers.ILabelProvider;
-import org.eclipse.jface.viewers.ISelection;
-import org.eclipse.jface.viewers.ISelectionChangedListener;
-import org.eclipse.jface.viewers.ISelectionProvider;
-import org.eclipse.jface.viewers.IStructuredSelection;
-import org.eclipse.jface.viewers.LabelProvider;
-import org.eclipse.jface.viewers.SelectionChangedEvent;
-import org.eclipse.jface.viewers.StructuredSelection;
-import org.eclipse.jface.viewers.TableViewer;
-import org.eclipse.jface.viewers.Viewer;
-import org.eclipse.jface.viewers.ViewerSorter;
-import org.eclipse.jface.window.ToolTip;
-import org.eclipse.mylyn.commons.core.StatusHandler;
-import org.eclipse.mylyn.internal.provisional.commons.ui.CommonImages;
-import org.eclipse.mylyn.internal.provisional.commons.ui.CommonThemes;
-import org.eclipse.mylyn.internal.tasks.core.AbstractTask;
-import org.eclipse.mylyn.internal.tasks.core.AbstractTaskCategory;
-import org.eclipse.mylyn.internal.tasks.core.CommentQuoter;
-import org.eclipse.mylyn.internal.tasks.core.ITaskListChangeListener;
-import org.eclipse.mylyn.internal.tasks.core.RepositoryQuery;
-import org.eclipse.mylyn.internal.tasks.core.TaskContainerDelta;
-import org.eclipse.mylyn.internal.tasks.core.deprecated.AbstractLegacyDuplicateDetector;
-import org.eclipse.mylyn.internal.tasks.core.deprecated.AbstractLegacyRepositoryConnector;
-import org.eclipse.mylyn.internal.tasks.core.deprecated.AbstractTaskDataHandler;
-import org.eclipse.mylyn.internal.tasks.core.deprecated.RepositoryAttachment;
-import org.eclipse.mylyn.internal.tasks.core.deprecated.RepositoryOperation;
-import org.eclipse.mylyn.internal.tasks.core.deprecated.RepositoryTaskAttribute;
-import org.eclipse.mylyn.internal.tasks.core.deprecated.RepositoryTaskData;
-import org.eclipse.mylyn.internal.tasks.core.deprecated.TaskComment;
-import org.eclipse.mylyn.internal.tasks.ui.PersonProposalLabelProvider;
-import org.eclipse.mylyn.internal.tasks.ui.PersonProposalProvider;
-import org.eclipse.mylyn.internal.tasks.ui.TaskHyperlink;
-import org.eclipse.mylyn.internal.tasks.ui.TasksUiPlugin;
-import org.eclipse.mylyn.internal.tasks.ui.actions.AbstractTaskEditorAction;
-import org.eclipse.mylyn.internal.tasks.ui.actions.AttachAction;
-import org.eclipse.mylyn.internal.tasks.ui.actions.AttachScreenshotAction;
-import org.eclipse.mylyn.internal.tasks.ui.actions.ClearOutgoingAction;
-import org.eclipse.mylyn.internal.tasks.ui.actions.NewSubTaskAction;
-import org.eclipse.mylyn.internal.tasks.ui.actions.SynchronizeEditorAction;
-import org.eclipse.mylyn.internal.tasks.ui.actions.ToggleTaskActivationAction;
-import org.eclipse.mylyn.internal.tasks.ui.editors.AttachmentTableLabelProvider;
-import org.eclipse.mylyn.internal.tasks.ui.editors.AttachmentsTableContentProvider;
-import org.eclipse.mylyn.internal.tasks.ui.editors.ContentOutlineTools;
-import org.eclipse.mylyn.internal.tasks.ui.editors.IRepositoryTaskAttributeListener;
-import org.eclipse.mylyn.internal.tasks.ui.editors.IRepositoryTaskSelection;
-import org.eclipse.mylyn.internal.tasks.ui.editors.RepositoryAttachmentEditorInput;
-import org.eclipse.mylyn.internal.tasks.ui.editors.RepositoryTaskEditorDropListener;
-import org.eclipse.mylyn.internal.tasks.ui.editors.RepositoryTaskOutlineNode;
-import org.eclipse.mylyn.internal.tasks.ui.editors.RepositoryTaskOutlinePage;
-import org.eclipse.mylyn.internal.tasks.ui.editors.RepositoryTaskSelection;
-import org.eclipse.mylyn.internal.tasks.ui.editors.TaskListChangeAdapter;
-import org.eclipse.mylyn.internal.tasks.ui.editors.TaskUrlHyperlink;
-import org.eclipse.mylyn.internal.tasks.ui.search.SearchHitCollector;
-import org.eclipse.mylyn.internal.tasks.ui.util.AttachmentUtil;
-import org.eclipse.mylyn.internal.tasks.ui.util.TasksUiInternal;
-import org.eclipse.mylyn.internal.tasks.ui.views.UpdateRepositoryConfigurationAction;
-import org.eclipse.mylyn.tasks.core.AbstractDuplicateDetector;
-import org.eclipse.mylyn.tasks.core.AbstractRepositoryConnector;
-import org.eclipse.mylyn.tasks.core.IRepositoryElement;
-import org.eclipse.mylyn.tasks.core.ITask;
-import org.eclipse.mylyn.tasks.core.ITaskAttachment;
-import org.eclipse.mylyn.tasks.core.RepositoryStatus;
-import org.eclipse.mylyn.tasks.core.TaskRepository;
-import org.eclipse.mylyn.tasks.core.ITask.SynchronizationState;
-import org.eclipse.mylyn.tasks.ui.AbstractRepositoryConnectorUi;
-import org.eclipse.mylyn.tasks.ui.TasksUi;
-import org.eclipse.mylyn.tasks.ui.TasksUiImages;
-import org.eclipse.mylyn.tasks.ui.TasksUiUtil;
-import org.eclipse.mylyn.tasks.ui.editors.AbstractRenderingEngine;
-import org.eclipse.mylyn.tasks.ui.editors.TaskEditor;
-import org.eclipse.osgi.util.NLS;
-import org.eclipse.search.ui.NewSearchUI;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.browser.Browser;
-import org.eclipse.swt.browser.LocationAdapter;
-import org.eclipse.swt.browser.LocationEvent;
-import org.eclipse.swt.custom.BusyIndicator;
-import org.eclipse.swt.custom.CCombo;
-import org.eclipse.swt.custom.CTabFolder;
-import org.eclipse.swt.custom.StackLayout;
-import org.eclipse.swt.custom.StyledText;
-import org.eclipse.swt.custom.VerifyKeyListener;
-import org.eclipse.swt.dnd.Clipboard;
-import org.eclipse.swt.dnd.DND;
-import org.eclipse.swt.dnd.DropTarget;
-import org.eclipse.swt.dnd.FileTransfer;
-import org.eclipse.swt.dnd.TextTransfer;
-import org.eclipse.swt.dnd.Transfer;
-import org.eclipse.swt.events.ControlAdapter;
-import org.eclipse.swt.events.ControlEvent;
-import org.eclipse.swt.events.FocusAdapter;
-import org.eclipse.swt.events.FocusEvent;
-import org.eclipse.swt.events.FocusListener;
-import org.eclipse.swt.events.KeyEvent;
-import org.eclipse.swt.events.KeyListener;
-import org.eclipse.swt.events.ModifyEvent;
-import org.eclipse.swt.events.ModifyListener;
-import org.eclipse.swt.events.SelectionAdapter;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.events.SelectionListener;
-import org.eclipse.swt.events.VerifyEvent;
-import org.eclipse.swt.graphics.Color;
-import org.eclipse.swt.graphics.Cursor;
-import org.eclipse.swt.graphics.Font;
-import org.eclipse.swt.graphics.Point;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.layout.RowLayout;
-import org.eclipse.swt.widgets.Button;
-import org.eclipse.swt.widgets.Combo;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.swt.widgets.Event;
-import org.eclipse.swt.widgets.FileDialog;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Link;
-import org.eclipse.swt.widgets.Listener;
-import org.eclipse.swt.widgets.Menu;
-import org.eclipse.swt.widgets.Spinner;
-import org.eclipse.swt.widgets.TabFolder;
-import org.eclipse.swt.widgets.Table;
-import org.eclipse.swt.widgets.TableColumn;
-import org.eclipse.swt.widgets.Text;
-import org.eclipse.swt.widgets.Tree;
-import org.eclipse.ui.IEditorDescriptor;
-import org.eclipse.ui.IEditorInput;
-import org.eclipse.ui.IEditorSite;
-import org.eclipse.ui.ISelectionListener;
-import org.eclipse.ui.ISharedImages;
-import org.eclipse.ui.IStorageEditorInput;
-import org.eclipse.ui.IWorkbenchActionConstants;
-import org.eclipse.ui.IWorkbenchPage;
-import org.eclipse.ui.IWorkbenchPart;
-import org.eclipse.ui.PartInitException;
-import org.eclipse.ui.PlatformUI;
-import org.eclipse.ui.dialogs.FilteredTree;
-import org.eclipse.ui.fieldassist.ContentAssistCommandAdapter;
-import org.eclipse.ui.forms.IFormColors;
-import org.eclipse.ui.forms.IManagedForm;
-import org.eclipse.ui.forms.editor.FormEditor;
-import org.eclipse.ui.forms.events.ExpansionAdapter;
-import org.eclipse.ui.forms.events.ExpansionEvent;
-import org.eclipse.ui.forms.events.HyperlinkAdapter;
-import org.eclipse.ui.forms.events.HyperlinkEvent;
-import org.eclipse.ui.forms.widgets.ExpandableComposite;
-import org.eclipse.ui.forms.widgets.FormToolkit;
-import org.eclipse.ui.forms.widgets.Hyperlink;
-import org.eclipse.ui.forms.widgets.ImageHyperlink;
-import org.eclipse.ui.forms.widgets.ScrolledForm;
-import org.eclipse.ui.forms.widgets.Section;
-import org.eclipse.ui.internal.ObjectActionContributorManager;
-import org.eclipse.ui.internal.WorkbenchImages;
-import org.eclipse.ui.keys.IBindingService;
-import org.eclipse.ui.themes.IThemeManager;
-import org.eclipse.ui.views.contentoutline.ContentOutline;
-import org.eclipse.ui.views.contentoutline.IContentOutlinePage;
-
-/**
- * @deprecated Do not use. This class is pending for removal: see bug 237552.
- */
-@Deprecated
-public abstract class AbstractRepositoryTaskEditor extends TaskFormPage {
-
-	private static final String PREF_SORT_ORDER_PREFIX = "org.eclipse.mylyn.editor.comments.sortDirectionUp.";
-
-	private static final String ERROR_NOCONNECTIVITY = "Unable to submit at this time. Check connectivity and retry.";
-
-	private static final String LABEL_HISTORY = "History";
-
-	private static final String LABEL_REPLY = "Reply";
-
-	private static final String LABEL_JOB_SUBMIT = "Submitting to repository";
-
-	private static final String HEADER_DATE_FORMAT = "yyyy-MM-dd HH:mm";
-
-	private static final String ATTACHMENT_DEFAULT_NAME = "attachment";
-
-	private static final String CTYPE_ZIP = "zip";
-
-	private static final String CTYPE_OCTET_STREAM = "octet-stream";
-
-	private static final String CTYPE_TEXT = "text";
-
-	private static final String CTYPE_HTML = "html";
-
-	private static final String LABEL_BROWSER = "Browser";
-
-	private static final String LABEL_DEFAULT_EDITOR = "Default Editor";
-
-	private static final String LABEL_TEXT_EDITOR = "Text Editor";
-
-	protected static final String CONTEXT_MENU_ID = "#MylynRepositoryEditor";
-
-	private FormToolkit toolkit;
-
-	private ScrolledForm form;
-
-	protected TaskRepository repository;
-
-	private static final int RADIO_OPTION_WIDTH = 120;
-
-	private static final Font TITLE_FONT = JFaceResources.getBannerFont();
-
-	protected static final Font TEXT_FONT = JFaceResources.getDefaultFont();
-
-	private static final int DESCRIPTION_WIDTH = 79 * 7; // 500;
-
-	private static final int DESCRIPTION_HEIGHT = 10 * 14;
-
-	protected static final int SUMMARY_HEIGHT = 20;
-
-	private static final String LABEL_BUTTON_SUBMIT = "Submit";
-
-	private static final String LABEL_COPY_URL_TO_CLIPBOARD = "Copy &URL";
-
-	private static final String LABEL_COPY_TO_CLIPBOARD = "Copy Contents";
-
-	private static final String LABEL_SAVE = "Save...";
-
-	private static final String LABEL_SEARCH_DUPS = "Search";
-
-	private static final String LABEL_SELECT_DETECTOR = "Duplicate Detection";
-
-	private RepositoryTaskEditorInput editorInput;
-
-	private TaskEditor parentEditor = null;
-
-	private RepositoryTaskOutlineNode taskOutlineModel = null;
-
-	private boolean expandedStateAttributes = false;
-
-	protected Button submitButton;
-
-	private Table attachmentsTable;
-
-	private boolean refreshEnabled = true;
-
-	private TableViewer attachmentsTableViewer;
-
-	private final String[] attachmentsColumns = { "Name", "Description", "Type", "Size", "Creator", "Created" };
-
-	private final int[] attachmentsColumnWidths = { 140, 160, 100, 70, 100, 100 };
-
-	private Composite editorComposite;
-
-	protected TextViewer summaryTextViewer;
-
-	private ImageHyperlink sortHyperlink;
-
-	private boolean commentSortIsUp = true;
-
-	private boolean commentSortEnable = false;
-
-	private Composite addCommentsComposite;
-
-	/**
-	 * WARNING: This is present for backward compatibility only. You can get and set text on this widget but all ui
-	 * related changes to this widget will have no affect as ui is now being presented with a StyledText widget. This
-	 * simply proxies get/setText calls to the StyledText widget.
-	 */
-	protected Text summaryText;
-
-	private TextViewer newCommentTextViewer;
-
-	private org.eclipse.swt.widgets.List ccList;
-
-	private Section commentsSection;
-
-	private Color colorIncoming;
-
-	private boolean hasAttributeChanges = false;
-
-	private boolean showAttachments = true;
-
-	private boolean attachContextEnabled = true;
-
-	protected Button searchForDuplicates;
-
-	protected CCombo duplicateDetectorChooser;
-
-	protected Label duplicateDetectorLabel;
-
-	private boolean ignoreLocationEvents = false;
-
-	private boolean refreshing = false;
-
-	private TaskComment selectedComment = null;
-
-	/**
-	 * @author Raphael Ackermann (bug 195514)
-	 */
-	private class TabVerifyKeyListener implements VerifyKeyListener {
-
-		public void verifyKey(VerifyEvent event) {
-			// if there is a tab key, do not "execute" it and instead select the Status control
-			if (event.keyCode == SWT.TAB) {
-				event.doit = false;
-				if (headerInfoComposite != null) {
-					headerInfoComposite.setFocus();
-				}
-			}
-		}
-
-	}
-
-	protected enum SECTION_NAME {
-		ATTRIBTUES_SECTION("Attributes"), ATTACHMENTS_SECTION("Attachments"), DESCRIPTION_SECTION("Description"), COMMENTS_SECTION(
-				"Comments"), NEWCOMMENT_SECTION("New Comment"), ACTIONS_SECTION("Actions"), PEOPLE_SECTION("People"), RELATEDBUGS_SECTION(
-				"Related Tasks");
-
-		private String prettyName;
-
-		public String getPrettyName() {
-			return prettyName;
-		}
-
-		SECTION_NAME(String prettyName) {
-			this.prettyName = prettyName;
-		}
-	}
-
-	private final List<IRepositoryTaskAttributeListener> attributesListeners = new ArrayList<IRepositoryTaskAttributeListener>();
-
-	protected RepositoryTaskData taskData;
-
-	protected final ISelectionProvider selectionProvider = new ISelectionProvider() {
-		public void addSelectionChangedListener(ISelectionChangedListener listener) {
-			selectionChangedListeners.add(listener);
-		}
-
-		public ISelection getSelection() {
-			RepositoryTaskSelection selection = new RepositoryTaskSelection(taskData.getTaskId(),
-					taskData.getRepositoryUrl(), taskData.getConnectorKind(), "", selectedComment,
-					taskData.getSummary());
-			selection.setIsDescription(true);
-			return selection;
-		}
-
-		public void removeSelectionChangedListener(ISelectionChangedListener listener) {
-			selectionChangedListeners.remove(listener);
-		}
-
-		public void setSelection(ISelection selection) {
-			// No implementation.
-		}
-	};
-
-	private final ITaskListChangeListener TASKLIST_CHANGE_LISTENER = new TaskListChangeAdapter() {
-
-		@Override
-		public void containersChanged(Set<TaskContainerDelta> containers) {
-			ITask taskToRefresh = null;
-			for (TaskContainerDelta taskContainerDelta : containers) {
-				if (!localChange && repositoryTask != null && repositoryTask.equals(taskContainerDelta.getElement())) {
-					if (taskContainerDelta.getKind().equals(TaskContainerDelta.Kind.CONTENT)
-							&& !taskContainerDelta.isTransient() && !refreshing) {
-						taskToRefresh = (ITask) taskContainerDelta.getElement();
-						break;
-					}
-				}
-			}
-			if (taskToRefresh != null) {
-				PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {
-					public void run() {
-						if (repositoryTask.getSynchronizationState() == SynchronizationState.INCOMING
-								|| repositoryTask.getSynchronizationState() == SynchronizationState.CONFLICT) {
-							parentEditor.setMessage("Task has incoming changes", IMessageProvider.WARNING,
-									new HyperlinkAdapter() {
-										@Override
-										public void linkActivated(HyperlinkEvent e) {
-											refreshEditor();
-										}
-									});
-							setSubmitEnabled(false);
-						} else {
-							refreshEditor();
-						}
-					}
-				});
-			}
-		}
-	};
-
-	private final List<ISelectionChangedListener> selectionChangedListeners = new ArrayList<ISelectionChangedListener>();
-
-	private IRepositoryTaskSelection lastSelected = null;
-
-	/**
-	 * Focuses on form widgets when an item in the outline is selected.
-	 */
-	private final ISelectionListener selectionListener = new ISelectionListener() {
-		public void selectionChanged(IWorkbenchPart part, ISelection selection) {
-			if ((part instanceof ContentOutline) && (selection instanceof StructuredSelection)) {
-				Object select = ((StructuredSelection) selection).getFirstElement();
-				if (select instanceof RepositoryTaskOutlineNode) {
-					RepositoryTaskOutlineNode n = (RepositoryTaskOutlineNode) select;
-
-					if (lastSelected != null
-							&& ContentOutlineTools.getHandle(n).equals(ContentOutlineTools.getHandle(lastSelected))) {
-						// we don't need to set the selection if it is already
-						// set
-						return;
-					}
-					lastSelected = n;
-
-					boolean highlight = true;
-					if (n.getKey().equals(RepositoryTaskOutlineNode.LABEL_COMMENTS)) {
-						highlight = false;
-					}
-
-					Object data = n.getData();
-					if (n.getKey().equals(RepositoryTaskOutlineNode.LABEL_NEW_COMMENT)) {
-						selectNewComment();
-					} else if (n.getKey().equals(RepositoryTaskOutlineNode.LABEL_DESCRIPTION)
-							&& descriptionTextViewer.isEditable()) {
-						focusDescription();
-					} else if (data != null) {
-						select(data, highlight);
-					}
-				}
-				part.setFocus();
-			}
-		}
-	};
-
-	private AbstractTask repositoryTask;
-
-	private Set<RepositoryTaskAttribute> changedAttributes;
-
-	private Menu menu;
-
-	private SynchronizeEditorAction synchronizeEditorAction;
-
-	private ToggleTaskActivationAction activateAction;
-
-	private Action historyAction;
-
-	private Action clearOutgoingAction;
-
-	private Action openBrowserAction;
-
-	private NewSubTaskAction newSubTaskAction;
-
-	private Control lastFocusControl;
-
-	private boolean localChange = false;
-
-	/**
-	 * Call upon change to attribute value
-	 * 
-	 * @param attribute
-	 *            changed attribute
-	 */
-	protected boolean attributeChanged(RepositoryTaskAttribute attribute) {
-		if (attribute == null) {
-			return false;
-		}
-		changedAttributes.add(attribute);
-		markDirty(true);
-		validateInput();
-		return true;
-	}
-
-	@Override
-	public void init(IEditorSite site, IEditorInput input) {
-		if (!(input instanceof RepositoryTaskEditorInput)) {
-			return;
-		}
-
-		initTaskEditor(site, (RepositoryTaskEditorInput) input);
-
-		if (taskData != null) {
-			editorInput.setToolTipText(taskData.getLabel());
-			taskOutlineModel = RepositoryTaskOutlineNode.parseBugReport(taskData);
-		}
-		hasAttributeChanges = hasVisibleAttributeChanges();
-		TasksUiInternal.getTaskList().addChangeListener(TASKLIST_CHANGE_LISTENER);
-	}
-
-	protected void initTaskEditor(IEditorSite site, RepositoryTaskEditorInput input) {
-		changedAttributes = new HashSet<RepositoryTaskAttribute>();
-		editorInput = input;
-		repositoryTask = editorInput.getRepositoryTask();
-		repository = editorInput.getRepository();
-		taskData = editorInput.getTaskData();
-		if (repositoryTask != null) {
-			TasksUiPlugin.getTaskDataManager().setTaskRead(repositoryTask, true);
-		}
-		connector = (AbstractLegacyRepositoryConnector) TasksUi.getRepositoryManager().getRepositoryConnector(
-				repository.getConnectorKind());
-		commentSortIsUp = TasksUiPlugin.getDefault().getPreferenceStore().getBoolean(
-				PREF_SORT_ORDER_PREFIX + repository.getConnectorKind());
-		setSite(site);
-		setInput(input);
-
-		isDirty = false;
-	}
-
-	public AbstractTask getRepositoryTask() {
-		return repositoryTask;
-	}
-
-	// @Override
-	// public void markDirty(boolean dirty) {
-	// if (repositoryTask != null) {
-	// repositoryTask.setDirty(dirty);
-	// }
-	// super.markDirty(dirty);
-	// }
-
-//	/**
-//	 * Update task state
-//	 */
-//	protected void updateTask() {
-//		if (taskData == null)
-//			return;
-//		if (repositoryTask != null) {
-//			TasksUiPlugin.getSynchronizationManager().saveOutgoing(repositoryTask, changedAttributes);
-//		}
-//		if (parentEditor != null) {
-//			parentEditor.notifyTaskChanged();
-//		}
-//		markDirty(false);
-//	}
-
-	protected abstract void validateInput();
-
-	/**
-	 * Creates a new <code>AbstractTaskEditor</code>.
-	 */
-	public AbstractRepositoryTaskEditor(FormEditor editor) {
-		// set the scroll increments so the editor scrolls normally with the
-		// scroll wheel
-		super(editor, "id", "label"); //$NON-NLS-1$ //$NON-NLS-2$
-	}
-
-	protected boolean supportsCommentSort() {
-		return false;
-	}
-
-	@Override
-	protected void createFormContent(final IManagedForm managedForm) {
-		IThemeManager themeManager = getSite().getWorkbenchWindow().getWorkbench().getThemeManager();
-		colorIncoming = themeManager.getCurrentTheme().getColorRegistry().get(CommonThemes.COLOR_INCOMING_BACKGROUND);
-
-		super.createFormContent(managedForm);
-		form = managedForm.getForm();
-		form.setRedraw(false);
-		try {
-			refreshEnabled = false;
-
-			toolkit = managedForm.getToolkit();
-			registerDropListener(form);
-
-			editorComposite = form.getBody();
-			GridLayout editorLayout = new GridLayout();
-			editorComposite.setLayout(editorLayout);
-			editorComposite.setLayoutData(new GridData(GridData.FILL_BOTH));
-
-			if (taskData != null) {
-				createSections();
-			}
-
-			AbstractRepositoryConnectorUi connectorUi = TasksUiPlugin.getConnectorUi(repository.getConnectorKind());
-			if (connectorUi == null) {
-				parentEditor.setMessage("The editor may not be fully loaded", IMessageProvider.INFORMATION,
-						new HyperlinkAdapter() {
-							@Override
-							public void linkActivated(HyperlinkEvent e) {
-								refreshEditor();
-							}
-						});
-			}
-
-			updateHeaderControls();
-			if (summaryTextViewer != null) {
-				summaryTextViewer.getTextWidget().setFocus();
-			}
-
-			form.setRedraw(true);
-		} finally {
-			refreshEnabled = true;
-		}
-
-		form.reflow(true);
-	}
-
-	private void updateHeaderControls() {
-		if (taskData == null) {
-			parentEditor.setMessage(
-					"Task data not available. Press synchronize button (right) to retrieve latest data.",
-					IMessageProvider.WARNING, new HyperlinkAdapter() {
-						@Override
-						public void linkActivated(HyperlinkEvent e) {
-							if (synchronizeEditorAction != null) {
-								synchronizeEditorAction.run();
-							}
-						}
-					});
-		}
-		getParentEditor().updateHeaderToolBar();
-	}
-
-	/**
-	 * Override for customizing the toolbar.
-	 * 
-	 * @since 2.1 (NOTE: likely to change for 3.0)
-	 */
-	public void fillToolBar(IToolBarManager toolBarManager) {
-		ControlContribution repositoryLabelControl = new ControlContribution("Title") { //$NON-NLS-1$
-			@Override
-			protected Control createControl(Composite parent) {
-				Composite composite = toolkit.createComposite(parent);
-				composite.setLayout(new RowLayout());
-				composite.setBackground(null);
-				String label = repository.getRepositoryLabel();
-				if (label.indexOf("//") != -1) {
-					label = label.substring((repository.getRepositoryUrl().indexOf("//") + 2));
-				}
-
-				Hyperlink link = new Hyperlink(composite, SWT.NONE);
-				link.setText(label);
-				link.setFont(TITLE_FONT);
-				link.setForeground(toolkit.getColors().getColor(IFormColors.TITLE));
-				link.addHyperlinkListener(new HyperlinkAdapter() {
-
-					@Override
-					public void linkActivated(HyperlinkEvent e) {
-						TasksUiUtil.openEditRepositoryWizard(repository);
-					}
-				});
-
-				return composite;
-			}
-		};
-		toolBarManager.add(repositoryLabelControl);
-
-		if ((taskData != null && !taskData.isNew()) || repositoryTask != null) {
-			synchronizeEditorAction = new SynchronizeEditorAction();
-			synchronizeEditorAction.selectionChanged(new StructuredSelection(this));
-			toolBarManager.add(synchronizeEditorAction);
-		}
-
-		if (taskData != null && !taskData.isNew()) {
-			if (repositoryTask != null) {
-				clearOutgoingAction = new ClearOutgoingAction(
-						Collections.singletonList((IRepositoryElement) repositoryTask));
-
-				if (clearOutgoingAction.isEnabled()) {
-					toolBarManager.add(clearOutgoingAction);
-				}
-
-				newSubTaskAction = new NewSubTaskAction();
-				newSubTaskAction.selectionChanged(newSubTaskAction, new StructuredSelection(getRepositoryTask()));
-				if (newSubTaskAction.isEnabled()) {
-					toolBarManager.add(newSubTaskAction);
-				}
-			}
-
-			if (getHistoryUrl() != null) {
-				historyAction = new Action() {
-					@Override
-					public void run() {
-						TasksUiUtil.openUrl(getHistoryUrl());
-					}
-				};
-
-				historyAction.setImageDescriptor(TasksUiImages.TASK_REPOSITORY_HISTORY);
-				historyAction.setToolTipText(LABEL_HISTORY);
-				toolBarManager.add(historyAction);
-			}
-
-			if (connector != null) {
-				String taskUrl = connector.getTaskUrl(taskData.getRepositoryUrl(), taskData.getTaskKey());
-				if (taskUrl == null && repositoryTask != null && TasksUiInternal.hasValidUrl(repositoryTask)) {
-					taskUrl = repositoryTask.getUrl();
-				}
-
-				final String taskUrlToOpen = taskUrl;
-
-				if (taskUrlToOpen != null) {
-					openBrowserAction = new Action() {
-						@Override
-						public void run() {
-							TasksUiUtil.openUrl(taskUrlToOpen);
-						}
-					};
-
-					openBrowserAction.setImageDescriptor(CommonImages.BROWSER_OPEN_TASK);
-					openBrowserAction.setToolTipText("Open with Web Browser");
-					toolBarManager.add(openBrowserAction);
-				}
-			}
-		}
-	}
-
-	private void createSections() {
-		createSummaryLayout(editorComposite);
-
-		Composite attribComp = createAttributeSection();
-		createAttributeLayout(attribComp);
-		createCustomAttributeLayout(attribComp);
-
-		createRelatedBugsSection(editorComposite);
-
-		if (showAttachments) {
-			createAttachmentLayout(editorComposite);
-		}
-		createDescriptionLayout(editorComposite);
-		createCommentLayout(editorComposite);
-		createNewCommentLayout(editorComposite);
-		Composite bottomComposite = toolkit.createComposite(editorComposite);
-		bottomComposite.setLayout(new GridLayout(2, false));
-		GridDataFactory.fillDefaults().grab(true, false).applyTo(bottomComposite);
-
-		createActionsLayout(bottomComposite);
-		createPeopleLayout(bottomComposite);
-		bottomComposite.pack(true);
-
-		getSite().getPage().addSelectionListener(selectionListener);
-		getSite().setSelectionProvider(selectionProvider);
-
-		FocusListener listener = new FocusAdapter() {
-			@Override
-			public void focusGained(FocusEvent e) {
-				lastFocusControl = (Control) e.widget;
-			}
-		};
-		addFocusListener(editorComposite, listener);
-	}
-
-	private void addFocusListener(Composite composite, FocusListener listener) {
-		Control[] children = composite.getChildren();
-		for (Control control : children) {
-			if ((control instanceof Text) || (control instanceof Button) || (control instanceof Combo)
-					|| (control instanceof CCombo) || (control instanceof Tree) || (control instanceof Table)
-					|| (control instanceof Spinner) || (control instanceof Link) || (control instanceof List)
-					|| (control instanceof TabFolder) || (control instanceof CTabFolder)
-					|| (control instanceof Hyperlink) || (control instanceof FilteredTree)
-					|| (control instanceof StyledText)) {
-				control.addFocusListener(listener);
-			}
-			if (control instanceof Composite) {
-				addFocusListener((Composite) control, listener);
-			}
-		}
-	}
-
-	private void removeSections() {
-		menu = editorComposite.getMenu();
-		setMenu(editorComposite, null);
-		for (Control control : editorComposite.getChildren()) {
-			control.dispose();
-		}
-		lastFocusControl = null;
-	}
-
-	/**
-	 * @author Raphael Ackermann (modifications) (bug 195514)
-	 */
-	protected void createSummaryLayout(Composite composite) {
-		addSummaryText(composite);
-		if (summaryTextViewer != null) {
-			summaryTextViewer.prependVerifyKeyListener(new TabVerifyKeyListener());
-		}
-
-		headerInfoComposite = toolkit.createComposite(composite);
-		GridLayout headerLayout = new GridLayout(11, false);
-		headerLayout.verticalSpacing = 1;
-		headerLayout.marginHeight = 1;
-		headerLayout.marginHeight = 1;
-		headerLayout.marginWidth = 1;
-		headerLayout.horizontalSpacing = 6;
-		headerInfoComposite.setLayout(headerLayout);
-
-		RepositoryTaskAttribute statusAtribute = taskData.getAttribute(RepositoryTaskAttribute.STATUS);
-		addNameValue(headerInfoComposite, statusAtribute);
-		toolkit.paintBordersFor(headerInfoComposite);
-
-		RepositoryTaskAttribute priorityAttribute = taskData.getAttribute(RepositoryTaskAttribute.PRIORITY);
-		addNameValue(headerInfoComposite, priorityAttribute);
-
-		String idLabel = (repositoryTask != null) ? repositoryTask.getTaskKey() : taskData.getTaskKey();
-		if (idLabel != null) {
-
-			Composite nameValue = toolkit.createComposite(headerInfoComposite);
-			nameValue.setLayout(new GridLayout(2, false));
-			Label label = toolkit.createLabel(nameValue, "ID:");// .setFont(TITLE_FONT);
-			label.setForeground(toolkit.getColors().getColor(IFormColors.TITLE));
-			// toolkit.createText(nameValue, idLabel, SWT.FLAT | SWT.READ_ONLY);
-			Text text = new Text(nameValue, SWT.FLAT | SWT.READ_ONLY);
-			toolkit.adapt(text, true, true);
-			text.setText(idLabel);
-		}
-
-		String openedDateString = "";
-		String modifiedDateString = "";
-		final AbstractTaskDataHandler taskDataManager = connector.getLegacyTaskDataHandler();
-		if (taskDataManager != null) {
-			Date created = taskData.getAttributeFactory().getDateForAttributeType(
-					RepositoryTaskAttribute.DATE_CREATION, taskData.getCreated());
-			openedDateString = created != null ? new SimpleDateFormat(HEADER_DATE_FORMAT).format(created) : "";
-
-			Date modified = taskData.getAttributeFactory().getDateForAttributeType(
-					RepositoryTaskAttribute.DATE_MODIFIED, taskData.getLastModified());
-			modifiedDateString = modified != null ? new SimpleDateFormat(HEADER_DATE_FORMAT).format(modified) : "";
-		}
-
-		RepositoryTaskAttribute creationAttribute = taskData.getAttribute(RepositoryTaskAttribute.DATE_CREATION);
-		if (creationAttribute != null) {
-			Composite nameValue = toolkit.createComposite(headerInfoComposite);
-			nameValue.setLayout(new GridLayout(2, false));
-			createLabel(nameValue, creationAttribute);
-			// toolkit.createText(nameValue, openedDateString, SWT.FLAT |
-			// SWT.READ_ONLY);
-			Text text = new Text(nameValue, SWT.FLAT | SWT.READ_ONLY);
-			toolkit.adapt(text, true, true);
-			text.setText(openedDateString);
-		}
-
-		RepositoryTaskAttribute modifiedAttribute = taskData.getAttribute(RepositoryTaskAttribute.DATE_MODIFIED);
-		if (modifiedAttribute != null) {
-			Composite nameValue = toolkit.createComposite(headerInfoComposite);
-			nameValue.setLayout(new GridLayout(2, false));
-			createLabel(nameValue, modifiedAttribute);
-			// toolkit.createText(nameValue, modifiedDateString, SWT.FLAT |
-			// SWT.READ_ONLY);
-			Text text = new Text(nameValue, SWT.FLAT | SWT.READ_ONLY);
-			toolkit.adapt(text, true, true);
-			text.setText(modifiedDateString);
-		}
-	}
-
-	private void addNameValue(Composite parent, RepositoryTaskAttribute attribute) {
-		Composite nameValue = toolkit.createComposite(parent);
-		nameValue.setLayout(new GridLayout(2, false));
-		if (attribute != null) {
-			createLabel(nameValue, attribute);
-			createTextField(nameValue, attribute, SWT.FLAT | SWT.READ_ONLY);
-		}
-	}
-
-	/**
-	 * Utility method to create text field sets background to TaskListColorsAndFonts.COLOR_ATTRIBUTE_CHANGED if
-	 * attribute has changed.
-	 * 
-	 * @param composite
-	 * @param attribute
-	 * @param style
-	 */
-	protected Text createTextField(Composite composite, RepositoryTaskAttribute attribute, int style) {
-		String value;
-		if (attribute == null || attribute.getValue() == null) {
-			value = "";
-		} else {
-			value = attribute.getValue();
-		}
-
-		final Text text;
-		if ((SWT.READ_ONLY & style) == SWT.READ_ONLY) {
-			text = new Text(composite, style);
-			toolkit.adapt(text, true, true);
-			text.setData(FormToolkit.KEY_DRAW_BORDER, Boolean.FALSE);
-			text.setText(value);
-		} else {
-			text = toolkit.createText(composite, value, style);
-		}
-
-		if (attribute != null && !attribute.isReadOnly()) {
-			text.setData(attribute);
-			text.addModifyListener(new ModifyListener() {
-				public void modifyText(ModifyEvent e) {
-					String newValue = text.getText();
-					RepositoryTaskAttribute attribute = (RepositoryTaskAttribute) text.getData();
-					attribute.setValue(newValue);
-					attributeChanged(attribute);
-				}
-			});
-		}
-		if (hasChanged(attribute)) {
-			text.setBackground(colorIncoming);
-		}
-		return text;
-	}
-
-	protected Label createLabel(Composite composite, RepositoryTaskAttribute attribute) {
-		Label label;
-		if (hasOutgoingChange(attribute)) {
-			label = toolkit.createLabel(composite, "*" + attribute.getName());
-		} else {
-			label = toolkit.createLabel(composite, attribute.getName());
-		}
-		label.setForeground(toolkit.getColors().getColor(IFormColors.TITLE));
-		GridDataFactory.fillDefaults().align(SWT.RIGHT, SWT.CENTER).applyTo(label);
-		return label;
-	}
-
-	public String getSectionLabel(SECTION_NAME labelName) {
-		return labelName.getPrettyName();
-	}
-
-	protected Composite createAttributeSection() {
-		attributesSection = createSection(editorComposite, getSectionLabel(SECTION_NAME.ATTRIBTUES_SECTION),
-				expandedStateAttributes || hasAttributeChanges);
-
-		Composite toolbarComposite = toolkit.createComposite(attributesSection);
-		toolbarComposite.setBackground(null);
-		RowLayout rowLayout = new RowLayout();
-		rowLayout.marginTop = 0;
-		rowLayout.marginBottom = 0;
-		toolbarComposite.setLayout(rowLayout);
-		UpdateRepositoryConfigurationAction repositoryConfigRefresh = new UpdateRepositoryConfigurationAction() {
-			@Override
-			public void performUpdate(TaskRepository repository, AbstractRepositoryConnector connector,
-					IProgressMonitor monitor) {
-				PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {
-
-					public void run() {
-						setGlobalBusy(true);
-
-					}
-				});
-				try {
-					super.performUpdate(repository, connector, monitor);
-					if (connector != null) {
-						TasksUiInternal.synchronizeTask(connector, repositoryTask, true, new JobChangeAdapter() {
-
-							@Override
-							public void done(IJobChangeEvent event) {
-								PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {
-
-									public void run() {
-										refreshEditor();
-									}
-								});
-
-							}
-						});
-					}
-				} catch (Exception e) {
-					PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {
-
-						public void run() {
-							refreshEditor();
-						}
-					});
-				}
-			}
-		};
-		repositoryConfigRefresh.setImageDescriptor(TasksUiImages.REPOSITORY_SYNCHRONIZE_SMALL);
-		repositoryConfigRefresh.selectionChanged(new StructuredSelection(repository));
-		repositoryConfigRefresh.setToolTipText("Refresh Attributes");
-
-		ToolBarManager barManager = new ToolBarManager(SWT.FLAT);
-		barManager.add(repositoryConfigRefresh);
-		repositoryConfigRefresh.setEnabled(supportsRefreshAttributes());
-		barManager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
-		barManager.createControl(toolbarComposite);
-		attributesSection.setTextClient(toolbarComposite);
-
-		// Attributes Composite- this holds all the combo fields and text fields
-		final Composite attribComp = toolkit.createComposite(attributesSection);
-		attribComp.addListener(SWT.MouseDown, new Listener() {
-			public void handleEvent(Event event) {
-				Control focus = event.display.getFocusControl();
-				if (focus instanceof Text && ((Text) focus).getEditable() == false) {
-					form.setFocus();
-				}
-			}
-		});
-		attributesSection.setClient(attribComp);
-
-		GridLayout attributesLayout = new GridLayout();
-		attributesLayout.numColumns = 4;
-		attributesLayout.horizontalSpacing = 5;
-		attributesLayout.verticalSpacing = 4;
-		attribComp.setLayout(attributesLayout);
-
-		GridData attributesData = new GridData(GridData.FILL_BOTH);
-		attributesData.horizontalSpan = 1;
-		attributesData.grabExcessVerticalSpace = false;
-		attribComp.setLayoutData(attributesData);
-
-		return attribComp;
-	}
-
-	/**
-	 * @since 2.2
-	 */
-	protected boolean supportsRefreshAttributes() {
-		return true;
-	}
-
-	/**
-	 * Creates the attribute section, which contains most of the basic attributes of the task (some of which are
-	 * editable).
-	 */
-	protected void createAttributeLayout(Composite attributesComposite) {
-		int numColumns = ((GridLayout) attributesComposite.getLayout()).numColumns;
-		int currentCol = 1;
-
-		for (final RepositoryTaskAttribute attribute : taskData.getAttributes()) {
-			if (attribute.isHidden()) {
-				continue;
-			}
-
-			GridData data = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
-			data.horizontalSpan = 1;
-
-			if (attribute.hasOptions() && !attribute.isReadOnly()) {
-				Label label = createLabel(attributesComposite, attribute);
-				GridDataFactory.fillDefaults().align(SWT.RIGHT, SWT.CENTER).applyTo(label);
-				final CCombo attributeCombo = new CCombo(attributesComposite, SWT.FLAT | SWT.READ_ONLY);
-				toolkit.adapt(attributeCombo, true, true);
-				attributeCombo.setFont(TEXT_FONT);
-				attributeCombo.setData(FormToolkit.KEY_DRAW_BORDER, FormToolkit.TEXT_BORDER);
-				if (hasChanged(attribute)) {
-					attributeCombo.setBackground(colorIncoming);
-				}
-				attributeCombo.setLayoutData(data);
-
-				List<String> values = attribute.getOptions();
-				if (values != null) {
-					for (String val : values) {
-						if (val != null) {
-							attributeCombo.add(val);
-						}
-					}
-				}
-
-				String value = attribute.getValue();
-				if (value == null) {
-					value = "";
-				}
-				if (attributeCombo.indexOf(value) != -1) {
-					attributeCombo.select(attributeCombo.indexOf(value));
-				}
-				attributeCombo.clearSelection();
-				attributeCombo.addSelectionListener(new SelectionAdapter() {
-					@Override
-					public void widgetSelected(SelectionEvent event) {
-						if (attributeCombo.getSelectionIndex() > -1) {
-							String sel = attributeCombo.getItem(attributeCombo.getSelectionIndex());
-							attribute.setValue(sel);
-							attributeChanged(attribute);
-							attributeCombo.clearSelection();
-						}
-					}
-				});
-				currentCol += 2;
-			} else {
-				Label label = createLabel(attributesComposite, attribute);
-				GridDataFactory.fillDefaults().align(SWT.RIGHT, SWT.CENTER).applyTo(label);
-				Composite textFieldComposite = toolkit.createComposite(attributesComposite);
-				GridLayout textLayout = new GridLayout();
-				textLayout.marginWidth = 1;
-				textLayout.marginHeight = 2;
-				textFieldComposite.setLayout(textLayout);
-				GridData textData = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
-				textData.horizontalSpan = 1;
-				textData.widthHint = 135;
-
-				if (attribute.isReadOnly()) {
-					final Text text = createTextField(textFieldComposite, attribute, SWT.FLAT | SWT.READ_ONLY);
-					text.setLayoutData(textData);
-				} else {
-					final Text text = createTextField(textFieldComposite, attribute, SWT.FLAT);
-					// text.setFont(COMMENT_FONT);
-					text.setLayoutData(textData);
-					toolkit.paintBordersFor(textFieldComposite);
-					text.setData(attribute);
-
-					if (hasContentAssist(attribute)) {
-						ContentAssistCommandAdapter adapter = applyContentAssist(text,
-								createContentProposalProvider(attribute));
-
-						ILabelProvider propsalLabelProvider = createProposalLabelProvider(attribute);
-						if (propsalLabelProvider != null) {
-							adapter.setLabelProvider(propsalLabelProvider);
-						}
-						adapter.setProposalAcceptanceStyle(ContentProposalAdapter.PROPOSAL_REPLACE);
-					}
-				}
-
-				currentCol += 2;
-			}
-
-			if (currentCol > numColumns) {
-				currentCol -= numColumns;
-			}
-		}
-
-		// make sure that we are in the first column
-		if (currentCol > 1) {
-			while (currentCol <= numColumns) {
-				toolkit.createLabel(attributesComposite, "");
-				currentCol++;
-			}
-		}
-
-		toolkit.paintBordersFor(attributesComposite);
-	}
-
-	/**
-	 * Adds a related bugs section to the bug editor
-	 */
-	protected void createRelatedBugsSection(Composite composite) {
-//		Section relatedBugsSection = createSection(editorComposite, getSectionLabel(SECTION_NAME.RELATEDBUGS_SECTION));
-//		Composite relatedBugsComposite = toolkit.createComposite(relatedBugsSection);
-//		relatedBugsComposite.setLayout(new GridLayout(4, false));
-//		relatedBugsComposite.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));
-//		relatedBugsSection.setClient(relatedBugsComposite);
-//		relatedBugsSection.setExpanded(repositoryTask == null);
-//
-//		List<AbstractDuplicateDetector> allCollectors = new ArrayList<AbstractDuplicateDetector>();
-//		if (getDuplicateSearchCollectorsList() != null) {
-//			allCollectors.addAll(getDuplicateSearchCollectorsList());
-//		}
-//		if (!allCollectors.isEmpty()) {
-//			duplicateDetectorLabel = new Label(relatedBugsComposite, SWT.LEFT);
-//			duplicateDetectorLabel.setText(LABEL_SELECT_DETECTOR);
-//
-//			duplicateDetectorChooser = new CCombo(relatedBugsComposite, SWT.FLAT | SWT.READ_ONLY | SWT.BORDER);
-//
-//			duplicateDetectorChooser.setLayoutData(GridDataFactory.swtDefaults().hint(150, SWT.DEFAULT).create());
-//			duplicateDetectorChooser.setFont(TEXT_FONT);
-//
-//			Collections.sort(allCollectors, new Comparator<AbstractDuplicateDetector>() {
-//
-//				public int compare(AbstractDuplicateDetector c1, AbstractDuplicateDetector c2) {
-//					return c1.getName().compareToIgnoreCase(c2.getName());
-//				}
-//
-//			});
-//
-//			for (AbstractDuplicateDetector detector : allCollectors) {
-//				duplicateDetectorChooser.add(detector.getName());
-//			}
-//
-//			duplicateDetectorChooser.select(0);
-//			duplicateDetectorChooser.setEnabled(true);
-//			duplicateDetectorChooser.setData(allCollectors);
-//
-//			if (allCollectors.size() > 0) {
-//
-//				searchForDuplicates = toolkit.createButton(relatedBugsComposite, LABEL_SEARCH_DUPS, SWT.NONE);
-//				GridData searchDuplicatesButtonData = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
-//				searchForDuplicates.setLayoutData(searchDuplicatesButtonData);
-//				searchForDuplicates.addListener(SWT.Selection, new Listener() {
-//					public void handleEvent(Event e) {
-//						searchForDuplicates();
-//					}
-//				});
-//			}
-//		} else {
-//			Label label = new Label(relatedBugsComposite, SWT.LEFT);
-//			label.setText(LABEL_NO_DETECTOR);
-//		}
-	}
-
-	/**
-	 * @since 3.0
-	 */
-	protected AbstractLegacyDuplicateDetector getDuplicateDetector(String name) {
-		String duplicateDetectorName = name.equals("default") ? "Stack Trace" : name;
-		Set<AbstractLegacyDuplicateDetector> allDetectors = getDuplicateDetectorList();
-
-		for (AbstractLegacyDuplicateDetector detector : allDetectors) {
-			if (detector.getName().equals(duplicateDetectorName)) {
-				return detector;
-			}
-		}
-		// didn't find it
-		return null;
-	}
-
-	/**
-	 * @since 3.0
-	 */
-	protected Set<AbstractLegacyDuplicateDetector> getDuplicateDetectorList() {
-		Set<AbstractLegacyDuplicateDetector> duplicateDetectors = new HashSet<AbstractLegacyDuplicateDetector>();
-		for (AbstractDuplicateDetector abstractDuplicateDetector : TasksUiPlugin.getDefault()
-				.getDuplicateSearchCollectorsList()) {
-			if (abstractDuplicateDetector instanceof AbstractLegacyDuplicateDetector
-					&& (abstractDuplicateDetector.getConnectorKind() == null || abstractDuplicateDetector.getConnectorKind()
-							.equals(getConnector().getConnectorKind()))) {
-				duplicateDetectors.add((AbstractLegacyDuplicateDetector) abstractDuplicateDetector);
-			}
-		}
-		return duplicateDetectors;
-	}
-
-	public boolean searchForDuplicates() {
-		String duplicateDetectorName = duplicateDetectorChooser.getItem(duplicateDetectorChooser.getSelectionIndex());
-		AbstractLegacyDuplicateDetector duplicateDetector = getDuplicateDetector(duplicateDetectorName);
-		if (duplicateDetector != null) {
-			RepositoryQuery duplicatesQuery = duplicateDetector.getDuplicatesQuery(repository, taskData);
-			if (duplicatesQuery != null) {
-				SearchHitCollector collector = new SearchHitCollector(TasksUiInternal.getTaskList(), repository,
-						duplicatesQuery);
-				NewSearchUI.runQueryInBackground(collector);
-				return true;
-			}
-		}
-
-		return false;
-	}
-
-	/**
-	 * Adds content assist to the given text field.
-	 * 
-	 * @param text
-	 *            text field to decorate.
-	 * @param proposalProvider
-	 *            instance providing content proposals
-	 * @return the ContentAssistCommandAdapter for the field.
-	 */
-	protected ContentAssistCommandAdapter applyContentAssist(Text text, IContentProposalProvider proposalProvider) {
-		ControlDecoration controlDecoration = new ControlDecoration(text, (SWT.TOP | SWT.LEFT));
-		controlDecoration.setMarginWidth(0);
-		controlDecoration.setShowHover(true);
-		controlDecoration.setShowOnlyOnFocus(true);
-
-		FieldDecoration contentProposalImage = FieldDecorationRegistry.getDefault().getFieldDecoration(
-				FieldDecorationRegistry.DEC_CONTENT_PROPOSAL);
-		controlDecoration.setImage(contentProposalImage.getImage());
-
-		TextContentAdapter textContentAdapter = new TextContentAdapter();
-
-		ContentAssistCommandAdapter adapter = new ContentAssistCommandAdapter(text, textContentAdapter,
-				proposalProvider, "org.eclipse.ui.edit.text.contentAssist.proposals", new char[0]);
-
-		IBindingService bindingService = (IBindingService) PlatformUI.getWorkbench().getService(IBindingService.class);
-		controlDecoration.setDescriptionText(NLS.bind("Content Assist Available ({0})",
-				bindingService.getBestActiveBindingFormattedFor(adapter.getCommandId())));
-
-		return adapter;
-	}
-
-	/**
-	 * Creates an IContentProposalProvider to provide content assist proposals for the given attribute.
-	 * 
-	 * @param attribute
-	 *            attribute for which to provide content assist.
-	 * @return the IContentProposalProvider.
-	 */
-	protected IContentProposalProvider createContentProposalProvider(RepositoryTaskAttribute attribute) {
-		return new PersonProposalProvider(repositoryTask, taskData);
-	}
-
-	/**
-	 * Creates an IContentProposalProvider to provide content assist proposals for the given operation.
-	 * 
-	 * @param operation
-	 *            operation for which to provide content assist.
-	 * @return the IContentProposalProvider.
-	 */
-	protected IContentProposalProvider createContentProposalProvider(RepositoryOperation operation) {
-
-		return new PersonProposalProvider(repositoryTask, taskData);
-	}
-
-	protected ILabelProvider createProposalLabelProvider(RepositoryTaskAttribute attribute) {
-		return new PersonProposalLabelProvider();
-	}
-
-	protected ILabelProvider createProposalLabelProvider(RepositoryOperation operation) {
-
-		return new PersonProposalLabelProvider();
-	}
-
-	/**
-	 * Called to check if there's content assist available for the given attribute.
-	 * 
-	 * @param attribute
-	 *            the attribute
-	 * @return true if content assist is available for the specified attribute.
-	 */
-	protected boolean hasContentAssist(RepositoryTaskAttribute attribute) {
-		return false;
-	}
-
-	/**
-	 * Called to check if there's content assist available for the given operation.
-	 * 
-	 * @param operation
-	 *            the operation
-	 * @return true if content assist is available for the specified operation.
-	 */
-	protected boolean hasContentAssist(RepositoryOperation operation) {
-		return false;
-	}
-
-	/**
-	 * Adds a text editor with spell checking enabled to display and edit the task's summary.
-	 * 
-	 * @author Raphael Ackermann (modifications) (bug 195514)
-	 * @param attributesComposite
-	 *            The composite to add the text editor to.
-	 */
-	protected void addSummaryText(Composite attributesComposite) {
-		Composite summaryComposite = toolkit.createComposite(attributesComposite);
-		GridLayout summaryLayout = new GridLayout(2, false);
-		summaryLayout.verticalSpacing = 0;
-		summaryLayout.marginHeight = 2;
-		summaryComposite.setLayout(summaryLayout);
-		GridDataFactory.fillDefaults().grab(true, false).applyTo(summaryComposite);
-
-		if (taskData != null) {
-			RepositoryTaskAttribute attribute = taskData.getAttribute(RepositoryTaskAttribute.SUMMARY);
-			if (attribute == null) {
-				taskData.setAttributeValue(RepositoryTaskAttribute.SUMMARY, "");
-				attribute = taskData.getAttribute(RepositoryTaskAttribute.SUMMARY);
-			}
-
-			final RepositoryTaskAttribute summaryAttribute = attribute;
-
-			summaryTextViewer = addTextEditor(repository, summaryComposite, attribute.getValue(), true, SWT.FLAT
-					| SWT.SINGLE);
-			Composite hiddenComposite = new Composite(summaryComposite, SWT.NONE);
-			hiddenComposite.setLayout(new GridLayout());
-			GridData hiddenLayout = new GridData();
-			hiddenLayout.exclude = true;
-			hiddenComposite.setLayoutData(hiddenLayout);
-
-			// bugg#210695 - work around for 2.0 api breakage
-			summaryText = new Text(hiddenComposite, SWT.NONE);
-			summaryText.setText(attribute.getValue());
-			summaryText.addKeyListener(new KeyListener() {
-
-				public void keyPressed(KeyEvent e) {
-					if (summaryTextViewer != null && !summaryTextViewer.getTextWidget().isDisposed()) {
-						String newValue = summaryText.getText();
-						String oldValue = summaryTextViewer.getTextWidget().getText();
-						if (!newValue.equals(oldValue)) {
-							summaryTextViewer.getTextWidget().setText(newValue);
-							summaryAttribute.setValue(newValue);
-							attributeChanged(summaryAttribute);
-						}
-					}
-				}
-
-				public void keyReleased(KeyEvent e) {
-					// ignore
-				}
-			});
-
-			summaryText.addFocusListener(new FocusListener() {
-
-				public void focusGained(FocusEvent e) {
-					summaryTextViewer.getTextWidget().setFocus();
-				}
-
-				public void focusLost(FocusEvent e) {
-					// ignore
-				}
-			});
-
-			summaryTextViewer.setEditable(true);
-			summaryTextViewer.getTextWidget().setIndent(2);
-			GridDataFactory.fillDefaults().grab(true, false).applyTo(summaryTextViewer.getControl());
-
-			if (hasChanged(attribute)) {
-				summaryTextViewer.getTextWidget().setBackground(colorIncoming);
-			}
-			summaryTextViewer.getControl().setData(FormToolkit.KEY_DRAW_BORDER, FormToolkit.TEXT_BORDER);
-
-			summaryTextViewer.addTextListener(new ITextListener() {
-				public void textChanged(TextEvent event) {
-					String newValue = summaryTextViewer.getTextWidget().getText();
-					if (!newValue.equals(summaryAttribute.getValue())) {
-						summaryAttribute.setValue(newValue);
-						attributeChanged(summaryAttribute);
-					}
-					if (summaryText != null && !newValue.equals(summaryText.getText())) {
-						summaryText.setText(newValue);
-					}
-				}
-			});
-
-		}
-		toolkit.paintBordersFor(summaryComposite);
-	}
-
-	protected boolean supportsAttachmentDelete() {
-		return false;
-	}
-
-	protected void deleteAttachment(RepositoryAttachment attachment) {
-
-	}
-
-	protected void createAttachmentLayout(Composite composite) {
-		// TODO: expand to show new attachments
-		Section section = createSection(composite, getSectionLabel(SECTION_NAME.ATTACHMENTS_SECTION), false);
-		section.setText(section.getText() + " (" + taskData.getAttachments().size() + ")");
-		final Composite attachmentsComposite = toolkit.createComposite(section);
-		attachmentsComposite.setLayout(new GridLayout(1, false));
-		attachmentsComposite.setLayoutData(new GridData(GridData.FILL_BOTH));
-		section.setClient(attachmentsComposite);
-
-		if (taskData.getAttachments().size() > 0) {
-
-			attachmentsTable = toolkit.createTable(attachmentsComposite, SWT.MULTI | SWT.BORDER | SWT.FULL_SELECTION);
-			attachmentsTable.setLinesVisible(true);
-			attachmentsTable.setHeaderVisible(true);
-			attachmentsTable.setLayout(new GridLayout());
-			GridData tableGridData = new GridData(SWT.FILL, SWT.FILL, true, true);
-			attachmentsTable.setLayoutData(tableGridData);
-
-			for (int i = 0; i < attachmentsColumns.length; i++) {
-				TableColumn column = new TableColumn(attachmentsTable, SWT.LEFT, i);
-				column.setText(attachmentsColumns[i]);
-				column.setWidth(attachmentsColumnWidths[i]);
-			}
-			attachmentsTable.getColumn(3).setAlignment(SWT.RIGHT);
-
-			attachmentsTableViewer = new TableViewer(attachmentsTable);
-			attachmentsTableViewer.setUseHashlookup(true);
-			attachmentsTableViewer.setColumnProperties(attachmentsColumns);
-			ColumnViewerToolTipSupport.enableFor(attachmentsTableViewer, ToolTip.NO_RECREATE);
-
-			final AbstractTaskDataHandler offlineHandler = connector.getLegacyTaskDataHandler();
-			if (offlineHandler != null) {
-				attachmentsTableViewer.setSorter(new ViewerSorter() {
-					@Override
-					public int compare(Viewer viewer, Object e1, Object e2) {
-						RepositoryAttachment attachment1 = (RepositoryAttachment) e1;
-						RepositoryAttachment attachment2 = (RepositoryAttachment) e2;
-						Date created1 = taskData.getAttributeFactory().getDateForAttributeType(
-								RepositoryTaskAttribute.ATTACHMENT_DATE, attachment1.getDateCreated());
-						Date created2 = taskData.getAttributeFactory().getDateForAttributeType(
-								RepositoryTaskAttribute.ATTACHMENT_DATE, attachment2.getDateCreated());
-						if (created1 != null && created2 != null) {
-							return created1.compareTo(created2);
-						} else if (created1 == null && created2 != null) {
-							return -1;
-						} else if (created1 != null && created2 == null) {
-							return 1;
-						} else {
-							return 0;
-						}
-					}
-				});
-			}
-
-			attachmentsTableViewer.setContentProvider(new AttachmentsTableContentProvider(taskData.getAttachments()));
-
-			attachmentsTableViewer.setLabelProvider(new AttachmentTableLabelProvider(this, new LabelProvider(),
-					PlatformUI.getWorkbench().getDecoratorManager().getLabelDecorator()));
-
-			attachmentsTableViewer.addDoubleClickListener(new IDoubleClickListener() {
-				public void doubleClick(DoubleClickEvent event) {
-					if (!event.getSelection().isEmpty()) {
-						StructuredSelection selection = (StructuredSelection) event.getSelection();
-						RepositoryAttachment attachment = (RepositoryAttachment) selection.getFirstElement();
-						TasksUiUtil.openUrl(attachment.getUrl());
-					}
-				}
-			});
-
-			attachmentsTableViewer.setInput(taskData);
-
-			final Action openWithBrowserAction = new Action(LABEL_BROWSER) {
-				@Override
-				public void run() {
-					RepositoryAttachment attachment = (RepositoryAttachment) (((StructuredSelection) attachmentsTableViewer.getSelection()).getFirstElement());
-					if (attachment != null) {
-						TasksUiUtil.openUrl(attachment.getUrl());
-					}
-				}
-			};
-
-			final Action openWithDefaultAction = new Action(LABEL_DEFAULT_EDITOR) {
-				@Override
-				public void run() {
-					// browser shortcut
-					RepositoryAttachment attachment = (RepositoryAttachment) (((StructuredSelection) attachmentsTableViewer.getSelection()).getFirstElement());
-					if (attachment == null) {
-						return;
-					}
-
-					if (attachment.getContentType().endsWith(CTYPE_HTML)) {
-						TasksUiUtil.openUrl(attachment.getUrl());
-						return;
-					}
-
-					IStorageEditorInput input = new RepositoryAttachmentEditorInput(repository, attachment);
-					IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
-					if (page == null) {
-						return;
-					}
-					IEditorDescriptor desc = PlatformUI.getWorkbench().getEditorRegistry().getDefaultEditor(
-							input.getName());
-					try {
-						page.openEditor(input, desc.getId());
-					} catch (PartInitException e) {
-						StatusHandler.log(new Status(IStatus.ERROR, TasksUiPlugin.ID_PLUGIN,
-								"Unable to open editor for: " + attachment.getDescription(), e));
-					}
-				}
-			};
-
-			final Action openWithTextEditorAction = new Action(LABEL_TEXT_EDITOR) {
-				@Override
-				public void run() {
-					RepositoryAttachment attachment = (RepositoryAttachment) (((StructuredSelection) attachmentsTableViewer.getSelection()).getFirstElement());
-					IStorageEditorInput input = new RepositoryAttachmentEditorInput(repository, attachment);
-					IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
-					if (page == null) {
-						return;
-					}
-
-					try {
-						page.openEditor(input, "org.eclipse.ui.DefaultTextEditor");
-					} catch (PartInitException e) {
-						StatusHandler.log(new Status(IStatus.ERROR, TasksUiPlugin.ID_PLUGIN,
-								"Unable to open editor for: " + attachment.getDescription(), e));
-					}
-				}
-			};
-
-			final Action saveAction = new Action(LABEL_SAVE) {
-				@Override
-				public void run() {
-					ITaskAttachment attachment = (ITaskAttachment) (((StructuredSelection) attachmentsTableViewer.getSelection()).getFirstElement());
-					/* Launch Browser */
-					FileDialog fileChooser = new FileDialog(attachmentsTable.getShell(), SWT.SAVE);
-					String fname = attachment.getFileName();
-					// Default name if none is found
-					if (fname.equals("")) {
-						String ctype = attachment.getContentType();
-						if (ctype.endsWith(CTYPE_HTML)) {
-							fname = ATTACHMENT_DEFAULT_NAME + ".html";
-						} else if (ctype.startsWith(CTYPE_TEXT)) {
-							fname = ATTACHMENT_DEFAULT_NAME + ".txt";
-						} else if (ctype.endsWith(CTYPE_OCTET_STREAM)) {
-							fname = ATTACHMENT_DEFAULT_NAME;
-						} else if (ctype.endsWith(CTYPE_ZIP)) {
-							fname = ATTACHMENT_DEFAULT_NAME + "." + CTYPE_ZIP;
-						} else {
-							fname = ATTACHMENT_DEFAULT_NAME + "." + ctype.substring(ctype.indexOf("/") + 1);
-						}
-					}
-					fileChooser.setFileName(fname);
-					String filePath = fileChooser.open();
-					// Check if the dialog was canceled or an error occurred
-					if (filePath == null) {
-						return;
-					}
-
-					DownloadAttachmentJob job = new DownloadAttachmentJob(attachment, new File(filePath));
-					job.setUser(true);
-					job.schedule();
-				}
-			};
-
-			final Action copyURLToClipAction = new Action(LABEL_COPY_URL_TO_CLIPBOARD) {
-				@Override
-				public void run() {
-					RepositoryAttachment attachment = (RepositoryAttachment) (((StructuredSelection) attachmentsTableViewer.getSelection()).getFirstElement());
-					Clipboard clip = new Clipboard(PlatformUI.getWorkbench().getDisplay());
-					clip.setContents(new Object[] { attachment.getUrl() },
-							new Transfer[] { TextTransfer.getInstance() });
-					clip.dispose();
-				}
-			};
-
-			final Action copyToClipAction = new Action(LABEL_COPY_TO_CLIPBOARD) {
-				@Override
-				public void run() {
-					RepositoryAttachment attachment = (RepositoryAttachment) (((StructuredSelection) attachmentsTableViewer.getSelection()).getFirstElement());
-					CopyAttachmentToClipboardJob job = new CopyAttachmentToClipboardJob(attachment);
-					job.setUser(true);
-					job.schedule();
-				}
-			};
-
-			final MenuManager popupMenu = new MenuManager();
-			final Menu menu = popupMenu.createContextMenu(attachmentsTable);
-			attachmentsTable.setMenu(menu);
-			final MenuManager openMenu = new MenuManager("Open With");
-			popupMenu.addMenuListener(new IMenuListener() {
-				public void menuAboutToShow(IMenuManager manager) {
-					popupMenu.removeAll();
-
-					IStructuredSelection selection = (IStructuredSelection) attachmentsTableViewer.getSelection();
-					if (selection.isEmpty()) {
-						return;
-					}
-
-					if (selection.size() == 1) {
-						RepositoryAttachment att = (RepositoryAttachment) ((StructuredSelection) selection).getFirstElement();
-
-						// reinitialize open menu
-						popupMenu.add(openMenu);
-						openMenu.removeAll();
-
-						IStorageEditorInput input = new RepositoryAttachmentEditorInput(repository, att);
-						IEditorDescriptor desc = PlatformUI.getWorkbench().getEditorRegistry().getDefaultEditor(
-								input.getName());
-						if (desc != null) {
-							openMenu.add(openWithDefaultAction);
-						}
-						openMenu.add(openWithBrowserAction);
-						openMenu.add(openWithTextEditorAction);
-
-						popupMenu.add(new Separator());
-						popupMenu.add(saveAction);
-
-						popupMenu.add(copyURLToClipAction);
-						if (att.getContentType().startsWith(CTYPE_TEXT) || att.getContentType().endsWith("xml")) {
-							popupMenu.add(copyToClipAction);
-						}
-					}
-					popupMenu.add(new Separator("actions"));
-
-					// TODO: use workbench mechanism for this?
-					ObjectActionContributorManager.getManager().contributeObjectActions(
-							AbstractRepositoryTaskEditor.this, popupMenu, attachmentsTableViewer);
-				}
-			});
-		} else {
-			Label label = toolkit.createLabel(attachmentsComposite, "No attachments");
-			registerDropListener(label);
-		}
-
-		final Composite attachmentControlsComposite = toolkit.createComposite(attachmentsComposite);
-		attachmentControlsComposite.setLayout(new GridLayout(2, false));
-		attachmentControlsComposite.setLayoutData(new GridData(GridData.BEGINNING));
-
-		Button attachFileButton = toolkit.createButton(attachmentControlsComposite, AttachAction.LABEL, SWT.PUSH);
-		attachFileButton.setImage(WorkbenchImages.getImage(ISharedImages.IMG_OBJ_FILE));
-
-		Button attachScreenshotButton = toolkit.createButton(attachmentControlsComposite, AttachScreenshotAction.LABEL,
-				SWT.PUSH);
-		attachScreenshotButton.setImage(CommonImages.getImage(CommonImages.IMAGE_CAPTURE));
-
-		final ITask task = TasksUiInternal.getTaskList().getTask(repository.getRepositoryUrl(), taskData.getTaskId());
-		if (task == null) {
-			attachFileButton.setEnabled(false);
-			attachScreenshotButton.setEnabled(false);
-		}
-
-		attachFileButton.addSelectionListener(new SelectionListener() {
-			public void widgetDefaultSelected(SelectionEvent e) {
-				// ignore
-			}
-
-			public void widgetSelected(SelectionEvent e) {
-				AbstractTaskEditorAction attachFileAction = new AttachAction();
-				attachFileAction.selectionChanged(new StructuredSelection(task));
-				attachFileAction.setEditor(parentEditor);
-				attachFileAction.run();
-			}
-		});
-
-		attachScreenshotButton.addSelectionListener(new SelectionListener() {
-			public void widgetDefaultSelected(SelectionEvent e) {
-				// ignore
-			}
-
-			public void widgetSelected(SelectionEvent e) {
-				AttachScreenshotAction attachScreenshotAction = new AttachScreenshotAction();
-				attachScreenshotAction.selectionChanged(new StructuredSelection(task));
-				attachScreenshotAction.setEditor(parentEditor);
-				attachScreenshotAction.run();
-			}
-		});
-
-		Button deleteAttachmentButton = null;
-		if (supportsAttachmentDelete()) {
-			deleteAttachmentButton = toolkit.createButton(attachmentControlsComposite, "Delete Attachment...", SWT.PUSH);
-
-			deleteAttachmentButton.addSelectionListener(new SelectionListener() {
-				public void widgetDefaultSelected(SelectionEvent e) {
-					// ignore
-				}
-
-				public void widgetSelected(SelectionEvent e) {
-					ITask task = TasksUiInternal.getTaskList().getTask(repository.getRepositoryUrl(),
-							taskData.getTaskId());
-					if (task == null) {
-						// Should not happen
-						return;
-					}
-					if (AbstractRepositoryTaskEditor.this.isDirty
-							|| task.getSynchronizationState().equals(SynchronizationState.OUTGOING)) {
-						MessageDialog.openInformation(attachmentsComposite.getShell(),
-								"Task not synchronized or dirty editor",
-								"Commit edits or synchronize task before deleting attachments.");
-						return;
-					} else {
-						if (attachmentsTableViewer != null
-								&& attachmentsTableViewer.getSelection() != null
-								&& ((StructuredSelection) attachmentsTableViewer.getSelection()).getFirstElement() != null) {
-							RepositoryAttachment attachment = (RepositoryAttachment) (((StructuredSelection) attachmentsTableViewer.getSelection()).getFirstElement());
-							deleteAttachment(attachment);
-							submitToRepository();
-						}
-					}
-				}
-			});
-
-		}
-		registerDropListener(section);
-		registerDropListener(attachmentsComposite);
-		registerDropListener(attachFileButton);
-		if (supportsAttachmentDelete()) {
-			registerDropListener(deleteAttachmentButton);
-		}
-	}
-
-	private void registerDropListener(final Control control) {
-		DropTarget target = new DropTarget(control, DND.DROP_COPY | DND.DROP_DEFAULT);
-		final TextTransfer textTransfer = TextTransfer.getInstance();
-		final FileTransfer fileTransfer = FileTransfer.getInstance();
-		Transfer[] types = new Transfer[] { textTransfer, fileTransfer };
-		target.setTransfer(types);
-
-		// Adapted from eclipse.org DND Article by Veronika Irvine, IBM OTI Labs
-		// http://www.eclipse.org/articles/Article-SWT-DND/DND-in-SWT.html#_dt10D
-		target.addDropListener(new RepositoryTaskEditorDropListener(this, repository, taskData, fileTransfer,
-				textTransfer, control));
-	}
-
-	protected void createDescriptionLayout(Composite composite) {
-		Section descriptionSection = createSection(composite, getSectionLabel(SECTION_NAME.DESCRIPTION_SECTION));
-		final Composite sectionComposite = toolkit.createComposite(descriptionSection);
-		descriptionSection.setClient(sectionComposite);
-		GridLayout addCommentsLayout = new GridLayout();
-		addCommentsLayout.numColumns = 1;
-		sectionComposite.setLayout(addCommentsLayout);
-
-		RepositoryTaskAttribute attribute = taskData.getDescriptionAttribute();
-		if (attribute != null && !attribute.isReadOnly()) {
-			if (getRenderingEngine() != null) {
-				// composite with StackLayout to hold text editor and preview widget
-				Composite descriptionComposite = toolkit.createComposite(sectionComposite);
-				descriptionComposite.setData(FormToolkit.KEY_DRAW_BORDER, FormToolkit.TEXT_BORDER);
-				GridData descriptionGridData = new GridData(GridData.FILL_BOTH);
-				descriptionGridData.widthHint = DESCRIPTION_WIDTH;
-				descriptionGridData.minimumHeight = DESCRIPTION_HEIGHT;
-				descriptionGridData.grabExcessHorizontalSpace = true;
-				descriptionComposite.setLayoutData(descriptionGridData);
-				final StackLayout descriptionLayout = new StackLayout();
-				descriptionComposite.setLayout(descriptionLayout);
-
-				descriptionTextViewer = addTextEditor(repository, descriptionComposite, taskData.getDescription(),
-						true, SWT.FLAT | SWT.MULTI | SWT.WRAP | SWT.V_SCROLL);
-				descriptionLayout.topControl = descriptionTextViewer.getControl();
-				descriptionComposite.layout();
-
-				// composite for edit/preview button
-				Composite buttonComposite = toolkit.createComposite(sectionComposite);
-				buttonComposite.setLayout(new GridLayout());
-				createPreviewButton(buttonComposite, descriptionTextViewer, descriptionComposite, descriptionLayout);
-			} else {
-				descriptionTextViewer = addTextEditor(repository, sectionComposite, taskData.getDescription(), true,
-						SWT.FLAT | SWT.MULTI | SWT.WRAP | SWT.V_SCROLL);
-				final GridData gd = new GridData(GridData.FILL_HORIZONTAL);
-				// wrap text at this margin, see comment below
-				gd.widthHint = DESCRIPTION_WIDTH;
-				gd.minimumHeight = DESCRIPTION_HEIGHT;
-				gd.grabExcessHorizontalSpace = true;
-				descriptionTextViewer.getControl().setLayoutData(gd);
-				descriptionTextViewer.getControl().setData(FormToolkit.KEY_DRAW_BORDER, FormToolkit.TEXT_BORDER);
-				// the goal is to make the text viewer as big as the text so it does not require scrolling when first drawn 
-				// on screen: when the descriptionTextViewer calculates its height it wraps the text according to the widthHint 
-				// which does not reflect the actual size of the widget causing the widget to be taller 
-				// (actual width > gd.widhtHint) or shorter (actual width < gd.widthHint) therefore the widthHint is tweaked 
-				// once in the listener  
-				sectionComposite.addControlListener(new ControlAdapter() {
-					private boolean first;
-
-					@Override
-					public void controlResized(ControlEvent e) {
-						if (!first) {
-							first = true;
-							int width = sectionComposite.getSize().x;
-							Point size = descriptionTextViewer.getTextWidget().computeSize(width, SWT.DEFAULT, true);
-							// limit width to parent widget
-							gd.widthHint = width;
-							// limit height to avoid dynamic resizing of the text widget
-							gd.heightHint = Math.min(Math.max(DESCRIPTION_HEIGHT, size.y), DESCRIPTION_HEIGHT * 4);
-							sectionComposite.layout();
-						}
-					}
-				});
-			}
-			descriptionTextViewer.setEditable(true);
-			descriptionTextViewer.addTextListener(new ITextListener() {
-				public void textChanged(TextEvent event) {
-					String newValue = descriptionTextViewer.getTextWidget().getText();
-					RepositoryTaskAttribute attribute = taskData.getAttribute(RepositoryTaskAttribute.DESCRIPTION);
-					if (attribute != null && !newValue.equals(attribute.getValue())) {
-						attribute.setValue(newValue);
-						attributeChanged(attribute);
-						taskData.setDescription(newValue);
-					}
-				}
-			});
-			StyledText styledText = descriptionTextViewer.getTextWidget();
-			controlBySelectableObject.put(taskData.getDescription(), styledText);
-		} else {
-			String text = taskData.getDescription();
-			descriptionTextViewer = addTextViewer(repository, sectionComposite, text, SWT.MULTI | SWT.WRAP);
-			StyledText styledText = descriptionTextViewer.getTextWidget();
-			GridDataFactory.fillDefaults().hint(DESCRIPTION_WIDTH, SWT.DEFAULT).applyTo(
-					descriptionTextViewer.getControl());
-
-			controlBySelectableObject.put(text, styledText);
-		}
-
-		if (hasChanged(taskData.getAttribute(RepositoryTaskAttribute.DESCRIPTION))) {
-			descriptionTextViewer.getTextWidget().setBackground(colorIncoming);
-		}
-		descriptionTextViewer.getTextWidget().addListener(SWT.FocusIn, new DescriptionListener());
-
-		Composite replyComp = toolkit.createComposite(descriptionSection);
-		replyComp.setLayout(new RowLayout());
-		replyComp.setBackground(null);
-
-		createReplyHyperlink(0, replyComp, taskData.getDescription());
-		descriptionSection.setTextClient(replyComp);
-		addDuplicateDetection(sectionComposite);
-		toolkit.paintBordersFor(sectionComposite);
-
-		if (descriptionTextViewer.isEditable()) {
-			descriptionSection.setExpanded(true);
-		}
-	}
-
-	protected ImageHyperlink createReplyHyperlink(final int commentNum, Composite composite, final String commentBody) {
-		final ImageHyperlink replyLink = new ImageHyperlink(composite, SWT.NULL);
-		toolkit.adapt(replyLink, true, true);
-		replyLink.setImage(CommonImages.getImage(TasksUiImages.COMMENT_REPLY));
-		replyLink.setToolTipText(LABEL_REPLY);
-		// no need for the background - transparency will take care of it
-		replyLink.setBackground(null);
-		// replyLink.setBackground(section.getTitleBarGradientBackground());
-		replyLink.addHyperlinkListener(new HyperlinkAdapter() {
-			@Override
-			public void linkActivated(HyperlinkEvent e) {
-				String oldText = newCommentTextViewer.getDocument().get();
-				StringBuilder strBuilder = new StringBuilder();
-				strBuilder.append(oldText);
-				if (strBuilder.length() != 0) {
-					strBuilder.append("\n");
-				}
-				strBuilder.append(" (In reply to comment #" + commentNum + ")\n");
-				CommentQuoter quoter = new CommentQuoter();
-				strBuilder.append(quoter.quote(commentBody));
-				newCommentTextViewer.getDocument().set(strBuilder.toString());
-				RepositoryTaskAttribute attribute = taskData.getAttribute(RepositoryTaskAttribute.COMMENT_NEW);
-				if (attribute != null) {
-					attribute.setValue(strBuilder.toString());
-					attributeChanged(attribute);
-				}
-				selectNewComment();
-				newCommentTextViewer.getTextWidget().setCaretOffset(strBuilder.length());
-			}
-		});
-
-		return replyLink;
-	}
-
-	protected void addDuplicateDetection(Composite composite) {
-		List<AbstractLegacyDuplicateDetector> allCollectors = new ArrayList<AbstractLegacyDuplicateDetector>();
-		if (getDuplicateDetectorList() != null) {
-			allCollectors.addAll(getDuplicateDetectorList());
-		}
-		if (!allCollectors.isEmpty()) {
-			Section duplicatesSection = toolkit.createSection(composite, ExpandableComposite.TWISTIE
-					| ExpandableComposite.SHORT_TITLE_BAR);
-			duplicatesSection.setText(LABEL_SELECT_DETECTOR);
-			duplicatesSection.setLayout(new GridLayout());
-			GridDataFactory.fillDefaults().indent(SWT.DEFAULT, 15).applyTo(duplicatesSection);
-			Composite relatedBugsComposite = toolkit.createComposite(duplicatesSection);
-			relatedBugsComposite.setLayout(new GridLayout(4, false));
-			relatedBugsComposite.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));
-			duplicatesSection.setClient(relatedBugsComposite);
-			duplicateDetectorLabel = new Label(relatedBugsComposite, SWT.LEFT);
-			duplicateDetectorLabel.setText("Detector:");
-
-			duplicateDetectorChooser = new CCombo(relatedBugsComposite, SWT.FLAT | SWT.READ_ONLY);
-			toolkit.adapt(duplicateDetectorChooser, true, true);
-			duplicateDetectorChooser.setData(FormToolkit.KEY_DRAW_BORDER, FormToolkit.TEXT_BORDER);
-			duplicateDetectorChooser.setFont(TEXT_FONT);
-			duplicateDetectorChooser.setLayoutData(GridDataFactory.swtDefaults().hint(150, SWT.DEFAULT).create());
-
-			Collections.sort(allCollectors, new Comparator<AbstractLegacyDuplicateDetector>() {
-
-				public int compare(AbstractLegacyDuplicateDetector c1, AbstractLegacyDuplicateDetector c2) {
-					return c1.getName().compareToIgnoreCase(c2.getName());
-				}
-
-			});
-
-			for (AbstractLegacyDuplicateDetector detector : allCollectors) {
-				duplicateDetectorChooser.add(detector.getName());
-			}
-
-			duplicateDetectorChooser.select(0);
-			duplicateDetectorChooser.setEnabled(true);
-			duplicateDetectorChooser.setData(allCollectors);
-
-			if (allCollectors.size() > 0) {
-
-				searchForDuplicates = toolkit.createButton(relatedBugsComposite, LABEL_SEARCH_DUPS, SWT.NONE);
-				GridData searchDuplicatesButtonData = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
-				searchForDuplicates.setLayoutData(searchDuplicatesButtonData);
-				searchForDuplicates.addListener(SWT.Selection, new Listener() {
-					public void handleEvent(Event e) {
-						searchForDuplicates();
-					}
-				});
-			}
-//		} else {
-//			Label label = new Label(composite, SWT.LEFT);
-//			label.setText(LABEL_NO_DETECTOR);
-
-			toolkit.paintBordersFor(relatedBugsComposite);
-
-		}
-
-	}
-
-	protected void createCustomAttributeLayout(Composite composite) {
-		// override
-	}
-
-	protected void createPeopleLayout(Composite composite) {
-		Section peopleSection = createSection(composite, getSectionLabel(SECTION_NAME.PEOPLE_SECTION));
-		GridDataFactory.fillDefaults().align(SWT.FILL, SWT.TOP).grab(true, true).applyTo(peopleSection);
-		Composite peopleComposite = toolkit.createComposite(peopleSection);
-		GridLayout layout = new GridLayout(2, false);
-		layout.marginWidth = 5;
-		peopleComposite.setLayout(layout);
-
-		addAssignedTo(peopleComposite);
-		boolean haveRealName = false;
-		RepositoryTaskAttribute reporterAttribute = taskData.getAttribute(RepositoryTaskAttribute.USER_REPORTER_NAME);
-		if (reporterAttribute == null) {
-			reporterAttribute = taskData.getAttribute(RepositoryTaskAttribute.USER_REPORTER);
-		} else {
-			haveRealName = true;
-		}
-		if (reporterAttribute != null) {
-			Label label = createLabel(peopleComposite, reporterAttribute);
-			GridDataFactory.fillDefaults().align(SWT.RIGHT, SWT.CENTER).applyTo(label);
-			Text textField = createTextField(peopleComposite, reporterAttribute, SWT.FLAT | SWT.READ_ONLY);
-			GridDataFactory.fillDefaults().grab(true, false).applyTo(textField);
-			if (haveRealName) {
-				textField.setText(textField.getText() + " <"
-						+ taskData.getAttributeValue(RepositoryTaskAttribute.USER_REPORTER) + ">");
-			}
-		}
-		addSelfToCC(peopleComposite);
-		addCCList(peopleComposite);
-		getManagedForm().getToolkit().paintBordersFor(peopleComposite);
-		peopleSection.setClient(peopleComposite);
-		peopleSection.setEnabled(true);
-	}
-
-	protected void addCCList(Composite attributesComposite) {
-
-		RepositoryTaskAttribute addCCattribute = taskData.getAttribute(RepositoryTaskAttribute.NEW_CC);
-		if (addCCattribute == null) {
-			// TODO: remove once TRAC is priming taskData with NEW_CC attribute
-			taskData.setAttributeValue(RepositoryTaskAttribute.NEW_CC, "");
-			addCCattribute = taskData.getAttribute(RepositoryTaskAttribute.NEW_CC);
-		}
-		if (addCCattribute != null) {
-			Label label = createLabel(attributesComposite, addCCattribute);
-			GridDataFactory.fillDefaults().align(SWT.RIGHT, SWT.CENTER).applyTo(label);
-			Text text = createTextField(attributesComposite, addCCattribute, SWT.FLAT);
-			GridDataFactory.fillDefaults().hint(150, SWT.DEFAULT).applyTo(text);
-
-			if (hasContentAssist(addCCattribute)) {
-				ContentAssistCommandAdapter adapter = applyContentAssist(text,
-						createContentProposalProvider(addCCattribute));
-				ILabelProvider propsalLabelProvider = createProposalLabelProvider(addCCattribute);
-				if (propsalLabelProvider != null) {
-					adapter.setLabelProvider(propsalLabelProvider);
-				}
-				adapter.setProposalAcceptanceStyle(ContentProposalAdapter.PROPOSAL_REPLACE);
-			}
-		}
-
-		RepositoryTaskAttribute CCattribute = taskData.getAttribute(RepositoryTaskAttribute.USER_CC);
-		if (CCattribute != null) {
-			Label label = createLabel(attributesComposite, CCattribute);
-			GridDataFactory.fillDefaults().align(SWT.RIGHT, SWT.TOP).applyTo(label);
-			ccList = new org.eclipse.swt.widgets.List(attributesComposite, SWT.MULTI | SWT.V_SCROLL);// SWT.BORDER
-			ccList.setData(FormToolkit.KEY_DRAW_BORDER, FormToolkit.TEXT_BORDER);
-			ccList.setFont(TEXT_FONT);
-			GridData ccListData = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
-			ccListData.horizontalSpan = 1;
-			ccListData.widthHint = 150;
-			ccListData.heightHint = 95;
-			ccList.setLayoutData(ccListData);
-			if (hasChanged(taskData.getAttribute(RepositoryTaskAttribute.USER_CC))) {
-				ccList.setBackground(colorIncoming);
-			}
-			java.util.List<String> ccs = taskData.getCc();
-			if (ccs != null) {
-				for (String cc : ccs) {
-					ccList.add(cc);
-				}
-			}
-			java.util.List<String> removedCCs = taskData.getAttributeValues(RepositoryTaskAttribute.REMOVE_CC);
-			if (removedCCs != null) {
-				for (String item : removedCCs) {
-					int i = ccList.indexOf(item);
-					if (i != -1) {
-						ccList.select(i);
-					}
-				}
-			}
-			ccList.addSelectionListener(new SelectionListener() {
-
-				public void widgetSelected(SelectionEvent e) {
-					for (String cc : ccList.getItems()) {
-						int index = ccList.indexOf(cc);
-						if (ccList.isSelected(index)) {
-							List<String> remove = taskData.getAttributeValues(RepositoryTaskAttribute.REMOVE_CC);
-							if (!remove.contains(cc)) {
-								taskData.addAttributeValue(RepositoryTaskAttribute.REMOVE_CC, cc);
-							}
-						} else {
-							taskData.removeAttributeValue(RepositoryTaskAttribute.REMOVE_CC, cc);
-						}
-					}
-					attributeChanged(taskData.getAttribute(RepositoryTaskAttribute.REMOVE_CC));
-				}
-
-				public void widgetDefaultSelected(SelectionEvent e) {
-				}
-			});
-			toolkit.createLabel(attributesComposite, "");
-			label = toolkit.createLabel(attributesComposite, "(Select to remove)");
-			GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(label);
-		}
-
-	}
-
-	/**
-	 * A listener for selection of the summary field.
-	 * 
-	 * @since 2.1
-	 */
-	protected class DescriptionListener implements Listener {
-		public DescriptionListener() {
-		}
-
-		public void handleEvent(Event event) {
-			fireSelectionChanged(new SelectionChangedEvent(selectionProvider, new StructuredSelection(
-					new RepositoryTaskSelection(taskData.getTaskId(), taskData.getRepositoryUrl(),
-							taskData.getConnectorKind(), getSectionLabel(SECTION_NAME.DESCRIPTION_SECTION), true,
-							taskData.getSummary()))));
-		}
-	}
-
-	protected boolean supportsCommentDelete() {
-		return false;
-	}
-
-	protected void deleteComment(TaskComment comment) {
-
-	}
-
-	private boolean expandCommentSection() {
-		for (final TaskComment taskComment : taskData.getComments()) {
-			if ((repositoryTask != null && repositoryTask.getLastReadTimeStamp() == null)
-					|| editorInput.getOldTaskData() == null) {
-				return true;
-			} else if (isNewComment(taskComment)) {
-				return true;
-			}
-		}
-
-		if (taskData.getComments() == null || taskData.getComments().size() == 0) {
-			return false;
-		} else if (editorInput.getTaskData() != null && editorInput.getOldTaskData() != null) {
-			List<TaskComment> newTaskComments = editorInput.getTaskData().getComments();
-			List<TaskComment> oldTaskComments = editorInput.getOldTaskData().getComments();
-			if (newTaskComments == null || oldTaskComments == null) {
-				return true;
-			} else if (newTaskComments.size() != oldTaskComments.size()) {
-				return true;
-			}
-		}
-		return false;
-	}
-
-	protected void createCommentLayout(Composite composite) {
-		commentsSection = createSection(composite, getSectionLabel(SECTION_NAME.COMMENTS_SECTION),
-				expandCommentSection());
-		commentsSection.setText(commentsSection.getText() + " (" + taskData.getComments().size() + ")");
-
-		final Composite commentsSectionClient = toolkit.createComposite(commentsSection);
-		RowLayout rowLayout = new RowLayout();
-		rowLayout.pack = true;
-		rowLayout.marginLeft = 0;
-		rowLayout.marginBottom = 0;
-		rowLayout.marginTop = 0;
-		commentsSectionClient.setLayout(rowLayout);
-		commentsSectionClient.setBackground(null);
-
-		if (supportsCommentSort()) {
-			sortHyperlink = new ImageHyperlink(commentsSectionClient, SWT.NONE);
-			sortHyperlink.setToolTipText("Change order of comments");
-			toolkit.adapt(sortHyperlink, true, true);
-			sortHyperlink.setBackground(null);
-
-			sortHyperlink.addHyperlinkListener(new HyperlinkAdapter() {
-				@Override
-				public void linkActivated(HyperlinkEvent e) {
-					sortComments();
-				}
-			});
-			sortHyperlinkState(false);
-		}
-
-		if (taskData.getComments().size() > 0) {
-			commentsSection.setEnabled(true);
-			commentsSection.addExpansionListener(new ExpansionAdapter() {
-				@Override
-				public void expansionStateChanged(ExpansionEvent e) {
-					if (commentsSection.isExpanded()) {
-						if (supportsCommentSort()) {
-							sortHyperlinkState(true);
-						}
-					} else {
-						if (supportsCommentSort()) {
-							sortHyperlinkState(false);
-						}
-					}
-				}
-			});
-
-			ImageHyperlink collapseAllHyperlink = new ImageHyperlink(commentsSectionClient, SWT.NONE);
-			collapseAllHyperlink.setToolTipText("Collapse All Comments");
-			toolkit.adapt(collapseAllHyperlink, true, true);
-			collapseAllHyperlink.setBackground(null);
-			collapseAllHyperlink.setImage(CommonImages.getImage(CommonImages.COLLAPSE_ALL_SMALL));
-			collapseAllHyperlink.addHyperlinkListener(new HyperlinkAdapter() {
-				@Override
-				public void linkActivated(HyperlinkEvent e) {
-					hideAllComments();
-				}
-			});
-
-			ImageHyperlink expandAllHyperlink = new ImageHyperlink(commentsSectionClient, SWT.NONE);
-			expandAllHyperlink.setToolTipText("Expand All Comments");
-			toolkit.adapt(expandAllHyperlink, true, true);
-			expandAllHyperlink.setBackground(null);
-			expandAllHyperlink.setImage(CommonImages.getImage(CommonImages.EXPAND_ALL_SMALL));
-			expandAllHyperlink.addHyperlinkListener(new HyperlinkAdapter() {
-				@Override
-				public void linkActivated(HyperlinkEvent e) {
-					BusyIndicator.showWhile(getControl().getDisplay(), new Runnable() {
-						public void run() {
-							revealAllComments();
-							if (supportsCommentSort()) {
-								sortHyperlinkState(true);
-							}
-						}
-					});
-				}
-			});
-			commentsSection.setTextClient(commentsSectionClient);
-		} else {
-			commentsSection.setEnabled(false);
-		}
-
-		// Additional (read-only) Comments Area
-		addCommentsComposite = toolkit.createComposite(commentsSection);
-		commentsSection.setClient(addCommentsComposite);
-		GridLayout addCommentsLayout = new GridLayout();
-		addCommentsLayout.numColumns = 1;
-		addCommentsComposite.setLayout(addCommentsLayout);
-		GridDataFactory.fillDefaults().grab(true, false).applyTo(addCommentsComposite);
-
-		boolean foundNew = false;
-
-		for (final TaskComment taskComment : taskData.getComments()) {
-			final ExpandableComposite expandableComposite = toolkit.createExpandableComposite(addCommentsComposite,
-					ExpandableComposite.TREE_NODE | ExpandableComposite.LEFT_TEXT_CLIENT_ALIGNMENT);
-
-			expandableComposite.setTitleBarForeground(toolkit.getColors().getColor(IFormColors.TITLE));
-
-			final Composite toolbarComp = toolkit.createComposite(expandableComposite);
-			rowLayout = new RowLayout();
-			rowLayout.pack = true;
-			rowLayout.marginLeft = 0;
-			rowLayout.marginBottom = 0;
-			rowLayout.marginTop = 0;
-			toolbarComp.setLayout(rowLayout);
-			toolbarComp.setBackground(null);
-
-			ImageHyperlink formHyperlink = toolkit.createImageHyperlink(toolbarComp, SWT.NONE);
-			formHyperlink.setBackground(null);
-			formHyperlink.setFont(expandableComposite.getFont());
-			formHyperlink.setForeground(toolkit.getColors().getColor(IFormColors.TITLE));
-			if (taskComment.getAuthor() != null && taskComment.getAuthor().equalsIgnoreCase(repository.getUserName())) {
-				formHyperlink.setImage(CommonImages.getImage(CommonImages.PERSON_ME_NARROW));
-			} else {
-				formHyperlink.setImage(CommonImages.getImage(CommonImages.PERSON_NARROW));
-			}
-
-			String authorName = taskComment.getAuthorName();
-			String tooltipText = taskComment.getAuthor();
-			if (authorName.length() == 0) {
-				authorName = taskComment.getAuthor();
-				tooltipText = null;
-			}
-
-			formHyperlink.setText(taskComment.getNumber() + ": " + authorName + ", "
-					+ formatDate(taskComment.getCreated()));
-
-			formHyperlink.setToolTipText(tooltipText);
-			formHyperlink.setEnabled(true);
-			formHyperlink.setUnderlined(false);
-
-			final Composite toolbarButtonComp = toolkit.createComposite(toolbarComp);
-			RowLayout buttonCompLayout = new RowLayout();
-			buttonCompLayout.marginBottom = 0;
-			buttonCompLayout.marginTop = 0;
-			toolbarButtonComp.setLayout(buttonCompLayout);
-			toolbarButtonComp.setBackground(null);
-
-			if (supportsCommentDelete()) {
-				final ImageHyperlink deleteComment = new ImageHyperlink(toolbarButtonComp, SWT.NULL);
-				toolkit.adapt(deleteComment, true, true);
-				deleteComment.setImage(CommonImages.getImage(CommonImages.REMOVE));
-				deleteComment.setToolTipText("Remove");
-
-				deleteComment.addHyperlinkListener(new HyperlinkAdapter() {
-
-					@Override
-					public void linkActivated(HyperlinkEvent e) {
-						deleteComment(taskComment);
-						submitToRepository();
-					}
-				});
-
-			}
-
-			final ImageHyperlink replyLink = createReplyHyperlink(taskComment.getNumber(), toolbarButtonComp,
-					taskComment.getText());
-
-			formHyperlink.addHyperlinkListener(new HyperlinkAdapter() {
-
-				@Override
-				public void linkActivated(HyperlinkEvent e) {
-					toggleExpandableComposite(!expandableComposite.isExpanded(), expandableComposite);
-				}
-
-				@Override
-				public void linkEntered(HyperlinkEvent e) {
-					replyLink.setUnderlined(true);
-					super.linkEntered(e);
-				}
-
-				@Override
-				public void linkExited(HyperlinkEvent e) {
-					replyLink.setUnderlined(false);
-					super.linkExited(e);
-				}
-			});
-
-			expandableComposite.setTextClient(toolbarComp);
-
-			toolbarButtonComp.setVisible(expandableComposite.isExpanded());
-
-			// HACK: This is necessary
-			// due to a bug in SWT's ExpandableComposite.
-			// 165803: Expandable bars should expand when clicking anywhere
-			// https://bugs.eclipse.org/bugs/show_bug.cgi?taskId=165803
-			expandableComposite.setData(toolbarButtonComp);
-
-			expandableComposite.setLayout(new GridLayout());
-			expandableComposite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-
-			final Composite ecComposite = toolkit.createComposite(expandableComposite);
-			GridLayout ecLayout = new GridLayout();
-			ecLayout.marginHeight = 0;
-			ecLayout.marginBottom = 3;
-			ecLayout.marginLeft = 15;
-			ecComposite.setLayout(ecLayout);
-			ecComposite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-			expandableComposite.setClient(ecComposite);
-			// code for outline
-			commentComposites.add(expandableComposite);
-			controlBySelectableObject.put(taskComment, expandableComposite);
-			expandableComposite.addExpansionListener(new ExpansionAdapter() {
-				@Override
-				public void expansionStateChanged(ExpansionEvent e) {
-					toolbarButtonComp.setVisible(expandableComposite.isExpanded());
-					TextViewer viewer = null;
-					if (e.getState() && expandableComposite.getData("viewer") == null) {
-						viewer = addTextViewer(repository, ecComposite, taskComment.getText().trim(), SWT.MULTI
-								| SWT.WRAP);
-						expandableComposite.setData("viewer", viewer.getTextWidget());
-						viewer.getTextWidget().addFocusListener(new FocusListener() {
-
-							public void focusGained(FocusEvent e) {
-								selectedComment = taskComment;
-
-							}
-
-							public void focusLost(FocusEvent e) {
-								selectedComment = null;
-							}
-						});
-
-						StyledText styledText = viewer.getTextWidget();
-						GridDataFactory.fillDefaults().hint(DESCRIPTION_WIDTH, SWT.DEFAULT).applyTo(styledText);
-						resetLayout();
-					} else {
-						// dispose viewer
-						if (expandableComposite.getData("viewer") instanceof StyledText) {
-							((StyledText) expandableComposite.getData("viewer")).dispose();
-							expandableComposite.setData("viewer", null);
-						}
-						resetLayout();
-					}
-				}
-			});
-
-			if ((repositoryTask != null && repositoryTask.getLastReadTimeStamp() == null)
-					|| editorInput.getOldTaskData() == null) {
-				// hit or lost task data, expose all comments
-				toggleExpandableComposite(true, expandableComposite);
-				foundNew = true;
-			} else if (isNewComment(taskComment)) {
-				expandableComposite.setBackground(colorIncoming);
-				toggleExpandableComposite(true, expandableComposite);
-				foundNew = true;
-			}
-
-		}
-		if (supportsCommentSort()) {
-			if (commentSortIsUp) {
-				commentSortIsUp = !commentSortIsUp;
-				sortComments();
-			} else {
-				sortHyperlinkState(commentSortEnable);
-			}
-		}
-		if (foundNew) {
-			if (supportsCommentSort()) {
-				sortHyperlinkState(true);
-			}
-		} else if (taskData.getComments() == null || taskData.getComments().size() == 0) {
-			if (supportsCommentSort()) {
-				sortHyperlinkState(false);
-			}
-		} else if (editorInput.getTaskData() != null && editorInput.getOldTaskData() != null) {
-			List<TaskComment> newTaskComments = editorInput.getTaskData().getComments();
-			List<TaskComment> oldTaskComments = editorInput.getOldTaskData().getComments();
-			if (newTaskComments == null || oldTaskComments == null) {
-				if (supportsCommentSort()) {
-					sortHyperlinkState(true);
-				}
-			} else if (newTaskComments.size() != oldTaskComments.size()) {
-				if (supportsCommentSort()) {
-					sortHyperlinkState(true);
-				}
-			}
-		}
-	}
-
-	public String formatDate(String dateString) {
-		return dateString;
-	}
-
-	private boolean isNewComment(TaskComment comment) {
-
-		// Simple test (will not reveal new comments if offline data was lost
-		if (editorInput.getOldTaskData() != null) {
-			return (comment.getNumber() > editorInput.getOldTaskData().getComments().size());
-		}
-		return false;
-
-		// OLD METHOD FOR DETERMINING NEW COMMENTS
-		// if (repositoryTask != null) {
-		// if (repositoryTask.getLastSyncDateStamp() == null) {
-		// // new hit
-		// return true;
-		// }
-		// AbstractRepositoryConnector connector = (AbstractRepositoryConnector)
-		// TasksUiPlugin.getRepositoryManager()
-		// .getRepositoryConnector(taskData.getRepositoryKind());
-		// AbstractTaskDataHandler offlineHandler = connector.getTaskDataHandler();
-		// if (offlineHandler != null) {
-		//
-		// Date lastSyncDate =
-		// taskData.getAttributeFactory().getDateForAttributeType(
-		// RepositoryTaskAttribute.DATE_MODIFIED,
-		// repositoryTask.getLastSyncDateStamp());
-		//
-		// if (lastSyncDate != null) {
-		//
-		// // reduce granularity to minutes
-		// Calendar calLastMod = Calendar.getInstance();
-		// calLastMod.setTimeInMillis(lastSyncDate.getTime());
-		// calLastMod.set(Calendar.SECOND, 0);
-		//
-		// Date commentDate =
-		// taskData.getAttributeFactory().getDateForAttributeType(
-		// RepositoryTaskAttribute.COMMENT_DATE, comment.getCreated());
-		// if (commentDate != null) {
-		//
-		// Calendar calComment = Calendar.getInstance();
-		// calComment.setTimeInMillis(commentDate.getTime());
-		// calComment.set(Calendar.SECOND, 0);
-		// if (calComment.after(calLastMod)) {
-		// return true;
-		// }
-		// }
-		// }
-		// }
-		// }
-		// return false;
-
-	}
-
-	/**
-	 * Subclasses that support HTML preview of ticket description and comments override this method to return an
-	 * instance of AbstractRenderingEngine
-	 * 
-	 * @return <code>null</code> if HTML preview is not supported for the repository (default)
-	 * @since 2.1
-	 */
-	protected AbstractRenderingEngine getRenderingEngine() {
-		return null;
-	}
-
-	protected void createNewCommentLayout(Composite composite) {
-		// Section newCommentSection = createSection(composite,
-		// getSectionLabel(SECTION_NAME.NEWCOMMENT_SECTION));
-
-		Section newCommentSection = toolkit.createSection(composite, ExpandableComposite.TITLE_BAR);
-		newCommentSection.setText(getSectionLabel(SECTION_NAME.NEWCOMMENT_SECTION));
-		newCommentSection.setLayout(new GridLayout());
-		newCommentSection.setLayoutData(new GridData(GridData.FILL_BOTH));
-
-		Composite newCommentsComposite = toolkit.createComposite(newCommentSection);
-		newCommentsComposite.setLayout(new GridLayout());
-
-		// HACK: new new comment attribute not created by connector, create one.
-		if (taskData.getAttribute(RepositoryTaskAttribute.COMMENT_NEW) == null) {
-			taskData.setAttributeValue(RepositoryTaskAttribute.COMMENT_NEW, "");
-		}
-		final RepositoryTaskAttribute attribute = taskData.getAttribute(RepositoryTaskAttribute.COMMENT_NEW);
-
-		if (getRenderingEngine() != null) {
-			// composite with StackLayout to hold text editor and preview widget
-			Composite editPreviewComposite = toolkit.createComposite(newCommentsComposite);
-			GridData editPreviewData = new GridData(GridData.FILL_BOTH);
-			editPreviewData.widthHint = DESCRIPTION_WIDTH;
-			editPreviewData.minimumHeight = DESCRIPTION_HEIGHT;
-			editPreviewData.grabExcessHorizontalSpace = true;
-			editPreviewComposite.setLayoutData(editPreviewData);
-			editPreviewComposite.setData(FormToolkit.KEY_DRAW_BORDER, FormToolkit.TEXT_BORDER);
-
-			final StackLayout editPreviewLayout = new StackLayout();
-			editPreviewComposite.setLayout(editPreviewLayout);
-
-			newCommentTextViewer = addTextEditor(repository, editPreviewComposite, attribute.getValue(), true, SWT.FLAT
-					| SWT.MULTI | SWT.WRAP | SWT.V_SCROLL);
-
-			editPreviewLayout.topControl = newCommentTextViewer.getControl();
-			editPreviewComposite.layout();
-
-			// composite for edit/preview button
-			Composite buttonComposite = toolkit.createComposite(newCommentsComposite);
-			buttonComposite.setLayout(new GridLayout());
-			createPreviewButton(buttonComposite, newCommentTextViewer, editPreviewComposite, editPreviewLayout);
-		} else {
-			newCommentTextViewer = addTextEditor(repository, newCommentsComposite, attribute.getValue(), true, SWT.FLAT
-					| SWT.MULTI | SWT.WRAP | SWT.V_SCROLL);
-			GridData addCommentsTextData = new GridData(GridData.FILL_BOTH);
-			addCommentsTextData.widthHint = DESCRIPTION_WIDTH;
-			addCommentsTextData.minimumHeight = DESCRIPTION_HEIGHT;
-			addCommentsTextData.grabExcessHorizontalSpace = true;
-			newCommentTextViewer.getControl().setLayoutData(addCommentsTextData);
-			newCommentTextViewer.getControl().setData(FormToolkit.KEY_DRAW_BORDER, FormToolkit.TEXT_BORDER);
-		}
-		newCommentTextViewer.setEditable(true);
-		newCommentTextViewer.addTextListener(new ITextListener() {
-			public void textChanged(TextEvent event) {
-				String newValue = addCommentsTextBox.getText();
-				if (!newValue.equals(attribute.getValue())) {
-					attribute.setValue(newValue);
-					attributeChanged(attribute);
-				}
-			}
-		});
-
-		newCommentTextViewer.getTextWidget().addListener(SWT.FocusIn, new NewCommentListener());
-		addCommentsTextBox = newCommentTextViewer.getTextWidget();
-
-		newCommentSection.setClient(newCommentsComposite);
-
-		toolkit.paintBordersFor(newCommentsComposite);
-	}
-
-	private Browser addBrowser(Composite parent, int style) {
-		Browser browser = new Browser(parent, style);
-		// intercept links to open tasks in rich editor and urls in separate browser
-		browser.addLocationListener(new LocationAdapter() {
-			@Override
-			public void changing(LocationEvent event) {
-				// ignore events that are caused by manually setting the contents of the browser
-				if (ignoreLocationEvents) {
-					return;
-				}
-
-				if (event.location != null && !event.location.startsWith("about")) {
-					event.doit = false;
-					IHyperlink link = new TaskUrlHyperlink(
-							new Region(0, 0)/* a fake region just to make constructor happy */, event.location);
-					link.open();
-				}
-			}
-
-		});
-
-		return browser;
-	}
-
-	/**
-	 * Creates and sets up the button for switching between text editor and HTML preview. Subclasses that support HTML
-	 * preview of new comments must override this method.
-	 * 
-	 * @param buttonComposite
-	 *            the composite that holds the button
-	 * @param editor
-	 *            the TextViewer for editing text
-	 * @param previewBrowser
-	 *            the Browser for displaying the preview
-	 * @param editorLayout
-	 *            the StackLayout of the <code>editorComposite</code>
-	 * @param editorComposite
-	 *            the composite that holds <code>editor</code> and <code>previewBrowser</code>
-	 * @since 2.1
-	 */
-	private void createPreviewButton(final Composite buttonComposite, final TextViewer editor,
-			final Composite editorComposite, final StackLayout editorLayout) {
-		// create an anonymous object that encapsulates the edit/preview button together with
-		// its state and String constants for button text;
-		// this implementation keeps all information needed to set up the button 
-		// in this object and the method parameters, and this method is reused by both the
-		// description section and new comments section.
-		new Object() {
-			private static final String LABEL_BUTTON_PREVIEW = "Preview";
-
-			private static final String LABEL_BUTTON_EDIT = "Edit";
-
-			private int buttonState = 0;
-
-			private Button previewButton;
-
-			private Browser previewBrowser;
-
-			{
-				previewButton = toolkit.createButton(buttonComposite, LABEL_BUTTON_PREVIEW, SWT.PUSH);
-				GridData previewButtonData = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
-				previewButtonData.widthHint = 100;
-				//previewButton.setImage(TasksUiImages.getImage(TasksUiImages.PREVIEW));
-				previewButton.setLayoutData(previewButtonData);
-				previewButton.addListener(SWT.Selection, new Listener() {
-					public void handleEvent(Event e) {
-						if (previewBrowser == null) {
-							previewBrowser = addBrowser(editorComposite, SWT.NONE);
-						}
-
-						buttonState = ++buttonState % 2;
-						if (buttonState == 1) {
-							setText(previewBrowser, "Loading preview...");
-							previewWiki(previewBrowser, editor.getTextWidget().getText());
-						}
-						previewButton.setText(buttonState == 0 ? LABEL_BUTTON_PREVIEW : LABEL_BUTTON_EDIT);
-						editorLayout.topControl = (buttonState == 0 ? editor.getControl() : previewBrowser);
-						editorComposite.layout();
-					}
-				});
-			}
-
-		};
-	}
-
-	private void setText(Browser browser, String html) {
-		try {
-			ignoreLocationEvents = true;
-			browser.setText((html != null) ? html : "");
-		} finally {
-			ignoreLocationEvents = false;
-		}
-
-	}
-
-	private void previewWiki(final Browser browser, String sourceText) {
-		final class PreviewWikiJob extends Job {
-			private final String sourceText;
-
-			private String htmlText;
-
-			private IStatus jobStatus;
-
-			public PreviewWikiJob(String sourceText) {
-				super("Formatting Wiki Text");
-
-				if (sourceText == null) {
-					throw new IllegalArgumentException("source text must not be null");
-				}
-
-				this.sourceText = sourceText;
-			}
-
-			@Override
-			protected IStatus run(IProgressMonitor monitor) {
-				AbstractRenderingEngine htmlRenderingEngine = getRenderingEngine();
-				if (htmlRenderingEngine == null) {
-					jobStatus = new RepositoryStatus(repository, IStatus.INFO, TasksUiPlugin.ID_PLUGIN,
-							RepositoryStatus.ERROR_INTERNAL, "The repository does not support HTML preview.");
-					return Status.OK_STATUS;
-				}
-
-				jobStatus = Status.OK_STATUS;
-				try {
-					htmlText = htmlRenderingEngine.renderAsHtml(repository, sourceText, monitor);
-				} catch (CoreException e) {
-					jobStatus = e.getStatus();
-				}
-				return Status.OK_STATUS;
-			}
-
-			public String getHtmlText() {
-				return htmlText;
-			}
-
-			public IStatus getStatus() {
-				return jobStatus;
-			}
-
-		}
-
-		final PreviewWikiJob job = new PreviewWikiJob(sourceText);
-
-		job.addJobChangeListener(new JobChangeAdapter() {
-
-			@Override
-			public void done(final IJobChangeEvent event) {
-				if (!form.isDisposed()) {
-					if (job.getStatus().isOK()) {
-						getPartControl().getDisplay().asyncExec(new Runnable() {
-							public void run() {
-								AbstractRepositoryTaskEditor.this.setText(browser, job.getHtmlText());
-								parentEditor.setMessage(null, IMessageProvider.NONE);
-							}
-						});
-					} else {
-						getPartControl().getDisplay().asyncExec(new Runnable() {
-							public void run() {
-								parentEditor.setMessage(job.getStatus().getMessage(), IMessageProvider.ERROR);
-							}
-						});
-					}
-				}
-				super.done(event);
-			}
-		});
-
-		job.setUser(true);
-		job.schedule();
-	}
-
-	/**
-	 * Creates the button layout. This displays options and buttons at the bottom of the editor to allow actions to be
-	 * performed on the bug.
-	 */
-	protected void createActionsLayout(Composite composite) {
-		Section section = createSection(composite, getSectionLabel(SECTION_NAME.ACTIONS_SECTION));
-		GridDataFactory.fillDefaults().align(SWT.FILL, SWT.TOP).grab(true, true).applyTo(section);
-		Composite buttonComposite = toolkit.createComposite(section);
-		GridLayout buttonLayout = new GridLayout();
-		GridDataFactory.fillDefaults().align(SWT.FILL, SWT.TOP).applyTo(buttonComposite);
-		buttonLayout.numColumns = 4;
-		buttonComposite.setLayout(buttonLayout);
-		addRadioButtons(buttonComposite);
-		addActionButtons(buttonComposite);
-		section.setClient(buttonComposite);
-	}
-
-	protected Section createSection(Composite composite, String title) {
-		return createSection(composite, title, true);
-	}
-
-	/**
-	 * @Since 2.3
-	 */
-	private Section createSection(Composite composite, String title, boolean expandedState) {
-		int style = ExpandableComposite.TITLE_BAR | Section.TWISTIE;
-		if (expandedState) {
-			style |= ExpandableComposite.EXPANDED;
-		}
-		Section section = toolkit.createSection(composite, style);
-		section.setText(title);
-		section.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-		return section;
-	}
-
-	/**
-	 * Adds buttons to this composite. Subclasses can override this method to provide different/additional buttons.
-	 * 
-	 * @param buttonComposite
-	 *            Composite to add the buttons to.
-	 */
-	protected void addActionButtons(Composite buttonComposite) {
-		submitButton = toolkit.createButton(buttonComposite, LABEL_BUTTON_SUBMIT, SWT.NONE);
-		GridData submitButtonData = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
-		submitButtonData.widthHint = 100;
-		submitButton.setImage(CommonImages.getImage(TasksUiImages.REPOSITORY_SUBMIT));
-		submitButton.setLayoutData(submitButtonData);
-		submitButton.addListener(SWT.Selection, new Listener() {
-			public void handleEvent(Event e) {
-				submitToRepository();
-			}
-		});
-
-		setSubmitEnabled(true);
-
-		toolkit.createLabel(buttonComposite, "    ");
-
-		ITask task = TasksUiInternal.getTaskList().getTask(repository.getRepositoryUrl(), taskData.getTaskId());
-		if (attachContextEnabled && task != null) {
-			addAttachContextButton(buttonComposite, task);
-		}
-	}
-
-	private void setSubmitEnabled(boolean enabled) {
-		if (submitButton != null && !submitButton.isDisposed()) {
-			submitButton.setEnabled(enabled);
-			if (enabled) {
-				submitButton.setToolTipText("Submit to " + this.repository.getRepositoryUrl());
-			}
-		}
-	}
-
-	/**
-	 * Override to make hyperlink available. If not overridden hyperlink will simply not be displayed.
-	 * 
-	 * @return url String form of url that points to task's past activity
-	 */
-	protected String getHistoryUrl() {
-		return null;
-	}
-
-	protected void saveTaskOffline(IProgressMonitor progressMonitor) {
-		if (taskData == null) {
-			return;
-		}
-		if (repositoryTask != null) {
-			try {
-				localChange = true;
-
-				TasksUiPlugin.getTaskDataManager().saveOutgoing(repositoryTask, changedAttributes);
-			} finally {
-				localChange = false;
-			}
-		}
-		markDirty(false);
-	}
-
-	// once the following bug is fixed, this check for first focus is probably
-	// not needed -> Bug# 172033: Restore editor focus
-	private boolean firstFocus = true;
-
-	@Override
-	public void setFocus() {
-		if (lastFocusControl != null && !lastFocusControl.isDisposed()) {
-			lastFocusControl.setFocus();
-		} else if (firstFocus && summaryTextViewer != null) {
-			summaryTextViewer.getControl().setFocus();
-			firstFocus = false;
-		}
-	}
-
-	/**
-	 * Updates the title of the editor
-	 * 
-	 */
-	protected void updateEditorTitle() {
-		setPartName(editorInput.getName());
-		((TaskEditor) this.getEditor()).updateTitle(editorInput.getName());
-	}
-
-	@Override
-	public boolean isSaveAsAllowed() {
-		return false;
-	}
-
-	@Override
-	public void doSave(IProgressMonitor monitor) {
-		saveTaskOffline(monitor);
-		updateEditorTitle();
-		updateHeaderControls();
-//		fillToolBar(getParentEditor().getTopForm().getToolBarManager());
-	}
-
-	@Override
-	public void doSaveAs() {
-		// we don't save, so no need to implement
-	}
-
-	/**
-	 * @return The composite for the whole editor.
-	 */
-	public Composite getEditorComposite() {
-		return editorComposite;
-	}
-
-	@Override
-	public void dispose() {
-		TasksUiInternal.getTaskList().removeChangeListener(TASKLIST_CHANGE_LISTENER);
-		getSite().getPage().removeSelectionListener(selectionListener);
-		if (waitCursor != null) {
-			waitCursor.dispose();
-		}
-		if (activateAction != null) {
-			activateAction.dispose();
-		}
-		super.dispose();
-	}
-
-	/**
-	 * Fires a <code>SelectionChangedEvent</code> to all listeners registered under
-	 * <code>selectionChangedListeners</code>.
-	 * 
-	 * @param event
-	 *            The selection event.
-	 */
-	protected void fireSelectionChanged(final SelectionChangedEvent event) {
-		Object[] listeners = selectionChangedListeners.toArray();
-		for (Object listener : listeners) {
-			final ISelectionChangedListener l = (ISelectionChangedListener) listener;
-			SafeRunnable.run(new SafeRunnable() {
-				public void run() {
-					l.selectionChanged(event);
-				}
-			});
-		}
-	}
-
-	/*----------------------------------------------------------*
-	 * CODE TO SCROLL TO A COMMENT OR OTHER PIECE OF TEXT
-	 *----------------------------------------------------------*/
-
-	private final HashMap<Object, Control> controlBySelectableObject = new HashMap<Object, Control>();
-
-	private final List<ExpandableComposite> commentComposites = new ArrayList<ExpandableComposite>();
-
-	private StyledText addCommentsTextBox = null;
-
-	protected TextViewer descriptionTextViewer = null;
-
-	private void revealAllComments() {
-		try {
-			form.setRedraw(false);
-			refreshEnabled = false;
-			if (supportsCommentSort()) {
-				sortHyperlinkState(false);
-			}
-
-			if (commentsSection != null && !commentsSection.isExpanded()) {
-				commentsSection.setExpanded(true);
-				if (supportsCommentSort()) {
-					sortHyperlinkState(true);
-				}
-			}
-			for (ExpandableComposite composite : commentComposites) {
-				if (composite.isDisposed()) {
-					continue;
-				}
-				if (!composite.isExpanded()) {
-					toggleExpandableComposite(true, composite);
-				}
-//			Composite comp = composite.getParent();
-//			while (comp != null && !comp.isDisposed()) {
-//				if (comp instanceof ExpandableComposite && !comp.isDisposed()) {
-//					ExpandableComposite ex = (ExpandableComposite) comp;
-//					setExpandableCompositeState(true, ex);
-//
-//					// HACK: This is necessary
-//					// due to a bug in SWT's ExpandableComposite.
-//					// 165803: Expandable bars should expand when clicking
-//					// anywhere
-//					// https://bugs.eclipse.org/bugs/show_bug.cgi?taskId=165803
-//					if (ex.getData() != null && ex.getData() instanceof Composite) {
-//						((Composite) ex.getData()).setVisible(true);
-//					}
-//
-//					break;
-//				}
-//				comp = comp.getParent();
-//			}
-			}
-		} finally {
-			refreshEnabled = true;
-			form.setRedraw(true);
-		}
-		resetLayout();
-	}
-
-	private void hideAllComments() {
-		try {
-			refreshEnabled = false;
-
-			for (ExpandableComposite composite : commentComposites) {
-				if (composite.isDisposed()) {
-					continue;
-				}
-
-				if (composite.isExpanded()) {
-					toggleExpandableComposite(false, composite);
-				}
-
-//			Composite comp = composite.getParent();
-//			while (comp != null && !comp.isDisposed()) {
-//				if (comp instanceof ExpandableComposite && !comp.isDisposed()) {
-//					ExpandableComposite ex = (ExpandableComposite) comp;
-//					setExpandableCompositeState(false, ex);
-//
-//					// HACK: This is necessary
-//					// due to a bug in SWT's ExpandableComposite.
-//					// 165803: Expandable bars should expand when clicking anywhere
-//					// https://bugs.eclipse.org/bugs/show_bug.cgi?taskId=165803
-//					if (ex.getData() != null && ex.getData() instanceof Composite) {
-//						((Composite) ex.getData()).setVisible(false);
-//					}
-//
-//					break;
-//				}
-//				comp = comp.getParent();
-//			}
-			}
-
-//		if (commentsSection != null) {
-//			commentsSection.setExpanded(false);
-//		}
-
-		} finally {
-			refreshEnabled = true;
-		}
-		resetLayout();
-	}
-
-	private void sortHyperlinkState(boolean enabled) {
-		commentSortEnable = enabled;
-
-		if (sortHyperlink == null) {
-			return;
-		}
-
-		sortHyperlink.setEnabled(enabled);
-		if (enabled) {
-			if (commentSortIsUp) {
-				sortHyperlink.setImage(CommonImages.getImage(TasksUiImages.COMMENT_SORT_UP));
-			} else {
-				sortHyperlink.setImage(CommonImages.getImage(TasksUiImages.COMMENT_SORT_DOWN));
-			}
-		} else {
-			if (commentSortIsUp) {
-				sortHyperlink.setImage(CommonImages.getImage(TasksUiImages.COMMENT_SORT_UP_GRAY));
-			} else {
-				sortHyperlink.setImage(CommonImages.getImage(TasksUiImages.COMMENT_SORT_DOWN_GRAY));
-			}
-		}
-	}
-
-	private void sortComments() {
-		if (addCommentsComposite != null) {
-			Control[] commentControlList = addCommentsComposite.getChildren();
-			int commentControlListLength = commentControlList.length;
-			for (int i = 1; i < commentControlListLength; i++) {
-				commentControlList[commentControlListLength - i].moveAbove(commentControlList[0]);
-			}
-		}
-		commentSortIsUp = !commentSortIsUp;
-		TasksUiPlugin.getDefault().getPreferenceStore().setValue(
-				PREF_SORT_ORDER_PREFIX + repository.getConnectorKind(), commentSortIsUp);
-		sortHyperlinkState(commentSortEnable);
-		resetLayout();
-	}
-
-	/**
-	 * Selects the given object in the editor.
-	 * 
-	 * @param o
-	 *            The object to be selected.
-	 * @param highlight
-	 *            Whether or not the object should be highlighted.
-	 */
-	public boolean select(Object o, boolean highlight) {
-		Control control = controlBySelectableObject.get(o);
-		if (control != null && !control.isDisposed()) {
-
-			// expand all children
-			if (control instanceof ExpandableComposite) {
-				ExpandableComposite ex = (ExpandableComposite) control;
-				if (!ex.isExpanded()) {
-					toggleExpandableComposite(true, ex);
-				}
-			}
-
-			// expand all parents of control
-			Composite comp = control.getParent();
-			while (comp != null) {
-				if (comp instanceof Section) {
-					if (!((Section) comp).isExpanded()) {
-						((Section) comp).setExpanded(true);
-					}
-				} else if (comp instanceof ExpandableComposite) {
-					ExpandableComposite ex = (ExpandableComposite) comp;
-					if (!ex.isExpanded()) {
-						toggleExpandableComposite(true, ex);
-					}
-
-					// HACK: This is necessary
-					// due to a bug in SWT's ExpandableComposite.
-					// 165803: Expandable bars should expand when clicking anywhere
-					// https://bugs.eclipse.org/bugs/show_bug.cgi?taskId=165803
-					if (ex.getData() != null && ex.getData() instanceof Composite) {
-						((Composite) ex.getData()).setVisible(true);
-					}
-				}
-				comp = comp.getParent();
-			}
-			focusOn(control, highlight);
-		} else if (o instanceof RepositoryTaskData) {
-			focusOn(null, highlight);
-		} else {
-			return false;
-		}
-		return true;
-	}
-
-	/**
-	 * Programmatically expand the provided ExpandableComposite, using reflection to fire the expansion listeners (see
-	 * bug#70358)
-	 * 
-	 * @param comp
-	 */
-	private void toggleExpandableComposite(boolean expanded, ExpandableComposite comp) {
-		if (comp.isExpanded() != expanded) {
-			Method method = null;
-			try {
-				method = comp.getClass().getDeclaredMethod("programmaticToggleState");
-				method.setAccessible(true);
-				method.invoke(comp);
-			} catch (Exception e) {
-				// ignore
-			}
-		}
-	}
-
-	private void selectNewComment() {
-		focusOn(addCommentsTextBox, false);
-	}
-
-	/**
-	 * @author Raphael Ackermann (bug 195514)
-	 * @since 2.1
-	 */
-	protected void focusAttributes() {
-		if (attributesSection != null) {
-			focusOn(attributesSection, false);
-		}
-	}
-
-	private void focusDescription() {
-		if (descriptionTextViewer != null) {
-			focusOn(descriptionTextViewer.getTextWidget(), false);
-		}
-	}
-
-	/**
-	 * Scroll to a specified piece of text
-	 * 
-	 * @param selectionComposite
-	 *            The StyledText to scroll to
-	 */
-	private void focusOn(Control selectionComposite, boolean highlight) {
-		int pos = 0;
-		// if (previousText != null && !previousText.isDisposed()) {
-		// previousText.setsetSelection(0);
-		// }
-
-		// if (selectionComposite instanceof FormText)
-		// previousText = (FormText) selectionComposite;
-
-		if (selectionComposite != null) {
-
-			// if (highlight && selectionComposite instanceof FormText &&
-			// !selectionComposite.isDisposed())
-			// ((FormText) selectionComposite).set.setSelection(0, ((FormText)
-			// selectionComposite).getText().length());
-
-			// get the position of the text in the composite
-			pos = 0;
-			Control s = selectionComposite;
-			if (s.isDisposed()) {
-				return;
-			}
-			s.setEnabled(true);
-			s.setFocus();
-			s.forceFocus();
-			while (s != null && s != getEditorComposite()) {
-				if (!s.isDisposed()) {
-					pos += s.getLocation().y;
-					s = s.getParent();
-				}
-			}
-
-			pos = pos - 60; // form.getOrigin().y;
-
-		}
-		if (!form.getBody().isDisposed()) {
-			form.setOrigin(0, pos);
-		}
-	}
-
-	private RepositoryTaskOutlinePage outlinePage = null;
-
-	@SuppressWarnings("unchecked")
-	@Override
-	public Object getAdapter(Class adapter) {
-		return getAdapterDelgate(adapter);
-	}
-
-	public Object getAdapterDelgate(Class<?> adapter) {
-		if (IContentOutlinePage.class.equals(adapter)) {
-			if (outlinePage == null && editorInput != null && taskOutlineModel != null) {
-				outlinePage = new RepositoryTaskOutlinePage(taskOutlineModel);
-			}
-			return outlinePage;
-		}
-		return super.getAdapter(adapter);
-	}
-
-	public RepositoryTaskOutlinePage getOutline() {
-		return outlinePage;
-	}
-
-	private Button[] radios;
-
-	private Control[] radioOptions;
-
-	private Button attachContextButton;
-
-	private AbstractLegacyRepositoryConnector connector;
-
-	private Cursor waitCursor;
-
-	private boolean formBusy = false;
-
-	private Composite headerInfoComposite;
-
-	private Section attributesSection;
-
-	public void close() {
-		Display activeDisplay = getSite().getShell().getDisplay();
-		activeDisplay.asyncExec(new Runnable() {
-			public void run() {
-				if (getSite() != null && getSite().getPage() != null && !getManagedForm().getForm().isDisposed()) {
-					if (parentEditor != null) {
-						getSite().getPage().closeEditor(parentEditor, false);
-					} else {
-						getSite().getPage().closeEditor(AbstractRepositoryTaskEditor.this, false);
-					}
-				}
-			}
-		});
-	}
-
-	public void addAttributeListener(IRepositoryTaskAttributeListener listener) {
-		attributesListeners.add(listener);
-	}
-
-	public void removeAttributeListener(IRepositoryTaskAttributeListener listener) {
-		attributesListeners.remove(listener);
-	}
-
-	public void setParentEditor(TaskEditor parentEditor) {
-		this.parentEditor = parentEditor;
-	}
-
-	/**
-	 * @since 2.1
-	 */
-	public TaskEditor getParentEditor() {
-		return parentEditor;
-	}
-
-	public RepositoryTaskOutlineNode getTaskOutlineModel() {
-		return taskOutlineModel;
-	}
-
-	public void setTaskOutlineModel(RepositoryTaskOutlineNode taskOutlineModel) {
-		this.taskOutlineModel = taskOutlineModel;
-	}
-
-	/**
-	 * A listener for selection of the textbox where a new comment is entered in.
-	 */
-	private class NewCommentListener implements Listener {
-		public void handleEvent(Event event) {
-			fireSelectionChanged(new SelectionChangedEvent(selectionProvider, new StructuredSelection(
-					new RepositoryTaskSelection(taskData.getTaskId(), taskData.getRepositoryUrl(),
-							taskData.getConnectorKind(), getSectionLabel(SECTION_NAME.NEWCOMMENT_SECTION), false,
-							taskData.getSummary()))));
-		}
-	}
-
-	public Control getControl() {
-		return form;
-	}
-
-	public void setSummaryText(String text) {
-		if (summaryTextViewer != null && summaryTextViewer.getTextWidget() != null) {
-			summaryTextViewer.getTextWidget().setText(text);
-		}
-	}
-
-	public void setDescriptionText(String text) {
-		this.descriptionTextViewer.getDocument().set(text);
-	}
-
-	protected void addRadioButtons(Composite buttonComposite) {
-		int i = 0;
-		Button selected = null;
-		radios = new Button[taskData.getOperations().size()];
-		radioOptions = new Control[taskData.getOperations().size()];
-		for (RepositoryOperation o : taskData.getOperations()) {
-			radios[i] = toolkit.createButton(buttonComposite, "", SWT.RADIO);
-			radios[i].setFont(TEXT_FONT);
-			GridData radioData = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
-			if (!o.hasOptions() && !o.isInput()) {
-				radioData.horizontalSpan = 4;
-			} else {
-				radioData.horizontalSpan = 1;
-			}
-			radioData.heightHint = 20;
-			String opName = o.getOperationName();
-			opName = opName.replaceAll("</.*>", "");
-			opName = opName.replaceAll("<.*>", "");
-			radios[i].setText(opName);
-			radios[i].setLayoutData(radioData);
-			// radios[i].setBackground(background);
-			radios[i].addSelectionListener(new RadioButtonListener());
-
-			if (o.hasOptions()) {
-				radioData = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
-				radioData.horizontalSpan = 3;
-				radioData.heightHint = 20;
-				radioData.widthHint = RADIO_OPTION_WIDTH;
-				radioOptions[i] = new CCombo(buttonComposite, SWT.FLAT | SWT.READ_ONLY);
-				radioOptions[i].setData(FormToolkit.KEY_DRAW_BORDER, FormToolkit.TEXT_BORDER);
-				toolkit.adapt(radioOptions[i], true, true);
-				radioOptions[i].setFont(TEXT_FONT);
-				radioOptions[i].setLayoutData(radioData);
-
-				Object[] a = o.getOptionNames().toArray();
-				Arrays.sort(a);
-				for (int j = 0; j < a.length; j++) {
-					if (a[j] != null) {
-						((CCombo) radioOptions[i]).add((String) a[j]);
-						if (((String) a[j]).equals(o.getOptionSelection())) {
-							((CCombo) radioOptions[i]).select(j);
-						}
-					}
-				}
-				((CCombo) radioOptions[i]).addSelectionListener(new RadioButtonListener());
-			} else if (o.isInput()) {
-				radioData = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
-				radioData.horizontalSpan = 3;
-				radioData.widthHint = RADIO_OPTION_WIDTH - 10;
-
-				String assignmentValue = "";
-				// NOTE: removed this because we now have content assit
-// if (opName.equals(REASSIGN_BUG_TO)) {
-// assignmentValue = repository.getUserName();
-// }
-				radioOptions[i] = toolkit.createText(buttonComposite, assignmentValue);
-				radioOptions[i].setFont(TEXT_FONT);
-				radioOptions[i].setLayoutData(radioData);
-				// radioOptions[i].setBackground(background);
-				((Text) radioOptions[i]).setText(o.getInputValue());
-				((Text) radioOptions[i]).addModifyListener(new RadioButtonListener());
-
-				if (hasContentAssist(o)) {
-					ContentAssistCommandAdapter adapter = applyContentAssist((Text) radioOptions[i],
-							createContentProposalProvider(o));
-					ILabelProvider propsalLabelProvider = createProposalLabelProvider(o);
-					if (propsalLabelProvider != null) {
-						adapter.setLabelProvider(propsalLabelProvider);
-					}
-					adapter.setProposalAcceptanceStyle(ContentProposalAdapter.PROPOSAL_REPLACE);
-				}
-			}
-
-			if (i == 0 || o.isChecked()) {
-				if (selected != null) {
-					selected.setSelection(false);
-				}
-				selected = radios[i];
-				radios[i].setSelection(true);
-				if (o.hasOptions() && o.getOptionSelection() != null) {
-					int j = 0;
-					for (String s : ((CCombo) radioOptions[i]).getItems()) {
-						if (s.compareTo(o.getOptionSelection()) == 0) {
-							((CCombo) radioOptions[i]).select(j);
-						}
-						j++;
-					}
-				}
-				taskData.setSelectedOperation(o);
-			}
-
-			i++;
-		}
-
-		toolkit.paintBordersFor(buttonComposite);
-	}
-
-	/**
-	 * If implementing custom attributes you may need to override this method
-	 * 
-	 * @return true if one or more attributes exposed in the editor have
-	 */
-	protected boolean hasVisibleAttributeChanges() {
-		if (taskData == null) {
-			return false;
-		}
-		for (RepositoryTaskAttribute attribute : taskData.getAttributes()) {
-			if (!attribute.isHidden()) {
-				if (hasChanged(attribute)) {
-					return true;
-				}
-			}
-		}
-		return false;
-	}
-
-	protected boolean hasOutgoingChange(RepositoryTaskAttribute newAttribute) {
-		return editorInput.getOldEdits().contains(newAttribute);
-	}
-
-	protected boolean hasChanged(RepositoryTaskAttribute newAttribute) {
-		if (newAttribute == null) {
-			return false;
-		}
-		RepositoryTaskData oldTaskData = editorInput.getOldTaskData();
-		if (oldTaskData == null) {
-			return false;
-		}
-
-		if (hasOutgoingChange(newAttribute)) {
-			return false;
-		}
-
-		RepositoryTaskAttribute oldAttribute = oldTaskData.getAttribute(newAttribute.getId());
-		if (oldAttribute == null) {
-			return true;
-		}
-		if (oldAttribute.getValue() != null && !oldAttribute.getValue().equals(newAttribute.getValue())) {
-			return true;
-		} else if (oldAttribute.getValues() != null && !oldAttribute.getValues().equals(newAttribute.getValues())) {
-			return true;
-		}
-		return false;
-	}
-
-	protected void addAttachContextButton(Composite buttonComposite, ITask task) {
-		attachContextButton = toolkit.createButton(buttonComposite, "Attach Context", SWT.CHECK);
-		attachContextButton.setImage(CommonImages.getImage(TasksUiImages.CONTEXT_ATTACH));
-	}
-
-	/**
-	 * Creates a check box for adding the repository user to the cc list. Does nothing if the repository does not have a
-	 * valid username, the repository user is the assignee, reporter or already on the the cc list.
-	 */
-	protected void addSelfToCC(Composite composite) {
-
-		if (repository.getUserName() == null) {
-			return;
-		}
-
-		RepositoryTaskAttribute owner = taskData.getAttribute(RepositoryTaskAttribute.USER_ASSIGNED);
-		if (owner != null && owner.getValue().indexOf(repository.getUserName()) != -1) {
-			return;
-		}
-
-		RepositoryTaskAttribute reporter = taskData.getAttribute(RepositoryTaskAttribute.USER_REPORTER);
-		if (reporter != null && reporter.getValue().indexOf(repository.getUserName()) != -1) {
-			return;
-		}
-
-		RepositoryTaskAttribute ccAttribute = taskData.getAttribute(RepositoryTaskAttribute.USER_CC);
-		if (ccAttribute != null && ccAttribute.getValues().contains(repository.getUserName())) {
-			return;
-		}
-
-		FormToolkit toolkit = getManagedForm().getToolkit();
-		toolkit.createLabel(composite, "");
-		final Button addSelfButton = toolkit.createButton(composite, "Add me to CC", SWT.CHECK);
-		addSelfButton.setSelection(RepositoryTaskAttribute.TRUE.equals(taskData.getAttributeValue(RepositoryTaskAttribute.ADD_SELF_CC)));
-		addSelfButton.setImage(CommonImages.getImage(CommonImages.PERSON));
-		addSelfButton.addSelectionListener(new SelectionAdapter() {
-			@Override
-			public void widgetSelected(SelectionEvent e) {
-				if (addSelfButton.getSelection()) {
-					taskData.setAttributeValue(RepositoryTaskAttribute.ADD_SELF_CC, RepositoryTaskAttribute.TRUE);
-				} else {
-					taskData.setAttributeValue(RepositoryTaskAttribute.ADD_SELF_CC, RepositoryTaskAttribute.FALSE);
-				}
-				RepositoryTaskAttribute attribute = taskData.getAttribute(RepositoryTaskAttribute.ADD_SELF_CC);
-				changedAttributes.add(attribute);
-				markDirty(true);
-			}
-		});
-	}
-
-	public boolean getAttachContext() {
-		if (attachContextButton == null || attachContextButton.isDisposed()) {
-			return false;
-		} else {
-			return attachContextButton.getSelection();
-		}
-	}
-
-	public void setExpandAttributeSection(boolean expandAttributeSection) {
-		this.expandedStateAttributes = expandAttributeSection;
-	}
-
-	public void setAttachContextEnabled(boolean attachContextEnabled) {
-		this.attachContextEnabled = attachContextEnabled;
-//		if (attachContextButton != null && attachContextButton.isEnabled()) {
-//			attachContextButton.setSelection(attachContext);
-//		}
-	}
-
-	@Override
-	public void showBusy(boolean busy) {
-		if (!getManagedForm().getForm().isDisposed() && busy != formBusy) {
-			// parentEditor.showBusy(busy);
-			if (synchronizeEditorAction != null) {
-				synchronizeEditorAction.setEnabled(!busy);
-			}
-
-			if (activateAction != null) {
-				activateAction.setEnabled(!busy);
-			}
-
-			if (openBrowserAction != null) {
-				openBrowserAction.setEnabled(!busy);
-			}
-
-			if (historyAction != null) {
-				historyAction.setEnabled(!busy);
-			}
-
-			if (newSubTaskAction != null) {
-				newSubTaskAction.setEnabled(!busy);
-			}
-
-			if (clearOutgoingAction != null) {
-				clearOutgoingAction.setEnabled(!busy);
-			}
-
-			if (submitButton != null && !submitButton.isDisposed()) {
-				submitButton.setEnabled(!busy);
-			}
-
-			setEnabledState(editorComposite, !busy);
-
-			formBusy = busy;
-		}
-	}
-
-	private void setEnabledState(Composite composite, boolean enabled) {
-		if (!composite.isDisposed()) {
-			composite.setEnabled(enabled);
-			for (Control control : composite.getChildren()) {
-				control.setEnabled(enabled);
-				if (control instanceof Composite) {
-					setEnabledState(((Composite) control), enabled);
-				}
-			}
-		}
-	}
-
-	public void setGlobalBusy(boolean busy) {
-		if (parentEditor != null) {
-			parentEditor.showBusy(busy);
-		} else {
-			showBusy(busy);
-		}
-	}
-
-	public void submitToRepository() {
-		setGlobalBusy(true);
-
-		if (isDirty()) {
-			saveTaskOffline(new NullProgressMonitor());
-			markDirty(false);
-		}
-
-		final boolean attachContext = getAttachContext();
-
-		Job submitJob = new Job(LABEL_JOB_SUBMIT) {
-
-			@Override
-			protected IStatus run(IProgressMonitor monitor) {
-				AbstractTask modifiedTask = null;
-				try {
-					monitor.beginTask("Submitting task", 3);
-					String taskId = connector.getLegacyTaskDataHandler().postTaskData(repository, taskData,
-							new SubProgressMonitor(monitor, 1));
-					final boolean isNew = taskData.isNew();
-					if (isNew) {
-						if (taskId != null) {
-							modifiedTask = updateSubmittedTask(taskId, new SubProgressMonitor(monitor, 1));
-						} else {
-							// null taskId, assume task could not be created...
-							throw new CoreException(
-									new RepositoryStatus(IStatus.ERROR, TasksUiPlugin.ID_PLUGIN,
-											RepositoryStatus.ERROR_INTERNAL,
-											"Task could not be created. No additional information was provided by the connector."));
-						}
-					} else {
-						modifiedTask = (AbstractTask) TasksUiInternal.getTaskList().getTask(
-								repository.getRepositoryUrl(), taskData.getTaskId());
-					}
-
-					// Synchronization accounting...
-					if (modifiedTask != null) {
-						// Attach context if required
-						if (attachContext && connector.getAttachmentHandler() != null) {
-							AttachmentUtil.attachContext(connector.getAttachmentHandler(), repository, modifiedTask,
-									"", new SubProgressMonitor(monitor, 1));
-						}
-
-						modifiedTask.setSubmitting(true);
-						final AbstractTask finalModifiedTask = modifiedTask;
-						TasksUiInternal.synchronizeTask(connector, modifiedTask, true, new JobChangeAdapter() {
-
-							@Override
-							public void done(IJobChangeEvent event) {
-
-								if (isNew) {
-									close();
-									TasksUiPlugin.getTaskDataManager().setTaskRead(finalModifiedTask, true);
-									PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {
-										public void run() {
-											TasksUiUtil.openTask(finalModifiedTask);
-										}
-									});
-								} else {
-//									PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {
-//										public void run() {
-//											refreshEditor();
-//										}
-//									});
-								}
-							}
-						});
-						TasksUiPlugin.getSynchronizationScheduler().synchronize(repository);
-					} else {
-						close();
-						// For some reason the task wasn't retrieved.
-						// Try to
-						// open local then via web browser...
-						PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {
-							public void run() {
-								TasksUiUtil.openTask(repository.getRepositoryUrl(), taskData.getTaskId(),
-										connector.getTaskUrl(taskData.getRepositoryUrl(), taskData.getTaskId()));
-							}
-						});
-					}
-
-					return Status.OK_STATUS;
-				} catch (OperationCanceledException e) {
-					if (modifiedTask != null) {
-						modifiedTask.setSubmitting(false);
-					}
-					PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {
-						public void run() {
-							setGlobalBusy(false);// enableButtons();
-						}
-					});
-					return Status.CANCEL_STATUS;
-				} catch (CoreException e) {
-					if (modifiedTask != null) {
-						modifiedTask.setSubmitting(false);
-					}
-					return handleSubmitError(e);
-				} catch (Exception e) {
-					if (modifiedTask != null) {
-						modifiedTask.setSubmitting(false);
-					}
-					StatusHandler.fail(new Status(IStatus.ERROR, TasksUiPlugin.ID_PLUGIN, e.getMessage(), e));
-					PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {
-						public void run() {
-							setGlobalBusy(false);// enableButtons();
-						}
-					});
-				} finally {
-					monitor.done();
-				}
-				return Status.OK_STATUS;
-			}
-
-		};
-
-		IJobChangeListener jobListener = getSubmitJobListener();
-		if (jobListener != null) {
-			submitJob.addJobChangeListener(jobListener);
-		}
-		submitJob.schedule();
-	}
-
-	/**
-	 * @since 2.0 If existing task editor, update contents in place
-	 */
-	public void refreshEditor() {
-		try {
-			if (!getManagedForm().getForm().isDisposed()) {
-				if (this.isDirty && taskData != null && !taskData.isNew()) {
-					this.doSave(new NullProgressMonitor());
-				}
-				setGlobalBusy(true);
-				changedAttributes.clear();
-				commentComposites.clear();
-				controlBySelectableObject.clear();
-				editorInput.refreshInput();
-
-				// Note: Marking read must run synchronously
-				// If not, incomings resulting from subsequent synchronization
-				// can get marked as read (without having been viewed by user
-				if (repositoryTask != null) {
-					try {
-						refreshing = true;
-						TasksUiPlugin.getTaskDataManager().setTaskRead(repositoryTask, true);
-					} finally {
-						refreshing = false;
-					}
-				}
-
-				this.setInputWithNotify(this.getEditorInput());
-				this.init(this.getEditorSite(), this.getEditorInput());
-
-				// Header must be updated after init is called to task data is available
-				updateHeaderControls();
-
-				PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {
-
-					public void run() {
-						if (editorComposite != null && !editorComposite.isDisposed()) {
-							if (taskData != null) {
-								updateEditorTitle();
-								menu = editorComposite.getMenu();
-								removeSections();
-								editorComposite.setMenu(menu);
-								createSections();
-								form.reflow(true);
-								// setFormHeaderLabel();
-								markDirty(false);
-								parentEditor.setMessage(null, 0);
-								AbstractRepositoryTaskEditor.this.getEditor().setActivePage(
-										AbstractRepositoryTaskEditor.this.getId());
-
-								// Activate editor disabled: bug#179078
-								// AbstractTaskEditor.this.getEditor().getEditorSite().getPage().activate(
-								// AbstractTaskEditor.this);
-
-								// TODO: expand sections that were previously
-								// expanded
-
-								if (taskOutlineModel != null && outlinePage != null
-										&& !outlinePage.getControl().isDisposed()) {
-									outlinePage.getOutlineTreeViewer().setInput(taskOutlineModel);
-									outlinePage.getOutlineTreeViewer().refresh(true);
-								}
-
-//								if (repositoryTask != null) {
-//									TasksUiPlugin.getTaskDataManager().setTaskRead(repositoryTask, true);
-//								}
-
-								setSubmitEnabled(true);
-							}
-						}
-					}
-				});
-
-			} else {
-				// Editor possibly closed as part of submit, mark read
-
-				// Note: Marking read must run synchronously
-				// If not, incomings resulting from subsequent synchronization
-				// can get marked as read (without having been viewed by user
-				if (repositoryTask != null) {
-					TasksUiPlugin.getTaskDataManager().setTaskRead(repositoryTask, true);
-				}
-			}
-		} finally {
-			if (!getManagedForm().getForm().isDisposed()) {
-				setGlobalBusy(false);
-			}
-		}
-	}
-
-	/**
-	 * Used to prevent form menu from being disposed when disposing elements on the form during refresh
-	 */
-	private void setMenu(Composite comp, Menu menu) {
-		if (!comp.isDisposed()) {
-			comp.setMenu(null);
-			for (Control child : comp.getChildren()) {
-				child.setMenu(null);
-				if (child instanceof Composite) {
-					setMenu((Composite) child, menu);
-				}
-			}
-		}
-	}
-
-	protected IJobChangeListener getSubmitJobListener() {
-		return null;
-	}
-
-	protected AbstractTaskCategory getCategory() {
-		return null;
-	}
-
-	protected IStatus handleSubmitError(final CoreException exception) {
-		PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {
-			public void run() {
-				if (form != null && !form.isDisposed()) {
-					if (exception.getStatus().getCode() == RepositoryStatus.ERROR_IO) {
-						parentEditor.setMessage(ERROR_NOCONNECTIVITY, IMessageProvider.ERROR);
-						StatusHandler.log(exception.getStatus());
-					} else if (exception.getStatus().getCode() == RepositoryStatus.REPOSITORY_COMMENT_REQUIRED) {
-						TasksUiInternal.displayStatus("Comment required", exception.getStatus());
-						if (!getManagedForm().getForm().isDisposed() && newCommentTextViewer != null
-								&& !newCommentTextViewer.getControl().isDisposed()) {
-							newCommentTextViewer.getControl().setFocus();
-						}
-					} else if (exception.getStatus().getCode() == RepositoryStatus.ERROR_REPOSITORY_LOGIN) {
-						if (TasksUiUtil.openEditRepositoryWizard(repository) == MessageDialog.OK) {
-							submitToRepository();
-							return;
-						}
-					} else {
-						TasksUiInternal.displayStatus("Submit failed", exception.getStatus());
-					}
-					setGlobalBusy(false);
-				}
-			}
-
-		});
-		return Status.OK_STATUS;
-	}
-
-	protected AbstractTask updateSubmittedTask(String postResult, IProgressMonitor monitor) throws CoreException {
-		final AbstractTask newTask = (AbstractTask) TasksUiInternal.createTask(repository, postResult, monitor);
-
-		if (newTask != null) {
-			PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {
-				public void run() {
-					if (getCategory() != null) {
-						TasksUiInternal.getTaskList().addTask(newTask, getCategory());
-					}
-				}
-			});
-		}
-
-		return newTask;
-	}
-
-	/**
-	 * Class to handle the selection change of the radio buttons.
-	 */
-	private class RadioButtonListener implements SelectionListener, ModifyListener {
-
-		public void widgetDefaultSelected(SelectionEvent e) {
-			widgetSelected(e);
-		}
-
-		public void widgetSelected(SelectionEvent e) {
-			Button selected = null;
-			for (Button radio : radios) {
-				if (radio.getSelection()) {
-					selected = radio;
-				}
-			}
-			// determine the operation to do to the bug
-			for (int i = 0; i < radios.length; i++) {
-				if (radios[i] != e.widget && radios[i] != selected) {
-					radios[i].setSelection(false);
-				}
-
-				if (e.widget == radios[i]) {
-					RepositoryOperation o = taskData.getOperation(radios[i].getText());
-					taskData.setSelectedOperation(o);
-					markDirty(true);
-				} else if (e.widget == radioOptions[i]) {
-					RepositoryOperation o = taskData.getOperation(radios[i].getText());
-					o.setOptionSelection(((CCombo) radioOptions[i]).getItem(((CCombo) radioOptions[i]).getSelectionIndex()));
-
-					if (taskData.getSelectedOperation() != null) {
-						taskData.getSelectedOperation().setChecked(false);
-					}
-					o.setChecked(true);
-
-					taskData.setSelectedOperation(o);
-					radios[i].setSelection(true);
-					if (selected != null && selected != radios[i]) {
-						selected.setSelection(false);
-					}
-					markDirty(true);
-				}
-			}
-			validateInput();
-		}
-
-		public void modifyText(ModifyEvent e) {
-			Button selected = null;
-			for (Button radio : radios) {
-				if (radio.getSelection()) {
-					selected = radio;
-				}
-			}
-			// determine the operation to do to the bug
-			for (int i = 0; i < radios.length; i++) {
-				if (radios[i] != e.widget && radios[i] != selected) {
-					radios[i].setSelection(false);
-				}
-
-				if (e.widget == radios[i]) {
-					RepositoryOperation o = taskData.getOperation(radios[i].getText());
-					taskData.setSelectedOperation(o);
-					markDirty(true);
-				} else if (e.widget == radioOptions[i]) {
-					RepositoryOperation o = taskData.getOperation(radios[i].getText());
-					o.setInputValue(((Text) radioOptions[i]).getText());
-
-					if (taskData.getSelectedOperation() != null) {
-						taskData.getSelectedOperation().setChecked(false);
-					}
-					o.setChecked(true);
-
-					taskData.setSelectedOperation(o);
-					radios[i].setSelection(true);
-					if (selected != null && selected != radios[i]) {
-						selected.setSelection(false);
-					}
-					markDirty(true);
-				}
-			}
-			validateInput();
-		}
-	}
-
-	public AbstractRepositoryConnector getConnector() {
-		return connector;
-	}
-
-	public void setShowAttachments(boolean showAttachments) {
-		this.showAttachments = showAttachments;
-	}
-
-	public String getCommonDateFormat() {
-		return HEADER_DATE_FORMAT;
-	}
-
-	public Color getColorIncoming() {
-		return colorIncoming;
-	}
-
-	/**
-	 * @see #select(Object, boolean)
-	 */
-	public void addSelectableControl(Object item, Control control) {
-		controlBySelectableObject.put(item, control);
-	}
-
-	/**
-	 * @see #addSelectableControl(Object, Control)
-	 */
-	public void removeSelectableControl(Object item) {
-		controlBySelectableObject.remove(item);
-	}
-
-	/**
-	 * This method allow you to overwrite the generation of the form area for "assigned to" in the peopleLayout.<br>
-	 * <br>
-	 * The overwrite is used for Bugzilla Versions > 3.0
-	 * 
-	 * @since 2.1
-	 * @author Frank Becker (bug 198027)
-	 */
-	protected void addAssignedTo(Composite peopleComposite) {
-		boolean haveRealName = false;
-		RepositoryTaskAttribute assignedAttribute = taskData.getAttribute(RepositoryTaskAttribute.USER_ASSIGNED_NAME);
-		if (assignedAttribute == null) {
-			assignedAttribute = taskData.getAttribute(RepositoryTaskAttribute.USER_ASSIGNED);
-		} else {
-			haveRealName = true;
-		}
-		if (assignedAttribute != null) {
-			Label label = createLabel(peopleComposite, assignedAttribute);
-			GridDataFactory.fillDefaults().align(SWT.RIGHT, SWT.CENTER).applyTo(label);
-			Text textField;
-			if (assignedAttribute.isReadOnly()) {
-				textField = createTextField(peopleComposite, assignedAttribute, SWT.FLAT | SWT.READ_ONLY);
-			} else {
-				textField = createTextField(peopleComposite, assignedAttribute, SWT.FLAT);
-				ContentAssistCommandAdapter adapter = applyContentAssist(textField,
-						createContentProposalProvider(assignedAttribute));
-				ILabelProvider propsalLabelProvider = createProposalLabelProvider(assignedAttribute);
-				if (propsalLabelProvider != null) {
-					adapter.setLabelProvider(propsalLabelProvider);
-				}
-				adapter.setProposalAcceptanceStyle(ContentProposalAdapter.PROPOSAL_REPLACE);
-			}
-			GridDataFactory.fillDefaults().grab(true, false).applyTo(textField);
-			if (haveRealName) {
-				textField.setText(textField.getText() + " <"
-						+ taskData.getAttributeValue(RepositoryTaskAttribute.USER_ASSIGNED) + ">");
-			}
-
-		}
-	}
-
-	/**
-	 * force a re-layout of entire form
-	 */
-	protected void resetLayout() {
-		if (refreshEnabled) {
-			form.layout(true, true);
-			form.reflow(true);
-		}
-	}
-
-	/**
-	 * @since 2.3
-	 */
-	protected Hyperlink createTaskListHyperlink(Composite parent, final String taskId, final String taskUrl,
-			final AbstractTask task) {
-		TaskHyperlink hyperlink = new TaskHyperlink(parent, SWT.SHORT | getManagedForm().getToolkit().getOrientation());
-		getManagedForm().getToolkit().adapt(hyperlink, true, true);
-		getManagedForm().getToolkit().getHyperlinkGroup().add(hyperlink);
-		hyperlink.setTask(task);
-		if (task == null) {
-			hyperlink.setText(taskId);
-		}
-		hyperlink.addHyperlinkListener(new HyperlinkAdapter() {
-			@Override
-			public void linkActivated(HyperlinkEvent e) {
-				if (task != null) {
-					TasksUiInternal.refreshAndOpenTaskListElement(task);
-				} else {
-					TasksUiUtil.openTask(repository.getRepositoryUrl(), taskId, taskUrl);
-				}
-			}
-		});
-		return hyperlink;
-	}
-
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/editors/AbstractRepositoryTaskEditorInput.java b/org.eclipse.mylyn.ide.dev/developer/src-old/editors/AbstractRepositoryTaskEditorInput.java
deleted file mode 100644
index aedca41..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/editors/AbstractRepositoryTaskEditorInput.java
+++ /dev/null
@@ -1,133 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004, 2008 Tasktop Technologies and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     Tasktop Technologies - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.mylyn.internal.tasks.ui.deprecated;
-
-import java.util.Set;
-
-import org.eclipse.jface.resource.ImageDescriptor;
-import org.eclipse.mylyn.internal.tasks.core.deprecated.RepositoryTaskAttribute;
-import org.eclipse.mylyn.internal.tasks.core.deprecated.RepositoryTaskData;
-import org.eclipse.mylyn.internal.tasks.ui.TasksUiPlugin;
-import org.eclipse.mylyn.tasks.core.TaskRepository;
-import org.eclipse.mylyn.tasks.ui.TasksUiImages;
-import org.eclipse.ui.IEditorInput;
-import org.eclipse.ui.IPersistableElement;
-
-/**
- * @deprecated Do not use. This class is pending for removal: see bug 237552.
- */
-@Deprecated
-public abstract class AbstractRepositoryTaskEditorInput implements IEditorInput {
-
-	protected String toolTipText = "";
-
-	final protected TaskRepository repository;
-
-	final private String taskId;
-
-	private RepositoryTaskData editableTaskData;
-
-	private RepositoryTaskData oldTaskData;
-
-	private Set<RepositoryTaskAttribute> oldEdits;
-
-	protected AbstractRepositoryTaskEditorInput(TaskRepository repository, String taskId) {
-		this.taskId = taskId;
-		this.repository = repository;
-		this.refreshInput();
-	}
-
-	/**
-	 * Sets the tool tip text for this editor input.
-	 * 
-	 * @param str
-	 *            The new tool tip text.
-	 */
-	protected void setToolTipText(String str) {
-		// 03-20-03 Allows editor to store title (once it is known)
-		toolTipText = str;
-	}
-
-	public boolean exists() {
-		return true;
-	}
-
-	/**
-	 * returns the new task data
-	 */
-	public RepositoryTaskData getTaskData() {
-		return editableTaskData;
-	}
-
-	/**
-	 * returns the old task data
-	 */
-	public RepositoryTaskData getOldTaskData() {
-		return oldTaskData;
-	}
-
-	public Set<RepositoryTaskAttribute> getOldEdits() {
-		return oldEdits;
-	}
-
-	public ImageDescriptor getImageDescriptor() {
-		return TasksUiImages.REPOSITORY_SMALL;
-	}
-
-	public IPersistableElement getPersistable() {
-		return null;
-	}
-
-	public String getToolTipText() {
-		return getName();
-	}
-
-	@SuppressWarnings("unchecked")
-	public Object getAdapter(Class adapter) {
-		return null;
-	}
-
-	/**
-	 * @return <code>true</code> if the argument is an editor input on the same bug.
-	 */
-	@Override
-	public abstract boolean equals(Object o);
-
-	public TaskRepository getRepository() {
-		return repository;
-	}
-
-	protected void setEditableTaskData(RepositoryTaskData editableTaskData) {
-//		if (editableTaskData == null) {
-//			throw new IllegalArgumentException();
-//		}
-		this.editableTaskData = editableTaskData;
-	}
-
-	protected void setOldTaskData(RepositoryTaskData oldTaskData) {
-		this.oldTaskData = oldTaskData;
-	}
-
-	/**
-	 * @since 2.2
-	 */
-	protected void setOldEdits(Set<RepositoryTaskAttribute> oldEdits) {
-		this.oldEdits = oldEdits;
-	}
-
-	public void refreshInput() {
-		setEditableTaskData(TasksUiPlugin.getTaskDataStorageManager().getEditableCopy(repository.getRepositoryUrl(),
-				taskId));
-		setOldTaskData(TasksUiPlugin.getTaskDataStorageManager().getOldTaskData(repository.getRepositoryUrl(), taskId));
-		setOldEdits(TasksUiPlugin.getTaskDataStorageManager().getEdits(repository.getRepositoryUrl(), taskId));
-	}
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/editors/AbstractTaskEditorFactory.java b/org.eclipse.mylyn.ide.dev/developer/src-old/editors/AbstractTaskEditorFactory.java
deleted file mode 100644
index ffeab9b..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/editors/AbstractTaskEditorFactory.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004, 2008 Tasktop Technologies and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     Tasktop Technologies - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.mylyn.internal.tasks.ui.deprecated;
-
-import org.eclipse.mylyn.tasks.core.ITask;
-import org.eclipse.mylyn.tasks.ui.editors.TaskEditor;
-import org.eclipse.ui.IEditorInput;
-import org.eclipse.ui.IEditorPart;
-
-/**
- * @deprecated Do not use. This class is pending for removal: see bug 237552.
- */
-@Deprecated
-public abstract class AbstractTaskEditorFactory {
-
-	public abstract IEditorPart createEditor(TaskEditor parentEditor, IEditorInput editorInput);
-
-	/**
-	 * @since 3.0
-	 */
-	public abstract IEditorInput createEditorInput(ITask task);
-
-	public abstract String getTitle();
-
-	/**
-	 * @since 3.0
-	 */
-	public abstract boolean canCreateEditorFor(ITask task);
-
-	public abstract boolean canCreateEditorFor(IEditorInput input);
-
-	public boolean providesOutline() {
-		return false;
-	}
-
-	/**
-	 * @return A higher integer for high priority, low integer for low priority. Higher priority editors will be placed
-	 *         earlier in the tab list.
-	 */
-	public int getTabOrderPriority() {
-		return 1;
-	}
-
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/editors/AutoFoldingStructureProvider.java b/org.eclipse.mylyn.ide.dev/developer/src-old/editors/AutoFoldingStructureProvider.java
deleted file mode 100644
index 846a2dd..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/editors/AutoFoldingStructureProvider.java
+++ /dev/null
@@ -1,944 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004 - 2005 University Of British Columbia and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     University Of British Columbia - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.mylyn.java.ui.editor;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.eclipse.jdt.core.ElementChangedEvent;
-import org.eclipse.jdt.core.ICompilationUnit;
-import org.eclipse.jdt.core.IElementChangedListener;
-import org.eclipse.jdt.core.IJavaElement;
-import org.eclipse.jdt.core.IJavaElementDelta;
-import org.eclipse.jdt.core.IMember;
-import org.eclipse.jdt.core.IParent;
-import org.eclipse.jdt.core.ISourceRange;
-import org.eclipse.jdt.core.ISourceReference;
-import org.eclipse.jdt.core.IType;
-import org.eclipse.jdt.core.JavaCore;
-import org.eclipse.jdt.core.JavaModelException;
-import org.eclipse.jdt.core.ToolFactory;
-import org.eclipse.jdt.core.compiler.IScanner;
-import org.eclipse.jdt.core.compiler.ITerminalSymbols;
-import org.eclipse.jdt.core.compiler.InvalidInputException;
-import org.eclipse.jdt.internal.ui.JavaPlugin;
-import org.eclipse.jdt.internal.ui.javaeditor.ClassFileEditor;
-import org.eclipse.jdt.internal.ui.javaeditor.CompilationUnitEditor;
-import org.eclipse.jdt.internal.ui.javaeditor.IClassFileEditorInput;
-import org.eclipse.jdt.internal.ui.javaeditor.JavaEditor;
-import org.eclipse.jdt.internal.ui.text.DocumentCharacterIterator;
-import org.eclipse.jdt.ui.IWorkingCopyManager;
-import org.eclipse.jdt.ui.text.folding.IJavaFoldingStructureProvider;
-import org.eclipse.jface.text.Assert;
-import org.eclipse.jface.text.BadLocationException;
-import org.eclipse.jface.text.IDocument;
-import org.eclipse.jface.text.IRegion;
-import org.eclipse.jface.text.Position;
-import org.eclipse.jface.text.Region;
-import org.eclipse.jface.text.source.Annotation;
-import org.eclipse.jface.text.source.IAnnotationModel;
-import org.eclipse.jface.text.source.projection.IProjectionListener;
-import org.eclipse.jface.text.source.projection.IProjectionPosition;
-import org.eclipse.jface.text.source.projection.ProjectionAnnotation;
-import org.eclipse.jface.text.source.projection.ProjectionAnnotationModel;
-import org.eclipse.jface.text.source.projection.ProjectionViewer;
-import org.eclipse.mylyn.core.IMylarElement;
-import org.eclipse.mylyn.core.MylarPlugin;
-import org.eclipse.mylyn.core.util.MylarStatusHandler;
-import org.eclipse.mylyn.ui.MylarUiPlugin;
-import org.eclipse.ui.texteditor.IDocumentProvider;
-import org.eclipse.ui.texteditor.ITextEditor;
-
-
-/**
- * Copied from: DefaultJavaFoldingStructureProvider
- * 
- * @author Mik Kersten
- */
-@SuppressWarnings("unchecked")
-public class AutoFoldingStructureProvider implements IProjectionListener, IJavaFoldingStructureProvider {
-
-    public static final String ID = "org.eclipse.mylyn.java.ui.editor.foldingprovider";
-    
-    private void computeAdditions(IJavaElement element, Map map) {
-        boolean createProjection= false;
-        boolean collapse= false;
-        switch (element.getElementType()) {
-            case IJavaElement.IMPORT_CONTAINER:
-                collapse = true;
-//                collapse= fAllowCollapsing && fCollapseImportContainer;
-                createProjection= true;
-                break;
-            case IJavaElement.TYPE:
-                if (isInnerType((IType)element)) {
-                    IMylarElement node = ContextCorePlugin.getContextManager().getElement(element.getHandleIdentifier());
-                    if (!MylarUiPlugin.getDefault().isGlobalFoldingEnabled()) {
-                        collapse = false;
-                    } else if (node == null || node.getInterest().isInteresting()) {
-                        collapse = false;
-                    } else {
-                        collapse = true;
-                    }
-                    createProjection= true;
-                    break;
-                }
-//                collapse= fAllowCollapsing && fCollapseInnerTypes && isInnerType((IType) element);
-                createProjection= true;
-                break;
-            case IJavaElement.METHOD:
-                IMylarElement node = ContextCorePlugin.getContextManager().getElement(element.getHandleIdentifier());
-                if (!MylarUiPlugin.getDefault().isGlobalFoldingEnabled()) {
-                    collapse = false;
-                } else if (node == null || node.getInterest().isInteresting()) {
-                    collapse = false;
-                } else {
-                    collapse = true;
-                }
-                createProjection= true;
-                break;
-            default: 
-                collapse = true;
-//                collapse= fAllowCollapsing && fCollapseMethods;
-//                createProjection= true;
-//                break;
-        }
-
-        if (createProjection) {
-            IRegion[] regions= computeProjectionRanges(element);
-            if (regions != null) {
-                // comments
-                for (int i= 0; i < regions.length - 1; i++) {
-                    Position position= createProjectionPosition(regions[i], null);
-                    boolean commentCollapse;
-                    if (position != null) {
-                        if (i == 0 && (regions.length > 2 || fHasHeaderComment) && element == fFirstType) {
-                            commentCollapse= fAllowCollapsing && fCollapseHeaderComments;
-                        } else {
-                            commentCollapse= fAllowCollapsing && fCollapseJavadoc;
-                        }
-                        map.put(new JavaProjectionAnnotation(element, commentCollapse, true), position);
-                    }
-                }
-                // code
-                Position position= createProjectionPosition(regions[regions.length - 1], element);
-                if (position != null)
-                    map.put(new JavaProjectionAnnotation(element, collapse, false), position);
-            }
-        }
-    }
-    
-    private void initializePreferences() {
-//        IPreferenceStore store= JavaPlugin.getDefault().getPreferenceStore();
-//      fCollapseInnerTypes= store.getBoolean(PreferenceConstants.EDITOR_FOLDING_INNERTYPES);
-//      fCollapseImportContainer= store.getBoolean(PreferenceConstants.EDITOR_FOLDING_IMPORTS);
-        fCollapseJavadoc= true ;//store.getBoolean(PreferenceConstants.EDITOR_FOLDING_JAVADOC);
-//      fCollapseMethods= store.getBoolean(PreferenceConstants.EDITOR_FOLDING_METHODS); XXX never used
-        fCollapseHeaderComments= true; //store.getBoolean(PreferenceConstants.EDITOR_FOLDING_HEADERS);
-    }
-    
-    /*
-     ************ COPIED FROM: DefaultJavaFoldingStructureProvider ****************
-     */
-    
-	private static final class JavaProjectionAnnotation extends ProjectionAnnotation {
-
-		private IJavaElement fJavaElement;
-		private boolean fIsComment;
-
-		public JavaProjectionAnnotation(IJavaElement element, boolean isCollapsed, boolean isComment) {
-			super(isCollapsed);
-			fJavaElement= element;
-			fIsComment= isComment;
-		}
-
-		public IJavaElement getElement() {
-			return fJavaElement;
-		}
-
-		public void setElement(IJavaElement element) {
-			fJavaElement= element;
-		}
-
-		public boolean isComment() {
-			return fIsComment;
-		}
-
-		public void setIsComment(boolean isComment) {
-			fIsComment= isComment;
-		}
-
-		@Override
-		public String toString() {
-			return "JavaProjectionAnnotation:\n" + //$NON-NLS-1$
-					"\telement: \t"+fJavaElement.toString()+"\n" + //$NON-NLS-1$ //$NON-NLS-2$
-					"\tcollapsed: \t" + isCollapsed() + "\n" + //$NON-NLS-1$ //$NON-NLS-2$
-					"\tcomment: \t" + fIsComment + "\n"; //$NON-NLS-1$ //$NON-NLS-2$
-		}
-	}
-
-	private static final class Tuple {
-		JavaProjectionAnnotation annotation;
-		Position position;
-		Tuple(JavaProjectionAnnotation annotation, Position position) {
-			this.annotation= annotation;
-			this.position= position;
-		}
-	}
-
-	private class ElementChangedListener implements IElementChangedListener {
-
-		/*
-		 * @see org.eclipse.jdt.core.IElementChangedListener#elementChanged(org.eclipse.jdt.core.ElementChangedEvent)
-		 */
-		public void elementChanged(ElementChangedEvent e) {
-			IJavaElementDelta delta= findElement(fInput, e.getDelta());
-			if (delta != null)
-				processDelta(delta);
-		}
-
-		private IJavaElementDelta findElement(IJavaElement target, IJavaElementDelta delta) {
-
-			if (delta == null || target == null)
-				return null;
-
-			IJavaElement element= delta.getElement();
-
-			if (element.getElementType() > IJavaElement.CLASS_FILE)
-				return null;
-
-			if (target.equals(element))
-				return delta;
-
-			IJavaElementDelta[] children= delta.getAffectedChildren();
-
-			for (int i= 0; i < children.length; i++) {
-				IJavaElementDelta d= findElement(target, children[i]);
-				if (d != null)
-					return d;
-			}
-
-			return null;
-		}
-	}
-
-	/**
-	 * Projection position that will return two foldable regions: one folding away
-	 * the region from after the '/**' to the beginning of the content, the other
-	 * from after the first content line until after the comment.
-	 *
-	 * @since 3.1
-	 */
-	private static final class CommentPosition extends Position implements IProjectionPosition {
-		CommentPosition(int offset, int length) {
-			super(offset, length);
-		}
-
-		/*
-		 * @see org.eclipse.jface.text.source.projection.IProjectionPosition#computeFoldingRegions(org.eclipse.jface.text.IDocument)
-		 */
-		public IRegion[] computeProjectionRegions(IDocument document) throws BadLocationException {
-			DocumentCharacterIterator sequence= new DocumentCharacterIterator(document, offset, offset + length);
-			int prefixEnd= 0;
-			int contentStart= findFirstContent(sequence, prefixEnd);
-
-			int firstLine= document.getLineOfOffset(offset + prefixEnd);
-			int captionLine= document.getLineOfOffset(offset + contentStart);
-			int lastLine= document.getLineOfOffset(offset + length);
-
-			Assert.isTrue(firstLine <= captionLine, "first folded line is greater than the caption line"); //$NON-NLS-1$
-			Assert.isTrue(captionLine <= lastLine, "caption line is greater than the last folded line"); //$NON-NLS-1$
-
-			IRegion preRegion;
-			if (firstLine < captionLine) {
-//				preRegion= new Region(offset + prefixEnd, contentStart - prefixEnd);
-				int preOffset= document.getLineOffset(firstLine);
-				IRegion preEndLineInfo= document.getLineInformation(captionLine);
-				int preEnd= preEndLineInfo.getOffset();
-				preRegion= new Region(preOffset, preEnd - preOffset);
-			} else {
-				preRegion= null;
-			}
-
-			if (captionLine < lastLine) {
-				int postOffset= document.getLineOffset(captionLine + 1);
-				IRegion postRegion= new Region(postOffset, offset + length - postOffset);
-
-				if (preRegion == null)
-					return new IRegion[] { postRegion };
-
-				return new IRegion[] { preRegion, postRegion };
-			}
-
-			if (preRegion != null)
-				return new IRegion[] { preRegion };
-
-			return null;
-		}
-
-		/**
-		 * Finds the offset of the first identifier part within <code>content</code>.
-		 * Returns 0 if none is found.
-		 *
-		 * @param content the content to search
-		 * @return the first index of a unicode identifier part, or zero if none can
-		 *         be found
-		 */
-		private int findFirstContent(final CharSequence content, int prefixEnd) {
-			int lenght= content.length();
-			for (int i= prefixEnd; i < lenght; i++) {
-				if (Character.isUnicodeIdentifierPart(content.charAt(i)))
-					return i;
-			}
-			return 0;
-		}
-
-//		/**
-//		 * Finds the offset of the first identifier part within <code>content</code>.
-//		 * Returns 0 if none is found.
-//		 *
-//		 * @param content the content to search
-//		 * @return the first index of a unicode identifier part, or zero if none can
-//		 *         be found
-//		 */
-//		private int findPrefixEnd(final CharSequence content) {
-//			// return the index after the leading '/*' or '/**'
-//			int len= content.length();
-//			int i= 0;
-//			while (i < len && isWhiteSpace(content.charAt(i)))
-//				i++;
-//			if (len >= i + 2 && content.charAt(i) == '/' && content.charAt(i + 1) == '*')
-//				if (len >= i + 3 && content.charAt(i + 2) == '*')
-//					return i + 3;
-//				else
-//					return i + 2;
-//			else
-//				return i;
-//		}
-//
-//		private boolean isWhiteSpace(char c) {
-//			return c == ' ' || c == '\t';
-//		}
-
-		/*
-		 * @see org.eclipse.jface.text.source.projection.IProjectionPosition#computeCaptionOffset(org.eclipse.jface.text.IDocument)
-		 */
-		public int computeCaptionOffset(IDocument document) {
-//			return 0;
-			DocumentCharacterIterator sequence= new DocumentCharacterIterator(document, offset, offset + length);
-			return findFirstContent(sequence, 0);
-		}
-	}
-
-	/**
-	 * Projection position that will return two foldable regions: one folding away
-	 * the lines before the one containing the simple name of the java element, one
-	 * folding away any lines after the caption.
-	 *
-	 * @since 3.1
-	 */
-	private static final class JavaElementPosition extends Position implements IProjectionPosition {
-
-		private final IMember fMember;
-
-		public JavaElementPosition(int offset, int length, IMember member) {
-			super(offset, length);
-			Assert.isNotNull(member);
-			fMember= member;
-		}
-
-		/*
-		 * @see org.eclipse.jface.text.source.projection.IProjectionPosition#computeFoldingRegions(org.eclipse.jface.text.IDocument)
-		 */
-		public IRegion[] computeProjectionRegions(IDocument document) throws BadLocationException {
-			int nameStart= offset;
-			try {
-				/* The member's name range may not be correct. However,
-				 * reconciling would trigger another element delta which would
-				 * lead to reentrant situations. Therefore, we optimistically
-				 * assume that the name range is correct, but double check the
-				 * received lines below. */
-				ISourceRange nameRange= fMember.getNameRange();
-				if (nameRange != null)
-					nameStart= nameRange.getOffset();
-
-			} catch (JavaModelException e) {
-				// ignore and use default
-			}
-
-			int firstLine= document.getLineOfOffset(offset);
-			int captionLine= document.getLineOfOffset(nameStart);
-			int lastLine= document.getLineOfOffset(offset + length);
-
-			/* see comment above - adjust the caption line to be inside the
-			 * entire folded region, and rely on later element deltas to correct
-			 * the name range. */
-			if (captionLine < firstLine)
-				captionLine= firstLine;
-			if (captionLine > lastLine)
-				captionLine= lastLine;
-
-			IRegion preRegion;
-			if (firstLine < captionLine) {
-				int preOffset= document.getLineOffset(firstLine);
-				IRegion preEndLineInfo= document.getLineInformation(captionLine);
-				int preEnd= preEndLineInfo.getOffset();
-				preRegion= new Region(preOffset, preEnd - preOffset);
-			} else {
-				preRegion= null;
-			}
-
-			if (captionLine < lastLine) {
-				int postOffset= document.getLineOffset(captionLine + 1);
-				IRegion postRegion= new Region(postOffset, offset + length - postOffset);
-
-				if (preRegion == null)
-					return new IRegion[] { postRegion };
-
-				return new IRegion[] { preRegion, postRegion };
-			}
-
-			if (preRegion != null)
-				return new IRegion[] { preRegion };
-
-			return null;
-		}
-
-		/*
-		 * @see org.eclipse.jface.text.source.projection.IProjectionPosition#computeCaptionOffset(org.eclipse.jface.text.IDocument)
-		 */
-		public int computeCaptionOffset(IDocument document) throws BadLocationException {
-			int nameStart= offset;
-			try {
-				// need a reconcile here?
-				ISourceRange nameRange= fMember.getNameRange();
-				if (nameRange != null)
-					nameStart= nameRange.getOffset();
-			} catch (JavaModelException e) {
-				// ignore and use default
-			}
-
-			return nameStart - offset;
-		}
-
-	}
-
-	private IDocument fCachedDocument;
-
-	private ITextEditor fEditor;
-	private ProjectionViewer fViewer;
-	private IJavaElement fInput;
-	private IElementChangedListener fElementListener;
-
-	private boolean fAllowCollapsing= false;
-	private boolean fCollapseJavadoc= false;
-//	private boolean fCollapseImportContainer= true;
-//	private boolean fCollapseInnerTypes= true;
-//	private boolean fCollapseMethods= false;
-	
-	private boolean fCollapseHeaderComments= true;
-
-	/* caches for header comment extraction. */
-	private IType fFirstType;
-	private boolean fHasHeaderComment;
-
-
-	public AutoFoldingStructureProvider() {
-		// no initialization needed
-	}
-
-	public void install(ITextEditor editor, ProjectionViewer viewer) {
-		if (editor instanceof JavaEditor) {
-			fEditor= editor;
-			fViewer= viewer;
-			fViewer.addProjectionListener(this);
-		}
-	}
-
-	public void uninstall() {
-		if (isInstalled()) {
-			projectionDisabled();
-			fViewer.removeProjectionListener(this);
-			fViewer= null;
-			fEditor= null;
-		}
-	}
-
-	protected boolean isInstalled() {
-		return fEditor != null;
-	}
-
-	/*
-	 * @see org.eclipse.jface.text.source.projection.IProjectionListener#projectionEnabled()
-	 */
-	public void projectionEnabled() {
-		// http://home.ott.oti.com/teams/wswb/anon/out/vms/index.html
-		// projectionEnabled messages are not always paired with projectionDisabled
-		// i.e. multiple enabled messages may be sent out.
-		// we have to make sure that we disable first when getting an enable
-		// message.
-		projectionDisabled();
-
-		if (fEditor instanceof JavaEditor) {
-			initialize();
-			fElementListener= new ElementChangedListener();
-			JavaCore.addElementChangedListener(fElementListener);
-		}
-	}
-
-	/*
-	 * @see org.eclipse.jface.text.source.projection.IProjectionListener#projectionDisabled()
-	 */
-	public void projectionDisabled() {
-		fCachedDocument= null;
-		if (fElementListener != null) {
-			JavaCore.removeElementChangedListener(fElementListener);
-			fElementListener= null;
-		}
-	}
-
-	public void initialize() {
-
-		if (!isInstalled())
-			return;
-
-		initializePreferences();
-
-		try {
-
-			IDocumentProvider provider= fEditor.getDocumentProvider();
-			fCachedDocument= provider.getDocument(fEditor.getEditorInput());
-			fAllowCollapsing= true;
-
-			fFirstType= null;
-			fHasHeaderComment= false;
-
-			if (fEditor instanceof CompilationUnitEditor) {
-				IWorkingCopyManager manager= JavaPlugin.getDefault().getWorkingCopyManager();
-				fInput= manager.getWorkingCopy(fEditor.getEditorInput());
-			} else if (fEditor instanceof ClassFileEditor) {
-				IClassFileEditorInput editorInput= (IClassFileEditorInput) fEditor.getEditorInput();
-				fInput= editorInput.getClassFile();
-			}
-
-			if (fInput != null) {
-				ProjectionAnnotationModel model= (ProjectionAnnotationModel) fEditor.getAdapter(ProjectionAnnotationModel.class);
-				if (model != null) {
-
-					if (fInput instanceof ICompilationUnit) {
-						ICompilationUnit unit= (ICompilationUnit) fInput;
-						synchronized (unit) {
-							try {
-								unit.reconcile(ICompilationUnit.NO_AST, false, null, null);
-							} catch (JavaModelException e) {
-								MylarStatusHandler.log(e, "could not initialize");
-							}
-						}
-					}
-
-					Map additions= computeAdditions((IParent) fInput);
-					model.removeAllAnnotations();
-					model.replaceAnnotations(null, additions);
-				}
-			}
-
-		} finally {
-			fCachedDocument= null;
-			fAllowCollapsing= false;
-
-			fFirstType= null;
-			fHasHeaderComment= false;
-		}
-	}
-
-
-	private Map computeAdditions(IParent parent) {
-		Map map= new LinkedHashMap(); // use a linked map to maintain ordering of comments
-		try {
-			computeAdditions(parent.getChildren(), map);
-		} catch (JavaModelException e) {
-		}
-		return map;
-	}
-
-	private void computeAdditions(IJavaElement[] elements, Map map) throws JavaModelException {
-		for (int i= 0; i < elements.length; i++) {
-			IJavaElement element= elements[i];
-
-			computeAdditions(element, map);
-
-			if (element instanceof IParent) {
-				IParent parent= (IParent) element;
-				computeAdditions(parent.getChildren(), map);
-			}
-		}
-	}
-
-	private boolean isInnerType(IType type) {
-
-		try {
-			return type.isMember();
-		} catch (JavaModelException x) {
-			IJavaElement parent= type.getParent();
-			if (parent != null) {
-				int parentType= parent.getElementType();
-				return (parentType != IJavaElement.COMPILATION_UNIT && parentType != IJavaElement.CLASS_FILE);
-			}
-		}
-
-		return false;
-	}
-
-	/**
-	 * Computes the projection ranges for a given <code>IJavaElement</code>.
-	 * More than one range may be returned if the element has a leading comment
-	 * which gets folded separately. If there are no foldable regions,
-	 * <code>null</code> is returned.
-	 *
-	 * @param element the java element that can be folded
-	 * @return the regions to be folded, or <code>null</code> if there are
-	 *         none
-	 */
-	private IRegion[] computeProjectionRanges(IJavaElement element) {
-
-		try {
-			if (element instanceof ISourceReference) {
-				ISourceReference reference= (ISourceReference) element;
-				ISourceRange range= reference.getSourceRange();
-
-				String contents= reference.getSource();
-				if (contents == null)
-					return null;
-
-				List regions= new ArrayList();
-				if (fFirstType == null && element instanceof IType) {
-					fFirstType= (IType) element;
-					IRegion headerComment= computeHeaderComment(fFirstType);
-					if (headerComment != null) {
-						regions.add(headerComment);
-						fHasHeaderComment= true;
-					}
-				}
-
-				IScanner scanner= ToolFactory.createScanner(true, false, false, false);
-				scanner.setSource(contents.toCharArray());
-				final int shift= range.getOffset();
-				int start= shift;
-				while (true) {
-
-					int token= scanner.getNextToken();
-					start= shift + scanner.getCurrentTokenStartPosition();
-
-					switch (token) {
-						case ITerminalSymbols.TokenNameCOMMENT_JAVADOC:
-						case ITerminalSymbols.TokenNameCOMMENT_BLOCK: {
-							int end= shift + scanner.getCurrentTokenEndPosition() + 1;
-							regions.add(new Region(start, end - start));
-						}
-						case ITerminalSymbols.TokenNameCOMMENT_LINE:
-							continue;
-					}
-
-					break;
-				}
-
-				regions.add(new Region(start, shift + range.getLength() - start));
-
-				if (regions.size() > 0) {
-					IRegion[] result= new IRegion[regions.size()];
-					regions.toArray(result);
-					return result;
-				}
-			}
-		} catch (JavaModelException e) {
-			MylarStatusHandler.log(e, "");
-		} catch (InvalidInputException e) {
-			MylarStatusHandler.log(e, "");
-		}
-
-		return null;
-	}
-
-	private IRegion computeHeaderComment(IType type) throws JavaModelException {
-		if (fCachedDocument == null)
-			return null;
-
-		// search at most up to the first type
-		ISourceRange range= type.getSourceRange();
-		if (range == null)
-			return null;
-		int start= 0;
-		int end= range.getOffset();
-
-		if (fInput instanceof ISourceReference) {
-			String content;
-			try {
-				content= fCachedDocument.get(start, end - start);
-			} catch (BadLocationException e) {
-				return null; // ignore header comment in that case
-			}
-
-			/* code adapted from CommentFormattingStrategy:
-			 * scan the header content up to the first type. Once a comment is
-			 * found, accumulate any additional comments up to the stop condition.
-			 * The stop condition is reaching a package declaration, import container,
-			 * or the end of the input.
-			 */
-			IScanner scanner= ToolFactory.createScanner(true, false, false, false);
-			scanner.setSource(content.toCharArray());
-
-			int headerStart= -1;
-			int headerEnd= -1;
-			try {
-				boolean foundComment= false;
-				int terminal= scanner.getNextToken();
-				while (terminal != ITerminalSymbols.TokenNameEOF && !(terminal == ITerminalSymbols.TokenNameclass || terminal == ITerminalSymbols.TokenNameinterface || terminal == ITerminalSymbols.TokenNameenum || (foundComment && (terminal == ITerminalSymbols.TokenNameimport || terminal == ITerminalSymbols.TokenNamepackage)))) {
-
-					if (terminal == ITerminalSymbols.TokenNameCOMMENT_JAVADOC || terminal == ITerminalSymbols.TokenNameCOMMENT_BLOCK || terminal == ITerminalSymbols.TokenNameCOMMENT_LINE) {
-						if (!foundComment)
-							headerStart= scanner.getCurrentTokenStartPosition();
-						headerEnd= scanner.getCurrentTokenEndPosition();
-						foundComment= true;
-					}
-					terminal= scanner.getNextToken();
-				}
-
-
-			} catch (InvalidInputException ex) {
-				return null;
-			}
-
-			if (headerEnd != -1) {
-				return new Region(headerStart, headerEnd - headerStart);
-			}
-		}
-		return null;
-	}
-
-	private Position createProjectionPosition(IRegion region, IJavaElement element) {
-
-		if (fCachedDocument == null)
-			return null;
-
-		try {
-
-			int start= fCachedDocument.getLineOfOffset(region.getOffset());
-			int end= fCachedDocument.getLineOfOffset(region.getOffset() + region.getLength());
-			if (start != end) {
-				int offset= fCachedDocument.getLineOffset(start);
-				int endOffset;
-				if (fCachedDocument.getNumberOfLines() > end + 1)
-					endOffset= fCachedDocument.getLineOffset(end + 1);
-				else if (end > start)
-					endOffset= fCachedDocument.getLineOffset(end) + fCachedDocument.getLineLength(end);
-				else
-					return null;
-				if (element instanceof IMember)
-					return new JavaElementPosition(offset, endOffset - offset, (IMember) element);
-				else
-					return new CommentPosition(offset, endOffset - offset);
-			}
-
-		} catch (BadLocationException e) {
-			MylarStatusHandler.log(e, "");
-		}
-
-		return null;
-	}
-
-	protected void processDelta(IJavaElementDelta delta) {
-
-		if (!isInstalled())
-			return;
-
-		ProjectionAnnotationModel model= (ProjectionAnnotationModel) fEditor.getAdapter(ProjectionAnnotationModel.class);
-		if (model == null)
-			return;
-
-		try {
-
-			IDocumentProvider provider= fEditor.getDocumentProvider();
-			fCachedDocument= provider.getDocument(fEditor.getEditorInput());
-			fAllowCollapsing= false;
-
-			fFirstType= null;
-			fHasHeaderComment= false;
-
-			Map additions= new HashMap();
-			List deletions= new ArrayList();
-			List updates= new ArrayList();
-
-			Map updated= computeAdditions((IParent) fInput);
-			Map previous= createAnnotationMap(model);
-
-
-			Iterator e= updated.keySet().iterator();
-			while (e.hasNext()) {
-				JavaProjectionAnnotation newAnnotation= (JavaProjectionAnnotation) e.next();
-				IJavaElement element= newAnnotation.getElement();
-				Position newPosition= (Position) updated.get(newAnnotation);
-
-				List annotations= (List) previous.get(element);
-				if (annotations == null) {
-
-					additions.put(newAnnotation, newPosition);
-
-				} else {
-					Iterator x= annotations.iterator();
-					boolean matched= false;
-					while (x.hasNext()) {
-						Tuple tuple= (Tuple) x.next();
-						JavaProjectionAnnotation existingAnnotation= tuple.annotation;
-						Position existingPosition= tuple.position;
-						if (newAnnotation.isComment() == existingAnnotation.isComment()) {
-							if (existingPosition != null && (!newPosition.equals(existingPosition))) {
-								existingPosition.setOffset(newPosition.getOffset());
-								existingPosition.setLength(newPosition.getLength());
-								updates.add(existingAnnotation);
-							}
-							matched= true;
-							x.remove();
-							break;
-						}
-					}
-					if (!matched)
-						additions.put(newAnnotation, newPosition);
-
-					if (annotations.isEmpty())
-						previous.remove(element);
-				}
-			}
-
-			e= previous.values().iterator();
-			while (e.hasNext()) {
-				List list= (List) e.next();
-				int size= list.size();
-				for (int i= 0; i < size; i++)
-					deletions.add(((Tuple) list.get(i)).annotation);
-			}
-
-			match(model, deletions, additions, updates);
-
-			Annotation[] removals= new Annotation[deletions.size()];
-			deletions.toArray(removals);
-			Annotation[] changes= new Annotation[updates.size()];
-			updates.toArray(changes);
-			model.modifyAnnotations(removals, additions, changes);
-
-		} finally {
-			fCachedDocument= null;
-			fAllowCollapsing= true;
-
-			fFirstType= null;
-			fHasHeaderComment= false;
-		}
-	}
-
-	private void match(ProjectionAnnotationModel model, List deletions, Map additions, List changes) {
-		if (deletions.isEmpty() || (additions.isEmpty() && changes.isEmpty()))
-			return;
-
-		List newDeletions= new ArrayList();
-		List newChanges= new ArrayList();
-
-		Iterator deletionIterator= deletions.iterator();
-		outer: while (deletionIterator.hasNext()) {
-			JavaProjectionAnnotation deleted= (JavaProjectionAnnotation) deletionIterator.next();
-			Position deletedPosition= model.getPosition(deleted);
-			if (deletedPosition == null)
-				continue;
-
-			Iterator changesIterator= changes.iterator();
-			while (changesIterator.hasNext()) {
-				JavaProjectionAnnotation changed= (JavaProjectionAnnotation) changesIterator.next();
-				if (deleted.isComment() == changed.isComment()) {
-					Position changedPosition= model.getPosition(changed);
-					if (changedPosition == null)
-						continue;
-
-					if (deletedPosition.getOffset() == changedPosition.getOffset()) {
-
-						deletedPosition.setLength(changedPosition.getLength());
-						deleted.setElement(changed.getElement());
-
-						deletionIterator.remove();
-						newChanges.add(deleted);
-
-						changesIterator.remove();
-						newDeletions.add(changed);
-
-						continue outer;
-					}
-				}
-			}
-
-			Iterator additionsIterator= additions.keySet().iterator();
-			while (additionsIterator.hasNext()) {
-				JavaProjectionAnnotation added= (JavaProjectionAnnotation) additionsIterator.next();
-				if (deleted.isComment() == added.isComment()) {
-					Position addedPosition= (Position) additions.get(added);
-
-					if (deletedPosition.getOffset() == addedPosition.getOffset()) {
-
-						deletedPosition.setLength(addedPosition.getLength());
-						deleted.setElement(added.getElement());
-
-						deletionIterator.remove();
-						newChanges.add(deleted);
-
-						additionsIterator.remove();
-
-						break;
-					}
-				}
-			}
-		}
-
-		deletions.addAll(newDeletions);
-		changes.addAll(newChanges);
-	}
-
-	private Map createAnnotationMap(IAnnotationModel model) {
-		Map map= new HashMap();
-		Iterator e= model.getAnnotationIterator();
-		while (e.hasNext()) {
-			Object annotation= e.next();
-			if (annotation instanceof JavaProjectionAnnotation) {
-				JavaProjectionAnnotation java= (JavaProjectionAnnotation) annotation;
-				Position position= model.getPosition(java);
-				Assert.isNotNull(position);
-				List list= (List) map.get(java.getElement());
-				if (list == null) {
-					list= new ArrayList(2);
-					map.put(java.getElement(), list);
-				}
-				list.add(new Tuple(java, position));
-			}
-		}
-
-		Comparator comparator= new Comparator() {
-			public int compare(Object o1, Object o2) {
-				return ((Tuple) o1).position.getOffset() - ((Tuple) o2).position.getOffset();
-			}
-		};
-		for (Iterator it= map.values().iterator(); it.hasNext();) {
-			List list= (List) it.next();
-			Collections.sort(list, comparator);
-		}
-		return map;
-	}
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/editors/ContentOutlineTools.java b/org.eclipse.mylyn.ide.dev/developer/src-old/editors/ContentOutlineTools.java
deleted file mode 100644
index d645ae5..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/editors/ContentOutlineTools.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004, 2008 Tasktop Technologies and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     Tasktop Technologies - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.mylyn.internal.tasks.ui.editors;
-
-/**
- * @deprecated Do not use. This class is pending for removal: see bug 237552.
- */
-@Deprecated
-public class ContentOutlineTools {
-
-	/** The default string used for locally created bugs. */
-	public static final String OFFLINE_SERVER_DEFAULT = "[local]";
-
-	/**
-	 * Returns a unique handle for the bugzilla selection. Contains the bug taskId, the bug server, and (if applicable)
-	 * the comment number.
-	 * 
-	 * @param taskSelection
-	 *            The bugzilla selection.
-	 * @return The handle for the bugzilla selection.
-	 */
-	public static String getHandle(IRepositoryTaskSelection taskSelection) {
-		String handle = taskSelection.getRepositoryUrl() + ";" + taskSelection.getId();
-		if (taskSelection.hasComment()) {
-			int number = taskSelection.getComment().getNumber() + 1;
-			handle += ";" + number;
-		} else if (taskSelection.isCommentHeader()) {
-			handle += ";1";
-		} else if (taskSelection.isDescription()) {
-			handle += ";0";
-		}
-		return handle;
-	}
-
-	public static String getName(IRepositoryTaskSelection taskSelection) {
-		String name = taskSelection.getRepositoryUrl() + ": Bug#: " + taskSelection.getId() + ": "
-				+ taskSelection.getBugSummary();
-		if (taskSelection.hasComment()) {
-			name += " : Comment#: " + taskSelection.getComment().getNumber();
-		} else if (taskSelection.isCommentHeader()) {
-			name += " : Comment Header";
-		} else if (taskSelection.isDescription()) {
-			name += ": Description";
-		}
-		return name;
-	}
-
-//	public static String getHandle(RepositoryTaskData taskData) {
-//		return getHandle(taskData.getRepositoryUrl(), taskData.getId());
-//	}
-//
-//	public static String getHandle(String server, String taskId) {
-//		return server + ";" + taskId;
-//	}
-
-//	public static String getName(RepositoryTaskData taskData) {
-//		return taskData.getRepositoryUrl() + ": Bug#: " + taskData.getId() + ": " + taskData.getSummary();
-//	}
-
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/editors/MylarClassFileEditor.java b/org.eclipse.mylyn.ide.dev/developer/src-old/editors/MylarClassFileEditor.java
deleted file mode 100644
index e163c2a..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/editors/MylarClassFileEditor.java
+++ /dev/null
@@ -1,148 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004 - 2005 University Of British Columbia and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     University Of British Columbia - initial API and implementation
- *******************************************************************************/
-/*
- * Created on Aug 6, 2004
-  */
-package org.eclipse.mylyn.java.ui.editor;
-
-import org.eclipse.jdt.core.IImportContainer;
-import org.eclipse.jdt.core.IImportDeclaration;
-import org.eclipse.jdt.core.IJavaElement;
-import org.eclipse.jdt.core.ISourceRange;
-import org.eclipse.jdt.core.ISourceReference;
-import org.eclipse.jdt.core.JavaModelException;
-import org.eclipse.jdt.internal.ui.javaeditor.ClassFileEditor;
-import org.eclipse.jdt.internal.ui.javaeditor.IClassFileEditorInput;
-import org.eclipse.jface.text.ITextViewerExtension5;
-import org.eclipse.jface.text.source.ISourceViewer;
-import org.eclipse.swt.custom.StyledText;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.ui.IPartService;
-import org.eclipse.ui.IWorkbenchPart;
-import org.eclipse.ui.IWorkbenchWindow;
-import org.eclipse.ui.views.contentoutline.ContentOutline;
-
-import org.eclipse.mylyn.core.MylarPlugin;
-
-/**
- * @author Mik Kersten
- */
-public class MylarClassFileEditor extends ClassFileEditor {
-
-//    private final ActiveFoldingListener FOLDING_LISTENER = new ActiveFoldingListener(this);
-    
-    @Override
-    public void createPartControl(Composite parent) {
-        super.createPartControl(parent);
-
-        PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {
-            public void run() {
-                ContextCorePlugin.getTaskscapeManager().addListener(FOLDING_LISTENER);
-            }
-        });
-    } 
-    
-    
-	// EXPOSED METHODS FROM SUPER CLASS, DO NOT MODIFY
-	// -----------------------------------------------
-	
-	/**
-	 * Computes and returns the source reference that includes the caret and
-	 * serves as provider for the outline page selection and the editor range
-	 * indication.
-	 * 
-	 * @return the computed source reference
-	 * @since 3.0
-	 */
-    @Override
-	protected ISourceReference computeHighlightRangeSourceReference() {
-		ISourceViewer sourceViewer= getSourceViewer();
-		if (sourceViewer == null)
-			return null;
-			
-		StyledText styledText= sourceViewer.getTextWidget();
-		if (styledText == null)
-			return null;
-		
-		int caret= 0;
-		if (sourceViewer instanceof ITextViewerExtension5) {
-			ITextViewerExtension5 extension= (ITextViewerExtension5)sourceViewer;
-			caret= extension.widgetOffset2ModelOffset(styledText.getCaretOffset());
-		} else {
-			int offset= sourceViewer.getVisibleRegion().getOffset();
-			caret= offset + styledText.getCaretOffset();
-		}
-
-		IJavaElement element= getElementAt(caret, false);
-		
-		if ( !(element instanceof ISourceReference))
-			return null;
-		
-		if (element.getElementType() == IJavaElement.IMPORT_DECLARATION) {
-			
-			IImportDeclaration declaration= (IImportDeclaration) element;
-			IImportContainer container= (IImportContainer) declaration.getParent();
-			ISourceRange srcRange= null;
-			
-			try {
-				srcRange= container.getSourceRange();
-			} catch (JavaModelException e) {
-				ContextCorePlugin.log(this.getClass().toString(), e);
-			}
-			
-			if (srcRange != null && srcRange.getOffset() == caret)
-				return container;
-		}
-		
-		return (ISourceReference) element;
-	}
-	
-	/**
-	 * Synchronizes the outliner selection with the given element
-	 * position in the editor.
-	 * 
-	 * @param element the java element to select
-	 * @param checkIfOutlinePageActive <code>true</code> if check for active outline page needs to be done
-	 */
-    @Override
-	protected void synchronizeOutlinePage(ISourceReference element, boolean checkIfOutlinePageActive) {
-		if (fOutlinePage != null && element != null && !(checkIfOutlinePageActive && isJavaOutlinePageActive())) {
-			fOutlineSelectionChangedListener.uninstall(fOutlinePage);
-			fOutlinePage.select(element);
-			fOutlineSelectionChangedListener.install(fOutlinePage);
-		}
-	}
-	
-	@Override
-	protected IJavaElement getElementAt(int offset) {
-		if (getEditorInput() instanceof IClassFileEditorInput) {
-			try {
-				IClassFileEditorInput input= (IClassFileEditorInput) getEditorInput();
-				return input.getClassFile().getElementAt(offset);
-			} catch (JavaModelException e) {
-				ContextCorePlugin.log(this.getClass().toString(), e);
-			}
-		}
-		return null;
-	}
-	
-	private boolean isJavaOutlinePageActive() {
-		IWorkbenchPart part= getActivePart();
-		return part instanceof ContentOutline && ((ContentOutline)part).getCurrentPage() == fOutlinePage;
-	}
-	
-	private IWorkbenchPart getActivePart() {
-		IWorkbenchWindow window= getSite().getWorkbenchWindow();
-		IPartService service= window.getPartService();
-		IWorkbenchPart part= service.getActivePart();
-		return part;
-	}
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/editors/NewTaskEditorInput.java b/org.eclipse.mylyn.ide.dev/developer/src-old/editors/NewTaskEditorInput.java
deleted file mode 100644
index 78357d9..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/editors/NewTaskEditorInput.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004, 2008 Tasktop Technologies and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     Tasktop Technologies - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.mylyn.internal.tasks.ui.deprecated;
-
-import java.util.Collections;
-import java.util.Set;
-
-import org.eclipse.mylyn.internal.tasks.core.deprecated.RepositoryTaskAttribute;
-import org.eclipse.mylyn.internal.tasks.core.deprecated.RepositoryTaskData;
-import org.eclipse.mylyn.tasks.core.TaskRepository;
-
-/**
- * @deprecated Do not use. This class is pending for removal: see bug 237552.
- */
-@Deprecated
-public class NewTaskEditorInput extends RepositoryTaskEditorInput {
-
-	public NewTaskEditorInput(TaskRepository repository, RepositoryTaskData taskData) {
-		super(repository, taskData.getTaskId(), "");
-		setOldTaskData(taskData);
-		Set<RepositoryTaskAttribute> edits = Collections.emptySet();
-		setOldEdits(edits);
-		setEditableTaskData(taskData);
-	}
-
-	@Override
-	public String getName() {
-		return this.toolTipText;
-	}
-
-	@Override
-	public boolean equals(Object o) {
-		if (o instanceof NewTaskEditorInput) {
-			NewTaskEditorInput input = (NewTaskEditorInput) o;
-			return input.getTaskData().equals(this.getTaskData());
-		}
-		return false;
-	}
-
-	@Override
-	public void refreshInput() {
-		// does nothing
-	}
-
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/editors/RepositoryTaskEditorCopyAction.java b/org.eclipse.mylyn.ide.dev/developer/src-old/editors/RepositoryTaskEditorCopyAction.java
deleted file mode 100644
index 8cb6d73..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/editors/RepositoryTaskEditorCopyAction.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004 - 2006 University Of British Columbia and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     University Of British Columbia - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.mylyn.internal.tasks.ui.editors;
-
-import org.eclipse.jface.action.Action;
-import org.eclipse.jface.viewers.ISelection;
-
-/**
- * Action used to copy selected text from a bug editor to the clipboard.
- */
-public class RepositoryTaskEditorCopyAction extends Action {
-	/** The editor to copy text selections from. */
-	private MylarTaskEditor bugEditor;
-
-	private ISelection selection;
-	
-	/**
-	 * Creates a new <code>RepositoryTaskEditorCopyAction</code>.
-	 * 
-	 * @param editor
-	 *            The editor that this action is copying text selections from.
-	 */
-	public RepositoryTaskEditorCopyAction(MylarTaskEditor editor) {
-		bugEditor = editor;
-		setText("AbstractTaskEditor.copy.text");
-	}
-
-	@Override
-	public void run() {
-		bugEditor.copyToClipboard(selection);		
-		//bugEditor.getCurrentText().copy();
-	}
-	
-	public void selectionChanged(ISelection selection) {
-		this.selection = selection;
-		setEnabled(bugEditor.canCopy(selection));
-	}
-
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/editors/RepositoryTaskEditorDropListener.java b/org.eclipse.mylyn.ide.dev/developer/src-old/editors/RepositoryTaskEditorDropListener.java
deleted file mode 100644
index 6806884..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/editors/RepositoryTaskEditorDropListener.java
+++ /dev/null
@@ -1,167 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004, 2008 Tasktop Technologies and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     Tasktop Technologies - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.mylyn.internal.tasks.ui.editors;
-
-import java.io.File;
-
-import org.eclipse.jface.dialogs.IMessageProvider;
-import org.eclipse.jface.window.Window;
-import org.eclipse.mylyn.internal.tasks.core.AbstractTask;
-import org.eclipse.mylyn.internal.tasks.core.deprecated.RepositoryTaskData;
-import org.eclipse.mylyn.internal.tasks.ui.deprecated.AbstractRepositoryTaskEditor;
-import org.eclipse.mylyn.internal.tasks.ui.util.TasksUiInternal;
-import org.eclipse.mylyn.internal.tasks.ui.wizards.NewAttachmentWizard;
-import org.eclipse.mylyn.internal.tasks.ui.wizards.NewAttachmentWizardDialog;
-import org.eclipse.mylyn.tasks.core.TaskRepository;
-import org.eclipse.swt.dnd.DND;
-import org.eclipse.swt.dnd.DropTargetEvent;
-import org.eclipse.swt.dnd.DropTargetListener;
-import org.eclipse.swt.dnd.FileTransfer;
-import org.eclipse.swt.dnd.TextTransfer;
-import org.eclipse.swt.dnd.TransferData;
-import org.eclipse.swt.widgets.Control;
-
-/**
- * @deprecated Do not use. This class is pending for removal: see bug 237552.
- */
-@Deprecated
-public class RepositoryTaskEditorDropListener implements DropTargetListener {
-
-	private final AbstractRepositoryTaskEditor editor;
-
-	private final FileTransfer fileTransfer;
-
-	private final TextTransfer textTransfer;
-
-	private final Control control;
-
-	private final TaskRepository repository;
-
-	private final RepositoryTaskData taskData;
-
-	public RepositoryTaskEditorDropListener(AbstractRepositoryTaskEditor editor, TaskRepository repository,
-			RepositoryTaskData taskData, FileTransfer fileTransfer, TextTransfer textTransfer, Control control) {
-		this.editor = editor;
-		this.repository = repository;
-		this.taskData = taskData;
-		this.fileTransfer = fileTransfer;
-		this.textTransfer = textTransfer;
-		this.control = control;
-	}
-
-	public void dragEnter(DropTargetEvent event) {
-		if (event.detail == DND.DROP_DEFAULT) {
-			if ((event.operations & DND.DROP_COPY) != 0) {
-				event.detail = DND.DROP_COPY;
-			} else {
-				event.detail = DND.DROP_NONE;
-			}
-		}
-		// will accept text but prefer to have files dropped
-		for (TransferData dataType : event.dataTypes) {
-			if (fileTransfer.isSupportedType(dataType)) {
-				event.currentDataType = dataType;
-				// files should only be copied
-				if (event.detail != DND.DROP_COPY) {
-					event.detail = DND.DROP_NONE;
-				}
-				break;
-			}
-		}
-	}
-
-	public void dragOver(DropTargetEvent event) {
-		event.feedback = DND.FEEDBACK_SELECT | DND.FEEDBACK_SCROLL;
-		// if (textTransfer.isSupportedType(event.currentDataType)) {
-		// // NOTE: on unsupported platforms this will return null
-		// Object o = textTransfer.nativeToJava(event.currentDataType);
-		// String t = (String)o;
-		// if (t != null) System.out.println(t);
-		// }
-	}
-
-	public void dragOperationChanged(DropTargetEvent event) {
-		if ((event.detail == DND.DROP_DEFAULT) || (event.operations & DND.DROP_COPY) != 0) {
-
-			event.detail = DND.DROP_COPY;
-		} else {
-			event.detail = DND.DROP_NONE;
-		}
-
-		// allow text to be moved but files should only be copied
-		if (fileTransfer.isSupportedType(event.currentDataType)) {
-			if (event.detail != DND.DROP_COPY) {
-				event.detail = DND.DROP_NONE;
-			}
-		}
-	}
-
-	public void dragLeave(DropTargetEvent event) {
-	}
-
-	public void dropAccept(DropTargetEvent event) {
-	}
-
-	public void drop(DropTargetEvent event) {
-		if (textTransfer.isSupportedType(event.currentDataType)) {
-			String text = (String) event.data;
-			AbstractTask task = (AbstractTask) TasksUiInternal.getTaskList().getTask(repository.getRepositoryUrl(),
-					taskData.getTaskId());
-			if (!(task != null)) {
-				// Should not happen
-				return;
-			}
-
-			editor.setGlobalBusy(true);
-			NewAttachmentWizard naw = new NewAttachmentWizard(repository, task, text);
-			openDialog(naw, null);
-		}
-		if (fileTransfer.isSupportedType(event.currentDataType)) {
-			String[] files = (String[]) event.data;
-			if (files.length > 0) {
-				AbstractTask task = (AbstractTask) TasksUiInternal.getTaskList().getTask(repository.getRepositoryUrl(),
-						taskData.getTaskId());
-				if (task == null) {
-					// Should not happen
-					return;
-				}
-
-				NewAttachmentWizard naw = new NewAttachmentWizard(repository, task, new File(files[0]));
-				String error = null;
-				if (files.length > 1) {
-					error = "Note that only the first file dragged will be attached.";
-				}
-				openDialog(naw, error);
-			}
-		}
-	}
-
-	/**
-	 * @param naw
-	 *            wizard to attach dialog to.
-	 * @param message
-	 *            error to display or none if <code>null</code>
-	 */
-	private void openDialog(NewAttachmentWizard naw, String message) {
-		editor.setGlobalBusy(true);
-		NewAttachmentWizardDialog dialog = new NewAttachmentWizardDialog(control.getShell(), naw, true);
-		naw.setDialog(dialog);
-		dialog.create();
-		if (null != message) {
-			dialog.setMessage(message, IMessageProvider.WARNING);
-		}
-		int result = dialog.open();
-		if (result != Window.OK) {
-			editor.setGlobalBusy(false);
-		}
-	}
-}
\ No newline at end of file
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/editors/RepositoryTaskEditorInput.java b/org.eclipse.mylyn.ide.dev/developer/src-old/editors/RepositoryTaskEditorInput.java
deleted file mode 100644
index f3fe9a6..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/editors/RepositoryTaskEditorInput.java
+++ /dev/null
@@ -1,109 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004, 2008 Tasktop Technologies and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     Tasktop Technologies - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.mylyn.internal.tasks.ui.deprecated;
-
-import org.eclipse.mylyn.internal.tasks.core.AbstractTask;
-import org.eclipse.mylyn.internal.tasks.ui.util.TasksUiInternal;
-import org.eclipse.mylyn.tasks.core.TaskRepository;
-
-/**
- * @deprecated Do not use. This class is pending for removal: see bug 237552.
- */
-@Deprecated
-public class RepositoryTaskEditorInput extends AbstractRepositoryTaskEditorInput {
-
-	protected String taskId;
-
-	protected String url;
-
-	protected AbstractTask repositoryTask = null;
-
-	public RepositoryTaskEditorInput(TaskRepository repository, String taskId, String taskUrl) {
-		super(repository, taskId);
-		this.taskId = taskId;
-		this.url = taskUrl;
-		AbstractTask task = (AbstractTask) TasksUiInternal.getTaskList().getTask(repository.getRepositoryUrl(), taskId);
-		if (task != null) {
-			this.repositoryTask = task;
-		}
-	}
-
-	public AbstractTask getRepositoryTask() {
-		return repositoryTask;
-	}
-
-	public String getName() {
-		if (repositoryTask != null) {
-			String idLabel = repositoryTask.getTaskKey();
-
-			String label = "";
-			if (idLabel != null) {
-				label += idLabel + ": ";
-			}
-			label += repositoryTask.getSummary();
-			return label;
-		} else if (getTaskData() != null && getTaskData().getLabel() != null) {
-			return getTaskData().getTaskKey() + ": " + getTaskData().getLabel();
-		} else if (taskId != null) {
-			return taskId;
-		} else {
-			return "<unknown>";
-		}
-	}
-
-	/**
-	 * @return The taskId of the bug for this editor input.
-	 */
-	public String getId() {
-		return taskId;
-	}
-
-	@Override
-	public int hashCode() {
-		final int PRIME = 31;
-		int result = 1;
-		result = PRIME * result + ((repositoryTask == null) ? 0 : repositoryTask.hashCode());
-		return result;
-	}
-
-	@Override
-	public boolean equals(Object obj) {
-		if (this == obj) {
-			return true;
-		}
-		if (obj == null) {
-			return false;
-		}
-		if (getClass() != obj.getClass()) {
-			return false;
-		}
-		final RepositoryTaskEditorInput other = (RepositoryTaskEditorInput) obj;
-		if (repositoryTask == null) {
-			if (other.repositoryTask != null) {
-				return false;
-			} else if (!other.getId().equals(this.getId())) {
-				return false;
-			}
-		} else if (!repositoryTask.equals(other.repositoryTask)) {
-			return false;
-		}
-		return true;
-	}
-
-	/**
-	 * @return url for the repositoryTask/hit. Used by TaskEditor when opening browser
-	 */
-	public String getUrl() {
-		return url;
-	}
-
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/editors/RepositoryTaskOutlineComparer.java b/org.eclipse.mylyn.ide.dev/developer/src-old/editors/RepositoryTaskOutlineComparer.java
deleted file mode 100644
index d58f0c8..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/editors/RepositoryTaskOutlineComparer.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004, 2008 Tasktop Technologies and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     Tasktop Technologies - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.mylyn.internal.tasks.ui.editors;
-
-import org.eclipse.jface.viewers.IElementComparer;
-
-/**
- * @deprecated Do not use. This class is pending for removal: see bug 237552.
- */
-@Deprecated
-public class RepositoryTaskOutlineComparer implements IElementComparer {
-
-	public boolean equals(Object a, Object b) {
-		if ((a instanceof IRepositoryTaskSelection) && (b instanceof IRepositoryTaskSelection)) {
-			IRepositoryTaskSelection s1 = (IRepositoryTaskSelection) a;
-			IRepositoryTaskSelection s2 = (IRepositoryTaskSelection) b;
-
-			// An IRepositoryTaskSelection is uniquely defined by its handle and
-			// its contents
-			return ((ContentOutlineTools.getHandle(s1).equals(ContentOutlineTools.getHandle(s2))) && ((s1.getContents() == null) ? (s2.getContents() == null)
-					: s1.getContents().equals(s2.getContents())));
-		}
-		return a.equals(b);
-	}
-
-	public int hashCode(Object element) {
-		if (element instanceof IRepositoryTaskSelection) {
-			IRepositoryTaskSelection sel = (IRepositoryTaskSelection) element;
-
-			// An IRepositoryTaskSelection is uniquely defined by its handle and
-			// its contents
-			return (ContentOutlineTools.getHandle(sel) + sel.getContents()).hashCode();
-		}
-		return element.hashCode();
-	}
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/editors/RepositoryTaskOutlineNode.java b/org.eclipse.mylyn.ide.dev/developer/src-old/editors/RepositoryTaskOutlineNode.java
deleted file mode 100644
index e3d8b4f..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/editors/RepositoryTaskOutlineNode.java
+++ /dev/null
@@ -1,338 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004, 2008 Tasktop Technologies and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     Tasktop Technologies - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.mylyn.internal.tasks.ui.editors;
-
-import java.util.ArrayList;
-import java.util.Locale;
-
-import org.eclipse.mylyn.internal.tasks.core.deprecated.RepositoryTaskData;
-import org.eclipse.mylyn.internal.tasks.core.deprecated.TaskComment;
-
-/**
- * @deprecated Do not use. This class is pending for removal: see bug 237552.
- */
-@Deprecated
-public class RepositoryTaskOutlineNode implements IRepositoryTaskSelection {
-
-	public static final String LABEL_DESCRIPTION = "Description";
-
-	public static final String LABEL_COMMENTS = "Comments";
-
-	public static final String LABEL_NEW_COMMENT = "New Comment";
-
-	/** The taskId of the Bugzilla object that the selection was on. */
-	protected String id;
-
-	/** The server of the Bugzilla object that the selection was on. */
-	protected String server;
-
-	/** connector kind */
-	private final String kind;
-
-	/** The label for this piece of data. */
-	private String key;
-
-	/** The children of this node. */
-	private ArrayList<RepositoryTaskOutlineNode> nodeChildren;
-
-	/** The parent of this node or null if it is the bug report */
-	private RepositoryTaskOutlineNode parent;
-
-	private Object data = null;
-
-	private final String bugSummary;
-
-	private final boolean fromEditor = false;
-
-	private boolean isCommentHeader = false;
-
-	private boolean isDescription = false;
-
-	/**
-	 * Creates a new <code>RepositoryTaskOutlineNode</code>.
-	 * 
-	 * @param taskId
-	 *            The taskId of the bug this outline is for.
-	 * @param server
-	 *            The server of the bug this outline is for.
-	 * @param key
-	 *            The label for this node.
-	 * @param image
-	 *            The image that will be displayed by this node in the tree.
-	 * @param data
-	 *            The data, if necessary, this node represents.
-	 * @param parent
-	 *            The parent of this node
-	 */
-	public RepositoryTaskOutlineNode(String id, String server, String kind, String key, Object data, String summary) {
-		this.id = id;
-		this.server = server;
-		this.kind = kind;
-		this.key = key;
-		this.nodeChildren = null;
-		this.data = data;
-		this.parent = null;
-		this.bugSummary = summary;
-	}
-
-	public boolean isFromEditor() {
-		return fromEditor;
-	}
-
-	/**
-	 * @return The children of this node, represented as an <code>Object</code> array.
-	 */
-	public RepositoryTaskOutlineNode[] getChildren() {
-		return (nodeChildren == null) ? new RepositoryTaskOutlineNode[0]
-				: nodeChildren.toArray(new RepositoryTaskOutlineNode[nodeChildren.size()]);
-	}
-
-	/**
-	 * Adds a node to this node's list of children.
-	 * 
-	 * @param bugNode
-	 *            The new child.
-	 */
-	public void addChild(RepositoryTaskOutlineNode bugNode) {
-		if (nodeChildren == null) {
-			nodeChildren = new ArrayList<RepositoryTaskOutlineNode>();
-		}
-		bugNode.setParent(this);
-		nodeChildren.add(bugNode);
-	}
-
-	/**
-	 * @return The label of this node.
-	 */
-	public String getKey() {
-		return key;
-	}
-
-	/**
-	 * @return <code>true</code> if the given object is another node representing the same piece of data in the editor.
-	 */
-	@Override
-	public boolean equals(Object arg0) {
-		if (arg0 instanceof RepositoryTaskOutlineNode) {
-			RepositoryTaskOutlineNode bugNode = (RepositoryTaskOutlineNode) arg0;
-			return getKey().equals(bugNode.getKey());
-		}
-		return super.equals(arg0);
-	}
-
-	@Override
-	public int hashCode() {
-		return getKey().hashCode();
-	}
-
-	/**
-	 * @return The name of this node.
-	 */
-	public String getName() {
-		return getKey();
-	}
-
-	/**
-	 * @return The data (where applicable) this node represents.
-	 */
-	public Object getData() {
-		return data;
-	}
-
-	/**
-	 * Sets the data that this node represents.
-	 * 
-	 * @param data
-	 *            The new piece of data.
-	 */
-	public void setData(Object data) {
-		this.data = data;
-	}
-
-	/**
-	 * Parses the given <code>IBugzillaBug</code> into a tree of <code>RepositoryTaskOutlineNode</code>'s suitable for
-	 * use in the <code>RepositoryTaskOutlinePage</code> view.
-	 * 
-	 * @param bug
-	 *            The bug that needs parsing.
-	 * @return The tree of <code>RepositoryTaskOutlineNode</code>'s.
-	 */
-	public static RepositoryTaskOutlineNode parseBugReport(RepositoryTaskData bug, boolean hasNewComment) {
-		// Choose the appropriate parsing function based on
-		// the type of IBugzillaBug.
-		// if (bug instanceof NewBugzillaReport) {
-		// return parseNewBugReport((NewBugzillaReport) bug);
-		// } else
-		if (bug != null) {
-			return parseExistingBugReport(bug, hasNewComment);
-		} else {
-			return null;
-		}
-	}
-
-	public static RepositoryTaskOutlineNode parseBugReport(RepositoryTaskData bug) {
-		return parseBugReport(bug, true);
-	}
-
-//	/**
-//	 * Parses the given <code>NewBugModel</code> into a tree of
-//	 * <code>RepositoryTaskOutlineNode</code>'s suitable for use in the
-//	 * <code>RepositoryTaskOutlinePage</code> view.
-//	 * 
-//	 * @param bug
-//	 *            The <code>NewBugModel</code> that needs parsing.
-//	 * @return The tree of <code>RepositoryTaskOutlineNode</code>'s.
-//	 */
-//	protected static RepositoryTaskOutlineNode parseNewBugReport(NewBugzillaReport bug) {
-//		int bugId = bug.getId();
-//		String bugServer = bug.getRepositoryUrl();
-//		Image bugImage = BugzillaImages.getImage(BugzillaImages.BUG);
-//		Image defaultImage = BugzillaImages.getImage(BugzillaImages.BUG_COMMENT);
-//		RepositoryTaskOutlineNode topNode = new RepositoryTaskOutlineNode(bugId, bugServer, bug.getLabel(), bugImage, bug, bug
-//				.getSummary());
-//
-//		topNode.addChild(new RepositoryTaskOutlineNode(bugId, bugServer, "New Description", defaultImage, null, bug
-//				.getSummary()));
-//
-//		RepositoryTaskOutlineNode titleNode = new RepositoryTaskOutlineNode(bugId, bugServer, "NewBugModel Object", defaultImage,
-//				null, bug.getSummary());
-//		titleNode.addChild(topNode);
-//
-//		return titleNode;
-//	}
-
-	/**
-	 * Parses the given <code>BugReport</code> into a tree of <code>RepositoryTaskOutlineNode</code>'s suitable for use
-	 * in the <code>RepositoryTaskOutlinePage</code> view.
-	 * 
-	 * @param bug
-	 *            The <code>BugReport</code> that needs parsing.
-	 * @return The tree of <code>RepositoryTaskOutlineNode</code>'s.
-	 */
-	protected static RepositoryTaskOutlineNode parseExistingBugReport(RepositoryTaskData bug, boolean hasNewComment) {
-
-		String bugId = bug.getTaskId();
-		String bugServer = bug.getRepositoryUrl();
-		RepositoryTaskOutlineNode topNode = new RepositoryTaskOutlineNode(bugId, bugServer, bug.getConnectorKind(),
-				bug.getLabel(), bug, bug.getSummary());
-
-		RepositoryTaskOutlineNode desc = new RepositoryTaskOutlineNode(bugId, bugServer, bug.getConnectorKind(),
-				LABEL_DESCRIPTION, bug.getDescription(), bug.getSummary());
-		desc.setIsDescription(true);
-
-		topNode.addChild(desc);
-
-		RepositoryTaskOutlineNode comments = null;
-		for (TaskComment taskComment : bug.getComments()) {
-			// first comment is the bug summary
-			if (taskComment.getNumber() == 0) {
-				continue;
-			}
-			if (comments == null) {
-				comments = new RepositoryTaskOutlineNode(bugId, bugServer, bug.getConnectorKind(), LABEL_COMMENTS,
-						taskComment, bug.getSummary());
-				comments.setIsCommentHeader(true);
-			}
-			comments.addChild(new RepositoryTaskOutlineNode(bugId, bugServer, bug.getConnectorKind(),
-					taskComment.getCreated(), taskComment, bug.getSummary()));
-		}
-		if (comments != null) {
-			topNode.addChild(comments);
-		}
-
-		if (hasNewComment) {
-			topNode.addChild(new RepositoryTaskOutlineNode(bugId, bugServer, bug.getConnectorKind(), LABEL_NEW_COMMENT,
-					null, bug.getSummary()));
-		}
-
-		RepositoryTaskOutlineNode titleNode = new RepositoryTaskOutlineNode(bugId, bugServer, bug.getConnectorKind(),
-				"BugReport Object", null, bug.getSummary());
-		titleNode.addChild(topNode);
-
-		return titleNode;
-	}
-
-	public boolean hasComment() {
-		// If the comment category was selected, then the comment object is
-		// not the intended selection (it is just used to help find the correct
-		// location in the editor).
-		return (data instanceof TaskComment) && !(key.toLowerCase(Locale.ENGLISH).equals("comments"));
-	}
-
-	public TaskComment getComment() {
-		return (hasComment()) ? (TaskComment) data : null;
-	}
-
-	public void setComment(TaskComment taskComment) {
-		data = taskComment;
-	}
-
-	public String getContents() {
-		return key;
-	}
-
-	public void setContents(String contents) {
-		key = contents;
-	}
-
-	public String getId() {
-		return id;
-	}
-
-	public void setId(String id) {
-		this.id = id;
-	}
-
-	public String getRepositoryUrl() {
-		return server;
-	}
-
-	public String getConnectorKind() {
-		return kind;
-	}
-
-	public void setServer(String server) {
-		this.server = server;
-	}
-
-	public boolean isEmpty() {
-		return (server == null) || ((getContents() == null) && (getComment() == null));
-	}
-
-	public RepositoryTaskOutlineNode getParent() {
-		return parent;
-	}
-
-	public void setParent(RepositoryTaskOutlineNode parent) {
-		this.parent = parent;
-	}
-
-	public boolean isCommentHeader() {
-		return isCommentHeader;
-	}
-
-	public boolean isDescription() {
-		return isDescription;
-	}
-
-	public void setIsCommentHeader(boolean isCommentHeader) {
-		this.isCommentHeader = isCommentHeader;
-	}
-
-	public void setIsDescription(boolean isDescription) {
-		this.isDescription = isDescription;
-	}
-
-	public String getBugSummary() {
-		return bugSummary;
-	}
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/editors/RepositoryTaskOutlinePage.java b/org.eclipse.mylyn.ide.dev/developer/src-old/editors/RepositoryTaskOutlinePage.java
deleted file mode 100644
index 5b4dc58..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/editors/RepositoryTaskOutlinePage.java
+++ /dev/null
@@ -1,208 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004, 2008 Tasktop Technologies and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     Tasktop Technologies - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.mylyn.internal.tasks.ui.editors;
-
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.Status;
-import org.eclipse.jface.viewers.ISelection;
-import org.eclipse.jface.viewers.IStructuredSelection;
-import org.eclipse.jface.viewers.ITreeContentProvider;
-import org.eclipse.jface.viewers.LabelProvider;
-import org.eclipse.jface.viewers.TreeViewer;
-import org.eclipse.jface.viewers.Viewer;
-import org.eclipse.mylyn.commons.core.StatusHandler;
-import org.eclipse.mylyn.internal.provisional.commons.ui.CommonImages;
-import org.eclipse.mylyn.internal.tasks.core.deprecated.TaskComment;
-import org.eclipse.mylyn.internal.tasks.ui.TasksUiPlugin;
-import org.eclipse.mylyn.tasks.core.TaskRepository;
-import org.eclipse.mylyn.tasks.ui.TasksUi;
-import org.eclipse.mylyn.tasks.ui.TasksUiImages;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.ui.ISelectionListener;
-import org.eclipse.ui.IWorkbenchPart;
-import org.eclipse.ui.views.contentoutline.ContentOutlinePage;
-
-/**
- * @deprecated Do not use. This class is pending for removal: see bug 237552.
- */
-@Deprecated
-public class RepositoryTaskOutlinePage extends ContentOutlinePage {
-
-	private final RepositoryTaskOutlineNode topTreeNode;
-
-	private final TaskRepository repository;
-
-	protected final ISelectionListener selectionListener = new ISelectionListener() {
-		public void selectionChanged(IWorkbenchPart part, ISelection selection) {
-			if (selection instanceof IStructuredSelection) {
-				if (((IStructuredSelection) selection).getFirstElement() instanceof IRepositoryTaskSelection) {
-					if (((IStructuredSelection) getSelection()).getFirstElement() instanceof IRepositoryTaskSelection) {
-						IRepositoryTaskSelection brs1 = (IRepositoryTaskSelection) ((IStructuredSelection) getSelection()).getFirstElement();
-						IRepositoryTaskSelection brs2 = ((IRepositoryTaskSelection) ((IStructuredSelection) selection).getFirstElement());
-						if (ContentOutlineTools.getHandle(brs1).compareTo(ContentOutlineTools.getHandle(brs2)) == 0) {
-							// don't need to make a selection for the same
-							// element
-							return;
-						}
-					}
-					getTreeViewer().setSelection(selection, true);
-				}
-			}
-		}
-	};
-
-	private TreeViewer viewer;
-
-	/**
-	 * Creates a new <code>RepositoryTaskOutlinePage</code>.
-	 * 
-	 * @param topTreeNode
-	 *            The top data node of the tree for this view.
-	 * @param editor
-	 *            The editor this outline page is for.
-	 */
-	public RepositoryTaskOutlinePage(RepositoryTaskOutlineNode topTreeNode) {
-		super();
-		this.topTreeNode = topTreeNode;
-		repository = TasksUi.getRepositoryManager().getRepository(topTreeNode.getConnectorKind(),
-				topTreeNode.getRepositoryUrl());
-	}
-
-	@Override
-	public void createControl(Composite parent) {
-		super.createControl(parent);
-		viewer = getTreeViewer();
-		viewer.setContentProvider(new BugTaskOutlineContentProvider());
-		viewer.setLabelProvider(new LabelProvider() {
-			@Override
-			public Image getImage(Object element) {
-				if (element instanceof RepositoryTaskOutlineNode) {
-					RepositoryTaskOutlineNode node = (RepositoryTaskOutlineNode) element;
-
-					if (RepositoryTaskOutlineNode.LABEL_COMMENTS.equals(node.getContents())
-							|| RepositoryTaskOutlineNode.LABEL_NEW_COMMENT.equals(node.getContents())) {
-						return CommonImages.getImage(TasksUiImages.COMMENT);
-					}
-					if (RepositoryTaskOutlineNode.LABEL_DESCRIPTION.equals(node.getContents())) {
-						return CommonImages.getImage(TasksUiImages.TASK_NOTES);
-					} else if (node.getComment() != null) {
-						if (repository != null && node.getComment().getAuthor().equals(repository.getUserName())) {
-							return CommonImages.getImage(CommonImages.PERSON_ME);
-						} else {
-							return CommonImages.getImage(CommonImages.PERSON);
-						}
-					} else {
-						return CommonImages.getImage(TasksUiImages.TASK);
-					}
-				} else {
-					return super.getImage(element);
-				}
-			}
-
-			@Override
-			public String getText(Object element) {
-				if (element instanceof RepositoryTaskOutlineNode) {
-					RepositoryTaskOutlineNode node = (RepositoryTaskOutlineNode) element;
-					TaskComment comment = node.getComment();
-					if (comment == null) {
-						return node.getName();
-					}
-					int n = comment.getNumber();
-//					if (n == 0) {
-//						return comment.getAuthorName() + " (" + node.getName() + ")";
-//					}
-
-					String name = comment.getAuthorName();
-					if (name != null) {
-						String id = comment.getAuthor();
-						if (id != null) {
-							name += " <" + id + ">";
-						}
-					} else {
-						name = comment.getAuthor();
-					}
-
-					return n + ": " + name + " (" + node.getName() + ")";
-				}
-				return super.getText(element);
-			}
-		});
-		try {
-			viewer.setInput(topTreeNode);
-			viewer.setComparer(new RepositoryTaskOutlineComparer());
-			viewer.expandAll();
-		} catch (Exception e) {
-			StatusHandler.fail(new Status(IStatus.ERROR, TasksUiPlugin.ID_PLUGIN, "Could not create bugzilla outline",
-					e));
-		}
-		getSite().getPage().addSelectionListener(selectionListener);
-	}
-
-	@Override
-	public void dispose() {
-		super.dispose();
-		getSite().getPage().removeSelectionListener(selectionListener);
-	}
-
-	public TreeViewer getOutlineTreeViewer() {
-		return viewer;
-	}
-
-	/**
-	 * A content provider for the tree for this view.
-	 * 
-	 * @see ITreeContentProvider
-	 */
-	protected static class BugTaskOutlineContentProvider implements ITreeContentProvider {
-
-		public Object[] getChildren(Object parentElement) {
-			if (parentElement instanceof RepositoryTaskOutlineNode) {
-				Object[] children = ((RepositoryTaskOutlineNode) parentElement).getChildren();
-				if (children.length > 0) {
-					return children;
-				}
-			}
-			return new Object[0];
-		}
-
-		public Object getParent(Object element) {
-			return null;
-		}
-
-		public boolean hasChildren(Object element) {
-			if (element instanceof RepositoryTaskOutlineNode) {
-				return ((RepositoryTaskOutlineNode) element).getChildren().length > 0;
-			}
-			return false;
-		}
-
-		public Object[] getElements(Object inputElement) {
-			if (inputElement instanceof RepositoryTaskOutlineNode) {
-				Object[] children = ((RepositoryTaskOutlineNode) inputElement).getChildren();
-				if (children.length > 0) {
-					return children;
-				}
-			}
-			return new Object[0];
-		}
-
-		public void dispose() {
-			// don't care when we are disposed
-		}
-
-		public void inputChanged(Viewer viewerChanged, Object oldInput, Object newInput) {
-			// don't care when the input changes
-		}
-	}
-
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/editors/TaskEditorUrlHyperlinkDetector.java b/org.eclipse.mylyn.ide.dev/developer/src-old/editors/TaskEditorUrlHyperlinkDetector.java
deleted file mode 100644
index af1a57a..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/editors/TaskEditorUrlHyperlinkDetector.java
+++ /dev/null
@@ -1,113 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004 - 2006 Mylar committers and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *******************************************************************************/
-
-package org.eclipse.mylyn.internal.tasks.ui.editors;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import org.eclipse.jface.text.BadLocationException;
-import org.eclipse.jface.text.IDocument;
-import org.eclipse.jface.text.IRegion;
-import org.eclipse.jface.text.ITextViewer;
-import org.eclipse.jface.text.Region;
-import org.eclipse.jface.text.hyperlink.IHyperlink;
-import org.eclipse.jface.text.hyperlink.IHyperlinkDetector;
-import org.eclipse.jface.text.hyperlink.URLHyperlink;
-import org.eclipse.mylyn.tasks.ui.TasksUiUtil;
-
-/**
- * @author Rob Elves
- */
-public class TaskEditorUrlHyperlinkDetector implements IHyperlinkDetector {
-
-	// URL BNF: http://www.foad.org/~abigail/Perl/url2.html
-	// Source:
-	// http://www.truerwords.net/articles/ut/urlactivation.html#expressions
-	// Original pattern: (^|[
-	// \\t\\r\\n])((ftp|http|https|gopher|mailto|news|nntp|telnet|wais|file|prospero|aim|webcal):(([A-Za-z0-9$_.+!*(),;/?:@&~=-])|%[A-Fa-f0-9]{2}){2,}(#([a-zA-Z0-9][a-zA-Z0-9$_.+!*(),;/?:@&~=%-]*))?([A-Za-z0-9$_+!*();/?:~-]))
-	private static final Pattern urlPattern = Pattern
-			.compile(
-					"((ftp|http|https|gopher|mailto|news|nntp|telnet|wais|file|prospero|aim|webcal):(([A-Za-z0-9$_.+!*,;/?:@&~=-])|%[A-Fa-f0-9]{2}){2,}(#([a-zA-Z0-9][a-zA-Z0-9$_.+!*,;/?:@&~=%-]*))?([A-Za-z0-9$_+!*;/?:~-]))",
-					Pattern.CASE_INSENSITIVE);
-
-	public IHyperlink[] detectHyperlinks(ITextViewer textViewer, IRegion region, boolean canShowMultipleHyperlinks) {
-
-		if (region == null || textViewer == null)
-			return null;
-
-		IDocument document = textViewer.getDocument();
-
-		List<IHyperlink> hyperlinksFound = new ArrayList<IHyperlink>();
-
-		int offset = region.getOffset();
-
-		if (document == null)
-			return null;
-
-		IRegion lineInfo;
-		String line;
-		try {
-			lineInfo = document.getLineInformationOfOffset(offset);
-			line = document.get(lineInfo.getOffset(), lineInfo.getLength());
-		} catch (BadLocationException ex) {
-			return null;
-		}
-
-		int offsetInLine = offset - lineInfo.getOffset();
-
-		Matcher m = urlPattern.matcher(line);
-
-		while (m.find()) {
-			if (offsetInLine >= m.start() && offsetInLine <= m.end()) {
-				IHyperlink link = extractHyperlink(lineInfo.getOffset(), m);
-				if (link != null)
-					hyperlinksFound.add(link);
-			}
-		}
-
-		if (hyperlinksFound.size() > 0) {
-			return hyperlinksFound.toArray(new IHyperlink[hyperlinksFound.size()]);
-		}
-
-		return null;
-
-	}
-
-	private TaskEditorUrlHyperlink extractHyperlink(int lineOffset, Matcher m) {
-
-		int start = m.start();
-		int end = m.end();
-
-		if (end == -1)
-			end = m.group().length();
-
-		start += lineOffset;
-		end += lineOffset;
-
-		IRegion sregion = new Region(start, end - start);
-		return new TaskEditorUrlHyperlink(sregion, m.group());
-	}
-
-	static class TaskEditorUrlHyperlink extends URLHyperlink {
-
-		public TaskEditorUrlHyperlink(IRegion region, String urlString) {
-			super(region, urlString);
-		}
-
-		@Override
-		public void open() {
-			// TODO: if url is to a repository task, open task instead of url
-			TasksUiUtil.openBrowser(getURLString());
-		}
-
-	}
-
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/editors/TaskFactory.java b/org.eclipse.mylyn.ide.dev/developer/src-old/editors/TaskFactory.java
deleted file mode 100644
index 5719fc7..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/editors/TaskFactory.java
+++ /dev/null
@@ -1,183 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004, 2008 Tasktop Technologies and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     Tasktop Technologies - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.mylyn.internal.tasks.ui.deprecated;
-
-import java.util.Set;
-
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.NullProgressMonitor;
-import org.eclipse.core.runtime.SubProgressMonitor;
-import org.eclipse.mylyn.internal.tasks.core.AbstractTask;
-import org.eclipse.mylyn.internal.tasks.core.ITaskList;
-import org.eclipse.mylyn.internal.tasks.core.TaskDataStorageManager;
-import org.eclipse.mylyn.internal.tasks.core.data.TaskDataManager;
-import org.eclipse.mylyn.internal.tasks.core.deprecated.AbstractLegacyRepositoryConnector;
-import org.eclipse.mylyn.internal.tasks.core.deprecated.AbstractTaskDataHandler;
-import org.eclipse.mylyn.internal.tasks.core.deprecated.ITaskFactory;
-import org.eclipse.mylyn.internal.tasks.core.deprecated.RepositoryTaskData;
-import org.eclipse.mylyn.internal.tasks.ui.TasksUiPlugin;
-import org.eclipse.mylyn.internal.tasks.ui.util.TasksUiInternal;
-import org.eclipse.mylyn.tasks.core.ITask;
-import org.eclipse.mylyn.tasks.core.TaskRepository;
-import org.eclipse.mylyn.tasks.core.ITask.SynchronizationState;
-import org.eclipse.mylyn.tasks.ui.TasksUi;
-
-/**
- * @deprecated Do not use. This class is pending for removal: see bug 237552.
- */
-@Deprecated
-public class TaskFactory implements ITaskFactory {
-
-	private final AbstractLegacyRepositoryConnector connector;
-
-	private final TaskDataManager synchManager;
-
-	private final TaskRepository repository;
-
-	private final ITaskList taskList;
-
-	private final AbstractTaskDataHandler dataHandler;
-
-	private final boolean updateTasklist;
-
-	private final boolean forced;
-
-	public TaskFactory(TaskRepository repository, boolean updateTasklist, boolean forced) {
-		this.repository = repository;
-		this.updateTasklist = updateTasklist;
-		this.forced = forced;
-		connector = (AbstractLegacyRepositoryConnector) TasksUi.getRepositoryManager().getRepositoryConnector(
-				repository.getConnectorKind());
-		synchManager = TasksUiPlugin.getTaskDataManager();
-		taskList = TasksUiInternal.getTaskList();
-		//dataManager = TasksUiPlugin.getTaskDataManager();
-		dataHandler = connector.getLegacyTaskDataHandler();
-	}
-
-	@Deprecated
-	public TaskFactory(TaskRepository repository) {
-		this(repository, true, false);
-	}
-
-	/**
-	 * @param updateTasklist
-	 *            - synchronize task with the provided taskData
-	 * @param forced
-	 *            - user requested synchronization
-	 * @throws CoreException
-	 */
-	public AbstractTask createTask(RepositoryTaskData taskData, IProgressMonitor monitor) throws CoreException {
-		AbstractTask repositoryTask = (AbstractTask) taskList.getTask(taskData.getRepositoryUrl(), taskData.getTaskId());
-		if (repositoryTask == null) {
-			repositoryTask = createTaskFromTaskData(connector, repository, taskData, updateTasklist, monitor);
-			repositoryTask.setSynchronizationState(SynchronizationState.INCOMING);
-			if (updateTasklist) {
-				taskList.addTask(repositoryTask);
-				synchManager.saveIncoming(repositoryTask, taskData, forced);
-			} else {
-				synchManager.saveOffline(repositoryTask, taskData);
-			}
-
-		} else {
-			if (updateTasklist) {
-				synchManager.saveIncoming(repositoryTask, taskData, forced);
-				connector.updateTaskFromTaskData(repository, repositoryTask, taskData);
-				if (dataHandler != null) {
-					for (ITask child : repositoryTask.getChildren()) {
-						taskList.removeFromContainer(repositoryTask, child);
-					}
-					Set<String> subTaskIds = dataHandler.getSubTaskIds(taskData);
-					if (subTaskIds != null) {
-						for (String subId : subTaskIds) {
-							if (subId == null || subId.trim().equals("")) {
-								continue;
-							}
-							AbstractTask subTask = createTaskFromExistingId(connector, repository, subId, false,
-									new SubProgressMonitor(monitor, 1));
-							if (subTask != null) {
-								taskList.addTask(subTask, repositoryTask);
-							}
-						}
-					}
-				}
-			}
-		}
-		return repositoryTask;
-	}
-
-	/**
-	 * Creates a new task from the given task data. Does NOT add resulting task to the tasklist
-	 */
-	private AbstractTask createTaskFromTaskData(AbstractLegacyRepositoryConnector connector, TaskRepository repository,
-			RepositoryTaskData taskData, boolean retrieveSubTasks, IProgressMonitor monitor) throws CoreException {
-		AbstractTask repositoryTask = null;
-		if (monitor == null) {
-			monitor = new NullProgressMonitor();
-		}
-		try {
-			TaskDataStorageManager taskDataManager = TasksUiPlugin.getTaskDataStorageManager();
-			if (taskData != null) {
-				// Use connector task factory
-				repositoryTask = connector.createTask(repository.getRepositoryUrl(), taskData.getTaskId(),
-						taskData.getTaskId() + ": " + taskData.getDescription());
-				connector.updateTaskFromTaskData(repository, repositoryTask, taskData);
-				taskDataManager.setNewTaskData(taskData);
-
-				if (retrieveSubTasks) {
-					monitor.beginTask("Creating task", connector.getLegacyTaskDataHandler()
-							.getSubTaskIds(taskData)
-							.size());
-					for (String subId : connector.getLegacyTaskDataHandler().getSubTaskIds(taskData)) {
-						if (subId == null || subId.trim().equals("")) {
-							continue;
-						}
-						AbstractTask subTask = createTaskFromExistingId(connector, repository, subId, false,
-								new SubProgressMonitor(monitor, 1));
-						if (subTask != null) {
-							taskList.addTask(subTask, repositoryTask);
-						}
-					}
-				}
-			}
-		} finally {
-			monitor.done();
-		}
-		return repositoryTask;
-	}
-
-	/**
-	 * Create new repository task, adding result to tasklist
-	 */
-	private AbstractTask createTaskFromExistingId(AbstractLegacyRepositoryConnector connector,
-			TaskRepository repository, String id, boolean retrieveSubTasks, IProgressMonitor monitor)
-			throws CoreException {
-		AbstractTask repositoryTask = (AbstractTask) taskList.getTask(repository.getRepositoryUrl(), id);
-		if (repositoryTask == null && connector.getLegacyTaskDataHandler() != null) {
-			RepositoryTaskData taskData = null;
-			taskData = connector.getLegacyTaskDataHandler().getTaskData(repository, id,
-					new SubProgressMonitor(monitor, 1));
-			if (taskData != null) {
-				repositoryTask = createTaskFromTaskData(connector, repository, taskData, retrieveSubTasks,
-						new SubProgressMonitor(monitor, 1));
-				if (repositoryTask != null) {
-					repositoryTask.setSynchronizationState(SynchronizationState.INCOMING);
-					taskList.addTask(repositoryTask);
-				}
-			}
-		} // TODO: Handle case similar to web tasks (no taskDataHandler but
-		// have tasks)
-
-		return repositoryTask;
-	}
-
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/editors/TaskSpellingReconcileStrategy.java b/org.eclipse.mylyn.ide.dev/developer/src-old/editors/TaskSpellingReconcileStrategy.java
deleted file mode 100644
index aedc276..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/editors/TaskSpellingReconcileStrategy.java
+++ /dev/null
@@ -1,193 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004, 2008 Jeff Pound and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     Jeff Pound - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.mylyn.internal.tasks.ui.editors;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.Platform;
-import org.eclipse.core.runtime.content.IContentTypeManager;
-import org.eclipse.jface.text.BadLocationException;
-import org.eclipse.jface.text.IDocument;
-import org.eclipse.jface.text.IRegion;
-import org.eclipse.jface.text.Position;
-import org.eclipse.jface.text.Region;
-import org.eclipse.jface.text.reconciler.DirtyRegion;
-import org.eclipse.jface.text.reconciler.IReconcilerExtension;
-import org.eclipse.jface.text.reconciler.IReconcilingStrategy;
-import org.eclipse.jface.text.source.Annotation;
-import org.eclipse.jface.text.source.IAnnotationModel;
-import org.eclipse.mylyn.internal.tasks.ui.deprecated.TaskFormPage.ErrorAnnotation;
-import org.eclipse.ui.editors.text.EditorsUI;
-import org.eclipse.ui.texteditor.spelling.ISpellingProblemCollector;
-import org.eclipse.ui.texteditor.spelling.SpellingContext;
-import org.eclipse.ui.texteditor.spelling.SpellingProblem;
-
-/**
- * Adapted from org.eclipse.jdt.internal.ui.text.spelling.PropertiesSpellingReconcileStrategy
- * 
- * @author Jeff Pound
- * @author Rob Elves
- */
-/**
- * @deprecated Do not use. This class is pending for removal: see bug 237552.
- */
-@Deprecated
-public class TaskSpellingReconcileStrategy implements IReconcilerExtension, IReconcilingStrategy {
-
-	/**
-	 * Spelling problem collector that forwards {@link SpellingProblem}s as {@link IProblem}s to the
-	 * {@link org.eclipse.jdt.core.IProblemRequestor}.
-	 */
-	private class SpellingProblemCollector implements ISpellingProblemCollector {
-
-		/** Annotation model */
-		private final IAnnotationModel fAnnotationModel;
-
-		/** Annotations to add */
-		private Map<ErrorAnnotation, Position> fAddAnnotations;
-
-		/**
-		 * Initializes this collector with the given annotation model.
-		 * 
-		 * @param annotationModel
-		 *            the annotation model
-		 */
-		public SpellingProblemCollector(IAnnotationModel annotationModel) {
-			fAnnotationModel = annotationModel;
-		}
-
-		/*
-		 * @see org.eclipse.ui.texteditor.spelling.ISpellingProblemCollector#accept(org.eclipse.ui.texteditor.spelling.SpellingProblem)
-		 */
-		public void accept(SpellingProblem problem) {
-			try {
-				int line = fDocument.getLineOfOffset(problem.getOffset()) + 1;
-
-				fAddAnnotations.put(new ErrorAnnotation(line, null), new Position(problem.getOffset(),
-						problem.getLength()));
-
-			} catch (BadLocationException x) {
-				// drop this SpellingProblem
-			}
-		}
-
-		/*
-		 * @see org.eclipse.ui.texteditor.spelling.ISpellingProblemCollector#beginCollecting()
-		 */
-		public void beginCollecting() {
-			fAddAnnotations = new HashMap<ErrorAnnotation, Position>();
-		}
-
-		/*
-		 * @see org.eclipse.ui.texteditor.spelling.ISpellingProblemCollector#endCollecting()
-		 */
-		@SuppressWarnings("unchecked")
-		public void endCollecting() {
-
-			List<Annotation> removeAnnotations = new ArrayList<Annotation>();
-			for (Iterator iter = fAnnotationModel.getAnnotationIterator(); iter.hasNext();) {
-				Annotation annotation = (Annotation) iter.next();
-				if (ErrorAnnotation.ERROR_TYPE.equals(annotation.getType())) {
-					removeAnnotations.add(annotation);
-				}
-			}
-
-			for (Object element : removeAnnotations) {
-				fAnnotationModel.removeAnnotation((Annotation) element);
-			}
-			for (Object element : fAddAnnotations.keySet()) {
-				Annotation annotation = (Annotation) element;
-				fAnnotationModel.addAnnotation(annotation, fAddAnnotations.get(annotation));
-			}
-
-			fAddAnnotations = null;
-		}
-	}
-
-	/** The taskId of the problem */
-	public static final int SPELLING_PROBLEM_ID = 0x80000000;
-
-	/** The document to operate on. */
-	private IDocument fDocument;
-
-	/** The progress monitor. */
-	private IProgressMonitor fProgressMonitor;
-
-	/**
-	 * The spelling context containing the Java properties content type.
-	 * <p>
-	 * Since his reconcile strategy is for the Properties File editor which normally edits Java properties files we
-	 * always use the Java properties file content type for performance reasons.
-	 * </p>
-	 * 
-	 * @since 3.2
-	 */
-	private final SpellingContext fSpellingContext;
-
-	private IAnnotationModel annotationModel;
-
-	public TaskSpellingReconcileStrategy() {
-		this.annotationModel = null;
-		fSpellingContext = new SpellingContext();
-		fSpellingContext.setContentType(Platform.getContentTypeManager().getContentType(IContentTypeManager.CT_TEXT));
-	}
-
-	/*
-	 * @see org.eclipse.jface.text.reconciler.IReconcilingStrategyExtension#initialReconcile()
-	 */
-	public void initialReconcile() {
-		reconcile(new Region(0, fDocument.getLength()));
-	}
-
-	/*
-	 * @see org.eclipse.jface.text.reconciler.IReconcilingStrategy#reconcile(org.eclipse.jface.text.reconciler.DirtyRegion,org.eclipse.jface.text.IRegion)
-	 */
-	public void reconcile(DirtyRegion dirtyRegion, IRegion subRegion) {
-		reconcile(subRegion);
-	}
-
-	/*
-	 * @see org.eclipse.jface.text.reconciler.IReconcilingStrategy#reconcile(org.eclipse.jface.text.IRegion)
-	 */
-	public void reconcile(IRegion region) {
-		TaskSpellingReconcileStrategy.SpellingProblemCollector collector = new SpellingProblemCollector(annotationModel);
-		EditorsUI.getSpellingService().check(fDocument, fSpellingContext, collector, fProgressMonitor);
-	}
-
-	/*
-	 * @see org.eclipse.jface.text.reconciler.IReconcilingStrategy#setDocument(org.eclipse.jface.text.IDocument)
-	 */
-	public void setDocument(IDocument document) {
-		fDocument = document;
-	}
-
-	/*
-	 * @see org.eclipse.jface.text.reconciler.IReconcilingStrategyExtension#setProgressMonitor(org.eclipse.core.runtime.IProgressMonitor)
-	 */
-	public void setProgressMonitor(IProgressMonitor monitor) {
-		fProgressMonitor = monitor;
-	}
-
-	public String getDocumentPartitioning() {
-		// ignore
-		return null;
-	}
-
-	public void setAnnotationModel(IAnnotationModel model) {
-		annotationModel = model;
-	}
-}
\ No newline at end of file
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/editors/plugin-scraps.xml b/org.eclipse.mylyn.ide.dev/developer/src-old/editors/plugin-scraps.xml
deleted file mode 100644
index 4b92226..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/editors/plugin-scraps.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-      <editor
-            name="Mylar Class File Viewer"
-            icon="icons/eview16/editor-mylar-class.gif"
-            extensions="class"
-            contributorClass="org.eclipse.jdt.internal.ui.javaeditor.ClassFileEditorActionContributor"
-            class="ca.ubc.mylar.java.ui.editor.MylarClassFileEditor"
-            id="ca.ubc.mylar.java.ui.editor.MylarClassFileEditor">
-      </editor> 
\ No newline at end of file
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/hypertext/RelatedLinks.java b/org.eclipse.mylyn.ide.dev/developer/src-old/hypertext/RelatedLinks.java
deleted file mode 100644
index 8b4820c..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/hypertext/RelatedLinks.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004 - 2006 University Of British Columbia and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     University Of British Columbia - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.mylyn.internal.hypertext.ui.editors;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Related links stored for each task used as input to the Table used in the
- * TaskInfoEditor
- * 
- * @author Ken Sueda
- */
-public class RelatedLinks {
-
-	private List<String> links;
-
-	public RelatedLinks() {
-		links = new ArrayList<String>();
-	}
-
-	public void add(String link) {
-		links.add(link);
-	}
-
-	public List<String> getLinks() {
-		return links;
-	}
-
-	public void remove(String link) {
-		links.remove(link);
-	}
-
-	public void clear() {
-		links.clear();
-	}
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/hypertext/WebElementsEditor.java b/org.eclipse.mylyn.ide.dev/developer/src-old/hypertext/WebElementsEditor.java
deleted file mode 100644
index 9314280..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/hypertext/WebElementsEditor.java
+++ /dev/null
@@ -1,480 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004 - 2006 University Of British Columbia and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     University Of British Columbia - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.mylyn.internal.hypertext.ui.editors;
-
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.List;
-
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.jface.action.Action;
-import org.eclipse.jface.action.IMenuListener;
-import org.eclipse.jface.action.IMenuManager;
-import org.eclipse.jface.action.MenuManager;
-import org.eclipse.jface.dialogs.MessageDialog;
-import org.eclipse.jface.viewers.IOpenListener;
-import org.eclipse.jface.viewers.IStructuredSelection;
-import org.eclipse.jface.viewers.OpenEvent;
-import org.eclipse.jface.viewers.TreeViewer;
-import org.eclipse.mylyn.internal.hypertext.HypertextStructureBridge;
-import org.eclipse.mylyn.internal.tasklist.ui.TaskListImages;
-import org.eclipse.mylyn.provisional.core.IMylarContext;
-import org.eclipse.mylyn.provisional.core.IMylarContextListener;
-import org.eclipse.mylyn.provisional.core.IMylarElement;
-import org.eclipse.mylyn.provisional.core.MylarPlugin;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.MouseEvent;
-import org.eclipse.swt.events.MouseTrackListener;
-import org.eclipse.swt.graphics.Cursor;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.swt.widgets.Menu;
-import org.eclipse.swt.widgets.Tree;
-import org.eclipse.ui.IEditorInput;
-import org.eclipse.ui.IEditorSite;
-import org.eclipse.ui.PartInitException;
-import org.eclipse.ui.browser.IWebBrowser;
-import org.eclipse.ui.forms.events.ExpansionEvent;
-import org.eclipse.ui.forms.events.IExpansionListener;
-import org.eclipse.ui.forms.widgets.ExpandableComposite;
-import org.eclipse.ui.forms.widgets.FormToolkit;
-import org.eclipse.ui.forms.widgets.ScrolledForm;
-import org.eclipse.ui.forms.widgets.Section;
-import org.eclipse.ui.forms.widgets.TableWrapData;
-import org.eclipse.ui.forms.widgets.TableWrapLayout;
-import org.eclipse.ui.internal.browser.WorkbenchBrowserSupport;
-import org.eclipse.ui.part.EditorPart;
-
-public class WebElementsEditor extends EditorPart {
-
-	private static final String LABEL = "Web Documents in Active Context";
-
-	private Composite editorComposite;
-
-	private ScrolledForm form;
-
-	private Tree linksTree;
-
-	private TreeViewer treeViewer;
-
-	private List<String> links;
-
-	private WebResourceContentProvider contentProvider;
-
-	private Action add;
-
-	private Action delete;
-
-	private final IMylarContextListener REFRESH_UPDATE_LISTENER = new IMylarContextListener() {
-		public void interestChanged(IMylarElement node) {
-			// ignore
-		}
-
-		public void interestChanged(List<IMylarElement> nodes) {
-			// ignore
-		}
-
-		public void contextActivated(IMylarContext taskscape) {
-			update();
-		}
-
-		public void contextDeactivated(IMylarContext taskscape) {
-			update();
-		}
-
-		public void presentationSettingsChanging(UpdateKind kind) {
-			// ignore
-		}
-
-		public void landmarkAdded(IMylarElement node) {
-			// ignore
-		}
-
-		public void landmarkRemoved(IMylarElement node) {
-			// ignore
-		}
-
-		public void edgesChanged(IMylarElement node) {
-			// ignore
-		}
-
-		public void nodeDeleted(IMylarElement node) {
-			// ignore
-		}
-
-		public void presentationSettingsChanged(UpdateKind kind) {
-			// ignore
-		}
-	};
-
-	@Override
-	public void doSave(IProgressMonitor monitor) {
-		// TODO Auto-generated method stub
-
-	}
-
-	@Override
-	public void doSaveAs() {
-
-	}
-
-	@SuppressWarnings("deprecation")
-	@Override
-	public void init(IEditorSite site, IEditorInput input) throws PartInitException {
-		setSite(site);
-		setInput(input);
-		setPartName(LABEL);
-	}
-
-	@Override
-	public boolean isDirty() {
-		// TODO Auto-generated method stub
-		return false;
-	}
-
-	@Override
-	public boolean isSaveAsAllowed() {
-		// TODO Auto-generated method stub
-		return false;
-	}
-
-	@Override
-	public void dispose() {
-		ContextCorePlugin.getContextManager().removeListener(REFRESH_UPDATE_LISTENER);
-	}
-
-	@Override
-	public void createPartControl(Composite parent) {
-		FormToolkit toolkit = new FormToolkit(parent.getDisplay());
-		form = toolkit.createScrolledForm(parent);
-		form.getBody().setLayout(new TableWrapLayout());
-		editorComposite = form.getBody();
-
-		TableWrapLayout layout = new TableWrapLayout();
-		layout.bottomMargin = 10;
-		layout.topMargin = 10;
-		layout.leftMargin = 10;
-		layout.rightMargin = 10;
-		layout.numColumns = 1;
-		layout.makeColumnsEqualWidth = true;
-		layout.verticalSpacing = 20;
-		layout.horizontalSpacing = 10;
-		editorComposite.setLayout(layout);
-		// editorComposite.setLayoutData(new
-		// TableWrapData(TableWrapData.FILL_GRAB));
-
-		// Put the info onto the editor
-		createContent(editorComposite, toolkit);
-		form.setFocus();
-		ContextCorePlugin.getContextManager().addListener(REFRESH_UPDATE_LISTENER);
-	}
-
-	private void createContent(Composite parent, FormToolkit toolkit) {
-		Section section = toolkit.createSection(parent, ExpandableComposite.TITLE_BAR);
-		section.setText(LABEL);
-		section.setLayout(new TableWrapLayout());
-		section.setLayoutData(new TableWrapData(TableWrapData.FILL_GRAB));
-		section.addExpansionListener(new IExpansionListener() {
-			public void expansionStateChanging(ExpansionEvent e) {
-				form.reflow(true);
-			}
-
-			public void expansionStateChanged(ExpansionEvent e) {
-				form.reflow(true);
-			}
-		});
-
-		Composite container = toolkit.createComposite(section);
-		section.setClient(container);
-		TableWrapLayout layout = new TableWrapLayout();
-		layout.numColumns = 3;
-		container.setLayout(layout);
-		container.setLayoutData(new TableWrapData(TableWrapData.FILL_GRAB));
-
-		createTable(container, toolkit);
-		createTableViewer(container, toolkit);
-		toolkit.paintBordersFor(container);
-		// createAddDeleteButtons(container, toolkit);
-	}
-
-	@Override
-	public void setFocus() {
-		// TODO Auto-generated method stub
-
-	}
-
-	private void createTableViewer(Composite parent, FormToolkit toolkit) {
-		// String[] columnNames = {"Links"};
-		treeViewer = new TreeViewer(linksTree);
-		// treeViewer.setColumnProperties(columnNames);
-
-		// CellEditor[] editors = new CellEditor[columnNames.length];
-		// TextCellEditor textEditor = new TextCellEditor(linksTree);
-		// ((Text) textEditor.getControl()).setTextLimit(50);
-		// ((Text) textEditor.getControl()).setOrientation(SWT.LEFT_TO_RIGHT);
-		// editors[0] = textEditor;
-		// tableViewer.setCellEditors(editors);
-		// tableViewer.setCellModifier(new RelatedLinksCellModifier());
-
-		contentProvider = new WebResourceContentProvider();
-		treeViewer.setContentProvider(contentProvider);
-		treeViewer.setLabelProvider(new WebResourceLabelProvider());
-		treeViewer.addOpenListener(new IOpenListener() {
-			public void open(OpenEvent event) {
-				String url = (String) ((IStructuredSelection) treeViewer.getSelection()).getFirstElement();
-				if (url != null)
-					openURLinBrowser(url);
-			}
-		});
-
-		update();
-		defineActions();
-		hookContextMenu();
-	}
-
-	public void update() {
-		if (treeViewer.getContentProvider() != null) {
-			treeViewer.setInput(getWebDocs());
-			treeViewer.expandAll();
-		}
-	}
-
-	private List<String> getWebDocs() {
-		links = new ArrayList<String>();
-		List<IMylarElement> elements = ContextCorePlugin.getContextManager().getInterestingDocuments();
-		for (IMylarElement element : elements) {
-			if (element.getContentType().equals(HypertextStructureBridge.CONTENT_TYPE)) {
-				links.add(element.getHandleIdentifier());
-			}
-		}
-		return links;
-	}
-
-	private void createTable(Composite parent, FormToolkit toolkit) {
-		linksTree = toolkit.createTree(parent, SWT.NONE);
-		// TreeColumn col1 = new TreeColumn(linksTree, SWT.NULL);
-		// TableLayout tlayout = new TableLayout();
-		// tlayout.addColumnData(new ColumnWeightData(0,0,false));
-		// linksTree.setLayout(tlayout);
-		TableWrapData wd = new TableWrapData(TableWrapData.FILL_GRAB);
-		wd.heightHint = 350;
-		wd.grabVertical = true;
-		linksTree.setLayoutData(wd);
-		linksTree.setHeaderVisible(false);
-		// col1.addSelectionListener(new SelectionAdapter() {
-		// @Override
-		// public void widgetSelected(SelectionEvent e) {
-		// treeViewer.setSorter(new RelatedLinksTableSorter(
-		// RelatedLinksTableSorter.LABEL));
-		// }
-		// });
-		linksTree.addMouseTrackListener(new MouseTrackListener() {
-			public void mouseEnter(MouseEvent e) {
-				if (!((WebResourceContentProvider) treeViewer.getContentProvider()).isEmpty()) {
-					Cursor hyperlinkCursor = new Cursor(Display.getCurrent(), SWT.CURSOR_HAND);
-					Display.getCurrent().getCursorControl().setCursor(hyperlinkCursor);
-				}
-			}
-
-			public void mouseExit(MouseEvent e) {
-				Cursor pointer = new Cursor(Display.getCurrent(), SWT.CURSOR_ARROW);
-				if (Display.getCurrent() != null && Display.getCurrent().getCursorControl() != null) {
-					Display.getCurrent().getCursorControl().setCursor(pointer);
-				}
-			}
-
-			public void mouseHover(MouseEvent e) {
-				if (!((WebResourceContentProvider) treeViewer.getContentProvider()).isEmpty()) {
-					Cursor hyperlinkCursor = new Cursor(Display.getCurrent(), SWT.CURSOR_HAND);
-					Display.getCurrent().getCursorControl().setCursor(hyperlinkCursor);
-				}
-			}
-		});
-	}
-
-	// private void createAddDeleteButtons(Composite parent, FormToolkit
-	// toolkit) {
-	// Composite container = toolkit.createComposite(parent);
-	// container.setLayout(new GridLayout(2, true));
-	// Button addButton = toolkit.createButton(container, " Add Hyperlink ",
-	// SWT.PUSH | SWT.CENTER);
-	// addButton.addSelectionListener(new SelectionAdapter() {
-	// @Override
-	// public void widgetSelected(SelectionEvent e) {
-	// addLinkToTable();
-	// }
-	// });
-	//
-	// Button deleteButton = toolkit.createButton(container, "Delete Hyperlink
-	// ", SWT.PUSH | SWT.CENTER);
-	// deleteButton.addSelectionListener(new SelectionAdapter() {
-	//			
-	// @Override
-	// public void widgetSelected(SelectionEvent e) {
-	// removeLinkFromTable();
-	// }
-	// });
-	// }
-
-	private void addLinkToTable() {
-		// InputDialog dialog = new InputDialog(Display.getDefault()
-		// .getActiveShell(), "New related link",
-		// "Enter new related link for this task", "", null);
-		// dialog.open();
-		// String url = null;
-		// String link = dialog.getValue();
-		// if (link != null) {
-		// if (!(link.startsWith("http://") || link.startsWith("https://"))) {
-		// url = "http://" + link;
-		// } else {
-		// url = link;
-		// }
-		// tableViewer.add(url);
-		// }
-	}
-
-	private void removeLinkFromTable() {
-		String url = (String) ((IStructuredSelection) treeViewer.getSelection()).getFirstElement();
-		if (url != null) {
-			ContextCorePlugin.getContextManager().delete(ContextCorePlugin.getContextManager().getElement(url));
-		}
-		treeViewer.setInput(getWebDocs());
-	}
-
-	private void defineActions() {
-		delete = new Action() {
-			@Override
-			public void run() {
-				removeLinkFromTable();
-			}
-		};
-		delete.setText("Mark as Uninteresting");
-		delete.setToolTipText("Mark as Uninteresting");
-		delete.setImageDescriptor(TaskListImages.REMOVE);
-
-		add = new Action() {
-			@Override
-			public void run() {
-				addLinkToTable();
-			}
-		};
-		add.setText("Add");
-		add.setToolTipText("Add");
-		// add.setImageDescriptor(MylarImages.REMOVE);
-	}
-
-	private void hookContextMenu() {
-		MenuManager menuMgr = new MenuManager("#PopupMenu");
-		menuMgr.setRemoveAllWhenShown(true);
-		menuMgr.addMenuListener(new IMenuListener() {
-			public void menuAboutToShow(IMenuManager manager) {
-				// manager.add(add);
-				manager.add(delete);
-			}
-		});
-		Menu menu = menuMgr.createContextMenu(treeViewer.getControl());
-		treeViewer.getControl().setMenu(menu);
-		// getSite().registerContextMenu(menuMgr, tableViewer);
-	}
-
-	private void openURLinBrowser(String url) {
-		try {
-			IWebBrowser browser = null;
-			int flags = 0;
-			if (WorkbenchBrowserSupport.getInstance().isInternalWebBrowserAvailable()) {
-				flags = WorkbenchBrowserSupport.AS_EDITOR | WorkbenchBrowserSupport.LOCATION_BAR
-						| WorkbenchBrowserSupport.NAVIGATION_BAR;
-
-			} else {
-				flags = WorkbenchBrowserSupport.AS_EXTERNAL | WorkbenchBrowserSupport.LOCATION_BAR
-						| WorkbenchBrowserSupport.NAVIGATION_BAR;
-			}
-			browser = WorkbenchBrowserSupport.getInstance().createBrowser(flags, "org.eclipse.mylyn.tasklist",
-					"Mylar Context Browser", "tasktooltip");
-			browser.openURL(new URL(url));
-		} catch (PartInitException e) {
-			MessageDialog.openError(Display.getDefault().getActiveShell(), "URL not found", url
-					+ " could not be opened");
-		} catch (MalformedURLException e) {
-			MessageDialog.openError(Display.getDefault().getActiveShell(), "URL not found", url
-					+ " could not be opened");
-		}
-	}
-
-	public TreeViewer getTreeViewer() {
-		return treeViewer;
-	}
-
-	// private class RelatedLinksCellModifier implements ICellModifier,
-	// IColorProvider {
-	// RelatedLinksCellModifier() {
-	// super();
-	//
-	// }
-	// public boolean canModify(Object element, String property) {
-	// return true;
-	// }
-	// public Object getValue(Object element, String property) {
-	// Object res = null;
-	// if (element instanceof String) {
-	// String url = (String) element;
-	// openURLinBrowser(url);
-	// res = (String) element;
-	// }
-	// return res;
-	// }
-	// public void modify(Object element, String property, Object value) {
-	// return;
-	// }
-	//		
-	// public Color getForeground(Object element) {
-	// return HYPERLINK;
-	// }
-	//		
-	// public Color getBackground(Object element) {
-	// return null;
-	// }
-	// }
-
-	// private class RelatedLinksTableSorter extends ViewerSorter {
-	//
-	// public final static int LABEL = 1;
-	//
-	// private int criteria;
-	//
-	// public RelatedLinksTableSorter(int criteria) {
-	// super();
-	// this.criteria = criteria;
-	// }
-	//
-	// @Override
-	// public int compare(Viewer viewer, Object o1, Object o2) {
-	// String s1 = (String) o1;
-	// String s2 = (String) o2;
-	// switch (criteria) {
-	// case LABEL:
-	// return compareLabel(s1, s2);
-	// default:
-	// return 0;
-	// }
-	// }
-	//
-	// protected int compareLabel(String s1, String s2) {
-	// return s1.compareTo(s2);
-	// }
-	//
-	// public int getCriteria() {
-	// return criteria;
-	// }
-	// }
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/hypertext/WebElementsEditorFactory.java b/org.eclipse.mylyn.ide.dev/developer/src-old/hypertext/WebElementsEditorFactory.java
deleted file mode 100644
index a594bed..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/hypertext/WebElementsEditorFactory.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004 - 2006 University Of British Columbia and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     University Of British Columbia - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.mylyn.internal.hypertext.ui.editors;
-
-import org.eclipse.mylyn.internal.tasklist.ui.ITaskEditorFactory;
-import org.eclipse.mylyn.internal.tasklist.ui.editors.MylarTaskEditor;
-import org.eclipse.mylyn.provisional.tasklist.ITask;
-import org.eclipse.ui.IEditorInput;
-import org.eclipse.ui.IEditorPart;
-import org.eclipse.ui.part.EditorPart;
-
-/**
- * @author Mik Kersten
- */
-public class WebElementsEditorFactory implements ITaskEditorFactory {
-
-	public void notifyEditorActivationChange(IEditorPart editor) {
-		if (editor instanceof WebElementsEditor) {
-			((WebElementsEditor) editor).update();
-		}
-	}
-
-	public EditorPart createEditor(MylarTaskEditor parentEditor) {
-		return new WebElementsEditor();
-	}
-
-	public IEditorInput createEditorInput(ITask task) {
-		return new WebElementsEditorInput(task);
-	}
-
-	public String getTitle() {
-		return "Web Docs";
-	}
-
-	public boolean canCreateEditorFor(ITask task) {
-		return true;
-	}
-
-	public boolean providesOutline() {
-		return false;
-	}
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/hypertext/WebElementsEditorInput.java b/org.eclipse.mylyn.ide.dev/developer/src-old/hypertext/WebElementsEditorInput.java
deleted file mode 100644
index 5e6c980..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/hypertext/WebElementsEditorInput.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004 - 2006 University Of British Columbia and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     University Of British Columbia - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.mylyn.internal.hypertext.ui.editors;
-
-import org.eclipse.jface.resource.ImageDescriptor;
-import org.eclipse.mylyn.provisional.tasklist.ITask;
-import org.eclipse.ui.IEditorInput;
-import org.eclipse.ui.IPersistableElement;
-
-/**
- * @author Ken Sueda
- */
-public class WebElementsEditorInput implements IEditorInput {
-
-	private static final String LABEL_EDITOR = "Web Docs";
-
-	// private IMylarContext context;
-
-	public WebElementsEditorInput(ITask task) {
-		// this.context = context;
-	}
-
-	public boolean exists() {
-		return true;
-	}
-
-	public ImageDescriptor getImageDescriptor() {
-		return null;
-	}
-
-	public String getName() {
-		return LABEL_EDITOR;
-	}
-
-	public IPersistableElement getPersistable() {
-		return null;
-	}
-
-	public String getToolTipText() {
-		return LABEL_EDITOR;
-	}
-
-	public Object getAdapter(Class adapter) {
-		return null;
-	}
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/hypertext/WebResourceContentProvider.java b/org.eclipse.mylyn.ide.dev/developer/src-old/hypertext/WebResourceContentProvider.java
deleted file mode 100644
index 55dbddc..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/hypertext/WebResourceContentProvider.java
+++ /dev/null
@@ -1,104 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004 - 2006 University Of British Columbia and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     University Of British Columbia - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.mylyn.internal.hypertext.ui.editors;
-
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-import org.eclipse.jface.viewers.IStructuredContentProvider;
-import org.eclipse.jface.viewers.ITreeContentProvider;
-import org.eclipse.jface.viewers.Viewer;
-import org.eclipse.mylyn.internal.hypertext.HypertextStructureBridge;
-import org.eclipse.mylyn.internal.hypertext.MylarHypertextPlugin;
-import org.eclipse.mylyn.provisional.core.IMylarStructureBridge;
-import org.eclipse.mylyn.provisional.core.MylarPlugin;
-
-/**
- * @author Mik Kersten
- */
-public class WebResourceContentProvider implements IStructuredContentProvider, ITreeContentProvider {
-
-//	private final WebElementsEditor editor;
-
-//	/**
-//	 * @param editor
-//	 */
-//	WebResourceContentProvider(WebElementsEditor editor) {
-//		this.editor = editor;
-//	}
-
-	@SuppressWarnings("unchecked")
-	public Object[] getElements(Object parent) {
-		if (parent instanceof ArrayList) {
-			List<String> webDocs = (ArrayList<String>) parent;
-			IMylarStructureBridge bridge = ContextCore.getStructureBridge(
-					HypertextStructureBridge.CONTENT_TYPE);
-			Set<String> sites = new HashSet<String>();
-			for (String link : webDocs) {
-				String webSite = bridge.getParentHandle(link);
-				if (webSite != null) {
-					sites.add(webSite);
-					List<String> pages = MylarHypertextPlugin.getWebResourceManager().getSitesMap().get(webSite);
-					if (pages == null) {
-						pages = new ArrayList<String>();
-						MylarHypertextPlugin.getWebResourceManager().getSitesMap().put(webSite, pages);
-					}
-					pages.add(link);
-				}
-			}
-			if (sites.size() > 0) {
-				return sites.toArray();
-			} else {
-				return new String[] { "Task context not activated" };
-			}
-		} else {
-			return getChildren(parent);
-		}
-	}
-
-	public void dispose() {
-		// don't care if we are disposed
-	}
-
-	public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
-		// don't care if the input chages
-	}
-
-	public boolean isEmpty() {
-		return false;
-	}
-
-	public Object[] getChildren(Object parentElement) {
-		if (parentElement instanceof String) {
-			String site = (String) parentElement;
-			List<String> pages = MylarHypertextPlugin.getWebResourceManager().getSitesMap().get(site);
-			if (pages != null)
-				return pages.toArray();
-		}
-		return null;
-	}
-
-	public Object getParent(Object element) {
-		return null;
-	}
-
-	public boolean hasChildren(Object parentElement) {
-		if (parentElement instanceof String) {
-			String site = (String) parentElement;
-			List<String> pages = MylarHypertextPlugin.getWebResourceManager().getSitesMap().get(site);
-			return pages != null && pages.size() > 0;
-		}
-		return false;
-	}
-}
\ No newline at end of file
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/hypertext/WebResourceLabelProvider.java b/org.eclipse.mylyn.ide.dev/developer/src-old/hypertext/WebResourceLabelProvider.java
deleted file mode 100644
index 6088610..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/hypertext/WebResourceLabelProvider.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004 - 2006 University Of British Columbia and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     University Of British Columbia - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.mylyn.internal.hypertext.ui.editors;
-
-import org.eclipse.jface.viewers.IColorProvider;
-import org.eclipse.jface.viewers.ITableLabelProvider;
-import org.eclipse.jface.viewers.LabelProvider;
-import org.eclipse.mylyn.internal.hypertext.MylarHypertextPlugin;
-import org.eclipse.mylyn.internal.hypertext.ui.HypertextImages;
-import org.eclipse.mylyn.internal.tasklist.ui.TaskListColorsAndFonts;
-import org.eclipse.mylyn.internal.ui.MylarImages;
-import org.eclipse.swt.graphics.Color;
-import org.eclipse.swt.graphics.Image;
-
-/**
- * @author Mik Kersten
- */
-public class WebResourceLabelProvider extends LabelProvider implements ITableLabelProvider, IColorProvider {
-
-	public String getColumnText(Object obj, int columnIndex) {
-		String result = "";
-		if (obj instanceof String) {
-			switch (columnIndex) {
-			case 0:
-				result = (String) obj;
-				break;
-			default:
-				break;
-			}
-		}
-		return result;
-	}
-
-	public Image getColumnImage(Object obj, int columnIndex) {
-		if (columnIndex == 0) {
-			if (!MylarHypertextPlugin.getWebResourceManager().getSitesMap().containsKey(obj)) {
-				return MylarImages.getImage(HypertextImages.WEB_PAGE);
-			}
-		}
-		return null;
-	}
-
-	public Color getForeground(Object element) {
-		return TaskListColorsAndFonts.COLOR_HYPERLINK;
-	}
-
-	public Color getBackground(Object element) {
-		return null;
-	}
-}
\ No newline at end of file
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/jira/JiraIssueContentOutlinePage.java b/org.eclipse.mylyn.ide.dev/developer/src-old/jira/JiraIssueContentOutlinePage.java
deleted file mode 100644
index 588f379..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/jira/JiraIssueContentOutlinePage.java
+++ /dev/null
@@ -1,136 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2006 Jira Dashboard project.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *    Brock Janiczak - initial API and implementation
- *******************************************************************************/
-package org.eclipse.mylyn.internal.jira.ui;
-
-import java.text.DateFormat;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-import org.eclipse.jface.viewers.IOpenListener;
-import org.eclipse.jface.viewers.IStructuredSelection;
-import org.eclipse.jface.viewers.ITreeContentProvider;
-import org.eclipse.jface.viewers.LabelProvider;
-import org.eclipse.jface.viewers.OpenEvent;
-import org.eclipse.jface.viewers.TreeViewer;
-import org.eclipse.jface.viewers.Viewer;
-import org.eclipse.mylyn.internal.jira.MylarJiraPlugin;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.ui.views.contentoutline.ContentOutlinePage;
-import org.tigris.jira.core.model.Comment;
-import org.tigris.jira.core.model.Issue;
-
-/**
- * @author Brock Janiczak
- */
-public class JiraIssueContentOutlinePage extends ContentOutlinePage {
-
-	private static final DateFormat DATE_FORMAT = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT);
-	
-	private final Issue issue;
-
-	private Image commentImage;
-	private Image jiraImage;
-
-	private final JiraTaskEditor editor;
-	
-	public JiraIssueContentOutlinePage(Issue issue) {
-		this(null, issue);
-	}
-	
-	public JiraIssueContentOutlinePage(JiraTaskEditor editor, Issue issue) {
-		this.editor = editor;
-		this.issue = issue;
-		commentImage = MylarJiraPlugin.getDefault().getImageRegistry().get("icons/obj16/comment.gif");
-		jiraImage = MylarJiraPlugin.getDefault().getImageRegistry().get("icons/obj16/jira.png");
-	}
-	
-	/* (non-Javadoc)
-	 * @see org.eclipse.ui.views.contentoutline.ContentOutlinePage#createControl(org.eclipse.swt.widgets.Composite)
-	 */
-	public void createControl(Composite parent) {
-		super.createControl(parent);
-		
-		TreeViewer treeViewer = getTreeViewer();
-		
-		treeViewer.setContentProvider(new ITreeContentProvider() {
-		
-			public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
-			}
-		
-			public void dispose() {
-			}
-		
-			public Object[] getElements(Object inputElement) {
-				List<Object> elements = new ArrayList<Object>();
-				elements.add(issue.getSummary());
-				elements.addAll(Arrays.asList(issue.getComments()));
-				
-				// root elements are summary, environment, description and "comments"
-				
-				return elements.toArray();
-			}
-		
-			public boolean hasChildren(Object element) {
-				// "comments" has children
-				return false;
-			}
-		
-			public Object getParent(Object element) {
-				return null;
-			}
-		
-			public Object[] getChildren(Object parentElement) {
-				// Get all of the comments from the comment list
-				return new Object[0];
-			}
-		
-		});
-		treeViewer.setLabelProvider(new LabelProvider() {
-		
-			public String getText(Object element) {
-				if (element instanceof Comment) {
-					Comment comment = (Comment)element;
-					return DATE_FORMAT.format(comment.getCreated()) + " " + comment.getAuthor();
-				}
-				return super.getText(element);
-			}
-		
-			public Image getImage(Object element) {
-				if (element instanceof Comment) {
-					return commentImage;
-				} else {
-					// TODO the summary should be a placeholder object
-					return jiraImage;
-				}
-			}
-		
-		});
-		
-		treeViewer.addOpenListener(new IOpenListener() {
-		
-			public void open(OpenEvent event) {
-				if (editor == null) {
-					return;
-				}
-				
-				Object selection = ((IStructuredSelection)event.getSelection()).getFirstElement();
-				if (selection instanceof Comment) {
-					editor.revealComment((Comment)selection);
-				}
-			}
-		
-		});
-		treeViewer.setInput(issue);
-	}
-	
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/jira/JiraIssueEditorInput.java b/org.eclipse.mylyn.ide.dev/developer/src-old/jira/JiraIssueEditorInput.java
deleted file mode 100644
index 9140c7d..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/jira/JiraIssueEditorInput.java
+++ /dev/null
@@ -1,99 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2005 Jira Dashboard project.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *    Brock Janiczak - initial API and implementation
- *******************************************************************************/
-package org.eclipse.mylyn.internal.jira.ui;
-
-import org.eclipse.core.runtime.Platform;
-import org.eclipse.jface.resource.ImageDescriptor;
-import org.eclipse.mylyn.internal.jira.JiraTask;
-import org.eclipse.ui.IEditorInput;
-import org.eclipse.ui.IPersistableElement;
-
-public class JiraIssueEditorInput implements IEditorInput {
-
-	private final JiraTask task;
-
-	public JiraIssueEditorInput(JiraTask task) {
-		this.task = task;
-	}
-	
-	/* (non-Javadoc)
-	 * @see org.eclipse.ui.IEditorInput#exists()
-	 */
-	public boolean exists() {
-		return false;
-	}
-
-	/* (non-Javadoc)
-	 * @see org.eclipse.ui.IEditorInput#getImageDescriptor()
-	 */
-	public ImageDescriptor getImageDescriptor() {
-		return null;
-	}
-
-	/* (non-Javadoc)
-	 * @see org.eclipse.ui.IEditorInput#getName()
-	 */
-	public String getName() {
-		return task.getHandleIdentifier();
-	}
-
-	/* (non-Javadoc)
-	 * @see org.eclipse.ui.IEditorInput#getPersistable()
-	 */
-	public IPersistableElement getPersistable() {
-		return null;
-	}
-
-	/* (non-Javadoc)
-	 * @see org.eclipse.ui.IEditorInput#getToolTipText()
-	 */
-	public String getToolTipText() {
-		return task.getDescription();
-	}
-
-	/* (non-Javadoc)
-	 * @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class)
-	 */
-	@SuppressWarnings("unchecked")
-	public Object getAdapter(Class adapter) {
-		return Platform.getAdapterManager().getAdapter(this, adapter);
-	}
-	
-	/* (non-Javadoc)
-	 * @see java.lang.Object#equals(java.lang.Object)
-	 */
-	@Override
-	public boolean equals(Object obj) {
-		if (!(obj instanceof JiraIssueEditorInput)) {
-			return false;
-		}
-		
-		JiraIssueEditorInput that = (JiraIssueEditorInput) obj;
-		return (this.task.getHandleIdentifier().equals(that.task.getHandleIdentifier()) &&
-				this.task.getRepositoryUrl().equals(that.task.getRepositoryUrl()));
-	}
-	
-	/* (non-Javadoc)
-	 * @see java.lang.Object#hashCode()
-	 */
-	@Override
-	public int hashCode() {
-		return this.task.getHandleIdentifier().hashCode() + this.task.getRepositoryUrl().hashCode();
-	}
-	
-	/**
-	 * @return the task
-	 */
-	public JiraTask getTask() {
-		return this.task;
-	}
-
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/jira/JiraTaskEditor.java b/org.eclipse.mylyn.ide.dev/developer/src-old/jira/JiraTaskEditor.java
deleted file mode 100644
index 31c5989..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/jira/JiraTaskEditor.java
+++ /dev/null
@@ -1,419 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2006 - 2006 Mylar eclipse.org project and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     Mylar project committers - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.mylyn.internal.jira.ui;
-
-import java.text.DateFormat;
-import java.util.HashMap;
-import java.util.Map;
-
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.jface.layout.GridDataFactory;
-import org.eclipse.jface.resource.JFaceResources;
-import org.eclipse.mylyn.internal.jira.JiraServerFacade;
-import org.eclipse.mylyn.internal.jira.JiraTask;
-import org.eclipse.mylyn.tasks.core.TaskRepository;
-import org.eclipse.mylyn.tasks.ui.TasksUiPlugin;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.custom.ScrolledComposite;
-import org.eclipse.swt.events.ControlAdapter;
-import org.eclipse.swt.events.ControlEvent;
-import org.eclipse.swt.events.ModifyEvent;
-import org.eclipse.swt.events.ModifyListener;
-import org.eclipse.swt.graphics.Point;
-import org.eclipse.swt.layout.FillLayout;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Text;
-import org.eclipse.ui.IEditorInput;
-import org.eclipse.ui.IEditorSite;
-import org.eclipse.ui.PartInitException;
-import org.eclipse.ui.forms.events.ExpansionAdapter;
-import org.eclipse.ui.forms.events.ExpansionEvent;
-import org.eclipse.ui.forms.widgets.ExpandableComposite;
-import org.eclipse.ui.forms.widgets.Form;
-import org.eclipse.ui.forms.widgets.FormToolkit;
-import org.eclipse.ui.forms.widgets.ImageHyperlink;
-import org.eclipse.ui.forms.widgets.Section;
-import org.eclipse.ui.internal.forms.widgets.*;
-import org.eclipse.ui.part.EditorPart;
-import org.eclipse.ui.views.contentoutline.IContentOutlinePage;
-import org.tigris.jira.core.model.Comment;
-import org.tigris.jira.core.model.Issue;
-import org.tigris.jira.core.service.JiraServer;
-
-/**
- * @author Brock Janiczak
- * @author Mik Kersten (minor fixes)
- */
-public class JiraTaskEditor extends EditorPart {
-
-	private static final DateFormat DATE_FORMAT = DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.SHORT);
-
-	private JiraIssueEditorInput input;
-
-	private Text comment;
-
-	private boolean isDirty = false;
-
-	private Map<Comment, ExpandableComposite> commentToControlMap = new HashMap<Comment, ExpandableComposite>();
-
-	private JiraServer server;
-
-	private Issue issue;
-
-	private ScrolledComposite sc;
-
-	private Section commentsSection;
-
-	public JiraTaskEditor() {
-		// commentImage =
-		// MylarJiraPlugin.getImageDescriptor("icons/ctool16/comment.gif").createImage();
-		// commentFont =
-		// JFaceResources.getFontRegistry().getBold(JFaceResources.DEFAULT_FONT);
-	}
-
-	public void doSave(IProgressMonitor monitor) {
-		server.addCommentToIssue(issue, comment.getText());
-		comment.setText("");
-		isDirty = false;
-	}
-
-	public boolean isSaveAsAllowed() {
-		return false;
-	}
-	
-	public void doSaveAs() {
-	}
-
-	public void init(IEditorSite site, IEditorInput input) throws PartInitException {
-		this.input = (JiraIssueEditorInput) input;
-		setSite(site);
-		setInput(input);
-		setPartName(this.input.getName());
-		JiraTask task = this.input.getTask();
-		TaskRepository repository = TasksUiPlugin.getRepositoryManager().getRepository(task.getRepositoryKind(),
-				task.getRepositoryUrl());
-		server = JiraServerFacade.getDefault().getJiraServer(repository);
-		String key = task.getKey();
-		if (key == null || key.trim().equals("")) {
-			throw new PartInitException("Could not find issue key, synchronize query to resolve.");
-		} else {
-			issue = server.getIssue(key);
-		}
-	}
-
-	public boolean isDirty() {
-		return isDirty;
-//		if (comment != null) {
-//			int charCount = comment.getCharCount();
-//			isDirty = charCount > 0;
-//			return isDirty;
-//		} else {
-//			return false;
-//		}
-	}
-
-	public void createPartControl(Composite parent) {
-		FormToolkit toolkit = new FormToolkit(getSite().getShell().getDisplay());
-		Form form = toolkit.createForm(parent);
-		GridLayout formLayout = new GridLayout(1, true);
-		final Composite formBody = form.getBody();
-		formBody.setLayout(formLayout);
-		
-		if (issue == null) {
-			form.setText("Error opening task");
-			toolkit.createLabel(formBody, "Could not download: " + this.input.getTask().getDescription());
-			toolkit.createLabel(formBody, "\nTry synchronizing the corresponding query");
-			return;
-		}
-		
-		form.setText(issue.getKey() + ": " + issue.getSummary());
-
-		Section summarySection = toolkit.createSection(formBody, ExpandableComposite.TITLE_BAR
-				| ExpandableComposite.TWISTIE);
-		summarySection.setText("Attributes");
-		summarySection.setLayoutData(GridDataFactory.fillDefaults().grab(true, false).create());
-		summarySection.setExpanded(true);
-		Composite summary = toolkit.createComposite(summarySection);
-		summary.setLayout(new GridLayout(6, false));
-
-		Label lblCreated = toolkit.createLabel(summary, "Created:");
-		lblCreated.setFont(JFaceResources.getFontRegistry().getBold(JFaceResources.DEFAULT_FONT));
-		toolkit.createLabel(summary, DATE_FORMAT.format(issue.getCreated()));
-
-		Label lblUpdated = toolkit.createLabel(summary, "Updated:");
-		lblUpdated.setFont(JFaceResources.getFontRegistry().getBold(JFaceResources.DEFAULT_FONT));
-		toolkit.createLabel(summary, DATE_FORMAT.format(issue.getUpdated()));
-
-		if (issue.getDue() != null) {
-			Label lblDue = toolkit.createLabel(summary, "Due:");
-			lblDue.setFont(JFaceResources.getFontRegistry().getBold(JFaceResources.DEFAULT_FONT));
-			toolkit.createLabel(summary, DATE_FORMAT.format(issue.getDue()));
-		} else {
-			Label spacer = toolkit.createLabel(summary, "");
-			spacer.setLayoutData(GridDataFactory.fillDefaults().span(2, 1).create());
-		}
-
-		Label lblStatus = toolkit.createLabel(summary, "Status:");
-		lblStatus.setFont(JFaceResources.getFontRegistry().getBold(JFaceResources.DEFAULT_FONT));
-		toolkit.createLabel(summary, issue.getStatus().getName());
-
-		Label lblResolution = toolkit.createLabel(summary, "Resolution:");
-		lblResolution.setFont(JFaceResources.getFontRegistry().getBold(JFaceResources.DEFAULT_FONT));
-		if (issue.getResolution() != null) {
-			Label resolution = toolkit.createLabel(summary, issue.getResolution().getName());
-			resolution.setToolTipText(issue.getResolution().getDescription());
-		} else {
-			toolkit.createLabel(summary, "Unresolved");
-		}
-
-		Label lblPriority = toolkit.createLabel(summary, "Priority:");
-		lblPriority.setFont(JFaceResources.getFontRegistry().getBold(JFaceResources.DEFAULT_FONT));
-		if (issue.getPriority() != null) {
-			Label priority = toolkit.createLabel(summary, issue.getPriority().getName());
-			priority.setToolTipText(issue.getPriority().getDescription());
-		} else {
-			toolkit.createLabel(summary, "No Priority");
-		}
-
-		Label lblReporter = toolkit.createLabel(summary, "Reporter:");
-		lblReporter.setFont(JFaceResources.getFontRegistry().getBold(JFaceResources.DEFAULT_FONT));
-		toolkit.createLabel(summary, issue.getReporter());
-
-		Label lblAssignee = toolkit.createLabel(summary, "Assignee");
-		lblAssignee.setFont(JFaceResources.getFontRegistry().getBold(JFaceResources.DEFAULT_FONT));
-		toolkit.createLabel(summary, issue.getAssignee());
-
-		// spacer
-		Label spacer2 = toolkit.createLabel(summary, "");
-		spacer2.setLayoutData(GridDataFactory.fillDefaults().span(2, 1).create());
-
-		StringBuffer sbComponents = new StringBuffer();
-		if (issue.getComponents().length > 0) {
-			for (int i = 0; i < issue.getComponents().length; i++) {
-				if (i != 0) {
-					sbComponents.append(", ");
-				}
-
-				sbComponents.append(issue.getComponents()[i].getName());
-			}
-		} else {
-			sbComponents.append("None");
-		}
-
-		Label lblComponents = toolkit.createLabel(summary, "Components");
-		lblComponents.setFont(JFaceResources.getFontRegistry().getBold(JFaceResources.DEFAULT_FONT));
-		toolkit.createLabel(summary, sbComponents.toString());
-
-		StringBuffer sbAffectsVersions = new StringBuffer();
-		if (issue.getReportedVersions().length > 0) {
-			for (int i = 0; i < issue.getReportedVersions().length; i++) {
-				if (i != 0) {
-					sbAffectsVersions.append(", ");
-				}
-
-				sbAffectsVersions.append(issue.getReportedVersions()[i].getName());
-			}
-		} else {
-			sbAffectsVersions.append("None");
-		}
-
-		Label lblAffectsVersion = toolkit.createLabel(summary, "Affects Versions");
-		lblAffectsVersion.setFont(JFaceResources.getFontRegistry().getBold(JFaceResources.DEFAULT_FONT));
-		toolkit.createLabel(summary, sbAffectsVersions.toString());
-
-		StringBuffer sbFixVersions = new StringBuffer();
-		if (issue.getFixVersions().length > 0) {
-			for (int i = 0; i < issue.getFixVersions().length; i++) {
-				if (i != 0) {
-					sbFixVersions.append(", ");
-				}
-
-				sbFixVersions.append(issue.getFixVersions()[i].getName());
-			}
-		} else {
-			sbFixVersions.append("None");
-		}
-
-		Label lblFixVersions = toolkit.createLabel(summary, "Fix Versions");
-		lblFixVersions.setFont(JFaceResources.getFontRegistry().getBold(JFaceResources.DEFAULT_FONT));
-		toolkit.createLabel(summary, sbFixVersions.toString());
-
-		summarySection.setClient(summary);
-
-		// created, updated, due (optional)
-
-		final Section descriptionSection = toolkit.createSection(formBody, ExpandableComposite.TITLE_BAR
-				| ExpandableComposite.TWISTIE);
-		descriptionSection.setExpanded(true);
-		descriptionSection.setText("Description");
-		final GridData dgd = GridDataFactory.fillDefaults().grab(true, false).create();
-		descriptionSection.setLayoutData(dgd);
-
-		Composite c = toolkit.createComposite(descriptionSection);
-		GridLayout gl = new GridLayout(1, true);
-		gl.marginHeight = 0;
-		gl.marginWidth = 0;
-		c.setLayout(gl);
-
-		Text description = toolkit.createText(c, issue.getDescription(), SWT.MULTI | SWT.WRAP | SWT.V_SCROLL);
-		description.setLayoutData(GridDataFactory.fillDefaults().grab(true, false).minSize(200, 80).hint(200, 80)
-				.create());
-
-		description.setText(issue.getDescription());
-		description.setEditable(false);
-		description.setFont(JFaceResources.getTextFont());
-		descriptionSection.setClient(c);
-
-		commentsSection = toolkit.createSection(formBody, ExpandableComposite.TITLE_BAR | ExpandableComposite.TWISTIE);
-		commentsSection.setExpanded(true);
-		ImageHyperlink sortOrder = toolkit.createImageHyperlink(commentsSection, SWT.NONE);
-		sortOrder.setText("Direction");
-
-		commentsSection.setTextClient(sortOrder);
-		commentsSection.setText("Comments");
-		commentsSection.setLayoutData(GridDataFactory.fillDefaults().grab(true, true).create());
-
-		sc = new ScrolledComposite(commentsSection, SWT.H_SCROLL | SWT.V_SCROLL);
-		sc.setExpandHorizontal(true);
-		sc.setExpandVertical(true);
-
-		sc.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
-
-		final Composite c1 = toolkit.createComposite(sc);
-		GridLayout commentsLayout = new GridLayout(1, true);
-		commentsLayout.marginWidth = 0;
-		commentsLayout.marginHeight = 0;
-
-		c1.setLayout(commentsLayout);
-
-		for (int i = 0; i < issue.getComments().length; i++) {
-			Comment comment = issue.getComments()[i];
-
-			ExpandableComposite expandableComposite = toolkit.createExpandableComposite(c1,
-					ExpandableComposite.TREE_NODE);
-			expandableComposite.setText("Comment by " + comment.getAuthor() + " ["
-					+ DATE_FORMAT.format(comment.getCreated()) + "]");
-			expandableComposite.setLayout(new FillLayout(SWT.HORIZONTAL));
-			expandableComposite.setLayoutData(GridDataFactory.fillDefaults().grab(true, false).create());
-
-			Text t = toolkit.createText(expandableComposite, comment.getComment(), SWT.MULTI | SWT.WRAP);
-			t.setEditable(false);
-			t.setFont(JFaceResources.getTextFont());
-
-			expandableComposite.setClient(t);
-			expandableComposite.addExpansionListener(new ExpansionAdapter() {
-
-				@Override
-				public void expansionStateChanged(ExpansionEvent e) {
-					sc.layout(true, true);
-				}
-
-			});
-			commentToControlMap.put(comment, expandableComposite);
-
-			t.setLayoutData(GridDataFactory.fillDefaults().grab(true, false).create());
-
-			if (i == issue.getComments().length - 1) {
-				expandableComposite.setExpanded(true);
-			}
-
-		}
-
-		commentsSection.setClient(sc);
-
-		sc.addControlListener(new ControlAdapter() {
-
-			public void controlResized(ControlEvent e) {
-				Point size = c1.computeSize(sc.getClientArea().width, SWT.DEFAULT);
-				sc.setMinSize(size);
-			}
-
-		});
-
-		final Section commentSection = toolkit.createSection(formBody, ExpandableComposite.TWISTIE
-				| ExpandableComposite.TITLE_BAR);
-		commentSection.setLayoutData(GridDataFactory.fillDefaults().grab(true, false).create());
-		commentSection.setText("Add Comment");
-		commentSection.setExpanded(false);
-		commentSection.addExpansionListener(new ExpansionAdapter() {
-
-			public void expansionStateChanged(ExpansionEvent e) {
-				formBody.layout(true);
-			}
-		});
-
-		final Composite commentArea = toolkit.createComposite(commentSection);
-		GridLayout commentAreaLayout = new GridLayout(1, false);
-		commentAreaLayout.marginHeight = 0;
-		commentAreaLayout.marginWidth = 0;
-		commentAreaLayout.verticalSpacing = 0;
-		commentAreaLayout.horizontalSpacing = 0;
-		commentArea.setLayout(commentAreaLayout);
-
-		commentSection.setClient(commentArea);
-
-		comment = new Text(commentArea, SWT.BORDER | SWT.MULTI | SWT.WRAP | SWT.V_SCROLL);
-		comment.setFont(JFaceResources.getTextFont());
-		final GridData commentGd = new GridData(SWT.FILL, SWT.FILL, true, false);
-		commentGd.heightHint = 80;
-		comment.setLayoutData(commentGd);
-
-		comment.addModifyListener(new ModifyListener() {
-
-			public void modifyText(ModifyEvent e) {
-				int charCount = comment.getCharCount();
-				if (charCount > 0) {
-					isDirty = true;
-//				if ((isDirty && charCount == 0) || (!isDirty && charCount > 0)) {
-					firePropertyChange(PROP_DIRTY);
-				}
-			}
-
-		});
-		sc.setContent(c1);
-		sc.setMinSize(c1.computeSize(SWT.DEFAULT, SWT.DEFAULT));
-	}
-
-	@SuppressWarnings("restriction")
-	public void revealComment(Comment comment) {
-		Control control = (Control) this.commentToControlMap.get(comment);
-		if (control != null) {
-			commentsSection.setExpanded(true);
-			((ExpandableComposite) control).setExpanded(true);
-			// XXX Clone or create a new version of this
-			FormUtil.ensureVisible(sc, control);
-			sc.layout(true, true);
-		}
-	}
-
-	public void setFocus() {
-	}
-
-	public void dispose() {
-		super.dispose();
-		// commentImage.dispose();
-	}
-
-	@SuppressWarnings("unchecked")
-	public Object getAdapter(Class adapter) {
-		if (IContentOutlinePage.class.equals(adapter)) {
-			return new JiraIssueContentOutlinePage(this, this.issue);
-		}
-
-		return super.getAdapter(adapter);
-	}
-
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/monitor/CardinalStatistic.java b/org.eclipse.mylyn.ide.dev/developer/src-old/monitor/CardinalStatistic.java
deleted file mode 100644
index cd9ea80..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/monitor/CardinalStatistic.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004 - 2005 University Of British Columbia and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     University Of British Columbia - initial API and implementation
- *******************************************************************************/
-/*
- * Created on Jul 20, 2004
-  */
-package org.eclipse.mylyn.monitor.internal;
-
-
-
-
-/**
- * @author Mik Kersten
- */
-public class CardinalStatistic extends UsageStatistic {
-    
-    private long count = 0;
-    
-    public CardinalStatistic(String handle) {
-        super(handle);
-    }
-    
-    public void increment() {
-        count++;
-    }
-    
-    public void increment(long increment) {
-        count += increment;
-    }
-    
-    public long getCount() {
-        return count;
-    }
-    
-    public void setCount(long count) {
-        this.count = count;
-    }
-    
-    @Override
-    public String toFormattedString() {
-        return toValueString();
-    }    
- 
-    @Override
-    public String toValueString() {
-        return "" + count;
-    }
-    
-    @Override
-    public boolean equals(Object object) {
-        if (object instanceof CardinalStatistic) {
-            CardinalStatistic cardinalStatistic = (CardinalStatistic)object;
-            return cardinalStatistic.getCount() == count
-            	&& super.equals(object);
-        } else {
-            return false;
-        }
-    }
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/monitor/PassiveTimer.java b/org.eclipse.mylyn.ide.dev/developer/src-old/monitor/PassiveTimer.java
deleted file mode 100644
index a41358c..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/monitor/PassiveTimer.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004 - 2006 University Of British Columbia and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     University Of British Columbia - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.mylyn.internal.sandbox.misc;
-
-/**
- * Check against the system clock--doesn't need to run as thread.
- * 
- * @author Mik Kersten
- */
-public class PassiveTimer {
-
-	private long elapsed = 0;
-
-	private long lastStartTime = System.currentTimeMillis();
-
-	public void restart() {
-		lastStartTime = System.currentTimeMillis();
-		elapsed = 0;
-	}
-
-	public long getElapsedInSeconds() {
-		elapsed = System.currentTimeMillis() - lastStartTime;
-		return elapsed / 1000;
-	}
-}
\ No newline at end of file
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/monitor/SelectionMonitor.java b/org.eclipse.mylyn.ide.dev/developer/src-old/monitor/SelectionMonitor.java
deleted file mode 100644
index f5fc67c..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/monitor/SelectionMonitor.java
+++ /dev/null
@@ -1,174 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004 - 2006 University Of British Columbia and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     University Of British Columbia - initial API and implementation
- *******************************************************************************/
-/*
- * Created on Jun 10, 2005
- */
-package org.eclipse.mylyn.internal.monitor.monitors;
-
-import org.eclipse.core.resources.IFile;
-import org.eclipse.core.resources.IResource;
-import org.eclipse.core.runtime.IAdaptable;
-import org.eclipse.jdt.core.IJavaElement;
-import org.eclipse.jdt.core.JavaModelException;
-import org.eclipse.jdt.internal.ui.actions.SelectionConverter;
-import org.eclipse.jdt.internal.ui.javaeditor.JavaEditor;
-import org.eclipse.jface.text.TextSelection;
-import org.eclipse.jface.viewers.ISelection;
-import org.eclipse.jface.viewers.StructuredSelection;
-import org.eclipse.mylyn.internal.core.MylarContextManager;
-import org.eclipse.mylyn.internal.monitor.HandleObfuscator;
-import org.eclipse.mylyn.provisional.core.AbstractUserInteractionMonitor;
-import org.eclipse.mylyn.provisional.core.IMylarElement;
-import org.eclipse.mylyn.provisional.core.InteractionEvent;
-import org.eclipse.mylyn.provisional.core.MylarPlugin;
-import org.eclipse.ui.IEditorInput;
-import org.eclipse.ui.IPathEditorInput;
-import org.eclipse.ui.IWorkbenchPart;
-import org.eclipse.ui.part.EditorPart;
-
-/**
- * Limited to Java selections.
- * 
- * @author Mik Kersten
- */
-public class SelectionMonitor extends AbstractUserInteractionMonitor {
-
-	private static final String ID_JAVA_UNKNOWN = "(non-source element)";
-
-	public static final String SELECTION_DEFAULT = "selected";
-
-	public static final String SELECTION_NEW = "new";
-
-	public static final String SELECTION_DECAYED = "decayed";
-
-	public static final String SELECTION_PREDICTED = "predicted";
-
-	private static final Object ID_JAVA_UNKNOW_OLD = "(non-existing element)";
-
-	private IJavaElement lastSelectedElement = null;
-
-	private HandleObfuscator obfuscator = new HandleObfuscator();
-	
-	@Override
-	protected void handleWorkbenchPartSelection(IWorkbenchPart part, ISelection selection) {
-		// ignored, since not using context monitoring facilities
-	}
-
-	@Override
-	public void selectionChanged(IWorkbenchPart part, ISelection selection) {
-		String structureKind = InteractionEvent.ID_UNKNOWN;
-		String obfuscatedElementHandle = InteractionEvent.ID_UNKNOWN;
-		String elementHandle = InteractionEvent.ID_UNKNOWN;
-		InteractionEvent.Kind interactionKind = InteractionEvent.Kind.SELECTION;
-		if (selection instanceof StructuredSelection) {
-			StructuredSelection structuredSelection = (StructuredSelection) selection;
-			Object selectedObject = structuredSelection.getFirstElement();
-			if (selectedObject == null)
-				return;
-			if (selectedObject instanceof IJavaElement) {
-				IJavaElement javaElement = (IJavaElement) selectedObject;
-				structureKind = "java:" + javaElement.getClass();
-				elementHandle = javaElement.getHandleIdentifier();
-				obfuscatedElementHandle = obfuscateJavaElementHandle(javaElement);
-				lastSelectedElement = javaElement;
-			} else {
-				structureKind = InteractionEvent.ID_UNKNOWN + ": " + selectedObject.getClass();
-				if (selectedObject instanceof IAdaptable) {
-					IResource resource = (IResource) ((IAdaptable) selectedObject).getAdapter(IResource.class);
-					if (resource != null) {
-						obfuscatedElementHandle = obfuscator.obfuscateResourcePath(resource.getProjectRelativePath());
-					}
-				}
-			}
-		} else {
-			if (selection instanceof TextSelection && part instanceof JavaEditor) {
-				TextSelection textSelection = (TextSelection) selection;
-				IJavaElement javaElement;
-				try {
-					javaElement = SelectionConverter.resolveEnclosingElement((JavaEditor) part, textSelection);
-					if (javaElement != null) {
-						structureKind = "java:" + javaElement.getClass();
-						obfuscatedElementHandle = obfuscateJavaElementHandle(javaElement);
-						elementHandle = javaElement.getHandleIdentifier();
-						if (javaElement != null && javaElement.equals(lastSelectedElement)) {
-							interactionKind = InteractionEvent.Kind.EDIT;
-						}
-						lastSelectedElement = javaElement;
-					}
-				} catch (JavaModelException e) {
-					// ignore unresolved elements
-				}
-			} else if (part instanceof EditorPart) {
-				EditorPart editorPart = (EditorPart) part;
-				IEditorInput input = editorPart.getEditorInput();
-				if (input instanceof IPathEditorInput) {
-					structureKind = "file";
-					obfuscatedElementHandle = obfuscator.obfuscateResourcePath(((IPathEditorInput) input).getPath());
-				}
-			}
-		}
-		IMylarElement node = ContextCorePlugin.getContextManager().getElement(elementHandle);
-		String delta = "";
-		float selectionFactor = MylarContextManager.getScalingFactors().get(InteractionEvent.Kind.SELECTION).getValue();
-
-		// XXX: broken in 0.4?
-		if (node != null) {
-			if (node.getInterest().getEncodedValue() <= selectionFactor
-					&& node.getInterest().getValue() > selectionFactor) {
-				delta = SELECTION_PREDICTED;
-			} else if (node.getInterest().getEncodedValue() < selectionFactor
-					&& node.getInterest().getDecayValue() > selectionFactor) {
-				delta = SELECTION_DECAYED;
-			} else if (node.getInterest().getValue() == selectionFactor
-					&& node.getInterest().getDecayValue() < selectionFactor) {
-				delta = SELECTION_NEW;
-			} else {
-				delta = SELECTION_DEFAULT;
-			}
-		}
-
-		InteractionEvent event = new InteractionEvent(interactionKind, structureKind, obfuscatedElementHandle, part
-				.getSite().getId(), "null", delta, 0);
-		ContextCore.notifyInteractionObserved(event);
-	}
-
-	private String obfuscateJavaElementHandle(IJavaElement javaElement) {
-		try {
-			StringBuffer obfuscatedPath = new StringBuffer();
-			IResource resource;
-			resource = (IResource) javaElement.getUnderlyingResource();
-			if (resource != null && (resource instanceof IFile)) {
-				IFile file = (IFile) resource;
-				obfuscatedPath.append(obfuscator.obfuscateResourcePath(file.getProjectRelativePath()));
-				obfuscatedPath.append(':');
-				obfuscatedPath.append(obfuscator.obfuscateString(javaElement.getElementName()));
-				return obfuscatedPath.toString();
-			} else {
-				return obfuscator.obfuscateString(javaElement.getHandleIdentifier());
-			}
-		} catch (JavaModelException e) {
-			// ignore non-existing element
-		}
-		return ID_JAVA_UNKNOWN;
-	}
-
-	/**
-	 * Some events do not have a valid handle, e.g. hande is null or ?
-	 */
-	public static boolean isValidStructureHandle(InteractionEvent event) {
-		String handle = event.getStructureHandle();
-		return handle != null 
-			&& !handle.trim().equals("") 
-			&& !handle.equals(SelectionMonitor.ID_JAVA_UNKNOWN)
-			&& !handle.equals(SelectionMonitor.ID_JAVA_UNKNOW_OLD)
-			&& event.isValidStructureHandle();
-	}
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/monitor/TemporalStatistic.java b/org.eclipse.mylyn.ide.dev/developer/src-old/monitor/TemporalStatistic.java
deleted file mode 100644
index 2ac20aa..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/monitor/TemporalStatistic.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004 - 2005 University Of British Columbia and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     University Of British Columbia - initial API and implementation
- *******************************************************************************/
-/*
- * Created on Jul 20, 2004
-  */
-package org.eclipse.mylyn.monitor.internal;
-
-import org.eclipse.jface.resource.ImageDescriptor;
-
-
-
-/**
- * @author Mik Kersten
- */
-public class TemporalStatistic extends UsageStatistic {
-
-    private String time;
-    
-    public TemporalStatistic(String handle, String time, ImageDescriptor icon) {
-        super(handle);
-        this.time = time;
-    }
-
-    @Override
-    public String toFormattedString() {
-        return toValueString();
-    }
-    
-    @Override
-    public String toValueString() {
-        return time;
-    }
-    
-    public String getTime() {
-        return time;
-    }
-    
-    public void setTime(String time) {
-        this.time = time;
-    }
-    
-    @Override
-    public boolean equals(Object object) {
-        if (object instanceof TemporalStatistic) {
-            TemporalStatistic statistic = (TemporalStatistic)object;
-            return statistic.getTime().equals(time)
-            	&& super.equals(object);
-        } else {
-            return false;
-        }
-    }
-} 
-
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/monitor/UsageCountView.java b/org.eclipse.mylyn.ide.dev/developer/src-old/monitor/UsageCountView.java
deleted file mode 100644
index f9b9ec2..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/monitor/UsageCountView.java
+++ /dev/null
Binary files differ
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/monitor/UsageSession.java b/org.eclipse.mylyn.ide.dev/developer/src-old/monitor/UsageSession.java
deleted file mode 100644
index 1fcbb53..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/monitor/UsageSession.java
+++ /dev/null
@@ -1,337 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004 - 2005 University Of British Columbia and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     University Of British Columbia - initial API and implementation
- *******************************************************************************/
-/*
- * Created on Jul 13, 2004
-  */
-package org.eclipse.mylyn.monitor.internal;
-
-import java.util.*;
-
-import org.eclipse.mylyn.core.util.DateUtil;
-
-
-
-/**
- * @author Mik Kersten
- */
-public class UsageSession {
-
-    public static final String START_DATE = "startDate";
-    public static final String START_TIME = "startTime";
-    public static final String NUM_SECONDS_ELAPSED = "numSecondsElapsed";
-    public static final String NUM_KEYSTROKES_JAVA_EDITOR = "numKeystrokesJavaEditor";
-    public static final String NUM_SELECTIONS_PKG_EXPLORER = "numSelectionsPkgExplorer";
-    public static final String NUM_SELECTIONS_PKG_EXPLORER_MYLAR = "numSelectionsPkgExplorerMylar";
-    public static final String NUM_SELECTIONS_PROBLEMS = "numSelectionsProblems";
-    public static final String NUM_SELECTIONS_PROBLEMS_MYLAR = "numSelectionsProblemsMylar";
-    public static final String NUM_SELECTIONS_JAVA_OUTLINE = "numSelectionsJavaOutline";
-    public static final String NUM_SELECTIONS_JAVA_OUTLINE_MYLAR = "numSelectionsJavaOutlineMylar";
-    public static final String NUM_SELECTIONS_JAVA_EDITOR = "numSelectionsJavaEditor";
-    public static final String NUM_SELECTIONS_JAVA_EDITOR_AUTOFOLD = "numSelectionsJavaEditorAutoFold";
-    public static final String NUM_SELECTIONS_SEARCH = "numSelectionsSearch";
-    public static final String NUM_SELECTIONS_SEARCH_MYLAR = "numSelectionsSearchMylar";
-    public static final String NUM_SELECTIONS_PATHFINDER = "numSelectionsPathfinder";
-    public static final String NUM_SELECTIONS_OTHER = "numSelectionsOther";
-    
-    private List<UsageStatistic> statistics; 
-    private static final String DELIM = ", ";
-   
-	
-	public UsageSession() {
-	    
-	    statistics = new ArrayList<UsageStatistic>();
-	    
-	    statistics.add(new TemporalStatistic(START_DATE, DateUtil.getFormattedDate(), null));
-	    statistics.add(new TemporalStatistic(START_TIME, DateUtil.getFormattedTime(), null));
-	    
-	    statistics.add(new CardinalStatistic(NUM_KEYSTROKES_JAVA_EDITOR));   
-	    statistics.add(new CardinalStatistic(NUM_SECONDS_ELAPSED));
-//	    statistics.add(new CardinalStatistic(NUM_SELECTIONS_PATHFINDER));
-	    statistics.add(new CardinalStatistic(NUM_SELECTIONS_JAVA_EDITOR));
-//	    statistics.add(new CardinalStatistic(NUM_SELECTIONS_JAVA_EDITOR_AUTOFOLD));
-	    statistics.add(new CardinalStatistic(NUM_SELECTIONS_JAVA_OUTLINE));
-//	    statistics.add(new CardinalStatistic(NUM_SELECTIONS_JAVA_OUTLINE_MYLAR));
-	    statistics.add(new CardinalStatistic(NUM_SELECTIONS_OTHER));
-	    statistics.add(new CardinalStatistic(NUM_SELECTIONS_PKG_EXPLORER));
-//	    statistics.add(new CardinalStatistic(NUM_SELECTIONS_PKG_EXPLORER_MYLAR));
-	    statistics.add(new CardinalStatistic(NUM_SELECTIONS_PROBLEMS));
-//	    statistics.add(new CardinalStatistic(NUM_SELECTIONS_PROBLEMS_MYLAR));
-	    statistics.add(new CardinalStatistic(NUM_SELECTIONS_SEARCH));
-//	    statistics.add(new CardinalStatistic(NUM_SELECTIONS_SEARCH_MYLAR));
-	}
-	
-	/**
-	 * Read in alphabetical order.
-	 * 
-	 * @param csv string that this session should be created from
-	 */
-	public UsageSession(String fromCsvString) {
-	    this();
-	    
-	    StringTokenizer tokenizer = new StringTokenizer(fromCsvString, DELIM);
-	    getTemporalStatistic(START_DATE).setTime(tokenizer.nextToken());
-	    getTemporalStatistic(START_TIME).setTime(tokenizer.nextToken());
-	    getCardinalStatistic(NUM_KEYSTROKES_JAVA_EDITOR).setCount(new Long(tokenizer.nextToken()).longValue());   
-	    getCardinalStatistic(NUM_SECONDS_ELAPSED).setCount(new Long(tokenizer.nextToken()).longValue());
-//	    getCardinalStatistic(NUM_SELECTIONS_PATHFINDER).setCount(new Long(tokenizer.nextToken()).longValue());
-	    getCardinalStatistic(NUM_SELECTIONS_JAVA_EDITOR).setCount(new Long(tokenizer.nextToken()).longValue());
-//	    getCardinalStatistic(NUM_SELECTIONS_JAVA_EDITOR_AUTOFOLD).setCount(new Long(tokenizer.nextToken()).longValue());
-	    getCardinalStatistic(NUM_SELECTIONS_JAVA_OUTLINE).setCount(new Long(tokenizer.nextToken()).longValue());
-//	    getCardinalStatistic(NUM_SELECTIONS_JAVA_OUTLINE_MYLAR).setCount(new Long(tokenizer.nextToken()).longValue());
-	    getCardinalStatistic(NUM_SELECTIONS_OTHER).setCount(new Long(tokenizer.nextToken()).longValue());
-	    getCardinalStatistic(NUM_SELECTIONS_PKG_EXPLORER).setCount(new Long(tokenizer.nextToken()).longValue());
-//	    getCardinalStatistic(NUM_SELECTIONS_PKG_EXPLORER_MYLAR).setCount(new Long(tokenizer.nextToken()).longValue());
-	    getCardinalStatistic(NUM_SELECTIONS_PROBLEMS).setCount(new Long(tokenizer.nextToken()).longValue());
-//	    getCardinalStatistic(NUM_SELECTIONS_PROBLEMS_MYLAR).setCount(new Long(tokenizer.nextToken()).longValue());
-	    getCardinalStatistic(NUM_SELECTIONS_SEARCH).setCount(new Long(tokenizer.nextToken()).longValue());
-//	    getCardinalStatistic(NUM_SELECTIONS_SEARCH_MYLAR).setCount(new Long(tokenizer.nextToken()).longValue());    		        
-	}
-
-	/**
-	 * @return a short one line summary string
-	 */
-    public String getSummary() {
-        long selections = 
-//	    	getCardinalStatistic(NUM_SELECTIONS_PATHFINDER).getCount() +
-		    getCardinalStatistic(NUM_SELECTIONS_JAVA_EDITOR).getCount() +
-//		    getCardinalStatistic(NUM_SELECTIONS_JAVA_EDITOR_AUTOFOLD).getCount() +
-		    getCardinalStatistic(NUM_SELECTIONS_JAVA_OUTLINE).getCount() +
-//		    getCardinalStatistic(NUM_SELECTIONS_JAVA_OUTLINE_MYLAR).getCount() +
-		    getCardinalStatistic(NUM_SELECTIONS_OTHER).getCount() +
-		    getCardinalStatistic(NUM_SELECTIONS_PKG_EXPLORER).getCount() +
-//		    getCardinalStatistic(NUM_SELECTIONS_PKG_EXPLORER_MYLAR).getCount() +
-		    getCardinalStatistic(NUM_SELECTIONS_PROBLEMS).getCount() +
-//		    getCardinalStatistic(NUM_SELECTIONS_PROBLEMS_MYLAR).getCount() +
-		    getCardinalStatistic(NUM_SELECTIONS_SEARCH).getCount();
-//		    getCardinalStatistic(NUM_SELECTIONS_SEARCH_MYLAR).getCount(); 
-        if (selections == 0) {
-            return "<no data>";
-        } else {
-	        long keystrokes = getCardinalStatistic(NUM_KEYSTROKES_JAVA_EDITOR).getCount();
-	        return "edit ratio: " + (float)keystrokes/selections/10;
-        }
-    }
-	
-	/**
-	 * @return null if not found
-	 */
-	public UsageStatistic getStatistic(String statisticHandle) {
-	    if (statisticHandle == null) return null;
-        for (UsageStatistic statistic : statistics) {
-            if (statistic.getHandle().equals(statisticHandle)) {
-                return statistic;
-            }
-        }
-	    return null;
-	}
-
-	public TemporalStatistic getTemporalStatistic(String statisticHandle) {
-	    return (TemporalStatistic)getStatistic(statisticHandle);
-	}
-
-	public CardinalStatistic getCardinalStatistic(String statisticHandle) {
-	    return (CardinalStatistic)getStatistic(statisticHandle);
-	}
-	
-	
-    public List<UsageStatistic> getStatistics() {
-        return statistics;
-    }
-    
-    /**
-     * @param session
-     */
-    public void appendData(UsageSession session) {
-        for (UsageStatistic statistic : session.getStatistics()) {
-            if (statistic instanceof CardinalStatistic) {
-                CardinalStatistic cardinal = (CardinalStatistic)statistic;
-                getCardinalStatistic(cardinal.getHandle()).increment(cardinal.getCount());
-            } 
-        }
-    }
-	
-	public String getCsvHeader() {
-	    StringBuffer buffer = new StringBuffer();
-        for (UsageStatistic statistic : statistics) {
-            buffer.append(statistic.getHandle());
-            buffer.append(DELIM);
-        }
-	    return buffer.toString();
-	}
-	
-    public static String formatTimeFromSeconds(long seconds) {
-        long hours = seconds/3600;
-        long minutes = seconds/60;
-        long secondsRemainder = seconds - hours*3600 - minutes*60;
-        return hours + " hours, " + minutes + " minutes, " + secondsRemainder + " seconds"; 
-    }
-	
-	/**
-	 * @return single line String in comma-separated value format 
-	 */
-	public String toCsvString() {
-	    StringBuffer buffer = new StringBuffer();
-        for (UsageStatistic statistic : statistics) {
-            buffer.append(statistic.toValueString());
-            buffer.append(DELIM);
-        }
-	    return buffer.toString();	    
-	}
-	
-    /**
-     * @return
-     */
-    public List toFormattedList() {
-        List<String> list = new ArrayList<String>();
-        for (UsageStatistic statistic : statistics) {
-            list.add(statistic.toFormattedString());
-        }
-        return list;
-//	    list.add("startDate: " + startDate);
-//	    list.add("startTime: " + startTime); 
-//	    list.add("timeSession: " + UsageSession.formatTimeFromSeconds(timeSession));
-//        list.add("numJavaEditorKeystrokes: " + numJavaEditorKeystrokes);
-//        list.add("numSelectionsOther: " + numSelectionsOther); 
-//        list.add("numSelectionsPkgExplorer: " + numSelectionsPkgExplorer); 
-//        list.add("numSelectionsMylarPkgExplorer: " + numSelectionsMylarPkgExplorer); 
-//        list.add("numSelectionsProblems: " + numSelectionsProblems); 
-//        list.add("numSelectionsMylarProblems: " + numSelectionsMylarProblems); 
-//        list.add("numSelectionsJavaOutline: " + numSelectionsJavaOutline); 
-//        list.add("numSelectionsMylarJavaOutline: " + numSelectionsMylarJavaOutline); 
-//        list.add("numSelectionsEditor: " + numSelectionsEditor); 
-//        list.add("numSelectionsPathfinder: " + numSelectionsPathfinder); 
-//        list.add("numSelectionsSearch: " + numSelectionsSearch);	  
-    }
-	
-	public String toLongString() {
-	    return
-	    	"------------------\n" + 
-	    	getCsvHeader() + "\n" + 
-	    	toCsvString() + "\n" + 
-	    	"------------------\n";
-	}
-	
-	@Override
-    public boolean equals(Object object) {
-        if (!(object instanceof UsageSession)) return false;
-        UsageSession session = (UsageSession)object;
-        return session.getStatistics().equals(statistics);
-        
-//        return 
-//	    	timeSession == session.getTimeSession() &&
-//	    	numJavaEditorKeystrokes == session.getNumJavaEditorKeystrokes() &&
-//	    	numSelectionsOther == session.getNumSelectionsOther() &&
-//	    	numSelectionsPkgExplorer == session.getNumSelectionsPkgExplorer() &&
-//	    	numSelectionsMylarPkgExplorer == session.getNumSelectionsMylarPkgExplorer() &&
-//	    	numSelectionsProblems == session.getNumSelectionsProblems() &&
-//	    	numSelectionsMylarProblems == session.getNumSelectionsMylarProblems() &&
-//	    	numSelectionsJavaOutline == session.getNumSelectionsJavaOutline() &&
-//	    	numSelectionsMylarJavaOutline == session.getNumSelectionsMylarJavaOutline() &&
-//	    	numSelectionsEditor == session.getNumSelectionsEditor() &&
-//	    	numSelectionsPathfinder == session.getNumSelectionsPathfinder() &&
-//	    	numSelectionsSearch == session.getNumSelectionsSearch();
-    }
-	
-	@Override
-	public String toString() {
-	    return toCsvString();
-	}
-
-//    public String getStartDate() {
-//        return startDate;
-//    }
-//    public void setStartDate(String date) {
-//        this.startDate = date;
-//    }
-//    
-//    /**
-//     * @return time in seconds
-//     */
-//    public long getTimeSession() {
-//        return timeSession;
-//    }
-//    
-//    public void setTimeSession(long duration) {
-//        this.timeSession = duration;
-//    }
-//    public int getNumSelectionsEditor() {
-//        return numSelectionsEditor;
-//    }
-//    public void incrementSelectionsEditor() {
-//        this.numSelectionsEditor++;
-//    }
-//    public int getNumSelectionsJavaOutline() {
-//        return numSelectionsJavaOutline;
-//    }
-//    public void incrementSelectionsJavaOutline() {
-//        this.numSelectionsJavaOutline++;
-//    }
-//    public int getNumSelectionsMylarJavaOutline() {
-//        return numSelectionsMylarJavaOutline;
-//    }
-//    public void incrementSelectionsMylarJavaOutline() {
-//        this.numSelectionsMylarJavaOutline++;
-//    }
-//    public int getNumSelectionsMylarPkgExplorer() {
-//        return numSelectionsMylarPkgExplorer;
-//    }
-//    public void setNumSelectionsMylarPkgExplorer() {
-//        this.numSelectionsMylarPkgExplorer++;
-//    }
-//    public int getNumSelectionsMylarProblems() {
-//        return numSelectionsMylarProblems;
-//    }
-//    public void incrementSelectionsMylarProblems() {
-//        this.numSelectionsMylarProblems++;
-//    }
-//    public int getNumSelectionsOther() {
-//        return numSelectionsOther;
-//    }
-//    public void incrementSelectionsOther() {
-//        this.numSelectionsOther++;
-//    }
-//    public int getNumSelectionsPathfinder() {
-//        return numSelectionsPathfinder;
-//    }
-//    public void incrementSelectionsPathfinder() {
-//        this.numSelectionsPathfinder++;
-//    }
-//    public int getNumSelectionsPkgExplorer() {
-//        return numSelectionsPkgExplorer;
-//    }
-//    public void incrementSelectionsPkgExplorer() {
-//        this.numSelectionsPkgExplorer++;
-//    }
-//    public int getNumSelectionsProblems() {
-//        return numSelectionsProblems;
-//    }
-//    public void incrementSelectionsProblems() {
-//        this.numSelectionsProblems++;
-//    }
-//    public int getNumSelectionsSearch() {
-//        return numSelectionsSearch;
-//    }
-//    public void incrementSelectionsSearch() {
-//        this.numSelectionsSearch++;
-//    }
-//    public String getStartTime() {
-//        return startTime;
-//    }
-//    public void setStartTime(String startTime) {
-//        this.startTime = startTime;
-//    }
-//    public int getNumJavaEditorKeystrokes() {
-//        return numJavaEditorKeystrokes;
-//    }
-//    public void incrementNumJavaEditorKeystrokes() {
-//        this.numJavaEditorKeystrokes++;
-//    }
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/monitor/UsageStatistic.java b/org.eclipse.mylyn.ide.dev/developer/src-old/monitor/UsageStatistic.java
deleted file mode 100644
index db20ad8..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/monitor/UsageStatistic.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004 - 2005 University Of British Columbia and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     University Of British Columbia - initial API and implementation
- *******************************************************************************/
-/*
- * Created on Jul 20, 2004
-  */
-package org.eclipse.mylyn.monitor.internal;
-
-
-/**
- * @author Mik Kersten
- */
-public abstract class UsageStatistic {
-    
-    private String handle;
-    
-    public abstract String toFormattedString(); 
-    
-    /**
-     * String value of this statistic, used for serialization.
-     */
-    public abstract String toValueString();
-    
-    public UsageStatistic(String handle) {
-        this.handle = handle;
-    }
-    
-    public String getHandle() {
-        return handle;
-    }
-    
-    @Override
-    public boolean equals(Object object) {
-        if (object instanceof UsageStatistic) {
-            UsageStatistic statistic = (UsageStatistic)object;
-            return statistic.handle.equals(handle);
-        } else {
-            return false;
-        }
-    }
-    
-    @Override
-    public String toString() {
-        return handle + ": " + toValueString();
-    }
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/tasks/AbstractTaskListFactory.java b/org.eclipse.mylyn.ide.dev/developer/src-old/tasks/AbstractTaskListFactory.java
deleted file mode 100644
index b797536..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/tasks/AbstractTaskListFactory.java
+++ /dev/null
@@ -1,184 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004, 2008 Tasktop Technologies and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     Tasktop Technologies - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.mylyn.internal.tasks.core.deprecated;
-
-import java.util.Collections;
-import java.util.Set;
-
-import org.eclipse.mylyn.internal.tasks.core.AbstractTask;
-import org.eclipse.mylyn.internal.tasks.core.RepositoryQuery;
-import org.eclipse.mylyn.tasks.core.IRepositoryQuery;
-import org.eclipse.mylyn.tasks.core.ITask;
-import org.w3c.dom.Element;
-
-/**
- * @deprecated Do not use. This class is pending for removal: see bug 237552.
- */
-@Deprecated
-public abstract class AbstractTaskListFactory {
-
-	public static final String KEY_QUERY = "Query";
-
-	public static final String KEY_QUERY_STRING = "QueryString";
-
-	public static final String KEY_TASK = "Task";
-
-	/**
-	 * Returns true if factory can create an XML element to store given {@link AbstractTask}.
-	 * <p>
-	 * The name of the XML element is taken from the {@link #getTaskElementName()} method and additional task attributes
-	 * can be stored in {@link #setAdditionalAttributes(AbstractTask, Element)} method.
-	 * 
-	 * @param task
-	 *            a task instance to create XML element for
-	 * 
-	 * @return true if factory can create XML element to store given {@link AbstractTask}.
-	 * 
-	 * @see #getTaskElementName()
-	 * @see #setAdditionalAttributes(AbstractTask, Element)
-	 * @since 3.0
-	 */
-	public abstract boolean canCreate(ITask task);
-
-	/**
-	 * Returns true if factory can create an XML element to store given {@link RepositoryQuery}.
-	 * <p>
-	 * The name of the XML element is taken from the {@link #getQueryElementName(RepositoryQuery)} method and additional
-	 * query attributes can be stored in {@link #setAdditionalAttributes(RepositoryQuery, Element)}.
-	 * 
-	 * @param query
-	 *            a query instance to create an XML element for
-	 * 
-	 * @return true if factory can create XML element to store given {@link AbstractTask}.
-	 * 
-	 * @see #getQueryElementName(RepositoryQuery)
-	 * @see #setAdditionalAttributes(RepositoryQuery, Element)
-	 * @since 3.0
-	 */
-	public boolean canCreate(IRepositoryQuery query) {
-		return false;
-	}
-
-	/**
-	 * Creates an {@link RepositoryQuery} instance from given XML element matching one of the names returned by
-	 * {@link #getQueryElementNames()}.
-	 * <p>
-	 * Concrete implementation should populate required query configuration using method parameters and content of the
-	 * passed XML element. Children tasks for this query instance will be created by the caller of this method.
-	 * 
-	 * @param repositoryUrl
-	 *            an url for the corresponding task repository
-	 * @param queryString
-	 *            a query string, e.g. connector-specific url used for query request
-	 * @param label
-	 *            a query label or name
-	 * @param element
-	 *            an XML element containing query data
-	 * @return instance of the {@link RepositoryQuery}
-	 * 
-	 * @see #getQueryElementNames()
-	 * @since 3.0
-	 */
-	public RepositoryQuery createQuery(String repositoryUrl, String queryString, String label, Element element) {
-		return null;
-	}
-
-	/**
-	 * Creates an {@link AbstractTask} instance from given XML element matching name returned by
-	 * {@link #getTaskElementName()}.
-	 * <p>
-	 * Concrete implementation should populate required task data using method parameters and content of the passed XML
-	 * element. Children tasks of this task instance will be created by the caller of this method.
-	 * 
-	 * @param repositoryUrl
-	 *            an url for the corresponding task repository
-	 * @param queryString
-	 *            a query string, e.g. connector-specific url used for query request
-	 * @param label
-	 *            a query label or name
-	 * @param element
-	 *            an XML element containing query data
-	 * @return instance of the {@link RepositoryQuery}
-	 * 
-	 * @see #getTaskElementName()
-	 * @since 3.0
-	 */
-	public abstract AbstractTask createTask(String repositoryUrl, String taskId, String label, Element element);
-
-	/**
-	 * Returns name of the XML element used to store given query instance if {@link #canCreate(RepositoryQuery)} return
-	 * true for given query instance.
-	 * 
-	 * @param query
-	 *            a query instance to get the name for
-	 * 
-	 * @return name for the XML element to store given query instance or null if factory doesn't support given
-	 *         {@link RepositoryQuery} instance.
-	 * 
-	 * @see #canCreate(RepositoryQuery)
-	 * @since 3.0
-	 */
-	public String getQueryElementName(IRepositoryQuery query) {
-		return "";
-	}
-
-	/**
-	 * Returns names for all query elements.
-	 * <p>
-	 * This collection is used to determine if this factory can create {@link RepositoryQuery} instance from the XML
-	 * element using {@link #createQuery(String, String, String, Element)} method.
-	 * 
-	 * @return a <code>Set</code> of query element names
-	 * 
-	 * @see #createQuery(String, String, String, Element)
-	 */
-	public Set<String> getQueryElementNames() {
-		return Collections.emptySet();
-	}
-
-	/**
-	 * Returns name for the XML element used to store subclass of the {@link AbstractTask} used by this factory. This
-	 * value is used to create an XML element when storing given {@link AbstractTask} as well as to determine if this
-	 * factory can read XML element with content of the task.
-	 * 
-	 * @return name of the task element
-	 * 
-	 * @see #canCreate(AbstractTask)
-	 */
-	public abstract String getTaskElementName();
-
-	/**
-	 * Adds additional attributes to an XML element used to store given {@link RepositoryQuery}.
-	 * 
-	 * @param query
-	 *            a query instance being stored
-	 * @param node
-	 *            an XML element used to store given query instance
-	 * @since 3.0
-	 */
-	public void setAdditionalAttributes(IRepositoryQuery query, Element node) {
-		// ignore
-	}
-
-	/**
-	 * Adds additional attributes to an XML element used to store given {@link AbstractTask}
-	 * 
-	 * @param task
-	 *            a task instance being stored
-	 * @param node
-	 *            an XML element used to store given task instance
-	 * @since 3.0
-	 */
-	public void setAdditionalAttributes(ITask task, Element element) {
-		// ignore
-	}
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/tasks/ITaskDataStorage.java b/org.eclipse.mylyn.ide.dev/developer/src-old/tasks/ITaskDataStorage.java
deleted file mode 100644
index f8ebc8d..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/tasks/ITaskDataStorage.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004, 2008 Tasktop Technologies and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     Tasktop Technologies - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.mylyn.internal.tasks.core;
-
-/**
- * @author Rob Elves
- */
-public interface ITaskDataStorage {
-
-	/**
-	 * Perform any initialization necessary storage
-	 * 
-	 * @throws Exception
-	 */
-	public void start() throws Exception;
-
-	public void stop() throws Exception;
-
-	public void put(TaskDataState taskDataState);
-
-	public TaskDataState get(String repositoryUrl, String id);
-
-	/**
-	 * if last id remove folder (i.e. in case of refactoring urls)
-	 */
-	public void remove(String repositoryUrl, String id);
-
-	/**
-	 * persist any unsaved data
-	 */
-	public void flush();
-
-	/**
-	 * DESTROY ALL OFFLINE DATA
-	 */
-	public void clear();
-
-	// Methods for NEW unsubmitted task data, currently not used
-
-//	public void putNew(TaskDataState newTaskDataState);
-//
-//	public Set<TaskDataState> getNew(String repositoryUrl);
-//
-//	public removeNew(id);
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/tasks/OfflineCachingStorage.java b/org.eclipse.mylyn.ide.dev/developer/src-old/tasks/OfflineCachingStorage.java
deleted file mode 100644
index df861dd..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/tasks/OfflineCachingStorage.java
+++ /dev/null
@@ -1,324 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004, 2008 Tasktop Technologies and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     Tasktop Technologies - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.mylyn.internal.tasks.ui;
-
-import java.util.Map;
-import java.util.Queue;
-import java.util.Timer;
-import java.util.TimerTask;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentLinkedQueue;
-
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.Platform;
-import org.eclipse.core.runtime.Status;
-import org.eclipse.core.runtime.jobs.Job;
-import org.eclipse.mylyn.commons.core.StatusHandler;
-import org.eclipse.mylyn.internal.tasks.core.ITaskDataStorage;
-import org.eclipse.mylyn.internal.tasks.core.TaskDataState;
-
-/**
- * @deprecated Do not use. This class is pending for removal: see bug 237552.
- */
-@Deprecated
-public class OfflineCachingStorage implements ITaskDataStorage {
-
-	private static final int DEFAULT_FLUSH_INTERVAL = 60 * 1000;
-
-	private static final int MAX_READ_QUEUE_SIZE = 80;
-
-	private final Map<String, Map<String, TaskDataState>> readCache = new ConcurrentHashMap<String, Map<String, TaskDataState>>();
-
-	private final Map<String, Map<String, TaskDataState>> writeCache = new ConcurrentHashMap<String, Map<String, TaskDataState>>();
-
-	private final Queue<TaskDataState> lruQueue = new ConcurrentLinkedQueue<TaskDataState>();
-
-	private final ITaskDataStorage storage;
-
-	private CacheFlushJob cacheFlushJob;
-
-	private Timer cacheFlushTimer;
-
-	public OfflineCachingStorage(ITaskDataStorage storage) {
-		this.storage = storage;
-	}
-
-	/**
-	 * FOR TESTING PURPOSES DESTROYS ALL DATA IN STORAGE
-	 */
-	public void clear() {
-		if (cacheFlushJob != null) {
-			cacheFlushJob.waitSaveCompleted();
-		}
-		readCache.clear();
-		writeCache.clear();
-		lruQueue.clear();
-		storage.clear();
-	}
-
-	public void flush() {
-		cacheFlushJob.waitSaveCompleted();
-		persistToStorage();
-	}
-
-	public TaskDataState get(String repositoryUrl, String id) {
-		TaskDataState result = null;
-		result = retrieveFromCache(writeCache, repositoryUrl, id);
-		if (result == null) {
-			result = retrieveFromCache(readCache, repositoryUrl, id);
-		}
-		if (result == null) {
-			result = retrieveFromStorage(repositoryUrl, id);
-		}
-		if (result != null) {
-			pushRead(result);
-		}
-		return result;
-	}
-
-	private TaskDataState retrieveFromCache(Map<String, Map<String, TaskDataState>> cache, String repositoryUrl,
-			String id) {
-		Map<String, TaskDataState> idMap = cache.get(repositoryUrl);
-		if (idMap != null) {
-			return idMap.get(id);
-		}
-		return null;
-	}
-
-	private TaskDataState retrieveFromStorage(String repositoryUrl, String id) {
-		TaskDataState result = null;
-		synchronized (readCache) {
-			Map<String, TaskDataState> idMap = readCache.get(repositoryUrl);
-			if (idMap == null) {
-				idMap = new ConcurrentHashMap<String, TaskDataState>();
-				readCache.put(repositoryUrl, idMap);
-			} else {
-				result = idMap.get(id);
-			}
-
-			if (result == null) {
-				result = storage.get(repositoryUrl, id);
-				if (result != null) {
-					idMap.put(id, result);
-				}
-			}
-		}
-		return result;
-	}
-
-	public void put(TaskDataState taskDataState) {
-		putReadCache(taskDataState);
-		putWriteCache(taskDataState);
-		if (cacheFlushJob != null) {
-			cacheFlushJob.requestSave();
-		}
-	}
-
-	public void remove(String repositoryUrl, String id) {
-		Map<String, TaskDataState> idMap = writeCache.get(repositoryUrl);
-		if (idMap != null) {
-			idMap.remove(id);
-		}
-		idMap = readCache.get(repositoryUrl);
-		if (idMap != null) {
-			idMap.remove(id);
-		}
-
-		lruQueue.remove(new TaskDataState(repositoryUrl, id));
-
-		storage.remove(repositoryUrl, id);
-	}
-
-	public void start() throws Exception {
-		storage.start();
-		if (cacheFlushTimer == null && cacheFlushJob == null) {
-			cacheFlushTimer = new Timer();
-			cacheFlushTimer.schedule(new RequestSaveTimerTask(), DEFAULT_FLUSH_INTERVAL, DEFAULT_FLUSH_INTERVAL);
-			cacheFlushJob = new CacheFlushJob();
-			cacheFlushJob.schedule();
-		}
-	}
-
-	public void stop() throws Exception {
-		cacheFlushTimer.cancel();
-		cacheFlushJob.cancel();
-		this.flush();
-		cacheFlushTimer = null;
-		cacheFlushJob = null;
-		storage.stop();
-	}
-
-	private void pushRead(TaskDataState state) {
-
-		lruQueue.remove(state);
-		lruQueue.add(state);
-		if (lruQueue.size() > MAX_READ_QUEUE_SIZE) {
-			flushReadCache(false);
-		}
-	}
-
-	private void putReadCache(TaskDataState taskDataState) {
-		if (taskDataState == null) {
-			return;
-		}
-		synchronized (readCache) {
-
-			Map<String, TaskDataState> idMap = readCache.get(taskDataState.getUrl());
-			if (idMap == null) {
-				idMap = new ConcurrentHashMap<String, TaskDataState>();
-				readCache.put(taskDataState.getUrl(), idMap);
-			}
-
-			idMap.put(taskDataState.getId(), taskDataState);
-		}
-		pushRead(taskDataState);
-	}
-
-	private synchronized void putWriteCache(TaskDataState taskDataState) {
-		if (taskDataState == null) {
-			return;
-		}
-
-		Map<String, TaskDataState> idMap = writeCache.get(taskDataState.getUrl());
-		if (idMap == null) {
-			idMap = new ConcurrentHashMap<String, TaskDataState>();
-			writeCache.put(taskDataState.getUrl(), idMap);
-		}
-		idMap.put(taskDataState.getId(), taskDataState);
-	}
-
-	private void persistToStorage() {
-		synchronized (writeCache) {
-			for (Map<String, TaskDataState> idMap : writeCache.values()) {
-				for (TaskDataState state : idMap.values()) {
-					storage.put(state);
-				}
-				idMap.clear();
-			}
-		}
-	}
-
-	private class CacheFlushJob extends Job {
-
-		private volatile boolean saveRequested = false;
-
-		private volatile boolean saveCompleted = true;
-
-		CacheFlushJob() {
-			super("Flush Cache Job");
-			setPriority(Job.LONG);
-			setSystem(true);
-		}
-
-		@Override
-		protected IStatus run(IProgressMonitor monitor) {
-			while (true) {
-				if (saveRequested) {
-					saveRequested = false;
-					saveCompleted = false;
-					try {
-						persistToStorage();
-					} catch (Throwable t) {
-						StatusHandler.log(new Status(IStatus.ERROR, TasksUiPlugin.ID_PLUGIN,
-								"Error saving offline cache", t));
-					}
-				}
-
-				if (!saveRequested) {
-					synchronized (this) {
-						saveCompleted = true;
-						notifyAll();
-						try {
-							wait();
-						} catch (InterruptedException ex) {
-							// ignore
-						}
-					}
-				}
-			}
-		}
-
-		void requestSave() {
-			saveRequested = true;
-		}
-
-		void runRequested() {
-			synchronized (this) {
-				notifyAll();
-			}
-		}
-
-		void waitSaveCompleted() {
-			while (!saveCompleted) {
-				synchronized (this) {
-					try {
-						wait();
-					} catch (InterruptedException ex) {
-						// ignore
-					}
-				}
-			}
-		}
-	}
-
-	private class RequestSaveTimerTask extends TimerTask {
-
-		@Override
-		public void run() {
-			if (!Platform.isRunning()) {
-				return;
-			} else {
-				flushReadCache(false);
-				cacheFlushJob.runRequested();
-			}
-		}
-	}
-
-	/**
-	 * @param reset
-	 *            if true all read cached data is dropped if false only remove until cache lower than
-	 *            MAX_READ_QUEUE_SIZE
-	 */
-	public void flushReadCache(boolean reset) {
-		if (reset) {
-			lruQueue.clear();
-			readCache.clear();
-		} else {
-			while (lruQueue.size() > MAX_READ_QUEUE_SIZE / 2) {
-				TaskDataState state = lruQueue.poll();
-				if (state != null) {
-					Map<String, TaskDataState> tasksMap = readCache.get(state.getUrl());
-					if (tasksMap != null) {
-						tasksMap.remove(state.getId());
-					}
-				}
-			}
-		}
-	}
-
-	/**
-	 * For testing...
-	 */
-	public Queue<TaskDataState> getReadQueue() {
-		return lruQueue;
-	}
-
-	public Map<String, Map<String, TaskDataState>> getReadCache() {
-		return readCache;
-	}
-
-	public Map<String, Map<String, TaskDataState>> getWriteCache() {
-		return writeCache;
-	}
-
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/tasks/OfflineDataStore.java b/org.eclipse.mylyn.ide.dev/developer/src-old/tasks/OfflineDataStore.java
deleted file mode 100644
index a3bd096..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/tasks/OfflineDataStore.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004, 2008 Tasktop Technologies and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     Tasktop Technologies - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.mylyn.internal.tasks.core;
-
-import java.io.Serializable;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-
-import org.eclipse.mylyn.internal.tasks.core.deprecated.RepositoryTaskAttribute;
-import org.eclipse.mylyn.internal.tasks.core.deprecated.RepositoryTaskData;
-
-/**
- * @deprecated Do not use. This class is pending for removal: see bug 237552.
- */
-@Deprecated
-class OfflineDataStore implements Serializable {
-
-	private static final long serialVersionUID = -3909632088254980426L;
-
-	/** Last new repository task taskId */
-	private int lastNewRepositoryTaskId = 0;
-
-	// Local changes to existing reports
-	private final Map<String, Set<RepositoryTaskAttribute>> localEdits = new ConcurrentHashMap<String, Set<RepositoryTaskAttribute>>();
-
-	/** Older version of Task Data */
-	private final Map<String, RepositoryTaskData> oldTaskDataMap = new ConcurrentHashMap<String, RepositoryTaskData>();
-
-	/** Newest version of the task data */
-	private final Map<String, RepositoryTaskData> newTaskDataMap = new ConcurrentHashMap<String, RepositoryTaskData>();
-
-	/** New unsubmitted repository task data */
-	private final Map<String, RepositoryTaskData> unsubmittedTaskData = new ConcurrentHashMap<String, RepositoryTaskData>();
-
-	public void setLastNewTaskId(int lastNumber) {
-		lastNewRepositoryTaskId = new Integer(lastNumber);
-	}
-
-	public int getNextTaskId() {
-		lastNewRepositoryTaskId++;
-		return lastNewRepositoryTaskId;
-	}
-
-	public Map<String, RepositoryTaskData> getOldDataMap() {
-		return oldTaskDataMap;
-	}
-
-	public Map<String, RepositoryTaskData> getNewDataMap() {
-		return newTaskDataMap;
-	}
-
-	public Map<String, RepositoryTaskData> getUnsubmittedTaskData() {
-		return unsubmittedTaskData;
-	}
-
-	public Map<String, Set<RepositoryTaskAttribute>> getLocalEdits() {
-		return localEdits;
-	}
-}
\ No newline at end of file
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/tasks/OfflineFileStorage.java b/org.eclipse.mylyn.ide.dev/developer/src-old/tasks/OfflineFileStorage.java
deleted file mode 100644
index e027513..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/tasks/OfflineFileStorage.java
+++ /dev/null
@@ -1,726 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004, 2008 Tasktop Technologies and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     Tasktop Technologies - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.mylyn.internal.tasks.ui;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.io.OutputStreamWriter;
-import java.net.URLEncoder;
-import java.nio.channels.FileChannel;
-import java.nio.channels.FileLock;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipInputStream;
-import java.util.zip.ZipOutputStream;
-
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.Status;
-import org.eclipse.mylyn.commons.core.StatusHandler;
-import org.eclipse.mylyn.internal.tasks.core.ITaskDataStorage;
-import org.eclipse.mylyn.internal.tasks.core.TaskDataState;
-import org.eclipse.mylyn.internal.tasks.core.deprecated.AbstractAttributeFactory;
-import org.eclipse.mylyn.internal.tasks.core.deprecated.RepositoryAttachment;
-import org.eclipse.mylyn.internal.tasks.core.deprecated.RepositoryOperation;
-import org.eclipse.mylyn.internal.tasks.core.deprecated.RepositoryTaskAttribute;
-import org.eclipse.mylyn.internal.tasks.core.deprecated.RepositoryTaskData;
-import org.eclipse.mylyn.internal.tasks.core.deprecated.TaskComment;
-import org.eclipse.ui.IMemento;
-import org.eclipse.ui.XMLMemento;
-
-/**
- * @deprecated Do not use. This class is pending for removal: see bug 237552.
- */
-@SuppressWarnings( { "restriction", "deprecation" })
-@Deprecated
-public class OfflineFileStorage implements ITaskDataStorage {
-
-	private static final String ATTRIBUTE_TASK_KIND = "taskKind";
-
-	private static final String ATTRIBUTE_IS_PATCH = "isPatch";
-
-	private static final String ATTRIBUTE_IS_OBSOLETE = "isObsolete";
-
-	private static final String ATTRIBUTE_CREATOR = "creator";
-
-	private static final String ATTRIBUTE_NUMBER = "number";
-
-	private static final String ATTRIBUTE_HAS_ATTACHMENT = "hasAttachment";
-
-	private static final String ATTRIBUTE_ATTACHMENT_ID = "attachmentId";
-
-	private static final String ATTRIBUTE_KNOB_NAME = "knob_name";
-
-	private static final String ATTRIBUTE_OPERATION_NAME = "operationName";
-
-	private static final String ATTRIBUTE_OPTION_NAME = "optionName";
-
-	private static final String ATTRIBUTE_OPTION_SELECTION = "optionSelection";
-
-	private static final String ATTRIBUTE_IS_CHECKED = "isChecked";
-
-	private static final String ATTRIBUTE_INPUT_NAME = "inputName";
-
-	private static final String ATTRIBUTE_INPUT_VALUE = "inputValue";
-
-	private static final String ATTRIBUTE_READONLY = "readonly";
-
-	private static final String ATTRIBUTE_HIDDEN = "hidden";
-
-	private static final String ATTRIBUTE_PARAMETER = "parameter";
-
-	private static final String ATTRIBUTE_VALUE = "value";
-
-	private static final String ELEMENT_META_DATA = "MetaData";
-
-	private static final String ELEMENT_META = "meta";
-
-	private static final String ELEMENT_OPTION = "option";
-
-	private static final String ELEMENT_OPTIONS = "options";
-
-	private static final String ELEMENT_VALUES = "values";
-
-	private static final String ELEMENT_VALUE = "value";
-
-	private static final String ELEMENT_ATTRIBUTE = "Attribute";
-
-	private static final String ELEMENT_NAME = "name";
-
-	private static final String ELEMENT_OPTION_NAMES = "optionNames";
-
-	private static final String ELEMENT_OPERATION = "Operation";
-
-	private static final String ELEMENT_SELECTED = "Selected";
-
-	private static final String ELEMENT_COMMENT = "Comment";
-
-	private static final String ELEMENT_ATTACHMENT = "Attachment";
-
-	private static final String ELEMENT_ATTACHMENTS = "Attachments";
-
-	private static final String ELEMENT_COMMENTS = "Comments";
-
-	private static final String ELEMENT_OPERATIONS = "Operations";
-
-	private static final String ELEMENT_ATTRIBUTES = "Attributes";
-
-	private static final String ATTRIBUTE_REPOSITORY_KIND = "repositoryKind";
-
-	private static final String ATTRIBUTE_REPOSITORY_URL = "repositoryUrl";
-
-	private static final String ATTRIBUTE_KEY = "key";
-
-	private static final String ATTRIBUTE_ID = "id";
-
-	private static final String ATTRIBUTE_NAME = "name";
-
-	private static final String FILE_NAME_INTERNAL = "data.xml";
-
-	private static final String ELEMENT_EDITS_DATA = "EditsData";
-
-	private static final String ELEMENT_OLD_DATA = "OldData";
-
-	private static final String ELEMENT_NEW_DATA = "NewData";
-
-	private static final String ATTRIBUTE_VERSION = "version";
-
-	private static final String ELEMENT_TASK_STATE = "TaskState";
-
-	private static final String ENCODING_UTF_8 = "UTF-8";
-
-	private static final String SCHEMA_VERSION = "1.0";
-
-	private static final String EXTENSION = ".zip";
-
-	private final File dataDir;
-
-	// HACK: Remove attribute factories all together!!!
-	private static final AbstractAttributeFactory temporaryFactory = new AbstractAttributeFactory() {
-		private static final long serialVersionUID = 1L;
-
-		@Override
-		public Date getDateForAttributeType(String attributeKey, String dateString) {
-			return null;
-		}
-
-		@Override
-		public boolean isHidden(String key) {
-			return false;
-		}
-
-		@Override
-		public String getName(String key) {
-			return key;
-		}
-
-		@Override
-		public boolean isReadOnly(String key) {
-			return false;
-		}
-
-		@Override
-		public String mapCommonAttributeKey(String key) {
-			return key;
-		}
-
-	};
-
-	public OfflineFileStorage(File rootFolder) {
-		dataDir = rootFolder;
-	}
-
-	public void start() throws Exception {
-		if (!dataDir.exists()) {
-			dataDir.mkdirs();
-		}
-	}
-
-	public void stop() throws Exception {
-		// ignore
-	}
-
-	public synchronized TaskDataState get(String repositoryUrl, String id) {
-		TaskDataState state = null;
-		FileInputStream fileInputStream = null;
-		FileLock lock = null;
-		try {
-			File dataFile = getDataFile(URLEncoder.encode(repositoryUrl, ENCODING_UTF_8), id);
-			if (dataFile != null && dataFile.exists()) {
-
-				fileInputStream = new FileInputStream(dataFile);
-				FileChannel channel = fileInputStream.getChannel();
-				lock = channel.tryLock(0L, Long.MAX_VALUE, true);
-				if (lock != null) {
-					state = new TaskDataState(repositoryUrl, id);
-					ZipInputStream inputStream = new ZipInputStream(fileInputStream);
-					ZipEntry entry = inputStream.getNextEntry();
-					if (entry != null) {
-						XMLMemento input = XMLMemento.createReadRoot(new InputStreamReader(inputStream, ENCODING_UTF_8));
-						if (input != null) {
-							readData(state, input);
-						}
-					}
-				}
-			}
-		} catch (Exception e) {
-			StatusHandler.log(new Status(IStatus.ERROR, TasksUiPlugin.ID_PLUGIN, "Error retrieving offline data", e));
-		} finally {
-			try {
-				if (lock != null && lock.isValid()) {
-					lock.release();
-				}
-				if (fileInputStream != null) {
-					fileInputStream.close();
-				}
-			} catch (IOException e) {
-				StatusHandler.log(new Status(IStatus.ERROR, TasksUiPlugin.ID_PLUGIN,
-						"Error closing offline data input stream", e));
-			}
-		}
-
-		return state;
-	}
-
-	public synchronized void put(TaskDataState taskDataState) {
-		FileOutputStream fileOutputStream = null;
-		FileLock lock = null;
-		try {
-			String repositoryFolder = URLEncoder.encode(taskDataState.getNewTaskData().getRepositoryUrl(),
-					ENCODING_UTF_8);
-			File dataFile = getDataFile(repositoryFolder, taskDataState.getId());
-			if (dataFile != null) {
-				if (!dataFile.getParentFile().exists()) {
-					if (!dataFile.getParentFile().mkdirs()) {
-						throw new IOException("Could not create offline data folder: "
-								+ dataFile.getParentFile().getAbsolutePath());
-					}
-				}
-				fileOutputStream = new FileOutputStream(dataFile);
-				FileChannel channel = fileOutputStream.getChannel();
-				lock = channel.tryLock();
-				if (lock != null) {
-					final ZipOutputStream outputStream = new ZipOutputStream(fileOutputStream);
-					outputStream.setMethod(ZipOutputStream.DEFLATED);
-					ZipEntry zipEntry = new ZipEntry(FILE_NAME_INTERNAL);
-					outputStream.putNextEntry(zipEntry);
-
-					OutputStreamWriter writer = new OutputStreamWriter(outputStream, ENCODING_UTF_8);
-					XMLMemento memento = XMLMemento.createWriteRoot(ELEMENT_TASK_STATE);
-					memento.putString(ATTRIBUTE_VERSION, SCHEMA_VERSION);
-					if (taskDataState.getNewTaskData() != null) {
-						IMemento child = memento.createChild(ELEMENT_NEW_DATA);
-						addTaskData(child, taskDataState.getNewTaskData());
-					}
-					if (taskDataState.getOldTaskData() != null) {
-						IMemento child = memento.createChild(ELEMENT_OLD_DATA);
-						addTaskData(child, taskDataState.getOldTaskData());
-					}
-					if (taskDataState.getEdits() != null && taskDataState.getEdits().size() > 0) {
-						IMemento child = memento.createChild(ELEMENT_EDITS_DATA);
-						addEdits(child, taskDataState.getEdits());
-					}
-					memento.save(writer);
-				}
-			}
-		} catch (Exception e) {
-			StatusHandler.log(new Status(IStatus.ERROR, TasksUiPlugin.ID_PLUGIN, "Error saving offline data"));
-		} finally {
-			try {
-				if (lock != null && lock.isValid()) {
-					lock.release();
-				}
-				if (fileOutputStream != null) {
-					fileOutputStream.flush();
-					fileOutputStream.close();
-				}
-			} catch (IOException e) {
-				StatusHandler.log(new Status(IStatus.ERROR, TasksUiPlugin.ID_PLUGIN,
-						"Error closing offline data output stream"));
-			}
-		}
-
-	}
-
-	private void readData(TaskDataState taskState, XMLMemento parent) {
-		IMemento newData = parent.getChild(ELEMENT_NEW_DATA);
-		if (newData != null) {
-			RepositoryTaskData newTaskData = readTaskData(newData);
-			if (newTaskData != null) {
-				taskState.setNewTaskData(newTaskData);
-			}
-		}
-
-		IMemento oldData = parent.getChild(ELEMENT_OLD_DATA);
-		if (oldData != null) {
-			RepositoryTaskData oldTaskData = readTaskData(oldData);
-			if (oldTaskData != null) {
-				taskState.setOldTaskData(oldTaskData);
-			}
-		}
-
-		IMemento editsData = parent.getChild(ELEMENT_EDITS_DATA);
-		if (editsData != null) {
-			Set<RepositoryTaskAttribute> edits = readEdits(editsData);
-			if (edits != null) {
-				taskState.setEdits(edits);
-			}
-		}
-
-	}
-
-	private RepositoryTaskData readTaskData(IMemento newData) {
-		String kind = newData.getString(ATTRIBUTE_REPOSITORY_KIND);
-		String id = newData.getString(ATTRIBUTE_ID);
-		String url = newData.getString(ATTRIBUTE_REPOSITORY_URL);
-		String taskKind = newData.getString(ATTRIBUTE_TASK_KIND);
-
-		if (kind == null || url == null || id == null) {
-			return null;
-		}
-
-		RepositoryTaskData data = new RepositoryTaskData(temporaryFactory, kind, url, id, taskKind);
-		IMemento attMemento = newData.getChild(ELEMENT_ATTRIBUTES);
-		if (attMemento != null) {
-			List<RepositoryTaskAttribute> attributes = readAttributes(attMemento);
-			for (RepositoryTaskAttribute repositoryTaskAttribute : attributes) {
-				data.addAttribute(repositoryTaskAttribute.getId(), repositoryTaskAttribute);
-			}
-		}
-
-		IMemento opsMemento = newData.getChild(ELEMENT_OPERATIONS);
-		if (opsMemento != null) {
-			List<RepositoryOperation> operations = readOperations(opsMemento);
-			for (RepositoryOperation operation : operations) {
-				data.addOperation(operation);
-			}
-		}
-
-		IMemento commentsMemento = newData.getChild(ELEMENT_COMMENTS);
-		if (commentsMemento != null) {
-			List<TaskComment> comments = readComments(commentsMemento);
-			for (TaskComment comment : comments) {
-				data.addComment(comment);
-			}
-		}
-
-		IMemento attachmentsMemento = newData.getChild(ELEMENT_ATTACHMENTS);
-		if (attachmentsMemento != null) {
-			List<RepositoryAttachment> attachments = readAttachments(attachmentsMemento);
-			for (RepositoryAttachment attachment : attachments) {
-				data.addAttachment(attachment);
-			}
-		}
-
-		return data;
-
-	}
-
-	private void addEdits(IMemento parent, Set<RepositoryTaskAttribute> edits) {
-		List<RepositoryTaskAttribute> changedAttributes = new ArrayList<RepositoryTaskAttribute>();
-		changedAttributes.addAll(edits);
-		addAttributes(parent, changedAttributes);
-	}
-
-	private Set<RepositoryTaskAttribute> readEdits(IMemento parent) {
-		return new HashSet<RepositoryTaskAttribute>(readAttributes(parent));
-	}
-
-	private void addTaskData(IMemento parent, RepositoryTaskData newTaskData) {
-		parent.putString(ATTRIBUTE_ID, getCleanText(newTaskData.getTaskId()));
-		parent.putString(ATTRIBUTE_TASK_KIND, getCleanText(newTaskData.getTaskKind()));
-		parent.putString(ATTRIBUTE_REPOSITORY_URL, getCleanText(newTaskData.getRepositoryUrl()));
-		parent.putString(ATTRIBUTE_REPOSITORY_KIND, getCleanText(newTaskData.getConnectorKind()));
-
-		IMemento attributes = parent.createChild(ELEMENT_ATTRIBUTES);
-		addAttributes(attributes, newTaskData.getAttributes());
-
-		IMemento operations = parent.createChild(ELEMENT_OPERATIONS);
-		addOperations(operations, newTaskData.getOperations());
-		if (newTaskData.getSelectedOperation() != null) {
-			addSelectedOperation(operations, newTaskData.getSelectedOperation());
-		}
-
-		IMemento comments = parent.createChild(ELEMENT_COMMENTS);
-		addComments(comments, newTaskData.getComments());
-
-		IMemento attachments = parent.createChild(ELEMENT_ATTACHMENTS);
-		addAttachments(attachments, newTaskData.getAttachments());
-
-	}
-
-	public void addAttachments(IMemento parent, List<RepositoryAttachment> attachments) {
-		for (RepositoryAttachment attachment : attachments) {
-			IMemento memento = parent.createChild(ELEMENT_ATTACHMENT);
-			memento.putString(ATTRIBUTE_IS_PATCH, String.valueOf(attachment.isPatch()));
-			memento.putString(ATTRIBUTE_IS_OBSOLETE, String.valueOf(attachment.isObsolete()));
-			memento.putString(ATTRIBUTE_CREATOR, getCleanText(attachment.getCreator()));
-			memento.putString(ATTRIBUTE_ID, getCleanText(attachment.getTaskId()));
-			memento.putString(ATTRIBUTE_REPOSITORY_KIND, getCleanText(attachment.getRepositoryKind()));
-			memento.putString(ATTRIBUTE_REPOSITORY_URL, getCleanText(attachment.getRepositoryUrl()));
-			IMemento attributes = memento.createChild(ELEMENT_ATTRIBUTES);
-			addAttributes(attributes, attachment.getAttributes());
-		}
-	}
-
-	public List<RepositoryAttachment> readAttachments(IMemento parent) {
-		List<RepositoryAttachment> attachments = new ArrayList<RepositoryAttachment>();
-		for (IMemento attachmentMemento : parent.getChildren(ELEMENT_ATTACHMENT)) {
-			RepositoryAttachment attachment = new RepositoryAttachment(temporaryFactory);
-			String isPatch = attachmentMemento.getString(ATTRIBUTE_IS_PATCH);
-			String isObsolete = attachmentMemento.getString(ATTRIBUTE_IS_OBSOLETE);
-			String taskId = attachmentMemento.getString(ATTRIBUTE_ID);
-			String creator = attachmentMemento.getString(ATTRIBUTE_CREATOR);
-			String repositoryKind = attachmentMemento.getString(ATTRIBUTE_REPOSITORY_KIND);
-			String repositoryUrl = attachmentMemento.getString(ATTRIBUTE_REPOSITORY_URL);
-
-			if (isPatch != null) {
-				attachment.setPatch(Boolean.parseBoolean(isPatch));
-			}
-			if (isObsolete != null) {
-				attachment.setObsolete(Boolean.parseBoolean(isObsolete));
-			}
-			if (creator != null) {
-				attachment.setCreator(creator);
-			}
-			if (repositoryKind != null) {
-				attachment.setRepositoryKind(repositoryKind);
-			}
-			if (repositoryUrl != null) {
-				attachment.setRepositoryUrl(repositoryUrl);
-			}
-			if (taskId != null) {
-				attachment.setTaskId(taskId);
-			}
-			IMemento attributesMemento = attachmentMemento.getChild(ELEMENT_ATTRIBUTES);
-			if (attributesMemento != null) {
-				List<RepositoryTaskAttribute> attributes = readAttributes(attributesMemento);
-				for (RepositoryTaskAttribute repositoryTaskAttribute : attributes) {
-					attachment.addAttribute(repositoryTaskAttribute.getId(), repositoryTaskAttribute);
-				}
-			}
-			attachments.add(attachment);
-		}
-		return attachments;
-	}
-
-	public void addComments(IMemento parent, List<TaskComment> comments) {
-		for (TaskComment taskComment : comments) {
-			IMemento comment = parent.createChild(ELEMENT_COMMENT);
-			comment.putInteger(ATTRIBUTE_NUMBER, taskComment.getNumber());
-			comment.putString(ATTRIBUTE_HAS_ATTACHMENT, String.valueOf(taskComment.hasAttachment()));
-			comment.putString(ATTRIBUTE_ATTACHMENT_ID, getCleanText(taskComment.getAttachmentId()));
-			IMemento attributes = comment.createChild(ELEMENT_ATTRIBUTES);
-			addAttributes(attributes, taskComment.getAttributes());
-		}
-	}
-
-	public List<TaskComment> readComments(IMemento parent) {
-		List<TaskComment> comments = new ArrayList<TaskComment>();
-		for (IMemento commentMemento : parent.getChildren(ELEMENT_COMMENT)) {
-			Integer commentNumber = commentMemento.getInteger(ATTRIBUTE_NUMBER);
-			String hasAttachment = commentMemento.getString(ATTRIBUTE_HAS_ATTACHMENT);
-			String attachmentId = commentMemento.getString(ATTRIBUTE_ATTACHMENT_ID);
-			if (commentNumber != null) {
-				TaskComment comment = new TaskComment(temporaryFactory, commentNumber);
-				if (hasAttachment != null) {
-					comment.setHasAttachment(Boolean.parseBoolean(hasAttachment));
-				}
-				if (attachmentId != null) {
-					comment.setAttachmentId(attachmentId);
-				}
-				IMemento attributesMemento = commentMemento.getChild(ELEMENT_ATTRIBUTES);
-				if (attributesMemento != null) {
-					List<RepositoryTaskAttribute> attributes = readAttributes(attributesMemento);
-					for (RepositoryTaskAttribute repositoryTaskAttribute : attributes) {
-						comment.addAttribute(repositoryTaskAttribute.getId(), repositoryTaskAttribute);
-					}
-				}
-				comments.add(comment);
-			}
-		}
-		return comments;
-	}
-
-	private void addSelectedOperation(IMemento operations, RepositoryOperation selectedOperation) {
-		IMemento selected = operations.createChild(ELEMENT_SELECTED);
-		ArrayList<RepositoryOperation> list = new ArrayList<RepositoryOperation>();
-		list.add(selectedOperation);
-		addOperations(selected, list);
-	}
-
-	public void addOperations(IMemento parent, List<RepositoryOperation> operations) {
-		for (RepositoryOperation operation : operations) {
-			IMemento operationMemento = parent.createChild(ELEMENT_OPERATION);
-			operationMemento.putString(ATTRIBUTE_KNOB_NAME, getCleanText(operation.getKnobName()));
-			operationMemento.putString(ATTRIBUTE_OPERATION_NAME, getCleanText(operation.getOperationName()));
-			operationMemento.putString(ATTRIBUTE_IS_CHECKED, String.valueOf(operation.isChecked()));
-			if (operation.isInput()) {
-				operationMemento.putString(ATTRIBUTE_INPUT_NAME, getCleanText(operation.getInputName()));
-				operationMemento.putString(ATTRIBUTE_INPUT_VALUE, getCleanText(operation.getInputValue()));
-			}
-			if (operation.hasOptions()) {
-				operationMemento.putString(ATTRIBUTE_OPTION_NAME, getCleanText(operation.getOptionName()));
-				operationMemento.putString(ATTRIBUTE_OPTION_SELECTION, getCleanText(operation.getOptionSelection()));
-
-				if (operation.getOptionNames() != null && operation.getOptionNames().size() > 0) {
-					IMemento optionNames = operationMemento.createChild(ELEMENT_OPTION_NAMES);
-					for (String name : operation.getOptionNames()) {
-						IMemento nameMemento = optionNames.createChild(ELEMENT_NAME);
-						nameMemento.putTextData(getCleanText(name));
-						nameMemento.putString(ATTRIBUTE_VALUE, getCleanText(operation.getOptionValue(name)));
-					}
-				}
-			}
-		}
-	}
-
-	/* public for testing */
-	public List<RepositoryOperation> readOperations(IMemento parent) {
-		List<RepositoryOperation> operations = new ArrayList<RepositoryOperation>();
-		for (IMemento operationMemento : parent.getChildren(ELEMENT_OPERATION)) {
-			String knobName = operationMemento.getString(ATTRIBUTE_KNOB_NAME);
-			String operationName = operationMemento.getString(ATTRIBUTE_OPERATION_NAME);
-			String optionName = operationMemento.getString(ATTRIBUTE_OPTION_NAME);
-			String selection = operationMemento.getString(ATTRIBUTE_OPTION_SELECTION);
-			String isChecked = operationMemento.getString(ATTRIBUTE_IS_CHECKED);
-			String inputName = operationMemento.getString(ATTRIBUTE_INPUT_NAME);
-			String inputValue = operationMemento.getString(ATTRIBUTE_INPUT_VALUE);
-
-			if (knobName == null || operationName == null) {
-				continue;
-			}
-
-			RepositoryOperation op = new RepositoryOperation(knobName, operationName);
-			if (optionName != null) {
-				op.setUpOptions(optionName);
-			}
-			if (isChecked != null) {
-				op.setChecked(Boolean.parseBoolean(isChecked));
-			}
-			if (inputName != null) {
-				op.setInputName(inputName);
-			}
-			if (inputValue != null) {
-				op.setInputValue(inputValue);
-			}
-
-			IMemento optionNames = operationMemento.getChild(ELEMENT_OPTION_NAMES);
-			if (optionNames != null) {
-				for (IMemento nameMemento : optionNames.getChildren(ELEMENT_NAME)) {
-					if (nameMemento.getTextData() != null && nameMemento.getTextData().length() > 0) {
-						op.addOption(nameMemento.getTextData(), nameMemento.getString(ATTRIBUTE_VALUE));
-					}
-				}
-			}
-
-			// Selection must be applied after addition of options
-			if (selection != null) {
-				op.setOptionSelection(selection);
-			}
-
-			operations.add(op);
-
-		}
-		return operations;
-	}
-
-	/* public for testing */
-	public void addAttributes(IMemento parent, List<RepositoryTaskAttribute> attributes) {
-		for (RepositoryTaskAttribute attribute : attributes) {
-			IMemento attribMemento = parent.createChild(ELEMENT_ATTRIBUTE);
-			attribMemento.putString(ATTRIBUTE_ID, getCleanText(attribute.getId()));
-			attribMemento.putString(ATTRIBUTE_NAME, getCleanText(attribute.getName()));
-			attribMemento.putString(ATTRIBUTE_HIDDEN, String.valueOf(attribute.isHidden()));
-			attribMemento.putString(ATTRIBUTE_READONLY, String.valueOf(attribute.isReadOnly()));
-
-			IMemento values = attribMemento.createChild(ELEMENT_VALUES);
-			for (String value : attribute.getValues()) {
-				values.createChild(ELEMENT_VALUE).putTextData(getCleanText(value));
-			}
-
-			IMemento options = attribMemento.createChild(ELEMENT_OPTIONS);
-			for (String optionValue : attribute.getOptions()) {
-				IMemento option = options.createChild(ELEMENT_OPTION);
-				option.putTextData(getCleanText(optionValue));
-				String parameter = attribute.getOptionParameter(optionValue);
-				if (parameter != null) {
-					option.putString(ATTRIBUTE_PARAMETER, getCleanText(parameter));
-				}
-			}
-			IMemento metaData = attribMemento.createChild(ELEMENT_META_DATA);
-			Map<String, String> metadata = attribute.getMetaData();
-			if (metadata != null && metadata.size() > 0) {
-				for (String key : metadata.keySet()) {
-					IMemento meta = metaData.createChild(ELEMENT_META);
-					meta.putString(ATTRIBUTE_KEY, getCleanText(key));
-					meta.putTextData(getCleanText(metadata.get(key)));
-				}
-			}
-		}
-	}
-
-	private String getCleanText(String text) {
-		if (text == null) {
-			return "";
-		}
-		String result = org.eclipse.mylyn.internal.commons.core.XmlStringConverter.cleanXmlString(text);
-		if (result == null) {
-			result = "";
-		}
-		return result;
-	}
-
-	/* public for testing */
-	public List<RepositoryTaskAttribute> readAttributes(IMemento parent) {
-		List<RepositoryTaskAttribute> attributes = new ArrayList<RepositoryTaskAttribute>();
-		for (IMemento attrMemento : parent.getChildren(ELEMENT_ATTRIBUTE)) {
-			String id = attrMemento.getString(ATTRIBUTE_ID);
-			String name = attrMemento.getString(ATTRIBUTE_NAME);
-			String hidden = attrMemento.getString(ATTRIBUTE_HIDDEN);
-			if (id != null && name != null && hidden != null) {
-				RepositoryTaskAttribute attribute = new RepositoryTaskAttribute(id, name, Boolean.parseBoolean(hidden));
-				attributes.add(attribute);
-				String readOnly = attrMemento.getString(ATTRIBUTE_READONLY);
-				if (readOnly != null) {
-					attribute.setReadOnly(Boolean.parseBoolean(readOnly));
-				}
-
-				IMemento values = attrMemento.getChild(ELEMENT_VALUES);
-				if (values != null) {
-					for (IMemento valueMemento : values.getChildren(ELEMENT_VALUE)) {
-						attribute.addValue(getCleanText(valueMemento.getTextData()));
-					}
-				}
-
-				IMemento options = attrMemento.getChild(ELEMENT_OPTIONS);
-				if (options != null) {
-					for (IMemento optionMemento : options.getChildren(ELEMENT_OPTION)) {
-						attribute.addOption(getCleanText(optionMemento.getTextData()),
-								optionMemento.getString(ATTRIBUTE_PARAMETER));
-					}
-				}
-
-				IMemento metaData = attrMemento.getChild(ELEMENT_META_DATA);
-				if (metaData != null) {
-					for (IMemento optionMemento : metaData.getChildren(ELEMENT_META)) {
-						attribute.putMetaDataValue(optionMemento.getString(ATTRIBUTE_KEY),
-								getCleanText(optionMemento.getTextData()));
-					}
-				}
-			}
-		}
-		return attributes;
-	}
-
-	public void remove(String repositoryUrl, String id) {
-		if (repositoryUrl == null || id == null) {
-			return;
-		}
-		File file;
-		try {
-			file = getDataFile(URLEncoder.encode(repositoryUrl, ENCODING_UTF_8), id);
-			if (file != null && file.exists()) {
-				file.delete();
-			}
-
-			if (file != null && file.getParentFile() != null && file.getParentFile().exists()
-					&& file.getParentFile().list().length == 0) {
-				file.getParentFile().delete();
-			}
-
-			// TODO: Remove folder if last file removed
-
-		} catch (Exception e) {
-			StatusHandler.log(new Status(IStatus.ERROR, TasksUiPlugin.ID_PLUGIN, "Error removing offline data: "
-					+ repositoryUrl + "-" + id, e));
-		}
-	}
-
-	private File getDataFile(String folder, String id) throws IOException {
-		File repositoryFolder = new File(dataDir, folder);
-		File dataFile = new File(repositoryFolder, id + EXTENSION);
-		return dataFile;
-	}
-
-	/**
-	 * Delete entire offline repositoy contents, FOR TESTING ONLY
-	 */
-	public void clear() {
-		if (dataDir.exists()) {
-			for (File file : dataDir.listFiles()) {
-				destroy(file);
-			}
-		}
-	}
-
-	private void destroy(File folder) {
-		if (folder.isDirectory()) {
-			for (File file : folder.listFiles()) {
-				destroy(file);
-			}
-		}
-		folder.delete();
-	}
-
-	public void flush() {
-		// ignore;
-	}
-
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/tasks/TaskDataStorageManager.java b/org.eclipse.mylyn.ide.dev/developer/src-old/tasks/TaskDataStorageManager.java
deleted file mode 100644
index e6546ef..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/tasks/TaskDataStorageManager.java
+++ /dev/null
@@ -1,357 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004, 2008 Tasktop Technologies and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     Tasktop Technologies - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.mylyn.internal.tasks.core;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.util.Collections;
-import java.util.List;
-import java.util.Set;
-
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.Status;
-import org.eclipse.mylyn.commons.core.StatusHandler;
-import org.eclipse.mylyn.internal.tasks.core.deprecated.AbstractAttributeFactory;
-import org.eclipse.mylyn.internal.tasks.core.deprecated.AbstractLegacyRepositoryConnector;
-import org.eclipse.mylyn.internal.tasks.core.deprecated.RepositoryTaskAttribute;
-import org.eclipse.mylyn.internal.tasks.core.deprecated.RepositoryTaskData;
-import org.eclipse.mylyn.tasks.core.IRepositoryManager;
-
-/**
- * @deprecated Do not use. This class is pending for removal: see bug 237552.
- */
-@Deprecated
-public class TaskDataStorageManager {
-
-	private final IRepositoryManager taskRepositoryManager;
-
-	private final ITaskDataStorage storage;
-
-	private int nextNewId = 1;
-
-	public TaskDataStorageManager(IRepositoryManager taskRepositoryManager, ITaskDataStorage storage) {
-		this.taskRepositoryManager = taskRepositoryManager;
-		this.storage = storage;
-	}
-
-	/**
-	 * Add a RepositoryTaskData to the offline reports file.
-	 */
-	public void setNewTaskData(RepositoryTaskData data) {
-		if (data == null || data.getRepositoryUrl() == null || data.getTaskId() == null) {
-			return;
-		}
-
-		TaskDataState state = retrieveState(data);
-		if (state != null) {
-			state.setNewTaskData(data);
-		} else {
-			state = new TaskDataState(data.getRepositoryUrl(), data.getTaskId());
-			state.setNewTaskData(data);
-		}
-		saveState(state);
-	}
-
-	/**
-	 * @since 2.3
-	 */
-	public void setNewTaskData(String repositoryUrl, String taskId, RepositoryTaskData data) {
-		TaskDataState state = retrieveState(repositoryUrl, taskId);
-		if (state != null) {
-			state.setNewTaskData(data);
-		} else {
-			state = new TaskDataState(repositoryUrl, taskId);
-			state.setNewTaskData(data);
-		}
-		saveState(state);
-	}
-
-	public void setOldTaskData(RepositoryTaskData data) {
-		if (data == null || data.getRepositoryUrl() == null || data.getTaskId() == null) {
-			return;
-		}
-		TaskDataState state = retrieveState(data);
-		if (state != null) {
-			state.setOldTaskData(data);
-		} else {
-			StatusHandler.log(new Status(IStatus.WARNING, ITasksCoreConstants.ID_PLUGIN,
-					"Attempt to save old data when no new data exists", new Exception()));
-		}
-		saveState(state);
-	}
-
-	/**
-	 * Returns the most recent copy of the task data.
-	 * 
-	 * @return offline task data, null if no data found
-	 */
-	public RepositoryTaskData getNewTaskData(String repositoryUrl, String id) {
-		if (repositoryUrl == null || id == null) {
-			return null;
-		}
-		TaskDataState state = retrieveState(repositoryUrl, id);
-		if (state != null) {
-			return state.getNewTaskData();
-		}
-		return null;
-	}
-
-	/**
-	 * Returns the old copy if exists, null otherwise.
-	 */
-	public RepositoryTaskData getOldTaskData(String repositoryUrl, String id) {
-		if (repositoryUrl == null || id == null) {
-			return null;
-		}
-		TaskDataState state = retrieveState(repositoryUrl, id);
-		if (state != null) {
-			return state.getOldTaskData();
-		}
-		return null;
-	}
-
-	/**
-	 * @return Get the next available temporary taskId. This taskId is given to new unsubmitted repository tasks.
-	 *         Incremented each time this method is called.
-	 */
-	public synchronized String getNewRepositoryTaskId() {
-		// TODO: generate based on values of unsubmitted offline report ids
-		nextNewId++;
-		if (nextNewId == Integer.MAX_VALUE) {
-			nextNewId = 1;
-		}
-		return "" + nextNewId;
-	}
-
-	/**
-	 * 
-	 * @return editable copy of task data with any edits applied
-	 */
-	public RepositoryTaskData getEditableCopy(String repositoryUrl, String id) {
-		if (repositoryUrl == null || id == null) {
-			return null;
-		}
-		TaskDataState state = retrieveState(repositoryUrl, id);
-		RepositoryTaskData clone = null;
-		if (state != null) {
-			if (state.getNewTaskData() != null) {
-				try {
-					clone = (RepositoryTaskData) ObjectCloner.deepCopy(state.getNewTaskData());
-					updateAttributeFactory(clone);
-				} catch (Exception e) {
-					StatusHandler.log(new Status(IStatus.ERROR, ITasksCoreConstants.ID_PLUGIN,
-							"Error constructing modifiable task", e));
-					return null;
-				}
-			}
-			if (clone != null) {
-				for (RepositoryTaskAttribute attribute : state.getEdits()) {
-					if (attribute == null) {
-						continue;
-					}
-					RepositoryTaskAttribute existing = clone.getAttribute(attribute.getId());
-					if (existing != null) {
-						existing.clearValues();
-						List<String> options = existing.getOptions();
-
-						for (String value : attribute.getValues()) {
-							if (options.size() > 0) {
-								if (options.contains(value)) {
-									existing.addValue(value);
-								}
-							} else {
-								existing.addValue(value);
-							}
-						}
-
-					} else {
-						clone.addAttribute(attribute.getId(), attribute);
-					}
-				}
-			}
-		}
-		return clone;
-
-	}
-
-	// TODO review: the state of the elements of changedAttribues could change between this call and the time state is written to disk, might need to make a full copy  
-	public void saveEdits(String repositoryUrl, String id, Set<RepositoryTaskAttribute> changedAttributes) {
-		TaskDataState state = retrieveState(repositoryUrl, id);
-		if (state != null) {
-			Set<RepositoryTaskAttribute> edits = state.getEdits();
-			if (edits == null) {
-				// Copy here?
-				state.setEdits(changedAttributes);
-			} else {
-				edits.removeAll(changedAttributes);
-				edits.addAll(changedAttributes);
-			}
-			try {
-				storage.put(state);
-			} catch (Exception e) {
-				// FIXME what exception is caught here?
-				StatusHandler.log(new Status(IStatus.ERROR, ITasksCoreConstants.ID_PLUGIN, "Error saving edits", e));
-			}
-		}
-
-	}
-
-	public Set<RepositoryTaskAttribute> getEdits(String repositoryUrl, String id) {
-		if (repositoryUrl == null || id == null) {
-			return Collections.emptySet();
-		}
-		TaskDataState state = retrieveState(repositoryUrl, id);
-		if (state != null) {
-			if (state.getEdits() != null) {
-				return Collections.unmodifiableSet(state.getEdits());
-			}
-		}
-		return Collections.emptySet();
-	}
-
-	public void discardEdits(String repositoryUrl, String id) {
-		if (repositoryUrl == null || id == null) {
-			return;
-		}
-		TaskDataState state = retrieveState(repositoryUrl, id);
-		if (state != null) {
-			state.discardEdits();
-			try {
-				storage.put(state);
-			} catch (Exception e) {
-				// FIXME what exception is caught here?
-				StatusHandler.log(new Status(IStatus.ERROR, ITasksCoreConstants.ID_PLUGIN, "Error discarding edits", e));
-			}
-		}
-	}
-
-	public void remove(String repositoryUrl, String id) {
-		if (repositoryUrl == null || id == null) {
-			return;
-		}
-		storage.remove(repositoryUrl, id);
-	}
-
-	/**
-	 * DESTROY ALL OFFLINE TASK DATA Public for testing only Forces a reset of all data maps Does not signal data
-	 * changed (doesn't request save)
-	 */
-	public void clear() {
-		nextNewId = 0;
-		storage.clear();
-	}
-
-	/**
-	 * After deserialization process the attributeFactory needs to be reset on each RepositoryTaskData.
-	 */
-	private void updateAttributeFactory(RepositoryTaskData taskData) {
-		if (taskData == null) {
-			return;
-		}
-		taskData.refresh();
-		AbstractLegacyRepositoryConnector connector = (AbstractLegacyRepositoryConnector) taskRepositoryManager.getRepositoryConnector(taskData.getConnectorKind());
-		if (connector != null && connector.getLegacyTaskDataHandler() != null) {
-			AbstractAttributeFactory factory = connector.getLegacyTaskDataHandler().getAttributeFactory(taskData);
-			if (factory != null) {
-				taskData.setAttributeFactory(factory);
-			}
-		}
-	}
-
-	// XXX: review if task data cloning can be done without using serialization
-	// Reference:
-	// http://www.javaworld.com/javaworld/javatips/jw-javatip76.html?page=2
-	public static class ObjectCloner {
-
-		private ObjectCloner() {
-			// can not instantiate
-		}
-
-		static public Object deepCopy(Object oldObj) throws Exception {
-			ObjectOutputStream outputStream = null;
-			ObjectInputStream inputStream = null;
-			try {
-				ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
-				outputStream = new ObjectOutputStream(byteArrayOutputStream);
-
-				outputStream.writeObject(oldObj);
-				outputStream.flush();
-				ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(
-						byteArrayOutputStream.toByteArray());
-				inputStream = new ObjectInputStream(byteArrayInputStream);
-				return inputStream.readObject();
-			} catch (Exception e) {
-				throw (e);
-			} finally {
-				if (outputStream != null) {
-					outputStream.close();
-				}
-				if (inputStream != null) {
-					inputStream.close();
-				}
-			}
-		}
-
-	}
-
-	public void start() {
-		try {
-			storage.start();
-		} catch (Exception e) {
-			StatusHandler.log(new Status(IStatus.ERROR, ITasksCoreConstants.ID_PLUGIN, "Offline storage start failed",
-					e));
-		}
-	}
-
-	public void stop() {
-		try {
-			storage.stop();
-		} catch (Exception e) {
-			StatusHandler.log(new Status(IStatus.ERROR, ITasksCoreConstants.ID_PLUGIN, "Offline storage stop failed", e));
-		}
-	}
-
-	public void saveNow() {
-		storage.flush();
-	}
-
-	private TaskDataState retrieveState(RepositoryTaskData data) {
-		return retrieveState(data.getRepositoryUrl(), data.getTaskId());
-	}
-
-	private TaskDataState retrieveState(String repositoryUrl, String id) {
-		TaskDataState state = null;
-		try {
-			state = storage.get(repositoryUrl, id);
-			if (state != null) {
-				// TODO: Get rid of attribute factory on containers!!!
-				if (state.getNewTaskData() != null) {
-					updateAttributeFactory(state.getNewTaskData());
-				}
-				if (state.getOldTaskData() != null) {
-					updateAttributeFactory(state.getOldTaskData());
-				}
-			}
-		} catch (Exception e) {
-			// FIXME what Exception is caught here?
-			StatusHandler.log(new Status(IStatus.ERROR, ITasksCoreConstants.ID_PLUGIN, "Error saving offline data", e));
-		}
-		return state;
-	}
-
-	private void saveState(TaskDataState state) {
-		storage.put(state);
-	}
-
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/tests/BugzillaTaskDataMigrationTest.java b/org.eclipse.mylyn.ide.dev/developer/src-old/tests/BugzillaTaskDataMigrationTest.java
deleted file mode 100644
index a5714a6..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/tests/BugzillaTaskDataMigrationTest.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004 - 2006 University Of British Columbia and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     University Of British Columbia - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.mylyn.bugzilla.tests;
-
-import org.eclipse.mylyn.internal.bugzilla.core.BugzillaTask;
-import org.eclipse.mylyn.internal.bugzilla.ui.tasklist.BugzillaTaskEditorInput;
-import org.eclipse.mylyn.tasks.core.RepositoryTaskAttribute;
-
-
-/**
- * @author Rob Elves
- */
-public class BugzillaTaskDataMigrationTest extends AbstractBugzillaTest {
-	
-	public void testMigrateDescriptionToReadOnly() throws Exception {
-		init222();
-		BugzillaTask task = generateLocalTaskAndDownload("1");
-		assertNotNull(task);
-		assertNotNull(task.getTaskData());
-		RepositoryTaskAttribute attrib = task.getTaskData().getDescriptionAttribute();
-		assertNotNull(attrib);
-		attrib.setReadOnly(false);
-		BugzillaTaskEditorInput editorInput = new BugzillaTaskEditorInput(repository, task, false);
-		assertTrue(editorInput.getBugTask().getTaskData().getDescriptionAttribute().isReadOnly());
-	}
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/tests/Job.java b/org.eclipse.mylyn.ide.dev/developer/src-old/tests/Job.java
deleted file mode 100644
index 1c7a875..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/tests/Job.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004 - 2005 University Of British Columbia and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     University Of British Columbia - initial API and implementation
- *******************************************************************************/
-package org.eclipse.mylyn.tasklist.tests;
-
-public class Job {
-	private String company;
-	private String position;
-	private int salary;
-	private String email;
-	private String supervisor;	
-	
-	public static String foo = "TESTING STATIC FOR XSTREAM";
-	
-	public Job() {
-		this.company = "Foo";
-		this.position = "slave";
-		this.salary = 100;
-		this.email = "a@bc.com";
-		//this.supervisor = "bill gates";
-	}
-	
-	public Job(String comp, String pos, int salary, String email, String supervisor) {
-		this.company = comp;
-		this.position = pos;
-		this.salary = salary;
-		this.email = email;
-		this.supervisor = supervisor;		
-	}
-	
-	public boolean equals(Job j) {
-		boolean result = true;
-		result = result && j.company == this.company;
-		result = result && j.position == this.position;
-		result = result && j.salary == this.salary;
-		result = result && j.email == this.email;
-		result = result && j.supervisor == this.supervisor;
-		return result;
-	}
-	
-	public String getCompany() {
-		return company;
-	}
-
-	public void setCompany(String company) {
-		this.company = company;
-	}
-
-	public String getEmail() {
-		return email;
-	}
-
-	public void setEmail(String email) {
-		this.email = email;
-	}
-
-	public String getPosition() {
-		return position;
-	}
-
-	public void setPosition(String position) {
-		this.position = position;
-	}
-
-	public int getSalary() {
-		return salary;
-	}
-
-	public void setSalary(int salary) {
-		this.salary = salary;
-	}
-
-	public String getSupervisor() {
-		return supervisor;
-	}
-
-	public void setSupervisor(String supervisor) {
-		this.supervisor = supervisor;
-	}
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/tests/People.java b/org.eclipse.mylyn.ide.dev/developer/src-old/tests/People.java
deleted file mode 100644
index 8512e61..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/tests/People.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004 - 2005 University Of British Columbia and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     University Of British Columbia - initial API and implementation
- *******************************************************************************/
-package org.eclipse.mylyn.tasklist.tests;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-
-public class People {
-	private List<Person> list = new ArrayList<Person>();
-	
-	public People() {
-		// don't need to do any initialization
-	}
-	
-	public void createDefault() {
-		Person p = new Person("Ken Sueda", "ksueda@hotmail.com", "123-4567", 22, 1);
-		Job j = new Job("UBCCS", "developer", 1000, "ksueda@cs.ubc.ca", "foo");
-		p.setJob(j);
-		list.add(p);
-		
-		p = new Person("Shawn Minto", "minto@hotmail.com", "798-1234", 23, 2);
-		j = new Job("UBCCS", "grad student", 3000, "minto@cs.ubc.ca", "foo");
-		p.setJob(j);
-		list.add(p);
-		
-		
-		p = new Person("Mik Kersten", "kersten@hotmail.com", "456-7891", 24, 3);
-		j = new Job("UBCCS", "PhD", 1000000, "kersten@cs.ubc.ca", "foo");
-		p.setJob(j);
-		list.add(p);
-		
-		p = new Person("Gail Murphy", "murphy@hotmail.com", "987-6543", 25, 4);
-		j = new Job("UBCCS", "Professor", 100000000, "", "");
-		p.setJob(j);
-		list.add(p);
-	}
-	
-	public boolean equals(People people) {
-		boolean result = true;		
-		if (list.size() == people.list.size()) {
-			Iterator<Person> itr = list.iterator();
-			Iterator<Person> itr2 = people.list.iterator();
-			
-			while(itr.hasNext()) {
-				Person p = itr.next();
-				Person p2 = itr2.next();
-				result = result && p.equals(p2);
-				if (!result) {
-					break;
-				}
-			}
-		} else {
-			result = false;
-		}
-		return result;
-	}
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/tests/Person.java b/org.eclipse.mylyn.ide.dev/developer/src-old/tests/Person.java
deleted file mode 100644
index a93a7ef..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/tests/Person.java
+++ /dev/null
@@ -1,107 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004 - 2005 University Of British Columbia and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     University Of British Columbia - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.mylyn.tasklist.tests;
-
-import java.util.ArrayList;
-import java.util.List;
-
-public class Person {
-	private String name;
-	private String emailAddress;
-	private String phoneNumber;
-	private int age;
-	private int id;
-	private Job job;
-	
-	private List<Person> list = new ArrayList<Person>();
-	
-	public Person() {
-		name = "Ken Sueda";
-		id = 1;
-		age = 22;
-		emailAddress = "ksueda@hotmail.com";
-		phoneNumber = "123-4567";
-		job = null;
-	}
-	
-	public Person(String name, String email, String phone, int age, int id) {
-		this.name = name;
-		this.emailAddress = email;
-		this.phoneNumber = phone;
-		this.age = age;
-		this.id = id;
-		this.job = null;		
-	}
-
-	public void add(Person p) {
-		list.add(p);
-	}
-	
-	public boolean equals(Person p) {
-		boolean result = true;
-		result = result && p.name == this.name;
-		result = result && p.emailAddress == this.emailAddress;
-		result = result && p.phoneNumber == this.phoneNumber;
-		result = result && p.age == this.age;
-		result = result && p.id == this.id;
-		result = result && p.job.equals(this.job);
-		return result;
-	}
-
-	public int getAge() {
-		return age;
-	}
-
-	public void setAge(int age) {
-		this.age = age;
-	}
-
-	public int getId() {
-		return id;
-	}
-
-	public void setId(int id) {
-		this.id = id;
-	}
-
-	public String getName() {
-		return name;
-	}
-
-	public void setName(String name) {
-		this.name = name;
-	}
-
-	public String getEmailAddress() {
-		return emailAddress;
-	}
-
-	public void setEmailAddress(String emailAddress) {
-		this.emailAddress = emailAddress;
-	}
-
-	public String getPhoneNumber() {
-		return phoneNumber;
-	}
-
-	public void setPhoneNumber(String phoneNumber) {
-		this.phoneNumber = phoneNumber;
-	}
-
-	public Job getJob() {
-		return job;
-	}
-
-	public void setJob(Job job) {
-		this.job = job;
-	}
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/trac/RepositorySearchQuery.java b/org.eclipse.mylyn.ide.dev/developer/src-old/trac/RepositorySearchQuery.java
deleted file mode 100644
index 36e2c1a..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/trac/RepositorySearchQuery.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004 - 2006 University Of British Columbia and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     University Of British Columbia - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.mylyn.internal.trac.ui.search;
-
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.OperationCanceledException;
-import org.eclipse.core.runtime.Status;
-import org.eclipse.jface.dialogs.ErrorDialog;
-import org.eclipse.mylyn.internal.tasks.ui.search.AbstractRepositorySearchQuery;
-import org.eclipse.mylyn.tasks.core.AbstractRepositoryConnector;
-import org.eclipse.mylyn.tasks.core.AbstractRepositoryQuery;
-import org.eclipse.mylyn.tasks.core.QueryHitCollector;
-import org.eclipse.mylyn.tasks.core.TaskRepository;
-import org.eclipse.mylyn.tasks.ui.TasksUiPlugin;
-import org.eclipse.ui.PlatformUI;
-
-/**
- * This class performs a search query.
- * 
- * @author Steffen Pingel
- */
-public class RepositorySearchQuery extends AbstractRepositorySearchQuery {
-
-	private QueryHitCollector collector;
-
-	private TaskRepository repository;
-
-	private AbstractRepositoryQuery query;
-
-	public RepositorySearchQuery(TaskRepository repository, AbstractRepositoryQuery query) {
-		this.repository = repository;
-		this.query = query;
-	}
-
-	public QueryHitCollector getCollector() {
-		return collector;
-	}
-
-	public void setCollector(QueryHitCollector collector) {
-		this.collector = collector;
-	}
-
-	public IStatus run(IProgressMonitor monitor) throws OperationCanceledException {
-		//MultiStatus queryStatus = new MultiStatus(TasksUiPlugin.PLUGIN_ID, IStatus.OK, "Query result", null);
-		IStatus queryStatus = Status.OK_STATUS;
-		try {
-			collector.setProgressMonitor(monitor);
-			collector.aboutToStart(0);
-
-			AbstractRepositoryConnector connector = TasksUiPlugin.getRepositoryManager().getRepositoryConnector(
-					repository.getKind());
-
-			queryStatus = connector.performQuery(query, repository, TasksUiPlugin.getDefault().getProxySettings(), monitor, collector);			
-			collector.done();
-		} catch (final CoreException e) {
-			PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {
-				public void run() {
-					ErrorDialog.openError(null, "Repository Search Error", null, e.getStatus());
-				}
-			});
-			return Status.OK_STATUS;
-		}
-
-		final IStatus status = queryStatus;
-		if (status.getCode() == IStatus.CANCEL) {
-			return Status.OK_STATUS;
-		} else if (!status.isOK()) {
-			PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {
-				public void run() {
-					ErrorDialog.openError(null, "Repository Search Error", null, status);
-				}
-			});
-			return Status.OK_STATUS;
-		}
-		return status;
-	}
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/views/ActiveTaskscapeView.java b/org.eclipse.mylyn.ide.dev/developer/src-old/views/ActiveTaskscapeView.java
deleted file mode 100644
index 1814b6e..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/views/ActiveTaskscapeView.java
+++ /dev/null
@@ -1,207 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004 - 2005 University Of British Columbia and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     University Of British Columbia - initial API and implementation
- *******************************************************************************/
-package org.eclipse.mylyn.tasklist.ui.views;
-
-
-import org.eclipse.jface.action.*;
-import org.eclipse.jface.dialogs.MessageDialog;
-import org.eclipse.jface.viewers.*;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Menu;
-import org.eclipse.ui.*;
-import org.eclipse.ui.part.ViewPart;
-
-
-/**
- * This sample class demonstrates how to plug-in a new
- * workbench view. The view shows data obtained from the
- * model. The sample creates a dummy model on the fly,
- * but a real implementation would connect to the model
- * available either in this or another plug-in (e.g. the workspace).
- * The view is connected to the model using a content provider.
- * <p>
- * The view uses a label provider to define how model
- * objects should be presented in the view. Each
- * view can present the same model objects using
- * different labels and icons, if needed. Alternatively,
- * a single label provider can be shared between views
- * in order to ensure that objects of the same type are
- * presented in the same way everywhere.
- * <p>
- */
-
-public class ActiveTaskscapeView extends ViewPart {
-    
-	private TableViewer viewer;
-	private Action action1;
-	private Action action2;
-	private Action doubleClickAction;
-
-	/*
-	 * The content provider class is responsible for
-	 * providing objects to the view. It can wrap
-	 * existing objects in adapters or simply return
-	 * objects as-is. These objects may be sensitive
-	 * to the current input of the view, or ignore
-	 * it and always show the same content 
-	 * (like Task List, for example).
-	 */
-	 
-	class ViewContentProvider implements IStructuredContentProvider {
-		public void inputChanged(Viewer v, Object oldInput, Object newInput) {
-			// don't care if the input changes
-		}
-		public void dispose() {
-			// don't care if we are disposed
-		}
-		public Object[] getElements(Object parent) {
-			return new String[] { "One", "Two", "Three" };
-		}
-	}
-	class ViewLabelProvider extends LabelProvider implements ITableLabelProvider {
-		public String getColumnText(Object obj, int index) {
-			return getText(obj);
-		}
-		public Image getColumnImage(Object obj, int index) {
-			return getImage(obj);
-		}
-		
-		@Override
-		public Image getImage(Object obj) {
-			return PlatformUI.getWorkbench().
-					getSharedImages().getImage(ISharedImages.IMG_OBJ_ELEMENT);
-		}
-	}
-	class NameSorter extends ViewerSorter {
-		// empty class used as default sorter for the view
-	}
-
-	/**
-	 * The constructor.
-	 */
-	public ActiveTaskscapeView() {
-		// don't have any initialization
-	}
-
-	/**
-	 * This is a callback that will allow us
-	 * to create the viewer and initialize it.
-	 */
-	@Override
-	public void createPartControl(Composite parent) {
-		viewer = new TableViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL);
-		viewer.setContentProvider(new ViewContentProvider());
-		viewer.setLabelProvider(new ViewLabelProvider());
-		viewer.setSorter(new NameSorter());
-		viewer.setInput(getViewSite());
- 
-		makeActions();
-		hookContextMenu();
-		hookDoubleClickAction();
-		contributeToActionBars();
-	}
-
-	private void hookContextMenu() {
-		MenuManager menuMgr = new MenuManager("#PopupMenu");
-		menuMgr.setRemoveAllWhenShown(true);
-		menuMgr.addMenuListener(new IMenuListener() {
-			public void menuAboutToShow(IMenuManager manager) {
-				ActiveTaskscapeView.this.fillContextMenu(manager);
-			}
-		});
-		Menu menu = menuMgr.createContextMenu(viewer.getControl());
-		viewer.getControl().setMenu(menu);
-		getSite().registerContextMenu(menuMgr, viewer);
-	}
-
-	private void contributeToActionBars() {
-		IActionBars bars = getViewSite().getActionBars();
-		fillLocalPullDown(bars.getMenuManager());
-		fillLocalToolBar(bars.getToolBarManager());
-	}
-
-	private void fillLocalPullDown(IMenuManager manager) {
-		manager.add(action1);
-		manager.add(new Separator());
-		manager.add(action2);
-	}
-
-	private void fillContextMenu(IMenuManager manager) {
-		manager.add(action1);
-		manager.add(action2);
-		// Other plug-ins can contribute there actions here
-		manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
-	}
-	
-	private void fillLocalToolBar(IToolBarManager manager) {
-		manager.add(action1);
-		manager.add(action2);
-	}
-
-	private void makeActions() {
-		action1 = new Action() {
-			
-			@Override
-			public void run() {
-				showMessage("Action 1 executed");
-			}
-		};
-		action1.setText("Action 1");
-		action1.setToolTipText("Action 1 tooltip");
-		action1.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages().
-			getImageDescriptor(ISharedImages.IMG_OBJS_INFO_TSK));
-		
-		action2 = new Action() {
-			
-			@Override
-			public void run() {
-				showMessage("Action 2 executed");
-			}
-		};
-		action2.setText("Action 2");
-		action2.setToolTipText("Action 2 tooltip");
-		action2.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages().
-				getImageDescriptor(ISharedImages.IMG_OBJS_INFO_TSK));
-		doubleClickAction = new Action() {
-			
-			@Override
-			public void run() {
-				ISelection selection = viewer.getSelection();
-				Object obj = ((IStructuredSelection)selection).getFirstElement();
-				showMessage("Double-click detected on "+obj.toString());
-			}
-		};
-	}
-
-	private void hookDoubleClickAction() {
-		viewer.addDoubleClickListener(new IDoubleClickListener() {
-			public void doubleClick(DoubleClickEvent event) {
-				doubleClickAction.run();
-			}
-		});
-	}
-	private void showMessage(String message) {
-		MessageDialog.openInformation(
-			viewer.getControl().getShell(),
-			"Sample View",
-			message);
-	}
-
-	/**
-	 * Passing the focus request to the viewer's control.
-	 */
-	@Override
-	public void setFocus() {
-		viewer.getControl().setFocus();
-	}
-}
\ No newline at end of file
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/views/DoiViewerFilter.java b/org.eclipse.mylyn.ide.dev/developer/src-old/views/DoiViewerFilter.java
deleted file mode 100644
index a06dfbb..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/views/DoiViewerFilter.java
+++ /dev/null
@@ -1,123 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004 - 2005 University Of British Columbia and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     University Of British Columbia - initial API and implementation
- *******************************************************************************/
-/*
- * Created on Jul 27, 2004
-  */
-package org.eclipse.mylyn.java.ui;
-
-import org.eclipse.core.internal.resources.File;
-import org.eclipse.core.resources.IMarker;
-import org.eclipse.jdt.core.*;
-import org.eclipse.jdt.internal.core.PackageFragment;
-import org.eclipse.jdt.internal.ui.packageview.ClassPathContainer;
-import org.eclipse.jface.viewers.Viewer;
-import org.eclipse.jface.viewers.ViewerFilter;
-import org.eclipse.ui.views.markers.internal.ProblemMarker;
-
-import org.eclipse.mylyn.core.MylarPlugin;
-import org.eclipse.mylyn.core.model.ITaskscapeNode;
-import org.eclipse.mylyn.java.JavaUiUtil;
-
-/**
- * @author Mik Kersten
- */
-public class DoiViewerFilter extends ViewerFilter {
-
-    private boolean filterUninterestingEnabled = false;
-    private boolean filterDeclarationsEnabled = false;
-    
-    public boolean select(Viewer viewer, Object parentElement, Object object) {
-        if (!filterUninterestingEnabled) return true;
-        
-        if (object instanceof ProblemMarker) {
-            ProblemMarker problemMarker = (ProblemMarker)object;
-            if (problemMarker.getSeverity() == IMarker.SEVERITY_ERROR) {
-                return true;
-            } else {
-                object = JavaUiUtil.getJavaElement(problemMarker); // TODO: don't reassing
-            }
-        }
-        
-        if (object instanceof IJavaElement) {
-            IJavaElement element = (IJavaElement)object;
-//            if (element instanceof IJavaProject) {
-//                return true;
-//            } else if (element instanceof PackageFragmentRoot && !(element instanceof JarPackageFragmentRoot)) {
-//                return true;
-//          } else if (element instanceof PackageFragment && !acceptPackageFragment((PackageFragment)element)) {
-//                return false;
-//          } else if (element instanceof IPackageDeclaration ||
-//                     element instanceof IImportContainer) {
-//              return false;
-//            } else 
-            if (ContextCorePlugin.getTaskscapeManager().isTempRaised(element.getParent().getHandleIdentifier())) {
-                return true;
-            } else {  
-                if (isDeclaration(element) && filterDeclarationsEnabled) {
-                    return false;
-                } else if (!filterUninterestingEnabled) {
-                    return true;
-                } else {
-                    ITaskscapeNode info = ContextCorePlugin.getTaskscapeManager().getDoi(element.getHandleIdentifier());
-                    return info != null && info.getDegreeOfInterest().getDegreeOfInterest().isInteresting();
-                }
-            }
-        } else if (object instanceof File) {
-            ITaskscapeNode info = ContextCorePlugin.getTaskscapeManager().getDoi(((File)object).getFullPath().toPortableString());
-            boolean interesting = info != null && info.getDegreeOfInterest().getDegreeOfInterest().isInteresting();
-            if (!filterUninterestingEnabled) {
-                return true;
-            } else {
-                return !(((File)object).getName().charAt(0) == '.') && interesting;
-            }
-        } else if (object instanceof ClassPathContainer) {
-            ClassPathContainer container = (ClassPathContainer)object;
-            return true;
-        } else {
-            return false;
-        }
-    }
-
-    private boolean acceptPackageFragment(PackageFragment fragment) {
-        try {
-            if (fragment.getChildren() == null) return false;
-            if (fragment.getChildren().length == 0) return false;
-        } catch (JavaModelException e) {
-            ContextCorePlugin.fail(e, "Could not determine if package fragment had children", false);
-        }
-        return true;
-    }
-
-    private boolean isDeclaration(IJavaElement element) {
-        return 
-            element instanceof IMember 
-            || element instanceof IPackageDeclaration 
-            || element instanceof IImportContainer
-            || element instanceof IImportDeclaration;
-    }
-
-    public boolean isFilterUninterestingEnabled() {
-        return filterUninterestingEnabled;
-    }
-    
-    public void setFilterUninterestingEnabled(boolean enabled) {
-        filterUninterestingEnabled = enabled;
-    }
-    
-    public boolean isFilterDeclarationsEnabled() {
-        return filterDeclarationsEnabled;
-    }
-    
-    public void setFilterDeclarationsEnabled(
-            boolean enabled) {
-        filterDeclarationsEnabled = enabled;
-    }
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/views/ImageTableCellEditor.java b/org.eclipse.mylyn.ide.dev/developer/src-old/views/ImageTableCellEditor.java
deleted file mode 100644
index e7e7547..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/views/ImageTableCellEditor.java
+++ /dev/null
@@ -1,215 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004 - 2006 University Of British Columbia and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     University Of British Columbia - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.mylyn.internal.tasklist.ui.views;
-
-
-import java.text.MessageFormat;
-
-import org.eclipse.jface.util.Assert;
-import org.eclipse.jface.viewers.CellEditor;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.FocusAdapter;
-import org.eclipse.swt.events.FocusEvent;
-import org.eclipse.swt.events.KeyAdapter;
-import org.eclipse.swt.events.KeyEvent;
-import org.eclipse.swt.events.SelectionAdapter;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.events.TraverseEvent;
-import org.eclipse.swt.events.TraverseListener;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Table;
-import org.eclipse.swt.widgets.TableItem;
-
-/**
- * @author Rob Elves
- * 
- * Cell editor that allows selection of icons. 
- * A replica of ComboBoxCellEditor but makes use of
- * swt Table widget in order to display images for selection.
- */
-public class ImageTableCellEditor extends CellEditor {
-
-    /**
-     * The list of items to present
-     */
-    private Image[] items;
-
-    /**
-     * The zero-based index of the selected item.
-     */
-    int selection;
-
-    private Table priorityTable;
-
-    private static final int defaultStyle = SWT.NONE;
-
-
-    public ImageTableCellEditor() {
-        setStyle(defaultStyle);
-    }
-
-    public ImageTableCellEditor(Composite parent, Image[] items) {
-        this(parent, items, defaultStyle);
-    }
-
-    public ImageTableCellEditor(Composite parent, Image[] items, int style) {
-        super(parent, style);
-        setItems(items);
-        
-    }
-
-    public Image[] getItems() {
-        return this.items;
-    }
-
-    public void setItems(Image[] items) {
-        Assert.isNotNull(items);
-        this.items = items;
-        populateTableItems();
-    }
-
-    /* (non-Javadoc)
-     * Method declared on CellEditor.
-     */
-    protected Control createControl(Composite parent) {
-
-    	priorityTable = new Table(parent, getStyle());
-
-    	priorityTable.setFont(parent.getFont());
-
-    	priorityTable.addKeyListener(new KeyAdapter() {
-            // hook key pressed - see PR 14201  
-            public void keyPressed(KeyEvent e) {
-                keyReleaseOccured(e);
-            }
-        });
-
-    	priorityTable.addSelectionListener(new SelectionAdapter() {
-            public void widgetDefaultSelected(SelectionEvent event) {
-                applyEditorValueAndDeactivate();
-            }
-
-            public void widgetSelected(SelectionEvent event) {
-                selection = priorityTable.getSelectionIndex();
-            }
-        });
-
-    	priorityTable.addTraverseListener(new TraverseListener() {
-            public void keyTraversed(TraverseEvent e) {
-                if (e.detail == SWT.TRAVERSE_ESCAPE
-                        || e.detail == SWT.TRAVERSE_RETURN) {
-                    e.doit = false;
-                }
-            }
-        });
-
-    	priorityTable.addFocusListener(new FocusAdapter() {
-            public void focusLost(FocusEvent e) {
-            	ImageTableCellEditor.this.focusLost();
-            }
-        });
-        return priorityTable;
-    }
-
-
-    protected Object doGetValue() {
-        return new Integer(selection);
-    }
-
-    /* (non-Javadoc)
-     * Method declared on CellEditor.
-     */
-    protected void doSetFocus() {
-    	priorityTable.setFocus();
-    }
-
-    public LayoutData getLayoutData() {
-        LayoutData layoutData = super.getLayoutData();      
-       	layoutData.minimumWidth = 38;       	
-        return layoutData;
-    }
-
-    protected void doSetValue(Object value) {
-        Assert.isTrue(priorityTable != null && (value instanceof Integer));
-        selection = ((Integer) value).intValue();
-        priorityTable.select(selection);
-    }
-
-    /**
-     * Updates the list of choices
-     */
-    private void populateTableItems() {
-        if (priorityTable != null) {
-        	priorityTable.removeAll();
-            for (int i = 0; i < items.length; i++)   {     	
-    			TableItem item = new TableItem(priorityTable, SWT.NONE);
-    			item.setImage(items[i]);    			    			
-    		}
-            setValueValid(true);
-            selection = 0;
-        }
-    }
-
-    /**
-     * Applies the currently selected value and deactiavates the cell editor
-     */
-    void applyEditorValueAndDeactivate() {
-        //	must set the selection before getting value
-        selection = priorityTable.getSelectionIndex();
-        Object newValue = doGetValue();
-        markDirty();
-        boolean isValid = isCorrect(newValue);
-        setValueValid(isValid);
-        
-        if (!isValid) {
-        	// Only format if the 'index' is valid
-        	if (priorityTable.getItemCount() > 0 && selection >= 0 && selection < priorityTable.getItemCount()) {
-	            // try to insert the current value into the error message.
-	            setErrorMessage(MessageFormat.format(getErrorMessage(),
-	                    new Object[] { priorityTable.getItem(selection) }));
-        	}
-        	else {
-	            // Since we don't have a valid index, pick a default
-	            setErrorMessage(MessageFormat.format(getErrorMessage(),
-	                    new Object[] { priorityTable.getItem(0) }));
-        	}
-        }
-
-        fireApplyEditorValue();
-        deactivate();
-    }
-
-    /*
-     *  (non-Javadoc)
-     * @see org.eclipse.jface.viewers.CellEditor#focusLost()
-     */
-    protected void focusLost() {
-        if (isActivated()) {
-            applyEditorValueAndDeactivate();
-        }
-    }
-
-    /*
-     *  (non-Javadoc)
-     * @see org.eclipse.jface.viewers.CellEditor#keyReleaseOccured(org.eclipse.swt.events.KeyEvent)
-     */
-    protected void keyReleaseOccured(KeyEvent keyEvent) {
-        if (keyEvent.character == '\u001b') { // Escape character
-            fireCancelEditor();
-        } else if (keyEvent.character == '\t') { // tab key
-            applyEditorValueAndDeactivate();
-        }
-    }
-    
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/views/MylarFontDecoratingJavaLabelProvider.java b/org.eclipse.mylyn.ide.dev/developer/src-old/views/MylarFontDecoratingJavaLabelProvider.java
deleted file mode 100644
index 4d57012..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/views/MylarFontDecoratingJavaLabelProvider.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004 - 2005 University Of British Columbia and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     University Of British Columbia - initial API and implementation
- *******************************************************************************/
-/*
- * Created on Aug 6, 2004
-  */
-package org.eclipse.mylyn.java.ui;
-
-import org.eclipse.jdt.core.IJavaElement;
-import org.eclipse.jdt.internal.ui.viewsupport.DecoratingJavaLabelProvider;
-import org.eclipse.jdt.internal.ui.viewsupport.JavaUILabelProvider;
-import org.eclipse.jface.viewers.IFontProvider;
-import org.eclipse.swt.graphics.Font;
-
-
-
-/**
- * @author Mik Kersten
- */
-public class MylarFontDecoratingJavaLabelProvider extends DecoratingJavaLabelProvider implements IFontProvider {
-    
-	public MylarFontDecoratingJavaLabelProvider(JavaUILabelProvider labelProvider, boolean errorTick) {
-	    super(labelProvider, errorTick);
-	}
-	
-    public String getText(Object element) {
-        if (element instanceof IJavaElement) {
-            return ((IJavaElement)element).getElementName();
-        }
-        return super.getText(element);
-    }
-    
-    public Font getFont(Object element) {
-	    if (element instanceof IJavaElement) {
-	        return JavaUiUtil.getFontForElement((IJavaElement)element);
-	    } else {
-	        return null;
-	    }
-    }
-} 
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/views/MylarJavaOutlinePage.java b/org.eclipse.mylyn.ide.dev/developer/src-old/views/MylarJavaOutlinePage.java
deleted file mode 100644
index 8985699..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/views/MylarJavaOutlinePage.java
+++ /dev/null
@@ -1,1433 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004 - 2005 University Of British Columbia and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     University Of British Columbia - initial API and implementation
- *******************************************************************************/
-/*
- * Created on Aug 6, 2004
-  */
-package org.eclipse.mylyn.java.ui.editor;
-
-import java.util.*;
-import java.util.List;
-
-import org.eclipse.core.resources.IResource;
-import org.eclipse.core.runtime.IAdaptable;
-import org.eclipse.jdt.core.*;
-import org.eclipse.jdt.internal.corext.util.JavaModelUtil;
-import org.eclipse.jdt.internal.ui.*;
-import org.eclipse.jdt.internal.ui.actions.AbstractToggleLinkingAction;
-import org.eclipse.jdt.internal.ui.actions.CompositeActionGroup;
-import org.eclipse.jdt.internal.ui.dnd.DelegatingDropAdapter;
-import org.eclipse.jdt.internal.ui.dnd.JdtViewerDragAdapter;
-import org.eclipse.jdt.internal.ui.javaeditor.*;
-import org.eclipse.jdt.internal.ui.packageview.SelectionTransferDragAdapter;
-import org.eclipse.jdt.internal.ui.packageview.SelectionTransferDropAdapter;
-import org.eclipse.jdt.internal.ui.preferences.MembersOrderPreferenceCache;
-import org.eclipse.jdt.internal.ui.viewsupport.*;
-import org.eclipse.jdt.ui.*;
-import org.eclipse.jdt.ui.ProblemsLabelDecorator.ProblemsLabelChangedEvent;
-import org.eclipse.jdt.ui.actions.*;
-import org.eclipse.jface.action.*;
-import org.eclipse.jface.preference.IPreferenceStore;
-import org.eclipse.jface.text.Assert;
-import org.eclipse.jface.text.ITextSelection;
-import org.eclipse.jface.util.*;
-import org.eclipse.jface.viewers.*;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.custom.BusyIndicator;
-import org.eclipse.swt.dnd.DND;
-import org.eclipse.swt.dnd.Transfer;
-import org.eclipse.swt.widgets.*;
-import org.eclipse.ui.IActionBars;
-import org.eclipse.ui.PlatformUI;
-import org.eclipse.ui.actions.ActionContext;
-import org.eclipse.ui.actions.ActionGroup;
-import org.eclipse.ui.internal.Workbench;
-import org.eclipse.ui.model.IWorkbenchAdapter;
-import org.eclipse.ui.model.WorkbenchAdapter;
-import org.eclipse.ui.part.*;
-import org.eclipse.ui.texteditor.*;
-import org.eclipse.ui.views.contentoutline.IContentOutlinePage;
-import org.eclipse.ui.views.navigator.LocalSelectionTransfer;
-
-import org.eclipse.mylyn.core.ITaskscapeListener;
-import org.eclipse.mylyn.core.MylarPlugin;
-import org.eclipse.mylyn.core.model.ITaskscapeNode;
-import org.eclipse.mylyn.java.ui.MylarAppearanceAwareLabelProvider;
-import org.eclipse.mylyn.tasklist.MylarImages;
-import org.eclipse.mylyn.tasklist.TaskListPlugin;
-
-/**
- * @author Mik Kersten
- */
-public class MylarJavaOutlinePage extends JavaOutlinePage implements IContentOutlinePage, IAdaptable , IPostSelectionProvider {
-
-    protected ITaskscapeListener modelListener;
-    protected JavaEditor fEditor;
-    protected MylarAppearanceAwareLabelProvider mylarLabelProvider;
-     
-    private final ITaskscapeListener MODEL_LISTENER = new ITaskscapeListener() {
-        public void interestChanged(ITaskscapeNode info) {
-            refresh();
-        }
-
-        public void modelUpdated() {
-            refresh();
-        }
-        
-        public void presentationSettingsChanged(ITaskscapeListener.PresentationChangeKind kind) {
-            refresh();
-        } 
-        
-        public void nodeDeleted(ITaskscapeNode node) {
-            refresh();
-        }
-        
-        private void refresh() {
-            if (fOutlineViewer != null) {
-                PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {
-                    public void run() {
-                        try { 
-                            if (fOutlineViewer != null && !fOutlineViewer.getTree().isDisposed()) {
-                                fOutlineViewer.refresh();
-                                fOutlineViewer.expandAll();
-                            }
-                        } catch (Throwable t) {
-                            ContextCorePlugin.fail(t, "Could not update viewer", false);
-                        }    
-                    }
-                });
-            }
-        }
-
-        public void landmarkAdded(ITaskscapeNode element) { 
-            refresh();
-        }
-
-        public void landmarkRemoved(ITaskscapeNode element) { 
-            refresh();
-        }
-
-        public void relationshipsChanged() {
-        }
-
-        public void presentationSettingsChanging(ITaskscapeListener.PresentationChangeKind kind) {
-            refresh();
-        }
-    };
-    
-    private FilterUniterestingAction filterUniterestingAction;
-    
-    public void extendControl(IActionBars actionBars) {
-        ContextCorePlugin.getTaskscapeManager().addListener(MODEL_LISTENER);
-        
-        mylarLabelProvider = new MylarAppearanceAwareLabelProvider(
-                AppearanceAwareLabelProvider.DEFAULT_TEXTFLAGS |  JavaElementLabels.F_APP_TYPE_SIGNATURE,
-                AppearanceAwareLabelProvider.DEFAULT_IMAGEFLAGS,
-                (ITreeContentProvider)fOutlineViewer.getContentProvider());  
-        
-        fOutlineViewer.getTree().setBackground(TaskListPlugin.getDefault().getColorMap().BACKGROUND_COLOR);
-        fOutlineViewer.setLabelProvider(mylarLabelProvider);
-//        fOutlineViewer.setLabelProvider(new MylarFontDecoratingJavaLabelProvider(mylarLabelProvider, true));
-
-        IToolBarManager toolBarManager = actionBars.getToolBarManager();
-        filterUniterestingAction = new FilterUniterestingAction();
-        if (toolBarManager != null) {   
-            toolBarManager.add(new Separator("StartMylar")); //$NON-NLS-1$
-            toolBarManager.add(filterUniterestingAction);
-        }
-        if (filterUniterestingAction.isChecked() && mylarLabelProvider != null) 
-            mylarLabelProvider.setInterestFilterEnabled(true);
-    }
-    
-    class FilterUniterestingAction extends Action {
-        
-        public FilterUniterestingAction() {
-            super();
-            setText("Filter Uninteresting"); //$NON-NLS-1$
-            setImageDescriptor(MylarImages.AUTO_EXPAND);    
-            setToolTipText("Filter uninteresting elements"); //$NON-NLS-1$
-            
-            boolean checked= ContextCore.getPreferenceStore().getBoolean("org.eclipse.mylyn.ui.outline.filter.isChecked"); //$NON-NLS-1$
-            valueChanged(checked, false);
-        }
-        
-        public void run() {
-            valueChanged(isChecked(), true);
-        }
-        
-        private void valueChanged(final boolean on, boolean store) {
-            setChecked(on);
-            if (mylarLabelProvider != null) mylarLabelProvider.setInterestFilterEnabled(on);
-
-            if (on) {
-                fOutlineViewer.addFilter(MYLAR_OUTLINE_FILTER);
-            } else {
-                fOutlineViewer.removeFilter(MYLAR_OUTLINE_FILTER);
-            }
-
-            if (store)
-                ContextCore.getPreferenceStore().setValue("org.eclipse.mylyn.ui.outline.filter.isChecked", on); //$NON-NLS-1$
-        }
-    }
-    
-    // TODO: extract and reuse
-    static final ViewerFilter MYLAR_OUTLINE_FILTER = new ViewerFilter() {
-        public boolean select(Viewer viewer, Object parentElement, Object object) {
-            if (object instanceof IJavaElement) {
-                IJavaElement element = (IJavaElement)object;
-            
-                ITaskscapeNode info = ContextCorePlugin.getTaskscapeManager().getDoi(element.getHandleIdentifier());
-                return info != null && info.getDegreeOfInterest().getDegreeOfInterest().isInteresting();
-            } else {
-                return false;
-            }
-        }
-    };
-    
-    // ---------------------------------------------------------------------
-    // BELOW IS COPIED FROM JDT DUE TO LACK OF EXTENSIBILITY, AVOID CHANGING
-//  public class JavaOutlinePage extends Page implements IContentOutlinePage, IAdaptable , IPostSelectionProvider {
-
-            
-    static Object[] NO_CHILDREN= new Object[0];
-    
-            /**
-             * The element change listener of the java outline viewer.
-             * @see IElementChangedListener
-             */
-            class ElementChangedListener implements IElementChangedListener {
-                
-                public void elementChanged(final ElementChangedEvent e) {
-                    
-                    if (getControl() == null)
-                        return;
-                        
-                    Display d= getControl().getDisplay();
-                    if (d != null) {
-                        d.asyncExec(new Runnable() {
-                            public void run() {
-                                ICompilationUnit cu= (ICompilationUnit) fInput;
-                                IJavaElement base= cu;
-                                if (fTopLevelTypeOnly) {
-                                    base= getMainType(cu);
-                                    if (base == null) {
-                                        if (fOutlineViewer != null)
-                                            fOutlineViewer.refresh(true);
-                                        return;
-                                    }
-                                }
-                                IJavaElementDelta delta= findElement(base, e.getDelta());
-                                if (delta != null && fOutlineViewer != null) {
-                                    fOutlineViewer.reconcile(delta);
-                                }
-                            }
-                        });
-                    }
-                }
-                
-                private boolean isPossibleStructuralChange(IJavaElementDelta cuDelta) {
-                    if (cuDelta.getKind() != IJavaElementDelta.CHANGED) {
-                        return true; // add or remove
-                    }
-                    int flags= cuDelta.getFlags();
-                    if ((flags & IJavaElementDelta.F_CHILDREN) != 0) {
-                        return true;
-                    }
-                    return (flags & (IJavaElementDelta.F_CONTENT | IJavaElementDelta.F_FINE_GRAINED)) == IJavaElementDelta.F_CONTENT;
-                }
-                
-                protected IJavaElementDelta findElement(IJavaElement unit, IJavaElementDelta delta) {
-                    
-                    if (delta == null || unit == null)
-                        return null;
-                    
-                    IJavaElement element= delta.getElement();
-                    
-                    if (unit.equals(element)) {
-                        if (isPossibleStructuralChange(delta)) {
-                            return delta;
-                        }
-                        return null;
-                    }
-                        
-                    
-                    if (element.getElementType() > IJavaElement.CLASS_FILE)
-                        return null;
-                        
-                    IJavaElementDelta[] children= delta.getAffectedChildren();
-                    if (children == null || children.length == 0)
-                        return null;
-                        
-                    for (int i= 0; i < children.length; i++) {
-                        IJavaElementDelta d= findElement(unit, children[i]);
-                        if (d != null)
-                            return d;
-                    }
-                    
-                    return null;
-                }
-            }
-          
-            static class NoClassElement extends WorkbenchAdapter implements IAdaptable {
-                /*
-                 * @see java.lang.Object#toString()
-                 */
-                public String toString() {
-                    return JavaEditorMessages.getString("JavaOutlinePage.error.NoTopLevelType"); //$NON-NLS-1$
-                }
-        
-                /*
-                 * @see org.eclipse.core.runtime.IAdaptable#getAdapter(Class)
-                 */
-                public Object getAdapter(Class clas) {
-                    if (clas == IWorkbenchAdapter.class)
-                        return this;
-                    return null;
-                }
-            }
-            
-            /**
-             * Content provider for the children of an ICompilationUnit or
-             * an IClassFile
-             * @see ITreeContentProvider
-             */
-            class ChildrenProvider implements ITreeContentProvider {
-             
-                private Object[] NO_CLASS= new Object[] {new NoClassElement()};
-                private ElementChangedListener fListener;
-                
-                protected boolean matches(IJavaElement element) {
-                    if (element.getElementType() == IJavaElement.METHOD) {
-                        String name= element.getElementName();
-                        return (name != null && name.indexOf('<') >= 0);
-                    }
-                    return false;
-                }
-                
-                protected IJavaElement[] filter(IJavaElement[] children) {
-                    boolean initializers= false;
-                    for (int i= 0; i < children.length; i++) {
-                        if (matches(children[i])) {
-                            initializers= true;
-                            break;
-                        }
-                    }
-                            
-                    if (!initializers)
-                        return children;
-                        
-                    Vector v= new Vector();
-                    for (int i= 0; i < children.length; i++) {
-                        if (matches(children[i]))
-                            continue;
-                        v.addElement(children[i]);
-                    }
-                    
-                    IJavaElement[] result= new IJavaElement[v.size()];
-                    v.copyInto(result);
-                    return result;
-                }
-                
-                public Object[] getChildren(Object parent) {
-                    if (parent instanceof IParent) {
-                        IParent c= (IParent) parent;
-                        try {
-                            return filter(c.getChildren());
-                        } catch (JavaModelException x) {
-                            // https://bugs.eclipse.org/bugs/show_bug.cgi?id=38341
-                            // don't log NotExist exceptions as this is a valid case
-                            // since we might have been posted and the element
-                            // removed in the meantime.
-                            if (JavaPlugin.isDebug() || !x.isDoesNotExist())
-                                JavaPlugin.log(x);
-                        }
-                    }
-                    return NO_CHILDREN;
-                }
-                
-                public Object[] getElements(Object parent) {
-                    if (fTopLevelTypeOnly) {
-                        if (parent instanceof ICompilationUnit) {
-                            try {
-                                IType type= getMainType((ICompilationUnit) parent);
-                                return type != null ? type.getChildren() : NO_CLASS;
-                            } catch (JavaModelException e) {
-                                JavaPlugin.log(e);
-                            }
-                        } else if (parent instanceof IClassFile) {
-                            try {
-                                IType type= getMainType((IClassFile) parent);
-                                return type != null ? type.getChildren() : NO_CLASS;
-                            } catch (JavaModelException e) {
-                                JavaPlugin.log(e);
-                            }                           
-                        }
-                    }
-                    return getChildren(parent);
-                }
-                
-                public Object getParent(Object child) {
-                    if (child instanceof IJavaElement) {
-                        IJavaElement e= (IJavaElement) child;
-                        return e.getParent();
-                    }
-                    return null;
-                }
-                
-                public boolean hasChildren(Object parent) {
-                    if (parent instanceof IParent) {
-                        IParent c= (IParent) parent;
-                        try {
-                            IJavaElement[] children= filter(c.getChildren());
-                            return (children != null && children.length > 0);
-                        } catch (JavaModelException x) {
-                            // https://bugs.eclipse.org/bugs/show_bug.cgi?id=38341
-                            // don't log NotExist exceptions as this is a valid case
-                            // since we might have been posted and the element
-                            // removed in the meantime.
-                            if (JavaPlugin.isDebug() || !x.isDoesNotExist())
-                                JavaPlugin.log(x);
-                        }
-                    }
-                    return false;
-                }
-                
-                public boolean isDeleted(Object o) {
-                    return false;
-                }
-                
-                public void dispose() {
-                    if (fListener != null) {
-                        JavaCore.removeElementChangedListener(fListener);
-                        fListener= null;
-                    }       
-                }
-                
-                /*
-                 * @see IContentProvider#inputChanged(Viewer, Object, Object)
-                 */
-                public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
-                    boolean isCU= (newInput instanceof ICompilationUnit);
-                                    
-                    if (isCU && fListener == null) {
-                        fListener= new ElementChangedListener();
-                        JavaCore.addElementChangedListener(fListener);
-                    } else if (!isCU && fListener != null) {
-                        JavaCore.removeElementChangedListener(fListener);
-                        fListener= null;
-                    }
-                }
-            }
-            
-            
-            class JavaOutlineViewer extends TreeViewer {
-                
-                /**
-                 * Indicates an item which has been reused. At the point of
-                 * its reuse it has been expanded. This field is used to
-                 * communicate between <code>internalExpandToLevel</code> and
-                 * <code>reuseTreeItem</code>.
-                 */
-                private Item fReusedExpandedItem;
-                private boolean fReorderedMembers;
-                private boolean fForceFireSelectionChanged;
-                
-                public JavaOutlineViewer(Tree tree) {
-                    super(tree);
-                    setAutoExpandLevel(ALL_LEVELS);
-                    setUseHashlookup(true);
-                }
-                
-                /**
-                 * Investigates the given element change event and if affected
-                 * incrementally updates the Java outline.
-                 * 
-                 * @param delta the Java element delta used to reconcile the Java outline
-                 */
-                public void reconcile(IJavaElementDelta delta) {
-                    fReorderedMembers= false;
-                    fForceFireSelectionChanged= false;
-                    if (getSorter() == null) {
-                        if (fTopLevelTypeOnly
-                            && delta.getElement() instanceof IType
-                            && (delta.getKind() & IJavaElementDelta.ADDED) != 0)
-                        {
-                            refresh(true);
-
-                        } else {
-                            Widget w= findItem(fInput);
-                            if (w != null && !w.isDisposed())
-                                update(w, delta);
-                            if (fForceFireSelectionChanged)
-                                fireSelectionChanged(new SelectionChangedEvent(getSite().getSelectionProvider(), this.getSelection()));
-                            if (fReorderedMembers) {
-                                refresh(false);
-                                fReorderedMembers= false;
-                        }
-                        }
-                    } else {
-                        // just for now
-                        refresh(true);
-                    }
-                }
-                
-                /*
-                 * @see TreeViewer#internalExpandToLevel
-                 */
-                protected void internalExpandToLevel(Widget node, int level) {
-                    if (node instanceof Item) {
-                        Item i= (Item) node;
-                        if (i.getData() instanceof IJavaElement) {
-                            IJavaElement je= (IJavaElement) i.getData();
-                            if (je.getElementType() == IJavaElement.IMPORT_CONTAINER || isInnerType(je)) {
-                                if (i != fReusedExpandedItem) {
-                                    setExpanded(i, false);
-                                    return;
-                                }
-                            }
-                        }
-                    }
-                    super.internalExpandToLevel(node, level);
-                }
-                                
-                protected void reuseTreeItem(Item item, Object element) {
-                    
-                    // remove children
-                    Item[] c= getChildren(item);
-                    if (c != null && c.length > 0) {
-                        
-                        if (getExpanded(item))
-                            fReusedExpandedItem= item;
-                        
-                        for (int k= 0; k < c.length; k++) {
-                            if (c[k].getData() != null)
-                                disassociate(c[k]);
-                            c[k].dispose();
-                        }
-                    }
-                    
-                    updateItem(item, element);
-                    updatePlus(item, element);
-                    internalExpandToLevel(item, ALL_LEVELS);
-                    
-                    fReusedExpandedItem= null;
-                    fForceFireSelectionChanged= true;
-                }
-                
-                protected boolean mustUpdateParent(IJavaElementDelta delta, IJavaElement element) {
-                    if (element instanceof IMethod) {
-                        if ((delta.getKind() & IJavaElementDelta.ADDED) != 0) {
-                            try {
-                                return ((IMethod)element).isMainMethod();
-                            } catch (JavaModelException e) {
-                                JavaPlugin.log(e.getStatus());
-                            }
-                        }
-                        return "main".equals(element.getElementName()); //$NON-NLS-1$
-                    }
-                    return false;
-                }
-                
-                /*
-                 * @see org.eclipse.jface.viewers.AbstractTreeViewer#isExpandable(java.lang.Object)
-                 */
-                public boolean isExpandable(Object element) {
-                    if (hasFilters()) {
-                        return getFilteredChildren(element).length > 0;
-                    }
-                    return super.isExpandable(element);
-                }
-                
-                protected ISourceRange getSourceRange(IJavaElement element) throws JavaModelException {
-                    if (element instanceof ISourceReference)
-                        return ((ISourceReference) element).getSourceRange();
-                    if (element instanceof IMember && !(element instanceof IInitializer))
-                        return ((IMember) element).getNameRange();
-                    return null;
-                }
-                
-                protected boolean overlaps(ISourceRange range, int start, int end) {
-                    return start <= (range.getOffset() + range.getLength() - 1) && range.getOffset() <= end;
-                }
-                
-                protected boolean filtered(IJavaElement parent, IJavaElement child) {
-                    
-                    Object[] result= new Object[] { child };
-                    ViewerFilter[] filters= getFilters();
-                    for (int i= 0; i < filters.length; i++) {
-                        result= filters[i].filter(this, parent, result);
-                        if (result.length == 0)
-                            return true;
-                    }
-                    
-                    return false;
-                }
-                
-                protected void update(Widget w, IJavaElementDelta delta) {
-                    
-                    Item item;
-                    
-                    IJavaElement parent= delta.getElement();
-                    IJavaElementDelta[] affected= delta.getAffectedChildren();
-                    Item[] children= getChildren(w);
-
-                    boolean doUpdateParent= false;
-                    boolean doUpdateParentsPlus= false;
-                                        
-                    Vector deletions= new Vector();
-                    Vector additions= new Vector();             
-
-                    for (int i= 0; i < affected.length; i++) {
-                        IJavaElementDelta affectedDelta= affected[i];
-                        IJavaElement affectedElement= affectedDelta.getElement();
-                        int status= affected[i].getKind();
-
-                        // find tree item with affected element
-                        int j;
-                        for (j= 0; j < children.length; j++)
-                            if (affectedElement.equals(children[j].getData()))
-                                break;
-                        
-                        if (j == children.length) {
-                            // remove from collapsed parent
-                            if ((status & IJavaElementDelta.REMOVED) != 0) {
-                                doUpdateParentsPlus= true;
-                                continue;
-                            }                           
-                            // addition
-                            if ((status & IJavaElementDelta.CHANGED) != 0 &&                            
-                                (affectedDelta.getFlags() & IJavaElementDelta.F_MODIFIERS) != 0 &&
-                                !filtered(parent, affectedElement))
-                            {
-                                additions.addElement(affectedDelta);
-                            }
-                            continue;
-                        }
-
-                        item= children[j];
-
-                        // removed                          
-                        if ((status & IJavaElementDelta.REMOVED) != 0) {
-                            deletions.addElement(item);
-                            doUpdateParent= doUpdateParent || mustUpdateParent(affectedDelta, affectedElement);
-
-                        // changed                          
-                        } else if ((status & IJavaElementDelta.CHANGED) != 0) {
-                            int change= affectedDelta.getFlags();
-                            doUpdateParent= doUpdateParent || mustUpdateParent(affectedDelta, affectedElement);
-                            
-                            if ((change & IJavaElementDelta.F_MODIFIERS) != 0) {
-                                if (filtered(parent, affectedElement))
-                                    deletions.addElement(item);
-                                else
-                                    updateItem(item, affectedElement);
-                            }
-                            
-                            if ((change & IJavaElementDelta.F_CONTENT) != 0)
-                                updateItem(item, affectedElement);
-                                
-                            if ((change & IJavaElementDelta.F_CHILDREN) != 0)
-                                update(item, affectedDelta);                                                                
-                            
-                            if ((change & IJavaElementDelta.F_REORDER) != 0)
-                                fReorderedMembers= true;
-                        }
-                    }
-                    
-                    // find all elements to add
-                    IJavaElementDelta[] add= delta.getAddedChildren();
-                    if (additions.size() > 0) {
-                        IJavaElementDelta[] tmp= new IJavaElementDelta[add.length + additions.size()];
-                        System.arraycopy(add, 0, tmp, 0, add.length);
-                        for (int i= 0; i < additions.size(); i++)
-                            tmp[i + add.length]= (IJavaElementDelta) additions.elementAt(i);
-                        add= tmp;
-                    }
-                    
-                    // add at the right position
-                    go2: for (int i= 0; i < add.length; i++) {
-                        
-                        try {
-                            
-                            IJavaElement e= add[i].getElement();
-                            if (filtered(parent, e))
-                                continue go2;
-                                
-                            doUpdateParent= doUpdateParent || mustUpdateParent(add[i], e);
-                            ISourceRange rng= getSourceRange(e);
-                            int start= rng.getOffset();
-                            int end= start + rng.getLength() - 1;
-                            int nameOffset= Integer.MAX_VALUE;
-                            if (e instanceof IField) {
-                                ISourceRange nameRange= ((IField) e).getNameRange();
-                                if (nameRange != null)
-                                    nameOffset= nameRange.getOffset();
-                            }
-                            
-                            Item last= null;
-                            item= null;
-                            children= getChildren(w);
-                            
-                            for (int j= 0; j < children.length; j++) {
-                                item= children[j];
-                                IJavaElement r= (IJavaElement) item.getData();
-                                
-                                if (r == null) {
-                                    // parent node collapsed and not be opened before -> do nothing
-                                    continue go2;
-                                }
-                                
-                                    
-                                try {
-                                    rng= getSourceRange(r);
-
-                                    // multi-field declarations always start at 
-                                    // the same offset. They also have the same
-                                    // end offset if the field sequence is terminated
-                                    // with a semicolon. If not, the source range
-                                    // ends behind the identifier / initializer
-                                    // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=51851
-                                    boolean multiFieldDeclaration= 
-                                        r.getElementType() == IJavaElement.FIELD 
-                                            && e.getElementType() == IJavaElement.FIELD
-                                            && rng.getOffset() == start;
-
-                                    // elements are inserted by occurrence
-                                    // however, multi-field declarations have
-                                    // equal source ranges offsets, therefore we
-                                    // compare name-range offsets.
-                                    boolean multiFieldOrderBefore= false;
-                                    if (multiFieldDeclaration) {
-                                        if (r instanceof IField) {
-                                            ISourceRange nameRange= ((IField) r).getNameRange();
-                                            if (nameRange != null) {
-                                                if (nameRange.getOffset() > nameOffset)
-                                                    multiFieldOrderBefore= true;
-                                            }
-                                        }
-                                    }
-                                    
-                                    if (!multiFieldDeclaration && overlaps(rng, start, end)) {
-                                        
-                                        // be tolerant if the delta is not correct, or if 
-                                        // the tree has been updated other than by a delta
-                                        reuseTreeItem(item, e);
-                                        continue go2;
-                                        
-                                    } else if (multiFieldOrderBefore || rng.getOffset() > start) {
-                                        
-                                        if (last != null && deletions.contains(last)) {
-                                            // reuse item
-                                            deletions.removeElement(last);
-                                            reuseTreeItem(last, e);
-                                        } else {
-                                            // nothing to reuse
-                                            createTreeItem(w, e, j);
-                                        }
-                                        continue go2;
-                                    }
-                                    
-                                } catch (JavaModelException x) {
-                                    // stumbled over deleted element
-                                }
-                                
-                                last= item;
-                            }
-                        
-                            // add at the end of the list
-                            if (last != null && deletions.contains(last)) {
-                                // reuse item
-                                deletions.removeElement(last);
-                                reuseTreeItem(last, e);
-                            } else {
-                                // nothing to reuse
-                                createTreeItem(w, e, -1);
-                            }
-                        
-                        } catch (JavaModelException x) {
-                            // the element to be added is not present -> don't add it
-                        }
-                    }
-                    
-                    
-                    // remove items which haven't been reused
-                    Enumeration e= deletions.elements();
-                    while (e.hasMoreElements()) {
-                        item= (Item) e.nextElement();
-                        disassociate(item);
-                        item.dispose();
-                    }
-                    
-                    if (doUpdateParent)
-                        updateItem(w, delta.getElement());
-                    if (!doUpdateParent && doUpdateParentsPlus && w instanceof Item)
-                        updatePlus((Item)w, delta.getElement());
-                }
-                
-
-                                
-                /*
-                 * @see ContentViewer#handleLabelProviderChanged(LabelProviderChangedEvent)
-                 */
-                protected void handleLabelProviderChanged(LabelProviderChangedEvent event) {
-                    Object input= getInput();
-                    if (event instanceof ProblemsLabelChangedEvent) {
-                        ProblemsLabelChangedEvent e= (ProblemsLabelChangedEvent) event;
-                        if (e.isMarkerChange() && input instanceof ICompilationUnit) {
-                            return; // marker changes can be ignored
-                        }
-                    }
-                    // look if the underlying resource changed
-                    Object[] changed= event.getElements();
-                    if (changed != null) {
-                        IResource resource= getUnderlyingResource();
-                        if (resource != null) {
-                            for (int i= 0; i < changed.length; i++) {
-                                if (changed[i] != null && changed[i].equals(resource)) {
-                                    // change event to a full refresh
-                                    event= new LabelProviderChangedEvent((IBaseLabelProvider) event.getSource());
-                                    break;
-                                }
-                            }
-                        }
-                    }
-                    super.handleLabelProviderChanged(event);
-                }
-                
-                private IResource getUnderlyingResource() {
-                    Object input= getInput();
-                    if (input instanceof ICompilationUnit) {
-                        ICompilationUnit cu= (ICompilationUnit) input;
-                        cu= JavaModelUtil.toOriginal(cu);
-                        return cu.getResource();        
-                    } else if (input instanceof IClassFile) {
-                        return ((IClassFile) input).getResource();
-                    }
-                    return null;
-                }               
-                
-
-            }
-                
-            class LexicalSortingAction extends Action {
-                
-                private JavaElementSorter fSorter= new JavaElementSorter();         
-
-                public LexicalSortingAction() {
-                    super();
-                    PlatformUI.getWorkbench().getHelpSystem().setHelp(this, IJavaHelpContextIds.LEXICAL_SORTING_OUTLINE_ACTION);
-                    setText(JavaEditorMessages.getString("JavaOutlinePage.Sort.label")); //$NON-NLS-1$
-                    JavaPluginImages.setLocalImageDescriptors(this, "alphab_sort_co.gif"); //$NON-NLS-1$
-                    setToolTipText(JavaEditorMessages.getString("JavaOutlinePage.Sort.tooltip")); //$NON-NLS-1$
-                    setDescription(JavaEditorMessages.getString("JavaOutlinePage.Sort.description")); //$NON-NLS-1$
-                    
-                    boolean checked= JavaPlugin.getDefault().getPreferenceStore().getBoolean("LexicalSortingAction.isChecked"); //$NON-NLS-1$
-                    valueChanged(checked, false);
-                }
-                
-                public void run() {
-                    valueChanged(isChecked(), true);
-                }
-                
-                private void valueChanged(final boolean on, boolean store) {
-                    setChecked(on);
-                    BusyIndicator.showWhile(fOutlineViewer.getControl().getDisplay(), new Runnable() {
-                        public void run() {
-                            fOutlineViewer.setSorter(on ? fSorter : null);                      }
-                    });
-
-                    if (store)
-                        JavaPlugin.getDefault().getPreferenceStore().setValue("LexicalSortingAction.isChecked", on); //$NON-NLS-1$
-                }
-            }
-
-        class ClassOnlyAction extends Action {
-
-            public ClassOnlyAction() {
-                super();
-                PlatformUI.getWorkbench().getHelpSystem().setHelp(this, IJavaHelpContextIds.GO_INTO_TOP_LEVEL_TYPE_ACTION);
-                setText(JavaEditorMessages.getString("JavaOutlinePage.GoIntoTopLevelType.label")); //$NON-NLS-1$
-                setToolTipText(JavaEditorMessages.getString("JavaOutlinePage.GoIntoTopLevelType.tooltip")); //$NON-NLS-1$
-                setDescription(JavaEditorMessages.getString("JavaOutlinePage.GoIntoTopLevelType.description")); //$NON-NLS-1$
-                JavaPluginImages.setLocalImageDescriptors(this, "gointo_toplevel_type.gif"); //$NON-NLS-1$
-
-                IPreferenceStore preferenceStore= JavaPlugin.getDefault().getPreferenceStore();
-                boolean showclass= preferenceStore.getBoolean("GoIntoTopLevelTypeAction.isChecked"); //$NON-NLS-1$
-                setTopLevelTypeOnly(showclass);
-            }
-
-            /*
-             * @see org.eclipse.jface.action.Action#run()
-             */
-            public void run() {
-                setTopLevelTypeOnly(!fTopLevelTypeOnly);
-            }
-
-            private void setTopLevelTypeOnly(boolean show) {
-                fTopLevelTypeOnly= show;
-                setChecked(show);
-                fOutlineViewer.refresh(false);
-                
-                IPreferenceStore preferenceStore= JavaPlugin.getDefault().getPreferenceStore(); 
-                preferenceStore.setValue("GoIntoTopLevelTypeAction.isChecked", show); //$NON-NLS-1$
-            }
-        }
-
-        /**
-         * This action toggles whether this Java Outline page links
-         * its selection to the active editor.
-         * 
-         * @since 3.0
-         */
-        public class ToggleLinkingAction extends AbstractToggleLinkingAction {
-        
-            JavaOutlinePage fJavaOutlinePage;
-        
-            /**
-             * Constructs a new action.
-             * 
-             * @param outlinePage the Java outline page
-             */
-            public ToggleLinkingAction(JavaOutlinePage outlinePage) {
-                boolean isLinkingEnabled= PreferenceConstants.getPreferenceStore().getBoolean(PreferenceConstants.EDITOR_SYNC_OUTLINE_ON_CURSOR_MOVE);
-                setChecked(isLinkingEnabled);
-                fJavaOutlinePage= outlinePage;
-            }
-    
-            /**
-             * Runs the action.
-             */
-            public void run() {
-                PreferenceConstants.getPreferenceStore().setValue(PreferenceConstants.EDITOR_SYNC_OUTLINE_ON_CURSOR_MOVE, isChecked());
-
-                // MOD: start
-                if (fEditor instanceof MylarClassFileEditor) {
-                    if (isChecked() && fEditor != null)
-                        ((MylarClassFileEditor)fEditor).synchronizeOutlinePage(((MylarClassFileEditor)fEditor).computeHighlightRangeSourceReference(), false);
-                } else if (fEditor instanceof MylarCompilationUnitEditor) {
-                    if (isChecked() && fEditor != null)
-                        ((MylarCompilationUnitEditor)fEditor).synchronizeOutlinePage(((MylarCompilationUnitEditor)fEditor).computeHighlightRangeSourceReference(), false);
-                }
-                // MOD: end
-            }
-    
-        }
-
-
-    /** A flag to show contents of top level type only */
-    private boolean fTopLevelTypeOnly;
-            
-    private IJavaElement fInput;
-    private String fContextMenuID;
-    private Menu fMenu;
-    private JavaOutlineViewer fOutlineViewer;
-//    private JavaEditor fEditor;
-    
-    private MemberFilterActionGroup fMemberFilterActionGroup;
-        
-    private ListenerList fSelectionChangedListeners= new ListenerList();
-    private ListenerList fPostSelectionChangedListeners= new ListenerList();
-    private Hashtable fActions= new Hashtable();
-    
-    private TogglePresentationAction fTogglePresentation;
-    private GotoAnnotationAction fPreviousAnnotation;
-    private GotoAnnotationAction fNextAnnotation;
-    private TextEditorAction fShowJavadoc;
-    private IAction fUndo;
-    private IAction fRedo;
-    
-    private ToggleLinkingAction fToggleLinkingAction;
-    
-    private CompositeActionGroup fActionGroups;
-
-    private IPropertyChangeListener fPropertyChangeListener;
-    /**
-     * Custom filter action group.
-     * @since 3.0
-     */
-    private CustomFiltersActionGroup fCustomFiltersActionGroup;
-    
-    public MylarJavaOutlinePage(String contextMenuID, JavaEditor editor) {
-        super(contextMenuID, editor);  // TODO: wierd overriding of consturction
-        
-        Assert.isNotNull(editor);
-        
-        fContextMenuID= contextMenuID;
-        fEditor= editor;
-        
-        fTogglePresentation= new TogglePresentationAction();
-        fPreviousAnnotation= new GotoAnnotationAction("PreviousAnnotation.", false); //$NON-NLS-1$
-        fNextAnnotation= new GotoAnnotationAction("NextAnnotation.", true); //$NON-NLS-1$
-        fShowJavadoc= (TextEditorAction) fEditor.getAction("ShowJavaDoc"); //$NON-NLS-1$
-        fUndo= fEditor.getAction(ITextEditorActionConstants.UNDO);
-        fRedo= fEditor.getAction(ITextEditorActionConstants.REDO);
-        
-        fTogglePresentation.setEditor(editor);
-        fPreviousAnnotation.setEditor(editor);
-        fNextAnnotation.setEditor(editor);  
-        
-        fPropertyChangeListener= new IPropertyChangeListener() {
-            public void propertyChange(PropertyChangeEvent event) {
-                doPropertyChange(event);
-            }
-        };
-        JavaPlugin.getDefault().getPreferenceStore().addPropertyChangeListener(fPropertyChangeListener);
-    }
-    
-    /**
-     * Returns the primary type of a compilation unit (has the same
-     * name as the compilation unit).
-     * 
-     * @param compilationUnit the compilation unit
-     * @return returns the primary type of the compilation unit, or
-     * <code>null</code> if is does not have one
-     */
-    protected IType getMainType(ICompilationUnit compilationUnit) {
-        
-        if (compilationUnit == null)
-            return null;
-        
-        String name= compilationUnit.getElementName();
-        int index= name.indexOf('.');
-        if (index != -1)
-            name= name.substring(0, index);
-        IType type= compilationUnit.getType(name);
-        return type.exists() ? type : null;
-    }
-
-    /**
-     * Returns the primary type of a class file.
-     * 
-     * @param classFile the class file
-     * @return returns the primary type of the class file, or <code>null</code>
-     * if is does not have one
-     */
-    protected IType getMainType(IClassFile classFile) {
-        try {
-            IType type= classFile.getType();
-            return type != null && type.exists() ? type : null;
-        } catch (JavaModelException e) {
-            return null;    
-        }
-    }
-    
-    /* (non-Javadoc)
-     * Method declared on Page
-     */
-    public void init(IPageSite pageSite) {
-        super.init(pageSite);
-    }
-    
-    private void doPropertyChange(PropertyChangeEvent event) {
-        if (fOutlineViewer != null) {
-            if (MembersOrderPreferenceCache.isMemberOrderProperty(event.getProperty())) {
-                fOutlineViewer.refresh(false);
-            }
-        }
-    }   
-    
-    /*
-     * @see ISelectionProvider#addSelectionChangedListener(ISelectionChangedListener)
-     */
-    public void addSelectionChangedListener(ISelectionChangedListener listener) {
-        if (fOutlineViewer != null)
-            fOutlineViewer.addSelectionChangedListener(listener);
-        else
-            fSelectionChangedListeners.add(listener);
-    }
-    
-    /*
-     * @see ISelectionProvider#removeSelectionChangedListener(ISelectionChangedListener)
-     */
-    public void removeSelectionChangedListener(ISelectionChangedListener listener) {
-        if (fOutlineViewer != null)
-            fOutlineViewer.removeSelectionChangedListener(listener);
-        else
-            fSelectionChangedListeners.remove(listener);
-    }
-    
-    /*
-     * @see ISelectionProvider#setSelection(ISelection)
-     */
-    public void setSelection(ISelection selection) {
-        if (fOutlineViewer != null)
-            fOutlineViewer.setSelection(selection);     
-    }   
-    
-    /*
-     * @see ISelectionProvider#getSelection()
-     */
-    public ISelection getSelection() {
-        if (fOutlineViewer == null)
-            return StructuredSelection.EMPTY;
-        return fOutlineViewer.getSelection();
-    }
-    
-    /*
-     * @see org.eclipse.jface.text.IPostSelectionProvider#addPostSelectionChangedListener(org.eclipse.jface.viewers.ISelectionChangedListener)
-     */
-    public void addPostSelectionChangedListener(ISelectionChangedListener listener) {
-        if (fOutlineViewer != null)
-            fOutlineViewer.addPostSelectionChangedListener(listener);
-        else
-            fPostSelectionChangedListeners.add(listener);
-    }
-    
-    /*
-     * @see org.eclipse.jface.text.IPostSelectionProvider#removePostSelectionChangedListener(org.eclipse.jface.viewers.ISelectionChangedListener)
-     */
-    public void removePostSelectionChangedListener(ISelectionChangedListener listener) {
-        if (fOutlineViewer != null)
-            fOutlineViewer.removePostSelectionChangedListener(listener);
-        else
-            fPostSelectionChangedListeners.remove(listener);    
-    }
-    
-    private void registerToolbarActions(IActionBars actionBars) {
-        
-        IToolBarManager toolBarManager= actionBars.getToolBarManager();
-        if (toolBarManager != null) {   
-            toolBarManager.add(new LexicalSortingAction());
-            
-            fMemberFilterActionGroup= new MemberFilterActionGroup(fOutlineViewer, "org.eclipse.jdt.ui.JavaOutlinePage"); //$NON-NLS-1$
-            fMemberFilterActionGroup.contributeToToolBar(toolBarManager);
-
-            fCustomFiltersActionGroup.fillActionBars(actionBars);
-            
-            IMenuManager menu= actionBars.getMenuManager();
-            menu.add(new Separator("EndFilterGroup")); //$NON-NLS-1$
-            
-            fToggleLinkingAction= new ToggleLinkingAction(this);
-            menu.add(new ClassOnlyAction());        
-            menu.add(fToggleLinkingAction);
-        }
-    }
-    
-    /*
-     * @see IPage#createControl
-     */
-    public void createControl(Composite parent) {
-        
-        Tree tree= new Tree(parent, SWT.MULTI);
-
-        AppearanceAwareLabelProvider lprovider= new AppearanceAwareLabelProvider(
-            AppearanceAwareLabelProvider.DEFAULT_TEXTFLAGS |  JavaElementLabels.F_APP_TYPE_SIGNATURE,
-            AppearanceAwareLabelProvider.DEFAULT_IMAGEFLAGS
-        );
-
-        fOutlineViewer= new JavaOutlineViewer(tree);        
-        initDragAndDrop();
-        fOutlineViewer.setContentProvider(new ChildrenProvider());
-        fOutlineViewer.setLabelProvider(new DecoratingJavaLabelProvider(lprovider));
-        
-        Object[] listeners= fSelectionChangedListeners.getListeners();
-        for (int i= 0; i < listeners.length; i++) {
-            fSelectionChangedListeners.remove(listeners[i]);
-            fOutlineViewer.addSelectionChangedListener((ISelectionChangedListener) listeners[i]);
-        }
-        
-        listeners= fPostSelectionChangedListeners.getListeners();
-        for (int i= 0; i < listeners.length; i++) {
-            fPostSelectionChangedListeners.remove(listeners[i]);
-            fOutlineViewer.addPostSelectionChangedListener((ISelectionChangedListener) listeners[i]);
-        }
-                        
-        MenuManager manager= new MenuManager(fContextMenuID, fContextMenuID);
-        manager.setRemoveAllWhenShown(true);
-        manager.addMenuListener(new IMenuListener() {
-            public void menuAboutToShow(IMenuManager m) {
-                contextMenuAboutToShow(m);
-            }
-        });
-        fMenu= manager.createContextMenu(tree);
-        tree.setMenu(fMenu);
-        
-        IPageSite site= getSite();
-        site.registerContextMenu(JavaPlugin.getPluginId() + ".outline", manager, fOutlineViewer); //$NON-NLS-1$
-        site.setSelectionProvider(fOutlineViewer);
-
-        // we must create the groups after we have set the selection provider to the site
-        fActionGroups= new CompositeActionGroup(new ActionGroup[] {
-                new OpenViewActionGroup(this), 
-                new CCPActionGroup(this),
-                new GenerateActionGroup(this),
-                new RefactorActionGroup(this), 
-                new JavaSearchActionGroup(this)});
-                
-        // register global actions
-        IActionBars bars= site.getActionBars();
-        
-        bars.setGlobalActionHandler(ITextEditorActionConstants.UNDO, fUndo);
-        bars.setGlobalActionHandler(ITextEditorActionConstants.REDO, fRedo);
-        bars.setGlobalActionHandler(ITextEditorActionConstants.PREVIOUS, fPreviousAnnotation);
-        bars.setGlobalActionHandler(ITextEditorActionConstants.NEXT, fNextAnnotation);
-        bars.setGlobalActionHandler(JdtActionConstants.SHOW_JAVA_DOC, fShowJavadoc);
-        bars.setGlobalActionHandler(ITextEditorActionDefinitionIds.TOGGLE_SHOW_SELECTED_ELEMENT_ONLY, fTogglePresentation);
-        bars.setGlobalActionHandler(ITextEditorActionDefinitionIds.GOTO_NEXT_ANNOTATION, fNextAnnotation);
-        bars.setGlobalActionHandler(ITextEditorActionDefinitionIds.GOTO_PREVIOUS_ANNOTATION, fPreviousAnnotation);
-        
-        
-        fActionGroups.fillActionBars(bars);
-
-        IStatusLineManager statusLineManager= bars.getStatusLineManager();
-        if (statusLineManager != null) {
-            StatusBarUpdater updater= new StatusBarUpdater(statusLineManager);
-            fOutlineViewer.addPostSelectionChangedListener(updater);
-        }
-        // Custom filter group
-        fCustomFiltersActionGroup= new CustomFiltersActionGroup("org.eclipse.jdt.ui.JavaOutlinePage", fOutlineViewer); //$NON-NLS-1$
-
-        registerToolbarActions(bars);
-                
-        fOutlineViewer.setInput(fInput);    
-    }
-
-    public void dispose() {
-        
-        if (fEditor == null)
-            return;
-            
-        if (fMemberFilterActionGroup != null) {
-            fMemberFilterActionGroup.dispose();
-            fMemberFilterActionGroup= null;
-        }
-        
-        if (fCustomFiltersActionGroup != null) {
-            fCustomFiltersActionGroup.dispose();
-            fCustomFiltersActionGroup= null;
-        }
-            
-            
-        fEditor.outlinePageClosed();
-        fEditor= null;
-
-        fSelectionChangedListeners.clear();
-        fSelectionChangedListeners= null;
-        
-        fPostSelectionChangedListeners.clear();
-        fPostSelectionChangedListeners= null;
-
-        if (fPropertyChangeListener != null) {
-            JavaPlugin.getDefault().getPreferenceStore().removePropertyChangeListener(fPropertyChangeListener);
-            fPropertyChangeListener= null;
-        }
-        
-        if (fMenu != null && !fMenu.isDisposed()) {
-            fMenu.dispose();
-            fMenu= null;
-        }
-        
-        if (fActionGroups != null)
-            fActionGroups.dispose();
-            
-        fTogglePresentation.setEditor(null);
-        fPreviousAnnotation.setEditor(null);
-        fNextAnnotation.setEditor(null);    
-        
-        fOutlineViewer= null;
-        
-        super.dispose();
-    }
-    
-    public Control getControl() {
-        if (fOutlineViewer != null)
-            return fOutlineViewer.getControl();
-        return null;
-    }
-    
-    public void setInput(IJavaElement inputElement) {
-        fInput= inputElement;   
-        if (fOutlineViewer != null)
-            fOutlineViewer.setInput(fInput);
-    }
-        
-    public void select(ISourceReference reference) {
-        if (fOutlineViewer != null) {
-            
-            ISelection s= fOutlineViewer.getSelection();
-            if (s instanceof IStructuredSelection) {
-                IStructuredSelection ss= (IStructuredSelection) s;
-                List elements= ss.toList();
-                if (!elements.contains(reference)) {
-                    s= (reference == null ? StructuredSelection.EMPTY : new StructuredSelection(reference));
-                    fOutlineViewer.setSelection(s, true);
-                }
-            }
-        }
-    }
-    
-    public void setAction(String actionID, IAction action) {
-        Assert.isNotNull(actionID);
-        if (action == null)
-            fActions.remove(actionID);
-        else
-            fActions.put(actionID, action);
-    }
-    
-    public IAction getAction(String actionID) {
-        Assert.isNotNull(actionID);
-        return (IAction) fActions.get(actionID);
-    }
-
-    /*
-     * @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class)
-     */
-    public Object getAdapter(Class key) {
-        if (key == IShowInSource.class) {
-            return getShowInSource();
-        }
-        if (key == IShowInTargetList.class) {
-            return new IShowInTargetList() {
-                public String[] getShowInTargetIds() {
-                    return new String[] { JavaUI.ID_PACKAGES };
-                }
-
-            };
-        }
-        if (key == IShowInTarget.class) {
-            return getShowInTarget();
-        }
-
-        return null;
-    }
-
-    /**
-     * Convenience method to add the action installed under the given actionID to the
-     * specified group of the menu.
-     * 
-     * @param menu      the menu manager
-     * @param group     the group to which to add the action
-     * @param actionID  the ID of the new action
-     */
-    protected void addAction(IMenuManager menu, String group, String actionID) {
-        IAction action= getAction(actionID);
-        if (action != null) {
-            if (action instanceof IUpdate)
-                ((IUpdate) action).update();
-                
-            if (action.isEnabled()) {
-                IMenuManager subMenu= menu.findMenuUsingPath(group);
-                if (subMenu != null)
-                    subMenu.add(action);
-                else
-                    menu.appendToGroup(group, action);
-            }
-        }
-    }
-     
-    protected void contextMenuAboutToShow(IMenuManager menu) {
-        
-        JavaPlugin.createStandardGroups(menu);
-                
-        IStructuredSelection selection= (IStructuredSelection)getSelection();
-        fActionGroups.setContext(new ActionContext(selection));
-        fActionGroups.fillContextMenu(menu);
-    }
-    
-    /*
-     * @see Page#setFocus()
-     */
-    public void setFocus() {
-        if (fOutlineViewer != null)
-            fOutlineViewer.getControl().setFocus();
-    }
-    
-    /**
-     * Checks whether a given Java element is an inner type.
-     * 
-     * @param element the java element
-     * @return <code>true</code> iff the given element is an inner type
-     */
-    private boolean isInnerType(IJavaElement element) {
-        
-        if (element != null && element.getElementType() == IJavaElement.TYPE) {
-            IType type= (IType)element;
-            try {
-                return type.isMember();
-            } catch (JavaModelException e) {
-                IJavaElement parent= type.getParent();
-                if (parent != null) {
-                    int parentElementType= parent.getElementType();
-                    return (parentElementType != IJavaElement.COMPILATION_UNIT && parentElementType != IJavaElement.CLASS_FILE);
-                }
-            }
-        }
-        
-        return false;       
-    }
-    
-    /**
-     * Returns the <code>IShowInSource</code> for this view.
-     * 
-     * @return the {@link IShowInSource}
-     */
-    protected IShowInSource getShowInSource() {
-        return new IShowInSource() {
-            public ShowInContext getShowInContext() {
-                return new ShowInContext(
-                    null,
-                    getSite().getSelectionProvider().getSelection());
-            }
-        };
-    }
-
-    /**
-     * Returns the <code>IShowInTarget</code> for this view.
-     * 
-     * @return the {@link IShowInTarget}
-     */
-    protected IShowInTarget getShowInTarget() {
-        return new IShowInTarget() {
-            public boolean show(ShowInContext context) {
-                ISelection sel= context.getSelection();
-                if (sel instanceof ITextSelection) {
-                    ITextSelection tsel= (ITextSelection) sel;
-                    int offset= tsel.getOffset();
-                    
-                    
-                    // MOD: start
-                    IJavaElement element= null; 
-                    if (fEditor instanceof MylarClassFileEditor) {
-                            element = ((MylarClassFileEditor)fEditor).getElementAt(offset);
-                    } else if (fEditor instanceof MylarCompilationUnitEditor) {
-                            element = ((MylarCompilationUnitEditor)fEditor).getElementAt(offset);
-                    }
-                    // MOD: end
-                    
-                    
-                    if (element != null) {
-                        setSelection(new StructuredSelection(element));
-                        return true;
-                    }
-                }
-                return false;
-            }
-        };
-    }
-    
-    private void initDragAndDrop() {
-        int ops= DND.DROP_COPY | DND.DROP_MOVE | DND.DROP_LINK;
-        Transfer[] transfers= new Transfer[] {
-            LocalSelectionTransfer.getInstance()
-            };
-        
-        // Drop Adapter
-        TransferDropTargetListener[] dropListeners= new TransferDropTargetListener[] {
-            new SelectionTransferDropAdapter(fOutlineViewer)
-        };
-        fOutlineViewer.addDropSupport(ops | DND.DROP_DEFAULT, transfers, new DelegatingDropAdapter(dropListeners));
-        
-        // Drag Adapter
-        TransferDragSourceListener[] dragListeners= new TransferDragSourceListener[] {
-            new SelectionTransferDragAdapter(fOutlineViewer)
-        };
-        fOutlineViewer.addDragSupport(ops, transfers, new JdtViewerDragAdapter(fOutlineViewer, dragListeners));
-    }
- }
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/views/MylarMonitorView.java b/org.eclipse.mylyn.ide.dev/developer/src-old/views/MylarMonitorView.java
deleted file mode 100644
index e710279..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/views/MylarMonitorView.java
+++ /dev/null
@@ -1,178 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004 - 2005 University Of British Columbia and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     University Of British Columbia - initial API and implementation
- *******************************************************************************/
-package org.eclipse.mylyn.monitor.views;
-
-
-import org.eclipse.jface.action.*;
-import org.eclipse.jface.dialogs.MessageDialog;
-import org.eclipse.jface.viewers.*;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.widgets.*;
-import org.eclipse.ui.IActionBars;
-import org.eclipse.ui.IWorkbenchActionConstants;
-import org.eclipse.ui.internal.Workbench;
-import org.eclipse.ui.part.ViewPart;
-
-import org.eclipse.mylyn.core.MylarPlugin;
-import org.eclipse.mylyn.monitor.MonitorImages;
-import org.eclipse.mylyn.monitor.MonitorPlugin;
-
-
-public abstract class MylarMonitorView extends ViewPart {
-    private LabelProvider labelProvider;
-    private ViewerSorter viewerSorter;
-	protected TableViewer viewer;
-	private Action refresh;
-	private Action deleteUsageFile;
-	private Action linkRefresh;
-	private boolean activeRefresh = ContextCorePlugin.DEBUG_MODE;
-	
-	class ViewContentProvider implements IStructuredContentProvider {
-		public void inputChanged(Viewer v, Object oldInput, Object newInput) {
-		}
-		public void dispose() {
-		}
-		public Object[] getElements(Object parent) {
-		    return refreshView(parent);
-		}
-	}
-	
-    protected abstract Object[] refreshView(Object parent);
-	
-    public MylarMonitorView(LabelProvider labelProvider, ViewerSorter viewerSorter) {
-        this.labelProvider = labelProvider;
-        this.viewerSorter = viewerSorter;
-        
-//        if (activeRefresh) ContextCorePlugin.getTaskscapeManager().addListener(REFRESH_UPDATE_LISTENER);
-    }
-    
-	/**
-	 * This is a callback that will allow us
-	 * to create the viewer and initialize it.
-	 */
-	public void createPartControl(Composite parent) {
-//	    Composite composite = new Composite(parent, SWT.TOP);
-//	    summaryLabel = new Label(composite, SWT.TOP);
-//	    summaryLabel.setText("no summary info");
-//	    JUnitProgressBar fProgressBar = new JUnitProgressBar(parent);
-	    
-		viewer = new TableViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL);
-		viewer.setContentProvider(new ViewContentProvider());
-		viewer.setLabelProvider(labelProvider);
-		viewer.setSorter(viewerSorter);
-		viewer.setInput(getViewSite());
-		makeActions();
-		hookContextMenu();
-		contributeToActionBars();
-	}
-
-	private void hookContextMenu() {
-		MenuManager menuMgr = new MenuManager("#PopupMenu");
-		menuMgr.setRemoveAllWhenShown(true);
-		menuMgr.addMenuListener(new IMenuListener() {
-			public void menuAboutToShow(IMenuManager manager) {
-				MylarMonitorView.this.fillContextMenu(manager);
-			}
-		});
-		Menu menu = menuMgr.createContextMenu(viewer.getControl());
-		viewer.getControl().setMenu(menu);
-		getSite().registerContextMenu(menuMgr, viewer);
-	}
-
-	private void contributeToActionBars() {
-		IActionBars bars = getViewSite().getActionBars();
-		fillLocalPullDown(bars.getMenuManager());
-		fillLocalToolBar(bars.getToolBarManager());
-	}
-
-	private void fillLocalPullDown(IMenuManager manager) {
-		manager.add(refresh);
-		manager.add(new Separator());
-	}
-
-	private void fillContextMenu(IMenuManager manager) {
-		manager.add(refresh);
-		// Other plug-ins can contribute there actions here
-		manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
-	}
-	
-	private void fillLocalToolBar(IToolBarManager manager) {
-	    manager.add(deleteUsageFile);
-	    manager.add(linkRefresh);
-	    manager.add(refresh);
-	}
-
-	private void makeActions() {
-		linkRefresh = new ActiveRefreshAction();
-		linkRefresh.setToolTipText("Active Refresh");
-		linkRefresh.setImageDescriptor(MonitorImages.SYNCHED);  
-		linkRefresh.setChecked(activeRefresh);
-	    
-	    refresh = new Action() {
-			public void run() {
-			    MonitorPlugin.getStatisticsManager().refreshCurrentSession();
-				MylarMonitorView.this.viewer.refresh(); 
-			}
-		};
-		refresh.setText("Refresh");
-		refresh.setToolTipText("Refresh Statistics");
-		refresh.setImageDescriptor(MonitorImages.REFRESH);  
-
-		deleteUsageFile = new Action() {
-			public void run() {
-				PlatformUI.getWorkbench().getDisplay().syncExec(new Runnable() {
-					public void run() {
-						try {
-							Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell();
-							boolean delete = MessageDialog.openQuestion(
-								shell,
-								"Confirm delete",
-								"Delete the underlying file?");
-							if (delete) resetUnderlyingModel();
-						} catch (Throwable t) {
-						    ContextCorePlugin.fail(t, "Could not delete usage file", true);
-						}
-					}
-				});
-				MylarMonitorView.this.viewer.refresh();
-			}
-		};
-		deleteUsageFile.setText("Delete usage file");
-		deleteUsageFile.setToolTipText("Delete usage file");
-		deleteUsageFile.setImageDescriptor(MonitorImages.REMOVE);
-	}
-
-	protected abstract void resetUnderlyingModel();
-	
-	/**
-	 * Passing the focus request to the viewer's control.
-	 */
-	public void setFocus() {
-		viewer.getControl().setFocus();
-	}
-	
-	class ActiveRefreshAction extends Action {
-	    public ActiveRefreshAction() {
-	        super(null, IAction.AS_CHECK_BOX);
-	    } 
-	     
-		public void run() {
-		    activeRefresh = !activeRefresh;
-		    setChecked(activeRefresh);
-		    if (activeRefresh) {
-//		        ContextCorePlugin.getTaskscapeManager().addListener(REFRESH_UPDATE_LISTENER);
-		    } else {
-//		        ContextCorePlugin.getTaskscapeManager().removeListener(REFRESH_UPDATE_LISTENER);
-		    }
-		}
-	};
-}
-
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/views/MylarPackageExplorer.java b/org.eclipse.mylyn.ide.dev/developer/src-old/views/MylarPackageExplorer.java
deleted file mode 100644
index 0e188d3..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/views/MylarPackageExplorer.java
+++ /dev/null
@@ -1,174 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004 - 2005 University Of British Columbia and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     University Of British Columbia - initial API and implementation
- *******************************************************************************/
-/*
- * Created on Jul 22, 2004
-  */
-package org.eclipse.mylyn.java.ui.views;
-
-import org.eclipse.jdt.internal.ui.packageview.PackageExplorerPart;
-import org.eclipse.jface.action.IToolBarManager;
-import org.eclipse.jface.action.Separator;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.ui.internal.Workbench;
-
-import org.eclipse.mylyn.core.ITaskscapeListener;
-import org.eclipse.mylyn.core.MylarPlugin;
-import org.eclipse.mylyn.core.model.ITaskscapeNode;
-import org.eclipse.mylyn.java.ui.*;
-import org.eclipse.mylyn.java.ui.actions.*;
-import org.eclipse.mylyn.tasklist.TaskListPlugin;
-
-/**
- * @author Mik Kersten
- */
-public class MylarPackageExplorer extends PackageExplorerPart {
-    
-    public static MylarPackageExplorer INSTANCE = null;
-    private boolean autoExpandModeEnabled = false; 
-    private MylarAppearanceAwareLabelProvider provider;
-    private ToggleAutoManagerExplorerAction autoExpandAction; 
-    private ToggleFilterDeclarationsAction filterDeclarationsAction;
-    private ToggleAutoFoldAction autoManageEditorsAction;
-    
-    private DoiViewerFilter doiFilter = new DoiViewerFilter();
-    
-	private final ITaskscapeListener MODEL_LISTENER = new ITaskscapeListener() {
-	    public void interestChanged(ITaskscapeNode info) {
-	        refresh(true);
-	    }
-
-	    public void modelUpdated() {
-	        refresh(true);
-	    }
-
-        public void presentationSettingsChanged(PresentationChangeKind kind) {
-            refresh(true);
-        }
-        
-        public void presentationSettingsChanging(PresentationChangeKind kind) {
-            refresh(true);
-        }
-        
-        public void landmarkAdded(ITaskscapeNode element) { 
-            refresh(false); 
-        }
-
-        public void landmarkRemoved(ITaskscapeNode element) { 
-            refresh(false);
-        } 
-
-        public void relationshipsChanged() {
-        }
-
-        public void nodeDeleted(ITaskscapeNode node) {
-            refresh(false);
-        }
-        
-        private void refresh(final boolean updateExpansionSate) {
-            PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {
-                public void run() { 
-                    try { 
-                        if (MylarPackageExplorer.this.getTreeViewer() != null && !MylarPackageExplorer.this.getTreeViewer().getTree().isDisposed()) { 
-                            MylarPackageExplorer.this.getTreeViewer().refresh();    
-                            if (autoExpandModeEnabled && updateExpansionSate) 
-                                MylarPackageExplorer.this.getTreeViewer().expandAll();
-                        }
-                    } catch (Throwable t) {
-                        ContextCorePlugin.fail(t, "Could not update viewer", false);
-                    }    
-                }
-            });
-        }
-	};
-    
-    public MylarPackageExplorer() {
-        ContextCorePlugin.getTaskscapeManager().addListener(MODEL_LISTENER);
-        INSTANCE = this;
-    }
-    
-    public void createPartControl(Composite parent) {
-        super.createPartControl(parent);
-        provider = new MylarAppearanceAwareLabelProvider(getTreeViewer()); 
- 
-        getTreeViewer().getTree().setBackground(TaskListPlugin.getDefault().getColorMap().BACKGROUND_COLOR);
-        getTreeViewer().setLabelProvider(new MylarFontDecoratingJavaLabelProvider(provider, true));
-        getTreeViewer().addFilter(doiFilter); 
-        
-        IToolBarManager toolBarManager = getViewSite().getActionBars().getToolBarManager();
-        autoExpandAction = new ToggleAutoManagerExplorerAction(this);	
-        filterDeclarationsAction = new ToggleFilterDeclarationsAction(this);
-        autoManageEditorsAction = new ToggleAutoFoldAction();
-        if (toolBarManager != null) {	
-		    toolBarManager.add(new Separator("StartMylar"));
-		    toolBarManager.add(filterDeclarationsAction);
-            toolBarManager.add(autoManageEditorsAction);
-		    toolBarManager.add(autoExpandAction);
-		} 
-		autoExpandAction.autoExpand(autoExpandAction.isChecked()); 
-        filterDeclarationsAction.filter(filterDeclarationsAction.isChecked());
-    }
-
-    public boolean isAutoExpandModeEnabled() {
-        return autoExpandModeEnabled;
-    }
-    
-    public void setAutoExpandModeEnabled(boolean autoExpandModeEnabled) {
-        this.autoExpandModeEnabled = autoExpandModeEnabled;
-        provider.setInterestFilterEnabled(autoExpandModeEnabled);
-    }
-    
-    // TODO: still too slow?
-    public void expandAllInteresting() {
-        if (autoExpandModeEnabled) getTreeViewer().expandAll();
-//        List<ITaskscapeNode> elements = ContextCorePlugin.getTaskscapeManager().getActiveTaskscape().getInteresting();
-//        if (elements == null) return;
-//        List<IJavaElement> prunedElements = new ArrayList<IJavaElement>();
-//        for (ITaskscapeNode node : elements) {
-//            if (node.getKind().equals(ITaskscapeNode.Kind.Java)) {
-//                IJavaElement curr = JavaCore.create(node.getElementHandle());
-//                if (curr != null) {
-//                    if (!(curr instanceof IPackageFragment
-//                          || curr instanceof IPackageFragmentRoot
-//                          || curr instanceof IJavaProject)) {
-//                        prunedElements.add(curr);
-//                    }
-//                }
-//            } else {
-//            }
-//        } 
-//        
-//        Collections.sort(prunedElements, new Comparator() {
-//            public int compare(Object o1, Object o2) {
-//                if (o1 instanceof IJavaElement && o2 instanceof IJavaElement) {
-//                    IJavaElement e1 = (IJavaElement)o1;
-//                    IJavaElement e2 = (IJavaElement)o2;
-//                    if (e1 != null && e2 != null) {
-//                        return e1.getHandleIdentifier().compareTo(e2.getHandleIdentifier());
-//                    } 
-//                } 
-//                return 0;
-//            }
-//        });
-//        for (Iterator it = prunedElements.iterator(); it.hasNext(); ) {
-//            getTreeViewer().expandToLevel(it.next(), 1);
-//        }
-    }
-    
-    public MylarAppearanceAwareLabelProvider getLabelProvider() {
-        return provider;
-    }
-    public DoiViewerFilter getDoiFilter() {
-        return doiFilter;
-    }
-}
-
-
-
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/views/MylarProblemView.java b/org.eclipse.mylyn.ide.dev/developer/src-old/views/MylarProblemView.java
deleted file mode 100644
index f2fe605..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/views/MylarProblemView.java
+++ /dev/null
@@ -1,289 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004 - 2005 University Of British Columbia and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     University Of British Columbia - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.mylyn.java.ui.views;
-
-import java.util.List;
-
-import org.eclipse.jdt.core.IJavaElement;
-import org.eclipse.jdt.internal.ui.JavaPlugin;
-import org.eclipse.jdt.ui.ProblemsLabelDecorator;
-import org.eclipse.jface.action.IToolBarManager;
-import org.eclipse.jface.action.Separator;
-import org.eclipse.jface.dialogs.IDialogSettings;
-import org.eclipse.jface.viewers.*;
-import org.eclipse.swt.graphics.*;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.ui.*;
-import org.eclipse.ui.internal.Workbench;
-import org.eclipse.ui.views.markers.internal.*;
-
-import org.eclipse.mylyn.core.ITaskscapeListener;
-import org.eclipse.mylyn.core.MylarPlugin;
-import org.eclipse.mylyn.core.model.*;
-import org.eclipse.mylyn.core.model.ITaskscapeNode;
-import org.eclipse.mylyn.core.model.InterestComparator;
-import org.eclipse.mylyn.java.ui.JavaUiUtil;
-import org.eclipse.mylyn.java.ui.actions.ToggleAutoManagerProblemsAction;
-import org.eclipse.mylyn.ui.*;
-
-/**
- * @author Mik Kersten
- */
-public class MylarProblemView extends ProblemView {
-
-    private static TableViewer currentViewer = null;
-    private final static String TAG_DIALOG_SECTION = "org.eclipse.mylyn.ui.views.problem";
-    private ProblemsListFilter doiFilter = new ProblemsListFilter();
-    private TableSorter sorter = null;
-    
-    // START: from super class
-    private final static int ASCENDING = TableSorter.ASCENDING;
-    private final static int DESCENDING = TableSorter.DESCENDING;
-    private final static int SEVERITY = 0;
-    private final static int DOI = 1;
-    private final static int DESCRIPTION = 2;
-    private final static int RESOURCE = 3;
-    private final static int[] DEFAULT_PRIORITIES = { 
-        SEVERITY, 
-        DOI, 
-        DESCRIPTION,
-        RESOURCE };
-    private final static int[] DEFAULT_DIRECTIONS = { 
-        DESCENDING, // severity
-        ASCENDING, // folder
-        ASCENDING, // resource
-        ASCENDING}; // location
-    //  END: from super class
-    
-	private final static IField[] VISIBLE_FIELDS = { 
-			new FieldSeverity(), 
-			new FieldMessage(),
-			new ProblemsFieldJavaElement(), 
-            new ProblemsFieldDoi(),
-//			new FieldFolder(), // TODO: remove
-//			new FieldLineNumber() // TODO: remove 
-		};
-	
-	private final static ColumnLayoutData[] COLUMN_LAYOUTS = { 
-			new ColumnPixelData(19, false), 
-			new ColumnWeightData(350), 
-			new ColumnWeightData(250), 
-            new ColumnWeightData(35), 
-//			new ColumnWeightData(0), 
-//			new ColumnWeightData(0) 
-		};
-	
-	private static final ITaskscapeListener MODEL_LISTENER = new ITaskscapeListener() {
-        public void presentationSettingsChanging(PresentationChangeKind kind) {
-//            refresh();
-        } 
-        
-        public void interestChanged(ITaskscapeNode info, IWorkbenchPart sourcePart) {
-            refresh();
-	    }
-
-        public void interestChanged(List<ITaskscapeNode> nodes, IWorkbenchPart part) {
-            refresh();
-        }
-        
-        public void taskscapeActivated(ITaskscape taskscape) {
-            refresh();
-        }
-
-        public void taskscapeDeactivated(ITaskscape taskscape) {
-            refresh();
-        } 
-        
-        public void landmarkAdded(ITaskscapeNode element) { }
-
-        public void landmarkRemoved(ITaskscapeNode element) { }
-
-        public void relationshipsChanged() {
-        }
-        
-        private void refresh() {
-            PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {
-                public void run() {
-                    try {
-                        if (currentViewer != null && !currentViewer.getTable().isDisposed()) {
-                            currentViewer.refresh();
-                        } 
-                    } catch (Throwable t) {
-                        ContextCorePlugin.fail(t, "Could not update viewer", false);
-                    }
-                }
-            });
-        }
-
-        public void presentationSettingsChanged(PresentationChangeKind kind) {
-            refresh();
-        }
-
-        public void nodeDeleted(ITaskscapeNode node) {
-            refresh();
-        }
-	};
-	
-	public MylarProblemView() {
-		super();
-		ContextCorePlugin.getTaskscapeManager().addListener(MODEL_LISTENER);
-	}    
-
-	public void init(IViewSite viewSite, IMemento memento) throws PartInitException {
-		super.init(viewSite, memento);
-	}	
- 
-	public void createPartControl(Composite parent) {
-		super.createPartControl(parent);
-
-		MylarLabelProvider labelProvider = new MylarLabelProvider(
-			new TableViewLabelProvider(getVisibleFields()), 
-			new ProblemsLabelDecorator()); 
-        
-		getViewer().setLabelProvider(labelProvider); 
-        getViewer().addFilter(doiFilter);
-//		getViewer().getTable().setHeaderVisible(false);
-		getViewer().getTable().setBackground(MylarUiPlugin.getDefault().getColorMap().BACKGROUND_COLOR);
-		
-        IToolBarManager toolBarManager = getViewSite().getActionBars().getToolBarManager();
-        ToggleAutoManagerProblemsAction autoExpandAction = new ToggleAutoManagerProblemsAction(this); 
-        if (toolBarManager != null) {   
-            toolBarManager.add(new Separator("StartMylar")); 
-            toolBarManager.add(autoExpandAction); 
-        } 
-//        autoExpandAction.autoExpand(autoExpandAction.isChecked());
-//        sorter = new ProblemsListDoiSorter(getFields(), DEFAULT_PRIORITIES, DEFAULT_DIRECTIONS);
-//        getViewer().setSorter(sorter);
-        getViewer().refresh();
-		currentViewer = getViewer();
-	}
-	 
-	protected IField[] getVisibleFields() {
-		return VISIBLE_FIELDS;
-	}
-	
-	protected ColumnLayoutData[] getDefaultColumnLayouts() {
-		return COLUMN_LAYOUTS;
-	}
-	
-	protected IDialogSettings getDialogSettings() {
-		IDialogSettings workbenchSettings = JavaPlugin.getDefault().getDialogSettings();
-		IDialogSettings settings = workbenchSettings.getSection(TAG_DIALOG_SECTION);
-		
-		if (settings == null)
-			settings = workbenchSettings.addNewSection(TAG_DIALOG_SECTION);
-
-		return settings;
-	}
-    
-    public InterestFilter getDoiFilter() {
-        return doiFilter;
-    }
-    
-    public TableViewer getViewer() {
-        return super.getViewer();
-    } 
-     
-    protected TableSorter getSorter() {
-        if (sorter == null)
-            sorter = new TableSorter(VISIBLE_FIELDS, DEFAULT_PRIORITIES, DEFAULT_DIRECTIONS);
-        return sorter;
-    }
-
-    public void setInterestFiltering(boolean on) {
-        if (on) {
-            this.getViewer().addFilter(doiFilter);
-        } else {
-            this.getViewer().removeFilter(doiFilter);
-        }
-    }
-}
-
-class ProblemsListDoiSorter extends TableSorter { 
-
-    public ProblemsListDoiSorter(IField[] properties, int[] defaultPriorities, int[] defaultDirections) {
-        super(properties, defaultPriorities, defaultDirections);
-    } 
-
-    protected InterestComparator comparator = new InterestComparator();
-    
-    protected int compare(Object obj1, Object obj2, int depth) {
-        return super.compare(obj1, obj2, depth);
-    }
-
-    public int compare(Viewer viewer, Object e1, Object e2) {
-        return super.compare(viewer, e1, e1);
-//        if (e1 instanceof ProblemMarker && e2 instanceof ProblemMarker) {
-//            if (((ProblemMarker)e2).getSeverity() == IMarker.SEVERITY_ERROR) {
-//                return 1;
-//            }
-//            IJavaElement element1 = Util.getJavaElement((ProblemMarker)e1);
-//            IJavaElement element2 = Util.getJavaElement((ProblemMarker)e2);
-//            if (element1 != null && element2 != null) {
-//                return comparator.compare(
-//                    ContextCorePlugin.getTaskscapeManager().getActiveTaskscape().get(element1.getHandleIdentifier()),
-//                    ContextCorePlugin.getTaskscapeManager().getActiveTaskscape().get(element1.getHandleIdentifier()));
-//            }
-//        } 
-//        
-//        return comparator.compare(e1, e2);  
-    }
-}
-
-class MylarLabelProvider extends DecoratingLabelProvider implements IFontProvider, ITableLabelProvider, IColorProvider {
-
-	TableViewLabelProvider provider;
-	
-	public MylarLabelProvider(TableViewLabelProvider provider, ILabelDecorator decorator) {
-		super(provider, decorator);
-		this.provider = provider;
-	}
-
-    public Font getFont(Object element) {
-        return null;
-//        ProblemMarker marker = (ProblemMarker)element;
-//        IJavaElement javaElement = Util.getJavaElement(marker);
-//        return UiUtil.getFontForElement(javaElement);
-    }
-	
-	public Image getColumnImage(Object element, int columnIndex) {
-		return provider.getColumnImage(element, columnIndex);
-	}
-
-	public String getColumnText(Object element, int columnIndex) {
-		return provider.getColumnText(element, columnIndex);
-	}
-	
-	public Color getForeground(Object element) {
-        ProblemMarker marker = (ProblemMarker)element;
-        IJavaElement javaElement = JavaUiUtil.getJavaElement(marker);
-        if (javaElement != null) {
-            ITaskscapeNode node = ContextCorePlugin.getTaskscapeManager().getNode(javaElement.getHandleIdentifier());
-            return UiUtil.getForegroundForElement(node);
-        } else {
-            return null;
-        }        
-//		return MylarUiPlugin.getDefault().getColorMap().TEXT;
-	}
-
-	public Color getBackground(Object element) {
-        ProblemMarker marker = (ProblemMarker)element;
-        IJavaElement javaElement = JavaUiUtil.getJavaElement(marker);
-        if (javaElement != null) {
-            ITaskscapeNode node = ContextCorePlugin.getTaskscapeManager().getNode(javaElement.getHandleIdentifier());
-            return UiUtil.getBackgroundForElement(node);
-        } else {
-            return null;
-        }
-	}
-}
-
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/views/NextTaskDropDownAction.java b/org.eclipse.mylyn.ide.dev/developer/src-old/views/NextTaskDropDownAction.java
deleted file mode 100644
index 0410221..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/views/NextTaskDropDownAction.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004 - 2006 University Of British Columbia and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     University Of British Columbia - initial API and implementation
- *******************************************************************************/
-package org.eclipse.mylyn.internal.tasks.ui.actions;
-
-import java.util.List;
-
-import org.eclipse.jface.action.Action;
-import org.eclipse.jface.action.ActionContributionItem;
-import org.eclipse.mylyn.internal.tasks.ui.TaskListImages;
-import org.eclipse.mylyn.internal.tasks.ui.views.TaskActivationHistory;
-import org.eclipse.mylyn.internal.tasks.ui.views.TaskListView;
-import org.eclipse.mylyn.tasks.core.ITask;
-
-/**
- * @author Wesley Coelho
- */
-public class NextTaskDropDownAction extends TaskNavigateDropDownAction {
-	public static final String ID = "org.eclipse.mylyn.tasklist.actions.navigate.next";
-
-	public NextTaskDropDownAction(TaskListView view, TaskActivationHistory history) {
-		super(view, history);
-		setText("Next Task");
-		setToolTipText("Next Task");
-		setId(ID);
-		setEnabled(false);
-		setImageDescriptor(TaskListImages.NAVIGATE_NEXT);
-	}
-
-	protected void addActionsToMenu() {
-//		List<ITask> tasks = taskHistory.getNextTasks();
-//
-//		if (tasks.size() > MAX_ITEMS_TO_DISPLAY) {
-//			tasks = tasks.subList(0, MAX_ITEMS_TO_DISPLAY);
-//		}
-//
-//		for (int i = 0; i < tasks.size(); i++) {
-//			ITask currTask = tasks.get(i);
-//			Action taskNavAction = new TaskNavigateAction(currTask);
-//			ActionContributionItem item = new ActionContributionItem(taskNavAction);
-//			item.fill(dropDownMenu, -1);
-//		}
-	}
-
-	public void run() {
-//		if (taskHistory.hasNext()) {
-//			new TaskActivateAction().run(taskHistory.getNextTask());
-//			setButtonStatus();
-//			view.refreshAndFocus(false);
-//		}
-	}
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/views/ProblemsFieldDoi.java b/org.eclipse.mylyn.ide.dev/developer/src-old/views/ProblemsFieldDoi.java
deleted file mode 100644
index 42c986b..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/views/ProblemsFieldDoi.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004 - 2005 University Of British Columbia and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     University Of British Columbia - initial API and implementation
- *******************************************************************************/
-/*
- * Created on Jul 6, 2004
- *
- * TODO To change the template for this generated file go to
- * Window - Preferences - Java - Code Style - Code Templates
- */
-package org.eclipse.mylyn.java.ui.views;
-
-import org.eclipse.jdt.core.IJavaElement;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.ui.views.markers.internal.*;
-
-import org.eclipse.mylyn.core.MylarPlugin;
-import org.eclipse.mylyn.core.model.ITaskscapeNode;
-import org.eclipse.mylyn.java.ui.JavaUiUtil;
-
-/**
- * @author beatmik
- *
- * TODO To change the template for this generated type comment go to
- * Window - Preferences - Java - Code Style - Code Templates
- */
-public class ProblemsFieldDoi implements org.eclipse.ui.views.markers.internal.IField {
-    
-	private String description;
-	
-	public ProblemsFieldDoi() {
-		description = Messages.getString("DOI"); //$NON-NLS-1$
-	}
-
-	public String getDescription() {
-		return description;
-	}
-
-	public Image getDescriptionImage() {
-		return null;
-	}
-
-	public String getColumnHeaderText() {
-		return description;
-	}
-
-	public Image getColumnHeaderImage() {
-		return null;
-	}
-
-	public String getValue(Object obj) {
-		if (obj == null || !(obj instanceof ConcreteMarker)) {
-			return ""; //$NON-NLS-1$
-		}
-		ConcreteMarker marker = (ConcreteMarker) obj;
-		IJavaElement javaElement= JavaUiUtil.getJavaElement(marker);//SearchUtil.getJavaElement(marker);
-		if (javaElement != null) {
-            return "" + ContextCorePlugin.getTaskscapeManager().getActiveTaskscape().get(javaElement.getHandleIdentifier()).getDegreeOfInterest().getDegreeOfInterest().getValue();
-//			return marker.getResourceName();
-		} else {
-		    return "<undefined>";
-        }
-	}
-
-	public Image getImage(Object obj) {
-		return null;
-	}
-
-    // TODO: slow?
-	public int compare(Object obj1, Object obj2) {
-		if (obj1 != null && obj2 != null && obj1 instanceof ProblemMarker && obj2 instanceof ProblemMarker) {
-            ProblemMarker m1 = (ProblemMarker) obj1;
-            ProblemMarker m2 = (ProblemMarker) obj2;
-            IJavaElement j1 = JavaUiUtil.getJavaElement(m1);//SearchUtil.getJavaElement(marker);
-            IJavaElement j2 = JavaUiUtil.getJavaElement(m2);//SearchUtil.getJavaElement(marker);
-            if (j1 != null && j2 != null) {
-                ITaskscapeNode n1 = ContextCorePlugin.getTaskscapeManager().getActiveTaskscape().get(j1.getHandleIdentifier());
-                ITaskscapeNode n2 = ContextCorePlugin.getTaskscapeManager().getActiveTaskscape().get(j2.getHandleIdentifier());
-                return  (int)(n1.getDegreeOfInterest().getDegreeOfInterest().getValue() - n2.getDegreeOfInterest().getDegreeOfInterest().getValue());
-            }
-        }
-        return 0;
-	}
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/views/ProblemsFieldJavaElement.java b/org.eclipse.mylyn.ide.dev/developer/src-old/views/ProblemsFieldJavaElement.java
deleted file mode 100644
index 6908391..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/views/ProblemsFieldJavaElement.java
+++ /dev/null
@@ -1,109 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004 - 2005 University Of British Columbia and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     University Of British Columbia - initial API and implementation
- *******************************************************************************/
-/*
- * Created on Jul 6, 2004
- *
- * TODO To change the template for this generated file go to
- * Window - Preferences - Java - Code Style - Code Templates
- */
-package org.eclipse.mylyn.java.ui.views;
-
-import org.eclipse.jdt.core.*;
-import org.eclipse.jdt.internal.ui.viewsupport.JavaElementImageProvider;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.ui.views.markers.internal.ConcreteMarker;
-import org.eclipse.ui.views.markers.internal.Messages;
-
-import org.eclipse.mylyn.java.ui.JavaUiUtil;
-
-/**
- * @author beatmik
- *
- * TODO To change the template for this generated type comment go to
- * Window - Preferences - Java - Code Style - Code Templates
- */
-public class ProblemsFieldJavaElement implements org.eclipse.ui.views.markers.internal.IField {
-    
-	private String description;
-	private Image image;
-	private JavaElementImageProvider imageProvider = new JavaElementImageProvider();
-	
-	public ProblemsFieldJavaElement() {
-		description = Messages.getString("Java Element"); //$NON-NLS-1$
-	}
-
-	public String getDescription() {
-		return description;
-	}
-
-	public Image getDescriptionImage() {
-		return image;
-	}
-
-	public String getColumnHeaderText() {
-		return description;
-	}
-
-	public Image getColumnHeaderImage() {
-		return image;
-	}
-
-	public String getValue(Object obj) {
-		if (obj == null || !(obj instanceof ConcreteMarker)) {
-			return ""; //$NON-NLS-1$
-		}
-		ConcreteMarker marker = (ConcreteMarker) obj;
-		IJavaElement javaElement= JavaUiUtil.getJavaElement(marker);//SearchUtil.getJavaElement(marker);
-		if (javaElement == null) {
-			return marker.getResourceName();
-		} else {
-		    String name;
-		    if (javaElement instanceof IMember 
-		        && javaElement.getParent() != null 
-		        && !(javaElement.getParent() instanceof ICompilationUnit)) {
-		        name = javaElement.getParent().getElementName()
-		        	+ "." + javaElement.getElementName();
-		    } else { 
-		        name = javaElement.getElementName();
-		    }
-			return name;
-		}
-	}
-
-	public Image getImage(Object obj) {
-		if (obj == null || !(obj instanceof ConcreteMarker)) {
-			return null; //$NON-NLS-1$
-		}
-		ConcreteMarker marker = (ConcreteMarker) obj;
-		IJavaElement javaElement= JavaUiUtil.getJavaElement(marker);//SearchUtil.getJavaElement(marker);
-		if (javaElement == null) {
-			return null;
-		} else {
-            Image image =  imageProvider.getImageLabel(javaElement, JavaElementImageProvider.SMALL_ICONS);
-		    return image; 
-		}
-	}
-
-	public int compare(Object obj1, Object obj2) {
-		if (obj1 == null || obj2 == null || !(obj1 instanceof ConcreteMarker) || !(obj2 instanceof ConcreteMarker)) {
-			return 0;
-		}
-		
-		ConcreteMarker marker1 = (ConcreteMarker) obj1;
-		ConcreteMarker marker2 = (ConcreteMarker) obj2;
-		
-		try {
-		    return marker1.getResourceNameKey().compareTo(marker2.getResourceNameKey());
-		} catch (NoSuchMethodError e) {
-		    return 0; // TODO: will not sorting these cause any problems?
-		} 
-	}
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/views/ProblemsListFilter.java b/org.eclipse.mylyn.ide.dev/developer/src-old/views/ProblemsListFilter.java
deleted file mode 100644
index 1ae57a9..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/views/ProblemsListFilter.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004 - 2005 University Of British Columbia and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     University Of British Columbia - initial API and implementation
- *******************************************************************************/
-/*
- * Created on Apr 18, 2005
-  */
-package org.eclipse.mylyn.java.ui.views;
-
-import org.eclipse.core.resources.IMarker;
-import org.eclipse.jdt.core.IJavaElement;
-import org.eclipse.jface.viewers.Viewer;
-import org.eclipse.ui.views.markers.internal.ProblemMarker;
-
-import org.eclipse.mylyn.java.ui.JavaUiUtil;
-import org.eclipse.mylyn.ui.InterestFilter;
-
-public class ProblemsListFilter extends InterestFilter{
-
-    public boolean select(Viewer viewer, Object parent, Object element) {
-        if (element instanceof ProblemMarker) {
-            ProblemMarker problemMarker = (ProblemMarker)element;
-            if (problemMarker.getSeverity() == IMarker.SEVERITY_ERROR) {
-                return true;
-            } else {
-                IJavaElement javaElement = JavaUiUtil.getJavaElement(problemMarker);
-                return super.select(viewer, null, javaElement);
-            }
-        }
-        return false;
-    }
-    
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/views/TaskListDropTargetListener.java b/org.eclipse.mylyn.ide.dev/developer/src-old/views/TaskListDropTargetListener.java
deleted file mode 100644
index f0e8ff6..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/views/TaskListDropTargetListener.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004 - 2005 University Of British Columbia and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     University Of British Columbia - initial API and implementation
- *******************************************************************************/
-/*
- * Created on Feb 9, 2005
-  */
-package org.eclipse.mylyn.tasklist.ui.views;
-
-import org.eclipse.jface.viewers.Viewer;
-import org.eclipse.swt.dnd.DND;
-import org.eclipse.swt.dnd.DropTargetEvent;
-import org.eclipse.swt.dnd.DropTargetListener;
-import org.eclipse.swt.dnd.TextTransfer;
-import org.eclipse.swt.widgets.Composite;
-
-import org.eclipse.mylyn.tasklist.ITask;
-import org.eclipse.mylyn.tasklist.TaskListPlugin;
-
-
-final class TaskListDropTargetListener implements DropTargetListener {
-    private final Composite component;
-    private boolean addMode;
-    final Viewer viewer;
-    final TextTransfer textTransfer;
-
-    TaskListDropTargetListener(Composite component, Viewer viewer, TextTransfer textTransfer, boolean addMode) {
-        super();
-        this.component = component;
-        this.viewer = viewer;
-        this.textTransfer = textTransfer;
-        this.addMode = addMode;
-    }
-
-    public void dragEnter(DropTargetEvent event) {
-        if (event.detail == DND.DROP_DEFAULT) event.detail = DND.DROP_COPY;
-    }
-
-    public void dragLeave(DropTargetEvent event) { }
-
-    public void dragOperationChanged(DropTargetEvent event) { }
-
-    public void dragOver(DropTargetEvent event) {
-        if (textTransfer.isSupportedType(event.currentDataType)) {
-            // NOTE: on unsupported platforms this will return null
-            String t = (String) (textTransfer.nativeToJava(event.currentDataType));
-            if (t != null) { }
-        }
-    }
-
-    public void drop(DropTargetEvent event) {  
-        if (textTransfer.isSupportedType(event.currentDataType)) {
-            String text = (String) event.data;
-            int id = Integer.parseInt(text);
-            ITask task = TaskListPlugin.getTaskListManager().getTaskList().getTaskForId(id);
-            if (task == null) return;  
-            if (viewer != null && addMode && !TaskListPlugin.getTaskListManager().getTaskList().getActiveTasks().contains(task)) {
-                TaskListPlugin.getTaskListManager().activateTask(task);
-                viewer.refresh();
-            } else {
-                TaskListPlugin.getTaskListManager().deactivateTask(task);
-            }
-        } 
-    }
-
-    public void dropAccept(DropTargetEvent event) { }
-}
\ No newline at end of file
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/views/TaskListToolTipHandler.java b/org.eclipse.mylyn.ide.dev/developer/src-old/views/TaskListToolTipHandler.java
deleted file mode 100644
index 44d75d4..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/views/TaskListToolTipHandler.java
+++ /dev/null
@@ -1,569 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004, 2007 Mylyn project committers and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *******************************************************************************/
-/**
- * Copied from newsgroup, forwarded from Make Technologies
- */
-
-package org.eclipse.mylyn.internal.tasks.ui.views;
-
-import java.text.DateFormat;
-import java.text.SimpleDateFormat;
-import java.util.Calendar;
-import java.util.Date;
-
-import org.eclipse.core.runtime.IAdaptable;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.mylyn.internal.tasks.core.ScheduledTaskContainer;
-import org.eclipse.mylyn.internal.tasks.ui.ITaskListNotification;
-import org.eclipse.mylyn.internal.tasks.ui.TasksUiImages;
-import org.eclipse.mylyn.monitor.core.DateUtil;
-import org.eclipse.mylyn.tasks.core.AbstractRepositoryConnector;
-import org.eclipse.mylyn.tasks.core.AbstractRepositoryQuery;
-import org.eclipse.mylyn.tasks.core.AbstractTask;
-import org.eclipse.mylyn.tasks.core.AbstractTaskContainer;
-import org.eclipse.mylyn.tasks.core.RepositoryStatus;
-import org.eclipse.mylyn.tasks.core.TaskRepository;
-import org.eclipse.mylyn.tasks.core.AbstractTask.RepositoryTaskSyncState;
-import org.eclipse.mylyn.tasks.ui.TasksUiPlugin;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.MouseAdapter;
-import org.eclipse.swt.events.MouseEvent;
-import org.eclipse.swt.events.MouseTrackAdapter;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.graphics.Point;
-import org.eclipse.swt.graphics.Rectangle;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Monitor;
-import org.eclipse.swt.widgets.Shell;
-import org.eclipse.swt.widgets.Table;
-import org.eclipse.swt.widgets.ToolBar;
-import org.eclipse.swt.widgets.Tree;
-import org.eclipse.swt.widgets.Widget;
-import org.eclipse.ui.IWindowListener;
-import org.eclipse.ui.IWorkbenchWindow;
-import org.eclipse.ui.PlatformUI;
-
-/**
- * @author Mik Kersten
- * @author Eric Booth
- * @author Leo Dos Santos - multi-monitor support
- * @author Steffen Pingel
- */
-public class TaskListToolTipHandler {
-
-	private Shell tipShell;
-
-	private Widget tipWidget;
-
-	private AbstractTaskContainer getTaskListElement(Object hoverObject) {
-		if (hoverObject instanceof Widget) {
-			Object data = ((Widget) hoverObject).getData();
-			if (data != null) {
-				if (data instanceof AbstractTaskContainer) {
-					return (AbstractTaskContainer) data;
-				} else if (data instanceof IAdaptable) {
-					return (AbstractTaskContainer) ((IAdaptable) data).getAdapter(AbstractTaskContainer.class);
-				}
-			}
-		}
-		return null;
-	}
-
-	private String getTitleText(AbstractTaskContainer element) {
-		if (element instanceof ScheduledTaskContainer) {
-			StringBuilder sb = new StringBuilder();
-			sb.append(element.getSummary());
-			Calendar start = ((ScheduledTaskContainer) element).getStart();
-			sb.append("  [");
-			sb.append(DateFormat.getDateInstance(DateFormat.LONG).format(start.getTime()));
-			sb.append("]");
-			return sb.toString();
-		} else if (element instanceof AbstractRepositoryQuery) {
-			AbstractRepositoryQuery query = (AbstractRepositoryQuery) element;
-			StringBuilder sb = new StringBuilder();
-			sb.append(element.getSummary());
-			sb.append("  [");
-			sb.append(getRepositoryLabel(query.getRepositoryKind(), query.getRepositoryUrl()));
-			sb.append("]");
-			return sb.toString();
-		} else {
-			return element.getSummary();
-		}
-	}
-
-	private String getDetailsText(AbstractTaskContainer element, TaskListView taskListView) {
-		if (element instanceof ScheduledTaskContainer) {
-			ScheduledTaskContainer container = (ScheduledTaskContainer) element;
-			int estimateTotal = 0;
-			long elapsedTotal = 0;
-			if (taskListView != null) {
-				Object[] children = ((TaskListContentProvider)taskListView.getViewer().getContentProvider()).getChildren(element);
-				for (Object object : children) {
-					if (object instanceof AbstractTask) {
-						estimateTotal += ((AbstractTask) object).getEstimateTimeHours();
-						elapsedTotal += TasksUiPlugin.getTaskActivityManager().getElapsedTime((AbstractTask) object,
-								container.getStart(), container.getEnd());
-					}
-				}
-			}
-
-			StringBuilder sb = new StringBuilder();
-			sb.append("Estimate: ");
-			sb.append(estimateTotal);
-			sb.append(" hours");
-			sb.append("\n");
-			sb.append("Elapsed: ");
-			sb.append(DateUtil.getFormattedDurationShort(elapsedTotal));
-			sb.append("\n");
-			return sb.toString();
-		} else if (element instanceof AbstractTask) {
-			AbstractTask task = (AbstractTask) element;
-			StringBuilder sb = new StringBuilder();
-			sb.append(TasksUiPlugin.getConnectorUi(task.getConnectorKind()).getTaskKindLabel(task));
-			String key = task.getTaskKey();
-			if (key != null) {
-				sb.append(" ");
-				sb.append(key);
-			}
-			sb.append(", ");
-			sb.append(task.getPriority());
-			sb.append("  [");
-			sb.append(getRepositoryLabel(task.getConnectorKind(), task.getRepositoryUrl()));
-			sb.append("]");
-			sb.append("\n");
-			return sb.toString();
-		} else {
-			return null;
-		}
-	}
-
-	private String getRepositoryLabel(String repositoryKind, String repositoryUrl) {
-		TaskRepository repository = TasksUiPlugin.getRepositoryManager().getRepository(repositoryKind, repositoryUrl);
-		if (repository != null) {
-			String label = repository.getRepositoryLabel();
-			if (label.indexOf("//") != -1) {
-				return label.substring((repository.getUrl().indexOf("//") + 2));
-			}
-			return label + "";
-		}
-		return "";
-	}
-
-	private String getActivityText(AbstractTaskContainer element) {
-//		if (element instanceof ScheduledTaskDelegate) {
-//			ScheduledTaskDelegate task = (ScheduledTaskDelegate) element;
-//
-//			StringBuilder sb = new StringBuilder();
-//			Date date = task.getScheduledForDate();
-//			if (date != null) {
-//				sb.append("Scheduled for: ");
-//				sb.append(new SimpleDateFormat("E").format(date)).append(", ");
-//				sb.append(DateFormat.getDateInstance(DateFormat.LONG).format(date));
-//				sb.append(" (").append(DateFormat.getTimeInstance(DateFormat.SHORT).format(date)).append(")\n");
-//			}
-//
-//			long elapsed = TasksUiPlugin.getTaskActivityManager().getElapsedTime(task.getCorrespondingTask(),
-//					task.getDateRangeContainer().getStart(), task.getDateRangeContainer().getEnd());
-//			String elapsedTimeString = DateUtil.getFormattedDurationShort(elapsed);
-//			sb.append("Elapsed: ");
-//			sb.append(elapsedTimeString);
-//			sb.append("\n");
-//
-//			return sb.toString();
-//		} else 
-//			
-		if (element instanceof AbstractTask) {
-			AbstractTask task = (AbstractTask) element;
-
-			StringBuilder sb = new StringBuilder();
-			Date date = task.getScheduledForDate();
-			if (date != null) {
-				sb.append("Scheduled for: ");
-				sb.append(new SimpleDateFormat("E").format(date)).append(", ");
-				sb.append(DateFormat.getDateInstance(DateFormat.LONG).format(date));
-				sb.append(" (").append(DateFormat.getTimeInstance(DateFormat.SHORT).format(date)).append(")\n");
-			}
-
-			long elapsed = TasksUiPlugin.getTaskActivityManager().getElapsedTime(task);
-			String elapsedTimeString = DateUtil.getFormattedDurationShort(elapsed);
-			sb.append("Elapsed: ");
-			sb.append(elapsedTimeString);
-			sb.append("\n");
-
-			return sb.toString();
-		}
-		return null;
-	}
-
-	private String getIncommingText(AbstractTaskContainer element) {
-		if (element instanceof AbstractTask) {
-			AbstractTask task = (AbstractTask) element;
-			if (task.getSynchronizationState() == RepositoryTaskSyncState.INCOMING) {
-				AbstractRepositoryConnector connector = TasksUiPlugin.getRepositoryManager().getRepositoryConnector(
-						task);
-				if (connector != null) {
-					ITaskListNotification notification = TasksUiPlugin.getDefault().getIncommingNotification(connector,
-							task);
-					if (notification != null) {
-						String res = null;
-						if (notification.getDescription() != null) {
-							String descriptionText = notification.getDescription();
-							if (descriptionText != null && descriptionText.length() > 0) {
-								res = descriptionText;
-							}
-						}
-						if (notification.getDetails() != null) {
-							String details = notification.getDetails();
-							if (details != null && details.length() > 0) {
-								res = res == null ? details : res + "\n" + details;
-							}
-						}
-						return res;
-					}
-				}
-			}
-		}
-		return null;
-	}
-
-	private String getStatusText(AbstractTaskContainer element) {
-		IStatus status = null;
-		if (element instanceof AbstractTask) {
-			AbstractTask task = (AbstractTask) element;
-			status = task.getSynchronizationStatus();
-		} else if (element instanceof AbstractRepositoryQuery) {
-			AbstractRepositoryQuery query = (AbstractRepositoryQuery) element;
-			status = query.getSynchronizationStatus();
-		}
-
-		if (status != null) {
-			StringBuilder sb = new StringBuilder();
-			sb.append(status.getMessage());
-			if (status instanceof RepositoryStatus && ((RepositoryStatus) status).isHtmlMessage()) {
-				sb.append(" Please synchronize manually for full error message.");
-			}
-			return sb.toString();
-		}
-
-		return null;
-	}
-
-	private ProgressData getProgressData(AbstractTaskContainer element, TaskListView taskListView) {
-		if (element instanceof AbstractTask) {
-			return null;
-		}
-		Object[] children = new Object[0];
-
-		if (element instanceof ScheduledTaskContainer && taskListView != null) {
-			children = ((TaskListContentProvider)taskListView.getViewer().getContentProvider()).getChildren(element);
-		} else {
-			children = element.getChildren().toArray();
-		}
-
-		int total = children.length;
-		int completed = 0;
-		for (AbstractTask task : element.getChildren()) {
-			if (task.isCompleted()) {
-				completed++;
-			}
-		}
-
-		String text = "Total: " + total + " (Complete: " + completed + ", Incomplete: " + (total - completed) + ")";
-		return new ProgressData(completed, total, text);
-	}
-
-	private Image getImage(AbstractTaskContainer element) {
-		if (element instanceof AbstractRepositoryQuery) {
-			AbstractRepositoryQuery query = (AbstractRepositoryQuery) element;
-			AbstractRepositoryConnector connector = TasksUiPlugin.getRepositoryManager().getRepositoryConnector(
-					query.getRepositoryKind());
-			if (connector != null) {
-				return TasksUiPlugin.getDefault().getBrandingIcon(connector.getConnectorKind());
-			}
-		} else if (element instanceof AbstractTask) {
-			AbstractTask repositoryTask = (AbstractTask) element;
-			AbstractRepositoryConnector connector = TasksUiPlugin.getRepositoryManager().getRepositoryConnector(
-					repositoryTask.getConnectorKind());
-			if (connector != null) {
-				return TasksUiPlugin.getDefault().getBrandingIcon(connector.getConnectorKind());
-			}
-		} else if (element instanceof ScheduledTaskContainer) {
-			return TasksUiImages.getImage(TasksUiImages.CALENDAR);
-		}
-		return null;
-	}
-
-	/**
-	 * Enables customized hover help for a specified control
-	 * 
-	 * @control the control on which to enable hoverhelp
-	 */
-	public void activateHoverHelp(final Control control) {
-		// hide tooltip if any window is deactivated 
-		PlatformUI.getWorkbench().addWindowListener(new IWindowListener() {
-
-			public void windowActivated(IWorkbenchWindow window) {
-			}
-
-			public void windowClosed(IWorkbenchWindow window) {
-			}
-
-			public void windowDeactivated(IWorkbenchWindow window) {
-				hideTooltip();
-			}
-
-			public void windowOpened(IWorkbenchWindow window) {
-			}
-		});
-
-		// hide tooltip if control underneath is activated 
-		control.addMouseListener(new MouseAdapter() {
-
-			@Override
-			public void mouseDown(MouseEvent e) {
-				hideTooltip();
-			}
-		});
-
-		// trap hover events to pop-up tooltip
-		control.addMouseTrackListener(new MouseTrackAdapter() {
-
-			@Override
-			public void mouseExit(MouseEvent e) {
-				// TODO can these conditions be simplified? see bug 131776
-				if (tipShell != null && !tipShell.isDisposed() && tipShell.getDisplay() != null
-						&& !tipShell.getDisplay().isDisposed() && tipShell.isVisible()) {
-					tipShell.setVisible(false);
-				}
-				tipWidget = null;
-			}
-
-			@Override
-			public void mouseHover(MouseEvent event) {
-				Point widgetPosition = new Point(event.x, event.y);
-				Widget widget = event.widget;
-				if (widget instanceof ToolBar) {
-					ToolBar w = (ToolBar) widget;
-					widget = w.getItem(widgetPosition);
-				}
-				if (widget instanceof Table) {
-					Table w = (Table) widget;
-					widget = w.getItem(widgetPosition);
-				}
-				if (widget instanceof Tree) {
-					Tree w = (Tree) widget;
-					widget = w.getItem(widgetPosition);
-				}
-
-				if (widget == null) {
-					hideTooltip();
-					tipWidget = null;
-					return;
-				}
-
-				if (widget == tipWidget) {
-					// already displaying tooltip
-					return;
-				}
-
-				tipWidget = widget;
-				
-				TaskListView taskListView = TaskListView.getFromActivePerspective();
-				
-				showTooltip(control.toDisplay(widgetPosition), taskListView);
-			}
-
-		});
-	}
-
-	/**
-	 * Sets the location for a hovering shell
-	 * 
-	 * @param shell
-	 *            the object that is to hover
-	 * @param position
-	 *            the position of a widget to hover over
-	 * @return the top-left location for a hovering box
-	 */
-	private void setHoverLocation(Shell shell, Point position) {
-		Rectangle displayBounds = shell.getMonitor().getClientArea();
-		Rectangle shellBounds = shell.getBounds();
-
-		// We need to find the exact monitor we're mousing over
-		// https://bugs.eclipse.org/bugs/show_bug.cgi?id=166990
-		Monitor[] array = PlatformUI.getWorkbench().getDisplay().getMonitors();
-		for (Monitor m : array) {
-			Rectangle monitorBounds = m.getBounds();
-			if ((position.x >= monitorBounds.x) && (position.x < (monitorBounds.x + monitorBounds.width))
-					&& (position.y >= monitorBounds.y) && (position.y < (monitorBounds.y + monitorBounds.height))) {
-				displayBounds = m.getClientArea();
-			}
-		}
-
-		if ((position.x + shellBounds.width) > (displayBounds.x + displayBounds.width))
-			shellBounds.x = displayBounds.x + displayBounds.width - shellBounds.width;
-		else
-			shellBounds.x = position.x;
-
-		if ((position.y + 10 + shellBounds.height) > (displayBounds.y + displayBounds.height))
-			shellBounds.y = displayBounds.y + displayBounds.height - shellBounds.height;
-		else
-			shellBounds.y = position.y + 10;
-
-		shell.setBounds(shellBounds);
-	}
-
-	private void hideTooltip() {
-		if (tipShell != null && !tipShell.isDisposed() && tipShell.isVisible()) {
-			tipShell.setVisible(false);
-		}
-	}
-
-	private void showTooltip(Point location, TaskListView taskListView) {
-		hideTooltip();
-
-		AbstractTaskContainer element = getTaskListElement(tipWidget);
-		if (element == null) {
-			return;
-		}
-
-		Shell parent = PlatformUI.getWorkbench().getDisplay().getActiveShell();
-		if (parent == null) {
-			return;
-		}
-
-		// dispose old tooltip
-		if (tipShell != null && !tipShell.isDisposed() && tipShell.getShell() != null) {
-			tipShell.close();
-		}
-
-		tipShell = new Shell(parent.getDisplay(), SWT.TOOL | SWT.NO_FOCUS | SWT.MODELESS | SWT.ON_TOP);
-		GridLayout gridLayout = new GridLayout();
-		gridLayout.numColumns = 2;
-		gridLayout.marginWidth = 5;
-		gridLayout.marginHeight = 2;
-		tipShell.setLayout(gridLayout);
-		tipShell.setBackground(tipShell.getDisplay().getSystemColor(SWT.COLOR_INFO_BACKGROUND));
-
-		addIconAndLabel(tipShell, getImage(element), getTitleText(element));
-
-		String detailsText = getDetailsText(element, taskListView);
-		if (detailsText != null) {
-			addIconAndLabel(tipShell, null, detailsText);
-		}
-
-		String synchText = getSynchText(element);
-		if (synchText != null) {
-			addIconAndLabel(tipShell, TasksUiImages.getImage(TasksUiImages.REPOSITORY_SYNCHRONIZE), synchText);
-		}
-
-		String activityText = getActivityText(element);
-		if (activityText != null) {
-			addIconAndLabel(tipShell, TasksUiImages.getImage(TasksUiImages.CALENDAR), activityText);
-		}
-
-		String incommingText = getIncommingText(element);
-		if (incommingText != null) {
-			addIconAndLabel(tipShell, TasksUiImages.getImage(TasksUiImages.OVERLAY_INCOMMING), incommingText);
-		}
-
-		ProgressData progress = getProgressData(element, taskListView);
-		if (progress != null) {
-			addIconAndLabel(tipShell, null, progress.text);
-
-			// label height need to be set to 0 to remove gap below the progress bar 
-			Label label = new Label(tipShell, SWT.NONE);
-			GridData labelGridData = new GridData(SWT.FILL, SWT.TOP, true, false);
-			labelGridData.heightHint = 0;
-			label.setLayoutData(labelGridData);
-
-			Composite progressComposite = new Composite(tipShell, SWT.NONE);
-			GridLayout progressLayout = new GridLayout(1, false);
-			progressLayout.marginWidth = 0;
-			progressLayout.marginHeight = 0;
-			progressComposite.setLayout(progressLayout);
-			progressComposite.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
-
-			WorkweekProgressBar taskProgressBar = new WorkweekProgressBar(progressComposite);
-			taskProgressBar.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
-			taskProgressBar.reset(progress.completed, progress.total);
-
-			// do we really need custom canvas? code below renders the same
-//			IThemeManager themeManager = PlatformUI.getWorkbench().getThemeManager();
-//			Color color = themeManager.getCurrentTheme().getColorRegistry().get(
-//					TaskListColorsAndFonts.THEME_COLOR_TASK_TODAY_COMPLETED);
-//			ProgressBar bar = new ProgressBar(tipShell, SWT.SMOOTH);
-//			bar.setForeground(color);
-//			bar.setSelection((int) (100d * progress.completed / progress.total));
-//			GridData gridData = new GridData(SWT.FILL, SWT.TOP, true, false);
-//			gridData.heightHint = 5;
-//			bar.setLayoutData(gridData);
-		}
-
-		String statusText = getStatusText(element);
-		if (statusText != null) {
-			addIconAndLabel(tipShell, TasksUiImages.getImage(TasksUiImages.WARNING), statusText);
-		}
-
-		tipShell.pack();
-		setHoverLocation(tipShell, location);
-		tipShell.setVisible(true);
-	}
-
-	private String getSynchText(AbstractTaskContainer element) {
-		if (element instanceof AbstractRepositoryQuery) {
-			String syncStamp = ((AbstractRepositoryQuery) element).getLastSynchronizedTimeStamp();
-			if (syncStamp != null) {
-				return "Synchronized: " + syncStamp;
-			}
-		}
-		return null;
-	}
-
-	private String removeTrailingNewline(String text) {
-		if (text.endsWith("\n")) {
-			return text.substring(0, text.length() - 1);
-		}
-		return text;
-	}
-
-	private void addIconAndLabel(Composite parent, Image image, String text) {
-		Label imageLabel = new Label(parent, SWT.NONE);
-		imageLabel.setForeground(parent.getDisplay().getSystemColor(SWT.COLOR_INFO_FOREGROUND));
-		imageLabel.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_INFO_BACKGROUND));
-		imageLabel.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING | GridData.VERTICAL_ALIGN_BEGINNING));
-		imageLabel.setImage(image);
-
-		Label textLabel = new Label(parent, SWT.NONE);
-		textLabel.setForeground(parent.getDisplay().getSystemColor(SWT.COLOR_INFO_FOREGROUND));
-		textLabel.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_INFO_BACKGROUND));
-		textLabel.setLayoutData(new GridData(GridData.FILL_HORIZONTAL | GridData.VERTICAL_ALIGN_CENTER));
-		textLabel.setText(removeTrailingNewline(text));
-	}
-
-	private static class ProgressData {
-
-		int completed;
-
-		int total;
-
-		String text;
-
-		public ProgressData(int completed, int total, String text) {
-			this.completed = completed;
-			this.total = total;
-			this.text = text;
-		}
-
-	}
-
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/views/ToggleAutoManagerExplorerAction.java b/org.eclipse.mylyn.ide.dev/developer/src-old/views/ToggleAutoManagerExplorerAction.java
deleted file mode 100644
index 3717f25..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/views/ToggleAutoManagerExplorerAction.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004 - 2005 University Of British Columbia and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     University Of British Columbia - initial API and implementation
- *******************************************************************************/
-/*
- * Created on Jul 27, 2004
-  */
-package org.eclipse.mylyn.java.ui.actions;
-
-import org.eclipse.jface.action.Action;
-
-import org.eclipse.mylyn.core.MylarPlugin;
-import org.eclipse.mylyn.java.ui.views.MylarPackageExplorer;
-import org.eclipse.mylyn.tasklist.MylarImages;
- 
-/**
- * @author Mik Kersten
- */
-public class ToggleAutoManagerExplorerAction extends Action {
-	
-    public static final String PREF_ID = "org.eclipse.mylyn.ui.explorer.manage.isChecked";
-    
-    private MylarPackageExplorer explorer;
-    
-	public ToggleAutoManagerExplorerAction(MylarPackageExplorer explorer) {
-		super();
-        this.explorer = explorer;
-		setText("DoI tree management"); //$NON-NLS-1$
-		setImageDescriptor(MylarImages.AUTO_EXPAND);	
-		setToolTipText("Degree of interest tree management"); 
-		
-		boolean checked= ContextCore.getPreferenceStore().getBoolean(PREF_ID); 
-		valueChanged(checked, false);
-	}
-	
-	public void run() {
-		valueChanged(isChecked(), true);
-	}
-	
-	private void valueChanged(final boolean on, boolean store) {
-		setChecked(on);
-		if (store) ContextCore.getPreferenceStore().setValue(PREF_ID, on); //$NON-NLS-1$
-		autoExpand(on);
-//        MonitorPlugin.log(this, getText() + " set to: " + on);
-	}
-	
-	public void autoExpand(boolean on) {
-	    explorer.getDoiFilter().setFilterUninterestingEnabled(on);
-        explorer.setAutoExpandModeEnabled(on);
-        explorer.getTreeViewer().refresh();
-        if (on) explorer.getTreeViewer().expandAll();
-	} 
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/views/ToggleAutoManagerProblemsAction.java b/org.eclipse.mylyn.ide.dev/developer/src-old/views/ToggleAutoManagerProblemsAction.java
deleted file mode 100644
index dff696a..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/views/ToggleAutoManagerProblemsAction.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004 - 2005 University Of British Columbia and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     University Of British Columbia - initial API and implementation
- *******************************************************************************/
-/*
- * Created on Jul 27, 2004
-  */
-package org.eclipse.mylyn.java.ui.actions;
-
-import org.eclipse.jface.action.Action;
-
-import org.eclipse.mylyn.core.MylarPlugin;
-import org.eclipse.mylyn.java.ui.views.MylarProblemView;
-import org.eclipse.mylyn.ui.MylarImages;
-
-/**
- * @author Mik Kersten
- */
-public class ToggleAutoManagerProblemsAction extends Action {
-    
-    public static final String PREF_ID = "org.eclipse.mylyn.ui.problems.manage.isChecked";
-    
-    private MylarProblemView problemsView;
-    
-    public ToggleAutoManagerProblemsAction(MylarProblemView problemsView) {
-        super();
-        this.problemsView = problemsView;
-        setText("DoI list management"); //$NON-NLS-1$
-        setImageDescriptor(MylarImages.AUTO_EXPAND);    
-        setToolTipText("Degree of interest list management"); 
-        
-        boolean checked= ContextCore.getPreferenceStore().getBoolean(PREF_ID); 
-        valueChanged(checked, false);
-    } 
-    
-    public void run() {
-        valueChanged(isChecked(), true);
-    }
-    
-    private void valueChanged(final boolean on, boolean store) {
-        setChecked(on);
-        if (store) ContextCore.getPreferenceStore().setValue(PREF_ID, on); //$NON-NLS-1$
-        autoExpand(on);
-//        MonitorPlugin.log(this, getText() + " set to: " + on);
-    }
-    
-    public void autoExpand(boolean on) {
-        problemsView.setInterestFiltering(on);//  .setFilterUninterestingEnabled(on);
-        problemsView.getViewer().refresh(); 
-//        problemsView.getViewer().getSorter().sort(problemsView.getViewer(), problemsView.getViewer().getTable().getItems());
-//        MylarPackageExplorer.getDefault().setAutoExpandModeEnabled(on);
-//        MylarPackageExplorer.getDefault().getTreeViewer().refresh();
-//        if (on) MylarPackageExplorer.getDefault().expandAllInteresting();
-    }
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/views/ToggleFilterDeclarationsAction.java b/org.eclipse.mylyn.ide.dev/developer/src-old/views/ToggleFilterDeclarationsAction.java
deleted file mode 100644
index 2c7c3b0..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/views/ToggleFilterDeclarationsAction.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004 - 2005 University Of British Columbia and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     University Of British Columbia - initial API and implementation
- *******************************************************************************/
-/*
- * Created on Jul 27, 2004
-  */
-package org.eclipse.mylyn.java.ui.actions;
-
-import org.eclipse.jface.action.Action;
-
-import org.eclipse.mylyn.core.MylarPlugin;
-import org.eclipse.mylyn.java.ui.views.MylarPackageExplorer;
-import org.eclipse.mylyn.tasklist.MylarImages;
-
-/**
- * @author Mik Kersten
- */
-public class ToggleFilterDeclarationsAction extends Action {
-    
-    public static final String PREF_ID = "org.eclipse.mylyn.ui.explorer.filter.declarations.isChecked";
-    
-    private MylarPackageExplorer explorer;
-    
-    public ToggleFilterDeclarationsAction(MylarPackageExplorer explorer) {
-        super();
-        this.explorer = explorer;
-        setText("Filter declarations"); 
-        setImageDescriptor(MylarImages.FILTER_DECLARATIONS);    
-        setToolTipText("Filter declarations from tree"); 
-        
-        boolean checked= ContextCore.getPreferenceStore().getBoolean(PREF_ID); 
-        valueChanged(checked, false);
-    }
-    
-    public void run() {
-        valueChanged(isChecked(), true);
-    }
-    
-    private void valueChanged(final boolean on, boolean store) {
-        setChecked(on);
-        if (store) ContextCore.getPreferenceStore().setValue(PREF_ID, on); //$NON-NLS-1$
-        filter(on);
-//        MonitorPlugin.log(this, getText() + " set to: " + on);
-    }
-    
-    public void filter(boolean on) {
-        if (explorer != null) {
-            explorer.getDoiFilter().setFilterDeclarationsEnabled(on);
-            explorer.getTreeViewer().refresh();
-            explorer.getLabelProvider().setFilterDeclarationsEnabled(on);
-            
-            if (explorer.isAutoExpandModeEnabled()) {
-                explorer.expandAllInteresting();
-            }
-        }
-    }
-}
\ No newline at end of file
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/views/UsageStatisticsView.java b/org.eclipse.mylyn.ide.dev/developer/src-old/views/UsageStatisticsView.java
deleted file mode 100644
index e09fe34..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/views/UsageStatisticsView.java
+++ /dev/null
@@ -1,123 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004 - 2005 University Of British Columbia and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     University Of British Columbia - initial API and implementation
- *******************************************************************************/
-/*
- * Created on Jul 26, 2004
-  */
-package org.eclipse.mylyn.monitor.views;
-
-import org.eclipse.jface.viewers.*;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.ui.ISharedImages;
-import org.eclipse.ui.PlatformUI;
-
-import org.eclipse.mylyn.core.MylarPlugin;
-import org.eclipse.mylyn.monitor.MonitorPlugin;
-import org.eclipse.mylyn.monitor.stats.UsageStatistic;
-
-/**
- * @author Mik Kersten
- */
-public class UsageStatisticsView extends MylarMonitorView {
-    
-    private static UsageStatisticsView INSTANCE = null;
-    
-    public UsageStatisticsView() {
-        super(new UsageViewLabelProvider(), new ViewerSorter());
-        INSTANCE = this;
-    }
-    
-    public void createPartControl(Composite parent) {
-        super.createPartControl(parent);
-    }
-    
-    protected Object[] refreshView(Object parent) {
-		if (MonitorPlugin.getStatisticsManager() == null) {
-			return new String[] { "No Statistics" };  
-		} else { 
-		    try {
-		        String summary = MonitorPlugin.getStatisticsManager().getGlobalMergedSession().getSummary();
-				super.setContentDescription(summary); 
-                return MonitorPlugin.getStatisticsManager().getGlobalMergedSession().getStatistics().toArray();
-			} catch (Throwable t) { 
-			    ContextCorePlugin.fail(t, "Failed to show usage data", false);
-                return new String[] { 
-                        "Absent or incompatible usage data: " + t.getMessage(), 
-                        "Consider resetting usage file." };
-			} 
-		}
-    } 
-
-    static class UsageViewLabelProvider extends LabelProvider implements ITableLabelProvider {
-		public String getColumnText(Object object, int index) {
-		        return getText(object);
-		} 
-		public Image getColumnImage(Object obj, int index) {
-			return getImage(obj);
-		}
-
-		public Image getImage(Object object) {
-		    if (object instanceof UsageStatistic) {
-		        String handle = ((UsageStatistic)object).getHandle();
-//		        if (handle.equals(UsageSession.NUM_KEYSTROKES_JAVA_EDITOR)) {
-//		            return MylarImages.getImage(MylarImages.USAGE_KEYSTROKES);
-//		        } else if (handle.equals(UsageSession.NUM_SECONDS_ELAPSED)) {
-//		            return MylarImages.getImage(MylarImages.TIME);
-//		        } else if (handle.equals(UsageSession.NUM_SELECTIONS_PATHFINDER)) {
-//		            return MylarImages.getImage(MylarImages.PATHFINDER);
-//		        } else if (handle.equals(UsageSession.NUM_SELECTIONS_JAVA_EDITOR)) {
-//		            return MylarImages.getImage(MylarImages.USAGE_SELECTIONS_EDITOR);
-//		        } else if (handle.equals(UsageSession.NUM_SELECTIONS_JAVA_EDITOR_AUTOFOLD)) {
-//		            return MylarImages.getImage(MylarImages.USAGE_SELECTIONS_EDITOR);
-//		        } else if (handle.equals(UsageSession.NUM_SELECTIONS_JAVA_OUTLINE)) {
-//		            return MylarImages.getImage(MylarImages.OUTLINE);
-//		        } else if (handle.equals(UsageSession.NUM_SELECTIONS_JAVA_OUTLINE_MYLAR)) {
-//		            return MylarImages.getImage(MylarImages.OUTLINE_MYLAR);
-//		        } else if (handle.equals(UsageSession.NUM_SELECTIONS_OTHER)) {
-//		            return MylarImages.getImage(MylarImages.USAGE_UNKNOWN);
-//		        } else if (handle.equals(UsageSession.NUM_SELECTIONS_PKG_EXPLORER)) {
-//		            return MylarImages.getImage(MylarImages.PACKAGE_EXPLORER);
-//		        } else if (handle.equals(UsageSession.NUM_SELECTIONS_PKG_EXPLORER_MYLAR)) {
-//		            return MylarImages.getImage(MylarImages.PACKAGE_EXPLORER_MYLAR);
-//		        } else if (handle.equals(UsageSession.NUM_SELECTIONS_PROBLEMS)) {
-//		            return MylarImages.getImage(MylarImages.PROBLEMS);
-//		        } else if (handle.equals(UsageSession.NUM_SELECTIONS_PROBLEMS_MYLAR)) {
-//		            return MylarImages.getImage(MylarImages.PROBLEMS_MYLAR);
-//		        } else if (handle.equals(UsageSession.NUM_SELECTIONS_SEARCH)) {
-//		            return MylarImages.getImage(MylarImages.SEARCH);
-//		        } else if (handle.equals(UsageSession.NUM_SELECTIONS_SEARCH_MYLAR)) {
-//		            return MylarImages.getImage(MylarImages.SEARCH_MYLAR);
-//		        } else if (handle.equals(UsageSession.START_DATE)) {
-//		            return MylarImages.getImage(MylarImages.TIME);
-//		        } else if (handle.equals(UsageSession.START_TIME)) {
-//		            return MylarImages.getImage(MylarImages.TIME);
-//		        } 
-		    }  
-		    return PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_OBJ_ELEMENT);
-		}
-	}
- 
-    protected void resetUnderlyingModel() {
-        if(!MonitorPlugin.getStatisticsManager().clearUsageDataAndStore()) {
-            ContextCorePlugin.fail(null, "Could not delete usage file", true);
-        }
-    }
-    public static UsageStatisticsView getDefault() {
-        return INSTANCE;
-    }
-
-    /**
-     * @return
-     */
-    public TableViewer getViewer() {
-        return viewer;
-    }
-}
diff --git a/org.eclipse.mylyn.ide.dev/developer/src-old/views/pugin-scraps.xml b/org.eclipse.mylyn.ide.dev/developer/src-old/views/pugin-scraps.xml
deleted file mode 100644
index e403243..0000000
--- a/org.eclipse.mylyn.ide.dev/developer/src-old/views/pugin-scraps.xml
+++ /dev/null
@@ -1,361 +0,0 @@
-
-
-      	<action
-             class="org.eclipse.mylyn.ui.actions.ToggleGlobalFilteringActionDelegate"
-             definitionId="org.eclipse.mylyn.ui.interest.filter.global2"
-             disabledIcon="icons/elcl16/auto-expand.gif"
-             icon="icons/elcl16/auto-expand.gif"
-             id="org.eclipse.mylyn.ui.interest.filter.global.action"
-             label="Toggle Mylar global filtering"
-             retarget="false"
-             style="toggle"
-             toolbarPath="org.eclipse.ui.edit.text.actionSet.presentation/Presentation"
-             tooltip="Toggle Mylar global filtering">
-         </action>
-         -->
-        <!--
-         <action 
-            label="Mylar interest filtering"
-         	style="toggle" 
-         	state="true"
-         	id="org.eclipse.mylyn.ui.actions.ToggleGlobalFilteringAction" 
-         	class="org.eclipse.mylyn.ui.actions.ToggleGlobalFilteringAction" 
-         	definitionId="org.eclipse.mylyn.ui.actions.ToggleGlobalFilteringAction" 
-         	hoverIcon="icons/elcl16/auto-expand.gif"
-         	disabledIcon="icons/elcl16/auto-expand.gif" 
-         	icon="icons/elcl16/auto-expand.gif" 
-         	tooltip="Toggle Mylar global filtering" />
-
-
-   <extension
-         id="org.eclipse.mylyn.reports.views.UsageCountView"
-         name="Simple Usage Count"
-         point="org.eclipse.ui.views">
-      <view
-            category="org.eclipse.mylyn.ui"
-            class="org.eclipse.mylyn.monitor.reports.ui.views.UsageCountView"
-            icon="icons/eview16/monitor.gif"
-            id="org.eclipse.mylyn.monitor.reports.ui.UsageCountView"
-            name="Usage Statistics"/>
-   </extension>
-
-  <extension point="org.eclipse.ui.actionSets">
-  	<actionSet 
-  		label="Mylar" 
-  		visible="true" 
-  		id="ca.ubc.mylar.ui.actions">
-      <action
-            toolbarPath="additions"
-            label="Mylar"
-            class="ca.ubc.mylar.EnableMylarMonitoringAction"
-            tooltip="Enable Mylar monitoring"
-            style="toggle"
-            state="false"
-            id="ca.ubc.mylar.EnableMylarMonitoringAction"/>
-  	</actionSet>
-  </extension>
-
-	  <view name="Interesting Problems" 
-	  	icon="icons/eview16/problems-mylar.gif" 
-	  	category="ca.ubc.mylar" 
-	  	class="ca.ubc.mylar.java.ui.views.MylarProblemView" 
-	  	id="ca.ubc.mylar.java.ui.views.MylarProblemView"> 
-	  </view>
-
-  	  <view name="Package Explorer" 
-	    icon="icons/eview16/package-explorer-mylar.gif" 
-	    category="ca.ubc.mylar" 
-	    class="ca.ubc.mylar.java.ui.views.MylarPackageExplorer" 
-	    id="ca.ubc.mylar.java.ui.views.MylarPackageExplorer" />
-	    
-	    <!-- ** STANDARD PACKAGE EXPLORER FILTERS ********************************************* -->
-      <filter
-            targetId="ca.ubc.mylar.java.ui.views.MylarPackageExplorer"
-            name="%HideSystemFiles.label"
-            enabled="true"
-            description="%HideSystemFiles.description"
-            pattern=".*">
-      </filter>
-      <filter
-            targetId="ca.ubc.mylar.java.ui.views.MylarPackageExplorer"
-            name="%HideInnerClassFiles.label"
-            enabled="true"
-            description="%HideInnerClassFiles.description"
-            pattern="*$*.class">
-      </filter> 
-      <filter
-            targetId="ca.ubc.mylar.java.ui.views.MylarPackageExplorer"
-            name="%HideEmptyPackages.label"
-            enabled="false"
-            description="%HideEmptyPackages.description"
-            class="org.eclipse.jdt.internal.ui.filters.EmptyPackageFilter"
-            id="ca.ubc.mylar.java.ui.views.PackageExplorer.EmptyPackageFilter">
-      </filter>    
-      <filter
-            targetId="ca.ubc.mylar.java.ui.views.MylarPackageExplorer"
-            name="%HideEmptyInnerPackages.label"
-            enabled="true"
-            description="%HideEmptyInnerPackages.description"
-            class="org.eclipse.jdt.internal.ui.filters.EmptyInnerPackageFilter"
-            id="ca.ubc.mylar.java.ui.views.MylarPackageExplorer.EmptyInnerPackageFilter">
-      </filter>
-      <filter
-            targetId="ca.ubc.mylar.java.ui.views.MylarPackageExplorer"
-            name="%HideNonJavaElements.label"
-            enabled="false"
-            description="%HideNonJavaElements.description"
-            class="org.eclipse.jdt.internal.ui.filters.NonJavaElementFilter"
-            id="ca.ubc.mylar.java.ui.views.MylarPackageExplorer.NonJavaElementFilter">
-      </filter>
-      <filter
-            targetId="ca.ubc.mylar.java.ui.views.MylarPackageExplorer"
-            name="%HideReferencedLibraries.label"
-            enabled="false"
-            description="%HideReferencedLibraries.description"
-            class="org.eclipse.jdt.internal.ui.filters.LibraryFilter"
-            id="ca.ubc.mylar.java.ui.views.MylarPackageExplorer.LibraryFilter">
-      </filter>
-      <filter
-            targetId="ca.ubc.mylar.java.ui.views.MylarPackageExplorer"
-            name="%HideJavaFiles.label"
-            enabled="false"
-            description="%HideJavaFiles.description"
-            class="org.eclipse.jdt.internal.ui.filters.JavaFileFilter"
-            id="ca.ubc.mylar.java.ui.views.MylarPackageExplorer.CuAndClassFileFilter">
-      </filter>
-      <filter
-            targetId="ca.ubc.mylar.java.ui.views.MylarPackageExplorer"
-            name="%HidePackageDeclaration.label"
-            enabled="true"
-            description="%HidePackageDeclaration.description"
-            class="org.eclipse.jdt.internal.ui.filters.PackageDeclarationFilter"
-            id="ca.ubc.mylar.java.ui.views.MylarPackageExplorer.PackageDeclarationFilter">
-      </filter>
-      <filter
-            targetId="ca.ubc.mylar.java.ui.views.MylarPackageExplorer"
-            name="%HideImportDeclaration.label"
-            enabled="true"
-            description="%HideImportDeclaration.description"
-            class="org.eclipse.jdt.internal.ui.filters.ImportDeclarationFilter"
-            id="ca.ubc.mylar.java.ui.views.MylarPackageExplorer.ImportDeclarationFilter">
-      </filter>
-      <filter
-            targetId="ca.ubc.mylar.java.ui.views.MylarPackageExplorer"
-            name="%HideNonJavaProjects.label"
-            enabled="false"
-            description="%HideNonJavaProjects.description"
-            class="org.eclipse.jdt.internal.ui.filters.NonJavaProjectsFilter"
-            id="ca.ubc.mylar.java.ui.views.MylarPackageExplorer.NonJavaProjectsFilter">
-      </filter>
-      <filter
-            targetId="ca.ubc.mylar.java.ui.views.MylarPackageExplorer"
-            name="%HideNonSharedProjects.label"
-            enabled="false"
-            description="%HideNonSharedProjects.description"
-            class="org.eclipse.jdt.internal.ui.filters.NonSharedProjectFilter"
-            id="ca.ubc.mylar.java.ui.views.MylarPackageExplorer.NonSharedProjectsFilter">
-      </filter>
-      <filter
-            targetId="ca.ubc.mylar.java.ui.views.MylarPackageExplorer"
-            name="%HideClosedProjects.label"
-            enabled="false"
-            description="%HideClosedProjects.description"
-            class="org.eclipse.jdt.internal.ui.filters.ClosedProjectFilter"
-            id="ca.ubc.mylar.java.ui.views.MylarPackageExplorer.ClosedProjectsFilter">
-      </filter>
-      <filter
-            targetId="ca.ubc.mylar.java.ui.views.MylarPackageExplorer"
-            name="%HideFields.label"
-            enabled="false"
-            description="%HideFields.description"
-            class="org.eclipse.jdt.internal.ui.filters.FieldsFilter"
-            id="ca.ubc.mylar.java.ui.views.MylarPackageExplorer.FieldsFilter">
-      </filter>
-      <filter
-            targetId="ca.ubc.mylar.java.ui.views.MylarPackageExplorer"
-            name="%HideStatics.label"
-            enabled="false"
-            description="%HideStatics.description"
-            class="org.eclipse.jdt.internal.ui.filters.StaticsFilter"
-            id="ca.ubc.mylar.java.ui.views.MylarPackageExplorer.StaticsFilter">
-      </filter>
-      <filter
-            targetId="ca.ubc.mylar.java.ui.views.MylarPackageExplorer"
-            name="%HideNonPublic.label"
-            enabled="false"
-            description="%HideNonPublic.description"
-            class="org.eclipse.jdt.internal.ui.filters.NonPublicFilter"
-            id="ca.ubc.mylar.java.ui.views.MylarPackageExplorer.NonPublicFilter">
-      </filter>
-      <filter
-            targetId="ca.ubc.mylar.java.ui.views.MylarPackageExplorer"
-            name="%HideLocalTypes.label"
-            enabled="false"
-            description="%HideLocalTypes.description"
-            class="org.eclipse.jdt.internal.ui.filters.LocalTypesFilter"
-            id="ca.ubc.mylar.java.ui.views.MylarPackageExplorer.LocalTypesFilter">
-      </filter>
-      -->
-  </extension>
-  
-  <!--
-   <extension
-         id="instrumentation"
-         name="Mylar Instrumentation"
-         point="org.eclipse.instrumentation.instrumentation">
-      <instrumentation
-            url="file://c:/reports"
-            confirmationTitle="Instrumentation Test: Data Transfer Authorization"
-            explanationTitle="Instrumentation Test: Data Collection Authorization"
-            template="template.xrpt"
-            class="org.eclipse.instrumentation.internal.LocalSender"
-            updatePeriod="0"> 
-         <explanation>
-            As part of an ongoing effort to improve usability, the Eclipse development team would like to request your permission to gather anonymous usage statistics from your installation of Eclipse.      
-			This confidential data, which can be reviewed prior to transmission, will not contain personal data or workspace content. The information collected through your participation in this study will be used for the sole purpose of improving usability.
-			Do you wish to contribute your usage statistics to this project?
-         </explanation>
-         <confirmationMessage>
-            Data has been gathered about your current Preference and Perspective settings. The data is anonymous and, if sent, will be used to improve the Eclipse user experience.
-			Please consider sending the data to the Eclipse development team. To review the usage data prior to transmission, click View Data
-         </confirmationMessage>
-      </instrumentation>
-   </extension>
-   -->
-   
-   <!--
-   <extension point="org.eclipse.ui.editorActions">
-		<editorContribution 
-			targetID="ca.ubc.mylar.ui.editor.MylarCompilationUnitEditor" 
-			id="ca.ubc.mylar.ui.editor.MylarCompilationUnitEditor.BreakpointRulerActions">
-	  		<action 
-	  			label="%AddBreakpoint.label" 
-	  			class="org.eclipse.jdt.internal.debug.ui.actions.ManageBreakpointRulerActionDelegate" 
-	  			actionID="RulerDoubleClick" 
-	  			id="org.eclipse.jdt.debug.ui.actions.ManageBreakpointRulerAction" /> 
-  			         <action
-               label="%Dummy.label"
-               class="org.eclipse.jdt.internal.ui.javaeditor.JavaSelectRulerAction"
-               actionID="RulerClick"
-               id="org.eclipse.jdt.internal.ui.javaeditor.JavaSelectRulerAction">
-         	</action>
-  		</editorContribution>
-		<editorContribution 
-			targetID="ca.ubc.mylar.ui.editor.MylarClassFileEditor" 
-			id="ca.ubc.mylar.ui.editor.MylarClassFileEditor.BreakpointRulerActions">
-  			<action 
-  				label="%AddBreakpoint.label" 
-  				class="org.eclipse.jdt.internal.debug.ui.actions.ManageBreakpointRulerActionDelegate" 
-  				actionID="RulerDoubleClick" 
-  				id="org.eclipse.jdt.debug.ui.actions.ManageBreakpointRulerAction" /> 
-         	<action
-               label="%Dummy.label"
-               class="org.eclipse.jdt.internal.ui.javaeditor.JavaSelectRulerAction"
-               actionID="RulerClick"
-               id="org.eclipse.jdt.internal.ui.javaeditor.JavaSelectRulerAction">
-         </action>
-      </editorContribution>
-  </extension>
-  -->
-  
-  <!--
-  <extension point="org.eclipse.ui.popupMenus">
-  	<viewerContribution 
-  		targetID="#CompilationUnitRulerContext" 
-  		id="org.eclipse.jdt.internal.ui.javaeditor.QuickFixRulerMenuAction">
-  		<action 
-  			label="%Dummy.label" 
-  			helpContextId="org.eclipse.jdt.ui.quick_fix_action" 
-  			class="org.eclipse.jdt.internal.ui.javaeditor.JavaSelectRulerAction" 
-  			menubarPath="additions" 
-  			definitionId="org.eclipse.jdt.ui.edit.text.java.correction.assist.proposals" 
-  			id="org.eclipse.jdt.internal.ui.javaeditor.JavaSelectRulerMenuAction" /> 
-  	</viewerContribution> 
-  </extension>
-  -->
-  
-  <!-- ** VIEWS ****************************************** -->
- 
- <!--  
-  <extension point = "org.eclipse.ui.viewActions">
-      <viewContribution 
-         id="ca.ubc.mylar.ui.actions" 
-         targetID="ca.ubc.mylar.ui.views.MylarPackageExplorer"> 
- 
-       <action id="ca.ubc.mylar.ui.actions.ToggleAutoManagerExplorerAction" 
-       		  style="toggle" 
-              label="Auto expand and filter" 
-              tooltip="Auto expand and filter tree nodes according to interest" 
-	      	  menubarPath="additions"
-              toolbarPath="additions" 
-              icon="icons/elcl16/auto-expand.gif" 
-              class="ca.ubc.mylar.ui.actions.ToggleAutoManagerExplorerAction"/> 
-       <action id="ca.ubc.mylar.ui.actions.FilterDeclarationsAction" 
-       		  style="toggle" 
-              label="Filter declarations" 
-              tooltip="Filter declarations" 
-	      	  menubarPath="additions"
-              toolbarPath="additions" 
-              icon="icons/elcl16/filter-declarations.gif" 
-              class="ca.ubc.mylar.ui.actions.FilterDeclarationsAction"/> 
-        <action id="ca.ubc.mylar.ui.actions.ResetModelAction" 
-       		  style="push" 
-              label="Erase model" 
-              tooltip="Erase interest model" 
-	      	  menubarPath="additions"
-              toolbarPath="additions" 
-              icon="icons/elcl16/erase-model.gif" 
-              class="ca.ubc.mylar.ui.actions.ResetModelAction"/>
-	   <action id="ca.ubc.mylar.ui.actions.ShowFilteredAction" 
-              label="Raise children" 
-	      	  menubarPath="additions"
-              toolbarPath="additions" 
-              icon="icons/elcl16/raise-children.gif" 
-              tooltip="Show all children of the current element" 
-              class="ca.ubc.mylar.ui.actions.ShowFilteredAction" 
-              enablesFor="1"/>       
-	   <action id="ca.ubc.mylar.ui.actions.SuppressFilterAction" 
-	     	  style="toggle" 
-              label="Filter uninteresting" 
-	      	  menubarPath="additions"
-              toolbarPath="additions" 
-              icon="icons/elcl16/filter-uninteresting.gif" 
-              tooltip="Toggle low interest filtering" 
-              class="ca.ubc.mylar.ui.actions.SuppressFilterAction"/> 
-      </viewContribution>
-  </extension>
--->
-  
-  <!--
-  <extension point="org.eclipse.ui.actionSets">
-  	<actionSet 
-  		label="Mylar" 
-  		visible="true" 
-  		id="ca.ubc.mylar.ui.actions">
-      <action
-            toolbarPath="mylar"
-            label="Auto fold"
-            icon="icons/elcl16/auto-fold.gif"
-            tooltip="Auto fold"
-            class="ca.ubc.mylar.ui.actions.ToggleAutoFoldAction"
-            style="toggle"
-            id="ca.ubc.mylar.ui.actions.ToggleAutoFoldAction"/>
-      <action
-            toolbarPath="mylar"
-            label="Auto close"
-            class="ca.ubc.mylar.ui.actions.ToggleAutoCloseAction"
-            icon="icons/elcl16/auto-close.gif"
-            tooltip="Auto close editor windows"
-            style="toggle"
-            id="ca.ubc.mylar.ui.actions.ToggleAutoCloseAction"/>
-      <action
-            toolbarPath="mylar"
-            class="ca.ubc.mylar.ui.actions.OpenPrefsAction"
-            label="Mylar"
-            tooltip="Open Mylar Preferences..."
-            style="push"
-            icon="icons/eview16/mylar-glasses.gif"
-            id="ca.ubc.mylar.ui.actions.null"/>
-  	</actionSet>
-  </extension>
-  -->
\ No newline at end of file
