custom ant work in progress
diff --git a/ant/org.eclipse.ant.ui/icons/full/eview16/classpath.gif b/ant/org.eclipse.ant.ui/icons/full/eview16/classpath.gif
new file mode 100644
index 0000000..f966fc3
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/icons/full/eview16/classpath.gif
Binary files differ
diff --git a/ant/org.eclipse.ant.ui/icons/full/eview16/jar_l_obj.gif b/ant/org.eclipse.ant.ui/icons/full/eview16/jar_l_obj.gif
new file mode 100644
index 0000000..11e04e2
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/icons/full/eview16/jar_l_obj.gif
Binary files differ
diff --git a/ant/org.eclipse.ant.ui/icons/full/eview16/type.gif b/ant/org.eclipse.ant.ui/icons/full/eview16/type.gif
new file mode 100644
index 0000000..2db7604
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/icons/full/eview16/type.gif
Binary files differ
diff --git a/ant/org.eclipse.ant.ui/plugin.properties b/ant/org.eclipse.ant.ui/plugin.properties
index 8960b0c..bfbbd18 100644
--- a/ant/org.eclipse.ant.ui/plugin.properties
+++ b/ant/org.eclipse.ant.ui/plugin.properties
@@ -2,7 +2,7 @@
 antBuilderPropertyName=Tool Script Builders
 antConsole = Ant Console
 antConsolePreferences = Console
-antClasspathPreferences = Classpath
+antClasspathPreferences = Customize
 antLauncher = Ant Targets
 antPreferences = Ant
 executeAntLabel = Run Ant Script
diff --git a/ant/org.eclipse.ant.ui/plugin.xml b/ant/org.eclipse.ant.ui/plugin.xml
index ccc603e..0aa3a1b 100644
--- a/ant/org.eclipse.ant.ui/plugin.xml
+++ b/ant/org.eclipse.ant.ui/plugin.xml
@@ -65,7 +65,7 @@
   	<page 
   		id="org.eclipse.ant.ui.AntClasspathPreferences" 
   		name="%antClasspathPreferences"
-  		class="org.eclipse.ant.internal.ui.AntClasspathPreferencePage"
+  		class="org.eclipse.ant.internal.ui.CustomizeAntPreferencePage"
   		category="org.eclipse.ant.ui.AntPreferences">
   	</page>
   </extension>
diff --git a/ant/org.eclipse.ant.ui/src/org/eclipse/ant/internal/ui/AntUIPlugin.java b/ant/org.eclipse.ant.ui/src/org/eclipse/ant/internal/ui/AntUIPlugin.java
index bbc0aa5..df7d68e 100644
--- a/ant/org.eclipse.ant.ui/src/org/eclipse/ant/internal/ui/AntUIPlugin.java
+++ b/ant/org.eclipse.ant.ui/src/org/eclipse/ant/internal/ui/AntUIPlugin.java
@@ -7,8 +7,7 @@
 
 import java.net.MalformedURLException;
 import java.net.URL;
-import java.util.MissingResourceException;
-import java.util.ResourceBundle;
+import java.util.*;
 
 import org.eclipse.core.resources.IFile;
 import org.eclipse.core.runtime.*;
@@ -28,6 +27,8 @@
 	 * 
 	 */
 	protected IProgressMonitor currentProgressMonitor;
+	
+	protected final HashMap imageDescriptors = new HashMap(30);
 
 	/**
 	 * Unique identifier constant (value <code>"org.eclipse.ant.ui"</code>)
@@ -40,6 +41,8 @@
 	public static final String IMG_ANT_SCRIPT= "icons/full/eview16/ant_view.gif";
 	public static final String IMG_BUILDER= "icons/full/eview16/build_exec.gif";
 	public static final String IMG_JAR_FILE = "icons/full/eview16/jar_l_obj.gif";
+	public static final String IMG_CLASSPATH = "icons/full/eview16/classpath.gif";
+	public static final String IMG_TYPE = "icons/full/eview16/type.gif";
 	
 	private static final String SETTINGS_COMMAND_HISTORY = "CommandHistory";
 	private static final int MAX_COMMAND_HISTORY = 15;
@@ -174,10 +177,15 @@
  * @return the ImageDescriptor object
  */
 public ImageDescriptor getImageDescriptor(String path) {
+	ImageDescriptor desc = (ImageDescriptor)imageDescriptors.get(path);
+	if (desc != null)
+		return desc;
 	try {
 		URL installURL = getDescriptor().getInstallURL();
 		URL url = new URL(installURL,path);
-		return ImageDescriptor.createFromURL(url);
+		desc = ImageDescriptor.createFromURL(url);
+		imageDescriptors.put(path, desc);
+		return desc;
 	} catch (MalformedURLException e) {
 		return null;
 	}
diff --git a/ant/org.eclipse.ant.ui/src/org/eclipse/ant/internal/ui/ClasspathPage.java b/ant/org.eclipse.ant.ui/src/org/eclipse/ant/internal/ui/ClasspathPage.java
index f8aed92..2f9def0 100644
--- a/ant/org.eclipse.ant.ui/src/org/eclipse/ant/internal/ui/ClasspathPage.java
+++ b/ant/org.eclipse.ant.ui/src/org/eclipse/ant/internal/ui/ClasspathPage.java
@@ -12,157 +12,72 @@
 
 import java.net.MalformedURLException;
 import java.net.URL;
-import java.util.*;
-import java.util.List;
 
-import org.eclipse.ant.core.AntCorePlugin;
-import org.eclipse.ant.internal.core.AntCorePreferences;
-import org.eclipse.jface.viewers.*;
+import org.eclipse.jface.dialogs.IDialogConstants;
 import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.SelectionAdapter;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.DisposeListener;
 import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.internal.win32.CREATESTRUCT;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
 import org.eclipse.swt.widgets.*;
-import org.eclipse.ui.ISharedImages;
-import org.eclipse.ui.PlatformUI;
 
 /**
  * A widget group for the jars tab of the ant classpath preference page.
  */
 public class ClasspathPage extends CustomizeAntPage {
-	protected final ArrayList elements = new ArrayList();
-	public class ClasspathLabelProvider extends LabelProvider implements ITableLabelProvider {
-		protected Image folderImage;
-		protected Image jarImage;
-		public ClasspathLabelProvider() {
-			folderImage = PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_OBJ_FOLDER);
-			jarImage = AntUIPlugin.getPlugin().getImageDescriptor(AntUIPlugin.IMG_JAR_FILE).createImage();
-		}
-		public Image getColumnImage(Object element, int columnIndex) {
-			URL url = (URL)element;
-			if (url.getFile().endsWith("/")) {
-				return folderImage;
-			} else {
-				return jarImage;
-			}
-		}
-		public String getColumnText(Object element, int columnIndex) {
-			URL url = (URL)element;
-			return url.getFile();
-		}
-		public void dispose() {
-			//note: folder image is a shared image
-			folderImage = null;
-			if (jarImage != null) {
-				jarImage.dispose();
-				jarImage = null;
-			}
-		}
-	}
-
-	class ClasspathContentProvider extends Object implements IStructuredContentProvider {
-		public Object[] getElements(Object inputElement) {
-			return (URL[]) inputElement;
-		}
-		public void dispose() {
-		}
-		public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
-			elements.clear();
-			AntCorePreferences prefs = AntCorePlugin.getPlugin().getPreferences();
-			elements.addAll(Arrays.asList(prefs.getURLs()));
-		}
-	}
-	
-	protected TableViewer jarTable;
-	
-	protected Button removeButton;
+	//button constants
+	protected static final int ADD_JAR_BUTTON = IDialogConstants.CLIENT_ID + 1;
+	protected static final int ADD_FOLDER_BUTTON = IDialogConstants.CLIENT_ID + 2;
+	protected static final int REMOVE_BUTTON = IDialogConstants.CLIENT_ID + 3;
 	
 public ClasspathPage() {
 }
+/**
+ * @see CustomizeAntPage#addButtonsToButtonGroup(Composite)
+ */
+protected void addButtonsToButtonGroup(Composite parent) {
+	createButton(parent, "preferences.customize.addJarButtonTitle", ADD_JAR_BUTTON);
+	createButton(parent, "preferences.customize.addFolderButtonTitle", ADD_FOLDER_BUTTON);
+	createSeparator(parent);
+	createButton(parent, "preferences.customize.removeButtonTitle", REMOVE_BUTTON);
+}
 protected void addFolderButtonPressed() {
-	DirectoryDialog dialog = new DirectoryDialog(jarTable.getControl().getShell());
+	DirectoryDialog dialog = new DirectoryDialog(tableViewer.getControl().getShell());
 	String result = dialog.open();
 	if (result != null) {
 		try {
 			URL url = new URL("file:" + result + "/");
-			elements.add(url);
-			jarTable.add(url);
+			contentProvider.add(url);
 		} catch (MalformedURLException e) {
 		}
 	}
 }
 protected void addJarButtonPressed() {
-	FileDialog dialog = new FileDialog(jarTable.getControl().getShell());
+	FileDialog dialog = new FileDialog(tableViewer.getControl().getShell());
 	dialog.setFilterExtensions(new String[] {"*.jar"});
 	String result = dialog.open();
 	if (result != null) {
 		try {
 			URL url = new URL("file:" + result);
-			elements.add(url);
-			jarTable.add(url);
+			contentProvider.add(url);
 		} catch (MalformedURLException e) {
 		}
 	}
 }
-protected void createButtonGroup(Composite top) {
-	Composite buttonGroup = new Composite(top, SWT.NONE);
-	GridLayout layout = new GridLayout();
-	layout.marginHeight = 0;
-	layout.marginWidth = 0;
-	buttonGroup.setLayout(layout);
-	buttonGroup.setLayoutData(new GridData(GridData.FILL_VERTICAL));
-	
-	Button button = createButton(buttonGroup, "preferences.customize.addJarButtonTitle");
-	button.addSelectionListener(new SelectionAdapter() {
-		public void widgetSelected(SelectionEvent e) {
-			addJarButtonPressed();
-		}
-	});
-	button = createButton(buttonGroup, "preferences.customize.addFolderButtonTitle");
-	button.addSelectionListener(new SelectionAdapter() {
-		public void widgetSelected(SelectionEvent e) {
-			addFolderButtonPressed();
-		}
-	});
-	createSeparator(buttonGroup);
-	removeButton = createButton(buttonGroup, "preferences.customize.removeButtonTitle");
-	removeButton.addSelectionListener(new SelectionAdapter() {
-		public void widgetSelected(SelectionEvent e) {
-			removeButtonPressed();
-		}
-	});
-}
 /**
- * Creates and returns a control that contains this widget group.
+ * @see CustomizeAntPage#buttonPressed(int)
  */
-public Control createControl(Composite parent) {
-	Composite top = new Composite(parent, SWT.NONE);
-	GridLayout layout = new GridLayout();
-	layout.numColumns = 2;
-	layout.marginHeight = 2;
-	layout.marginWidth = 2;
-	top.setLayout(layout);
-	
-	//get font metrics for DLU -> pixel conversions
-	GC gc = new GC(top);
-	gc.setFont(top.getFont());
-	fontMetrics = gc.getFontMetrics();
-	gc.dispose();
-	
-	createTable(top);
-	createButtonGroup(top);
-	return top;
-}
-protected void createTable(Composite parent) {
-	Table table = new Table(parent, SWT.MULTI | SWT.FULL_SELECTION | SWT.BORDER);
-	table.setLayoutData(new GridData(GridData.FILL_BOTH));
-	jarTable = new TableViewer(table);
-	jarTable.setContentProvider(new ClasspathContentProvider());
-	jarTable.setLabelProvider(new ClasspathLabelProvider());
+protected void buttonPressed(int buttonId) {
+	switch (buttonId) {
+		case ADD_JAR_BUTTON:
+			addJarButtonPressed();
+			break;
+		case ADD_FOLDER_BUTTON:
+			addFolderButtonPressed();
+			break;
+		case REMOVE_BUTTON:
+			removeButtonPressed();
+			break;
+	}
 }
 /**
  * Creates and returns a tab item that contains this widget group.
@@ -170,34 +85,25 @@
 public TabItem createTabItem(TabFolder folder) {
 	TabItem item = new TabItem(folder, SWT.NONE);
 	item.setText(Policy.bind("preferences.customize.classpathPageTitle"));
-//	item.setImage(imageRegistry.get(JavaPluginImages.IMG_OBJS_PACKFRAG_ROOT));
+	final Image image = AntUIPlugin.getPlugin().getImageDescriptor(AntUIPlugin.IMG_CLASSPATH).createImage();
+	item.setImage(image);
 	item.setData(this);
 	item.setControl(createControl(folder));
+	item.addDisposeListener(new DisposeListener() {
+		public void widgetDisposed(DisposeEvent e) {
+			if (image != null)
+				image.dispose();
+		}
+	});
+
 	return item;
 }
-protected void defaultButtonPressed() {
-}
-/**
- * Returns the currently listed set of URLs.  Returns null
- * if this widget has not yet been created or has been disposed.
- */
-public URL[] getURLs() {
-	if (jarTable == null || jarTable.getControl().isDisposed())
-		return null;
-	return (URL[]) elements.toArray(new URL[elements.size()]);
-}
+
 	
-protected void removeButtonPressed() {
-	IStructuredSelection selection = (IStructuredSelection)jarTable.getSelection();
-	jarTable.remove(selection.toArray());
-}
-/**
- * Sets the currently listed set of URLs.  Has no effect
- * if this widget has not yet been created or has been disposed.
- */
-public void setURLs(URL[] urls) {
-	if (jarTable == null || jarTable.getControl().isDisposed())
-		return;
-	jarTable.setInput(urls);
-}
+
+
+
+
+
+
 }
\ No newline at end of file
diff --git a/ant/org.eclipse.ant.ui/src/org/eclipse/ant/internal/ui/CustomizeAntContentProvider.java b/ant/org.eclipse.ant.ui/src/org/eclipse/ant/internal/ui/CustomizeAntContentProvider.java
new file mode 100644
index 0000000..566c4bf
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/src/org/eclipse/ant/internal/ui/CustomizeAntContentProvider.java
@@ -0,0 +1,45 @@
+/*******************************************************************************
+ * Copyright (c) 2002 IBM Corporation and others.
+ * All rights reserved.   This program and the accompanying materials
+ * are made available under the terms of the Common Public License v0.5
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v05.html
+ * 
+ * Contributors:
+ * IBM - Initial API and implementation
+ ******************************************************************************/
+package org.eclipse.ant.internal.ui;
+
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.jface.viewers.*;
+
+/**
+ * Maintains a generic list of objects that are shown in a table viewer.
+ */
+public class CustomizeAntContentProvider implements IStructuredContentProvider {
+	protected final ArrayList elements = new ArrayList();
+	protected TableViewer viewer;
+	
+void add(Object o) {
+	elements.add(o);
+	viewer.add(o);
+}
+public void dispose() {
+}
+public Object[] getElements(Object inputElement) {
+	return (Object[]) elements.toArray(new Object[elements.size()]);
+}
+public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+	this.viewer = (TableViewer)viewer;
+	elements.clear();
+	if (newInput != null)
+		elements.addAll((List)newInput);
+}
+void remove(Object o) {
+	elements.remove(o);
+	viewer.remove(o);
+}
+}
diff --git a/ant/org.eclipse.ant.ui/src/org/eclipse/ant/internal/ui/CustomizeAntLabelProvider.java b/ant/org.eclipse.ant.ui/src/org/eclipse/ant/internal/ui/CustomizeAntLabelProvider.java
new file mode 100644
index 0000000..6c8d3cb
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/src/org/eclipse/ant/internal/ui/CustomizeAntLabelProvider.java
@@ -0,0 +1,103 @@
+/*******************************************************************************
+ * Copyright (c) 2002 IBM Corporation and others.
+ * All rights reserved.   This program and the accompanying materials
+ * are made available under the terms of the Common Public License v0.5
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v05.html
+ * 
+ * Contributors:
+ * IBM - Initial API and implementation
+ ******************************************************************************/
+package org.eclipse.ant.internal.ui;
+
+import java.net.URL;
+
+import org.eclipse.ant.internal.core.Task;
+import org.eclipse.ant.internal.core.Type;
+import org.eclipse.jface.viewers.ITableLabelProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.ui.ISharedImages;
+import org.eclipse.ui.PlatformUI;
+
+/**
+ * Label provider for the items in the custmomize ant preference page: 
+ * URLs, Tasks, and Types.
+ */
+public class CustomizeAntLabelProvider extends LabelProvider implements ITableLabelProvider {
+	protected Image folderImage;
+	protected Image jarImage;
+	protected Image taskImage;
+	protected Image typeImage;
+	
+public CustomizeAntLabelProvider() {
+}
+public void dispose() {
+	//note: folder and task are shared images
+	folderImage = null;
+	taskImage = null;
+	if (jarImage != null) {
+		jarImage.dispose();
+		jarImage = null;
+	}
+	if (typeImage != null) {
+		typeImage.dispose();
+		typeImage = null;
+	}
+}
+public Image getColumnImage(Object element, int columnIndex) {
+	if (element instanceof URL) {
+		URL url = (URL)element;
+		if (url.getFile().endsWith("/")) {
+			return folderImage();
+		} else {
+			return jarImage();
+		}
+	}
+	if (element instanceof Task) {
+		return taskImage();
+	}
+	if (element instanceof Type) {
+		return typeImage();
+	}
+	return null;
+}
+public String getColumnText(Object element, int columnIndex) {
+	if (element instanceof URL) {
+		return ((URL)element).getFile();
+	}
+	if (element instanceof Task) {
+		Task task = (Task)element;
+		return task.getTaskName() + "(" + task.getClassName() + ")";
+	}
+	if (element instanceof Type) {
+		Type type = (Type)element;
+		return type.getTypeName() + "(" + type.getClassName() + ")";
+	}
+	return element.toString();
+}
+protected Image folderImage() {
+	if (folderImage != null)
+		return folderImage;
+	folderImage = PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_OBJ_FOLDER);
+	return folderImage;
+}
+protected Image jarImage() {
+	if (jarImage != null)
+		return jarImage;
+	jarImage = AntUIPlugin.getPlugin().getImageDescriptor(AntUIPlugin.IMG_JAR_FILE).createImage();
+	return jarImage;
+}
+protected Image taskImage() {
+	if (taskImage != null)
+		return taskImage;
+	taskImage = PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_OBJS_TASK_TSK);
+	return taskImage;
+}
+protected Image typeImage() {
+	if (typeImage != null)
+		return typeImage;
+	typeImage = AntUIPlugin.getPlugin().getImageDescriptor(AntUIPlugin.IMG_TYPE).createImage();
+	return typeImage;
+}
+}
\ No newline at end of file
diff --git a/ant/org.eclipse.ant.ui/src/org/eclipse/ant/internal/ui/CustomizeAntPage.java b/ant/org.eclipse.ant.ui/src/org/eclipse/ant/internal/ui/CustomizeAntPage.java
index 225199d..07d83d0 100644
--- a/ant/org.eclipse.ant.ui/src/org/eclipse/ant/internal/ui/CustomizeAntPage.java
+++ b/ant/org.eclipse.ant.ui/src/org/eclipse/ant/internal/ui/CustomizeAntPage.java
@@ -10,19 +10,47 @@
  ******************************************************************************/
 package org.eclipse.ant.internal.ui;
 
+import java.util.Arrays;
+import java.util.List;
+
 import org.eclipse.jface.dialogs.Dialog;
 import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.TableViewer;
 import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
 import org.eclipse.swt.graphics.FontMetrics;
+import org.eclipse.swt.graphics.GC;
 import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
 import org.eclipse.swt.widgets.*;
 
+
+
 /**
  * Abstract superclass for all tabs that contribute to the ant classpath
  * preference page.
  */
 public abstract class CustomizeAntPage extends Object {
+	SelectionAdapter selectionAdapter = new SelectionAdapter() {
+		public void widgetSelected(SelectionEvent e) {
+			buttonPressed(((Integer) e.widget.getData()).intValue());
+		}
+	};
 	protected FontMetrics fontMetrics;
+	protected TableViewer tableViewer;
+	protected CustomizeAntContentProvider contentProvider;
+
+/**
+ * This is where subclasses should add the buttons that are interesting for their page.
+ */
+protected abstract void addButtonsToButtonGroup(Composite parent);
+/**
+ * Should be overwritten by subclasses to handle button behaviour.
+ */
+protected void buttonPressed(int buttonID) {
+}
 
 /**
  * Creates and returns a button with appropriate size and layout.
@@ -30,7 +58,7 @@
  * @param labelKey The button text key, used to fetch the appropriate
  * message from the externalized catalog.
  */
-protected Button createButton(Composite parent, String labelKey) {
+protected Button createButton(Composite parent, String labelKey, int buttonId) {
 	Button button = new Button(parent, SWT.PUSH);
 	button.setText(Policy.bind(labelKey));
 	GridData data = new GridData(GridData.FILL_HORIZONTAL);
@@ -38,8 +66,21 @@
 	data.widthHint = Math.max(widthHint, button.computeSize(SWT.DEFAULT, SWT.DEFAULT, true).x);
 	data.heightHint = Dialog.convertVerticalDLUsToPixels(fontMetrics, IDialogConstants.BUTTON_HEIGHT);
 	button.setLayoutData(data);
+	button.setData(new Integer(buttonId));
+	button.addSelectionListener(selectionAdapter);
 	return button;
 }
+protected void createButtonGroup(Composite top) {
+	Composite buttonGroup = new Composite(top, SWT.NONE);
+	GridLayout layout = new GridLayout();
+	layout.marginHeight = 0;
+	layout.marginWidth = 0;
+	buttonGroup.setLayout(layout);
+	buttonGroup.setLayoutData(new GridData(GridData.FILL_VERTICAL));
+	
+	addButtonsToButtonGroup(buttonGroup);
+}
+
 protected Label createSeparator(Composite parent) {
 	Label separator= new Label(parent, SWT.NONE);
 	separator.setVisible(false);
@@ -50,4 +91,58 @@
 	separator.setLayoutData(gd);
 	return separator;
 }
+protected void createTable(Composite parent) {
+	Table table = new Table(parent, SWT.MULTI | SWT.FULL_SELECTION | SWT.BORDER);
+	table.setLayoutData(new GridData(GridData.FILL_BOTH));
+	tableViewer = new TableViewer(table);
+	contentProvider = new CustomizeAntContentProvider();
+	tableViewer.setContentProvider(contentProvider);
+	tableViewer.setLabelProvider(new CustomizeAntLabelProvider());
+}
+/**
+ * Returns the currently listed objects in the table.  Returns null
+ * if this widget has not yet been created or has been disposed.
+ */
+public List getContents() {
+	if (tableViewer == null || tableViewer.getControl().isDisposed())
+		return null;
+	Object[] elements = contentProvider.getElements(tableViewer.getInput());
+	return Arrays.asList(elements);
+}
+protected void removeButtonPressed() {
+	IStructuredSelection selection = (IStructuredSelection)tableViewer.getSelection();
+	tableViewer.remove(selection.toArray());
+}
+/**
+ * Sets the contents of the table on this page.  Has no effect
+ * if this widget has not yet been created or has been disposed.
+ */
+public void setInput(List inputs) {
+	if (tableViewer == null || tableViewer.getControl().isDisposed())
+		return;
+	tableViewer.setInput(inputs);
+}
+
+/**
+ * Creates and returns a control that contains this widget group.
+ */
+public Control createControl(Composite parent) {
+	Composite top = new Composite(parent, SWT.NONE);
+	GridLayout layout = new GridLayout();
+	layout.numColumns = 2;
+	layout.marginHeight = 2;
+	layout.marginWidth = 2;
+	top.setLayout(layout);
+	
+	//get font metrics for DLU -> pixel conversions
+	GC gc = new GC(top);
+	gc.setFont(top.getFont());
+	fontMetrics = gc.getFontMetrics();
+	gc.dispose();
+	
+	createTable(top);
+	createButtonGroup(top);
+	return top;
+}
+
 }
diff --git a/ant/org.eclipse.ant.ui/src/org/eclipse/ant/internal/ui/CustomizeAntPreferencePage.java b/ant/org.eclipse.ant.ui/src/org/eclipse/ant/internal/ui/CustomizeAntPreferencePage.java
index e6cb25f..1790321 100644
--- a/ant/org.eclipse.ant.ui/src/org/eclipse/ant/internal/ui/CustomizeAntPreferencePage.java
+++ b/ant/org.eclipse.ant.ui/src/org/eclipse/ant/internal/ui/CustomizeAntPreferencePage.java
@@ -11,8 +11,11 @@
 package org.eclipse.ant.internal.ui;
 
 import java.net.URL;
+import java.util.Arrays;
+import java.util.List;
 
 import org.eclipse.ant.core.AntCorePlugin;
+import org.eclipse.ant.internal.core.*;
 import org.eclipse.jface.preference.IPreferenceStore;
 import org.eclipse.jface.preference.PreferencePage;
 import org.eclipse.swt.SWT;
@@ -31,9 +34,6 @@
 	protected ClasspathPage jarsPage;
 	protected TasksPage tasksPage;
 	protected TypesPage typesPage;
-	
-	protected CustomizeAntPage currentPage;
-	
 /**
  * Create the console page.
  */
@@ -51,22 +51,19 @@
 	TabFolder folder= new TabFolder(parent, SWT.NONE);
 	folder.setLayout(new GridLayout());	
 	folder.setLayoutData(new GridData(GridData.FILL_BOTH));
-	folder.addSelectionListener(new SelectionAdapter() {
-		public void widgetSelected(SelectionEvent e) {
-			tabChanged(e.item);
-		}	
-	});
 
 	jarsPage = new ClasspathPage();
 	jarsPage.createTabItem(folder);
-	jarsPage.setURLs(AntCorePlugin.getPlugin().getPreferences().getURLs());
-	currentPage = jarsPage;
-	
 	tasksPage = new TasksPage();
 	tasksPage.createTabItem(folder);
-
 	typesPage = new TypesPage();
 	typesPage.createTabItem(folder);
+	
+	//set the page inputs
+	AntCorePreferences prefs = AntCorePlugin.getPlugin().getPreferences();
+	jarsPage.setInput(Arrays.asList(prefs.getCustomURLs()));
+	tasksPage.setInput(Arrays.asList(prefs.getCustomTasks()));
+	typesPage.setInput(Arrays.asList(prefs.getCustomTypes()));
 
 	return folder;
 }
@@ -75,19 +72,30 @@
  */
 protected void performDefaults() {
 	super.performDefaults();
-	jarsPage.setURLs(AntCorePlugin.getPlugin().getPreferences().getURLs());
+	AntCorePreferences prefs = AntCorePlugin.getPlugin().getPreferences();
+	jarsPage.setInput(Arrays.asList(prefs.getCustomURLs()));
+	tasksPage.setInput(Arrays.asList(prefs.getCustomTasks()));
+	typesPage.setInput(Arrays.asList(prefs.getCustomTypes()));
 }
 /**
  * @see IPreferencePage#performOk()
  */
 public boolean performOk() {
-	URL[] urls = jarsPage.getURLs();
-	if (urls != null) {
+	List contents = jarsPage.getContents();
+	if (contents != null) {
+		URL[] urls = (URL[]) contents.toArray(new URL[contents.size()]);
 		AntCorePlugin.getPlugin().getPreferences().setCustomURLs(urls);
 	}
+	contents = tasksPage.getContents();
+	if (contents != null) {
+		Task[] tasks= (Task[]) contents.toArray(new Task[contents.size()]);
+		AntCorePlugin.getPlugin().getPreferences().setCustomTasks(tasks);
+	}
+	contents = typesPage.getContents();
+	if (contents != null) {
+		Type[] types= (Type[]) contents.toArray(new Type[contents.size()]);
+		AntCorePlugin.getPlugin().getPreferences().setCustomTypes(types);
+	}
 	return super.performOk();
 }
-protected void tabChanged(Widget widget) {
-	currentPage = (CustomizeAntPage)widget.getData();
-}
 }
diff --git a/ant/org.eclipse.ant.ui/src/org/eclipse/ant/internal/ui/TasksPage.java b/ant/org.eclipse.ant.ui/src/org/eclipse/ant/internal/ui/TasksPage.java
index 6588b22..76db60c 100644
--- a/ant/org.eclipse.ant.ui/src/org/eclipse/ant/internal/ui/TasksPage.java
+++ b/ant/org.eclipse.ant.ui/src/org/eclipse/ant/internal/ui/TasksPage.java
@@ -10,8 +10,11 @@
  ******************************************************************************/
 package org.eclipse.ant.internal.ui;
 
+import org.eclipse.jface.dialogs.IDialogConstants;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.widgets.*;
+import org.eclipse.ui.ISharedImages;
+import org.eclipse.ui.PlatformUI;
 
 /**
  * A widget group for the tasks tab of the ant classpath preference page.
@@ -19,25 +22,31 @@
 public class TasksPage extends CustomizeAntPage {
 	protected Control control;
 
+	//button constants
+	protected static final int ADD_TASK_BUTTON= IDialogConstants.CLIENT_ID + 1;
+	protected static final int EDIT_TASK_BUTTON = IDialogConstants.CLIENT_ID + 2;
+	protected static final int REMOVE_BUTTON = IDialogConstants.CLIENT_ID + 3;
+
 public TasksPage() {
 }
+protected void addButtonsToButtonGroup(Composite parent) {
+	createButton(parent, "preferences.customize.addTaskButtonTitle", ADD_TASK_BUTTON);
+	createButton(parent, "preferences.customize.editTaskButtonTitle", EDIT_TASK_BUTTON);
+	createSeparator(parent);
+	createButton(parent, "preferences.customize.removeButtonTitle", REMOVE_BUTTON);
+}
+protected void buttonPressed(int buttonID) {
+	super.buttonPressed(buttonID);
+}
 /**
  * Creates and returns a tab item that contains this widget group.
  */
 public TabItem createTabItem(TabFolder folder) {
 	TabItem item = new TabItem(folder, SWT.NONE);
 	item.setText(Policy.bind("preferences.customize.tasksPageTitle"));
-//	item.setImage(imageRegistry.get(JavaPluginImages.IMG_OBJS_PACKFRAG_ROOT));
+	item.setImage(PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_OBJS_TASK_TSK));
 	item.setData(this);
 	item.setControl(createControl(folder));
 	return item;
 }
-/**
- * Creates and returns a control that contains this widget group.
- */
-public Control createControl(Composite parent) {
-	Label label = new Label(parent, SWT.NONE);
-	label.setText("Hello from Tasks page");
-	return label;
-}
 }
\ No newline at end of file
diff --git a/ant/org.eclipse.ant.ui/src/org/eclipse/ant/internal/ui/TypesPage.java b/ant/org.eclipse.ant.ui/src/org/eclipse/ant/internal/ui/TypesPage.java
index 2d508a6..8bedbe3 100644
--- a/ant/org.eclipse.ant.ui/src/org/eclipse/ant/internal/ui/TypesPage.java
+++ b/ant/org.eclipse.ant.ui/src/org/eclipse/ant/internal/ui/TypesPage.java
@@ -10,33 +10,46 @@
  ******************************************************************************/
 package org.eclipse.ant.internal.ui;
 
+import org.eclipse.jface.dialogs.IDialogConstants;
 import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.DisposeListener;
+import org.eclipse.swt.graphics.Image;
 import org.eclipse.swt.widgets.*;
 
 /**
  * A widget group for the types tab of the ant classpath preference page.
  */
 public class TypesPage extends CustomizeAntPage {
-	protected Control control;
+	//button constants
+	protected static final int ADD_TYPE_BUTTON= IDialogConstants.CLIENT_ID + 1;
+	protected static final int EDIT_TYPE_BUTTON = IDialogConstants.CLIENT_ID + 2;
+	protected static final int REMOVE_BUTTON = IDialogConstants.CLIENT_ID + 3;
+
 public TypesPage() {
 }
-/**
- * Creates and returns a tab item that contains this widget group.
- */
+protected void addButtonsToButtonGroup(Composite parent) {
+	createButton(parent, "preferences.customize.addTypeButtonTitle", ADD_TYPE_BUTTON);
+	createButton(parent, "preferences.customize.editTypeButtonTitle", EDIT_TYPE_BUTTON);
+	createSeparator(parent);
+	createButton(parent, "preferences.customize.removeButtonTitle", REMOVE_BUTTON);
+}
+protected void buttonPressed(int buttonID) {
+	super.buttonPressed(buttonID);
+}
 public TabItem createTabItem(TabFolder folder) {
 	TabItem item = new TabItem(folder, SWT.NONE);
 	item.setText(Policy.bind("preferences.customize.typesPageTitle"));
-//	item.setImage(imageRegistry.get(JavaPluginImages.IMG_OBJS_PACKFRAG_ROOT));
+	final Image image = AntUIPlugin.getPlugin().getImageDescriptor(AntUIPlugin.IMG_TYPE).createImage();
+	item.setImage(image);
 	item.setData(this);
 	item.setControl(createControl(folder));
+	item.addDisposeListener(new DisposeListener() {
+		public void widgetDisposed(DisposeEvent e) {
+			if (image != null)
+				image.dispose();
+		}
+	});
 	return item;
 }
-/**
- * Creates and returns a control that contains this widget group.
- */
-public Control createControl(Composite parent) {
-	Label label = new Label(parent, SWT.NONE);
-	label.setText("Hello from types page");
-	return label;
-}
 }
\ No newline at end of file
diff --git a/ant/org.eclipse.ant.ui/src/org/eclipse/ant/internal/ui/messages.properties b/ant/org.eclipse.ant.ui/src/org/eclipse/ant/internal/ui/messages.properties
index 8d27f2b..df4bd07 100644
--- a/ant/org.eclipse.ant.ui/src/org/eclipse/ant/internal/ui/messages.properties
+++ b/ant/org.eclipse.ant.ui/src/org/eclipse/ant/internal/ui/messages.properties
@@ -37,6 +37,11 @@
 preferences.customize.addJarButtonTitle = Add &Jar...
 preferences.customize.defaultButtonTitle = Restore &Defaults
 preferences.customize.removeButtonTitle = &Remove
+preferences.customize.addTypeButtonTitle = &Add Type
+preferences.customize.editTypeButtonTitle = &Edit Type
+preferences.customize.addTaskButtonTitle = &Add Task
+preferences.customize.editTaskButtonTitle = &Edit Task
+
 
 ### console labels
 find_action.label=&Find...@Ctrl+F