Merge branch 'master' into lttng-kepler
[deliverable/tracecompass.git] / org.eclipse.linuxtools.tmf.ui / src / org / eclipse / linuxtools / internal / tmf / ui / parsers / wizards / CustomTxtParserInputWizardPage.java
index e84e37d4caa8df0dba30ef7609c9668a7dab89c3..541746556b1431d99a071dfe8e848e4b7c0412d4 100644 (file)
-package org.eclipse.linuxtools.internal.tmf.ui.parsers.wizards;\r
-\r
-import java.io.BufferedReader;\r
-import java.io.IOException;\r
-import java.io.InputStreamReader;\r
-import java.text.ParseException;\r
-import java.text.SimpleDateFormat;\r
-import java.util.ArrayList;\r
-import java.util.Arrays;\r
-import java.util.Date;\r
-import java.util.HashMap;\r
-import java.util.Iterator;\r
-import java.util.List;\r
-import java.util.Map;\r
-import java.util.Scanner;\r
-import java.util.regex.Matcher;\r
-import java.util.regex.Pattern;\r
-import java.util.regex.PatternSyntaxException;\r
-\r
-import org.eclipse.core.resources.IFile;\r
-import org.eclipse.core.runtime.CoreException;\r
-import org.eclipse.jface.viewers.ColumnLabelProvider;\r
-import org.eclipse.jface.viewers.ISelection;\r
-import org.eclipse.jface.viewers.ISelectionChangedListener;\r
-import org.eclipse.jface.viewers.IStructuredSelection;\r
-import org.eclipse.jface.viewers.ITreeContentProvider;\r
-import org.eclipse.jface.viewers.SelectionChangedEvent;\r
-import org.eclipse.jface.viewers.StructuredSelection;\r
-import org.eclipse.jface.viewers.TreeViewer;\r
-import org.eclipse.jface.viewers.Viewer;\r
-import org.eclipse.jface.wizard.WizardPage;\r
-import org.eclipse.linuxtools.internal.tmf.ui.Activator;\r
-import org.eclipse.linuxtools.internal.tmf.ui.Messages;\r
-import org.eclipse.linuxtools.internal.tmf.ui.parsers.custom.CustomTraceDefinition;\r
-import org.eclipse.linuxtools.internal.tmf.ui.parsers.custom.CustomTxtTraceDefinition;\r
-import org.eclipse.linuxtools.internal.tmf.ui.parsers.custom.CustomTxtTraceDefinition.Cardinality;\r
-import org.eclipse.linuxtools.internal.tmf.ui.parsers.custom.CustomTxtTraceDefinition.InputData;\r
-import org.eclipse.linuxtools.internal.tmf.ui.parsers.custom.CustomTxtTraceDefinition.InputLine;\r
-import org.eclipse.swt.SWT;\r
-import org.eclipse.swt.browser.Browser;\r
-import org.eclipse.swt.browser.TitleEvent;\r
-import org.eclipse.swt.browser.TitleListener;\r
-import org.eclipse.swt.custom.SashForm;\r
-import org.eclipse.swt.custom.ScrolledComposite;\r
-import org.eclipse.swt.custom.StyleRange;\r
-import org.eclipse.swt.custom.StyledText;\r
-import org.eclipse.swt.events.ModifyEvent;\r
-import org.eclipse.swt.events.ModifyListener;\r
-import org.eclipse.swt.events.SelectionAdapter;\r
-import org.eclipse.swt.events.SelectionEvent;\r
-import org.eclipse.swt.events.SelectionListener;\r
-import org.eclipse.swt.events.VerifyEvent;\r
-import org.eclipse.swt.events.VerifyListener;\r
-import org.eclipse.swt.graphics.Color;\r
-import org.eclipse.swt.graphics.Font;\r
-import org.eclipse.swt.graphics.FontData;\r
-import org.eclipse.swt.graphics.Image;\r
-import org.eclipse.swt.layout.FillLayout;\r
-import org.eclipse.swt.layout.GridData;\r
-import org.eclipse.swt.layout.GridLayout;\r
-import org.eclipse.swt.widgets.Button;\r
-import org.eclipse.swt.widgets.Combo;\r
-import org.eclipse.swt.widgets.Composite;\r
-import org.eclipse.swt.widgets.Display;\r
-import org.eclipse.swt.widgets.Group;\r
-import org.eclipse.swt.widgets.Label;\r
-import org.eclipse.swt.widgets.Shell;\r
-import org.eclipse.swt.widgets.Text;\r
-\r
-public class CustomTxtParserInputWizardPage extends WizardPage {\r
-\r
-    private static final String DEFAULT_REGEX = "\\s*(.*\\S)"; //$NON-NLS-1$\r
-    private static final String DEFAULT_TIMESTAMP_FORMAT = "yyyy-MM-dd HH:mm:ss.SSS"; //$NON-NLS-1$\r
-    private static final String SIMPLE_DATE_FORMAT_URL = "http://java.sun.com/javase/6/docs/api/java/text/SimpleDateFormat.html#skip-navbar_top"; //$NON-NLS-1$\r
-    private static final String PATTERN_URL = "http://java.sun.com/javase/6/docs/api/java/util/regex/Pattern.html#sum"; //$NON-NLS-1$\r
-    private static final Image lineImage = Activator.getDefault().getImageFromPath("/icons/elcl16/line_icon.gif"); //$NON-NLS-1$\r
-    private static final Image addImage = Activator.getDefault().getImageFromPath("/icons/elcl16/add_button.gif"); //$NON-NLS-1$\r
-    private static final Image addNextImage = Activator.getDefault().getImageFromPath("/icons/elcl16/addnext_button.gif"); //$NON-NLS-1$\r
-    private static final Image addChildImage = Activator.getDefault().getImageFromPath("/icons/elcl16/addchild_button.gif"); //$NON-NLS-1$\r
-    private static final Image deleteImage = Activator.getDefault().getImageFromPath("/icons/elcl16/delete_button.gif"); //$NON-NLS-1$\r
-    private static final Image moveUpImage = Activator.getDefault().getImageFromPath("/icons/elcl16/moveup_button.gif"); //$NON-NLS-1$\r
-    private static final Image moveDownImage = Activator.getDefault().getImageFromPath("/icons/elcl16/movedown_button.gif"); //$NON-NLS-1$\r
-    private static final Image helpImage = Activator.getDefault().getImageFromPath("/icons/elcl16/help_button.gif"); //$NON-NLS-1$\r
-    private static final Color COLOR_BLACK = Display.getCurrent().getSystemColor(SWT.COLOR_BLACK);\r
-    private static final Color COLOR_LIGHT_GREEN = new Color(Display.getDefault(), 192, 255, 192);\r
-    private static final Color COLOR_GREEN = Display.getCurrent().getSystemColor(SWT.COLOR_GREEN);\r
-    private static final Color COLOR_LIGHT_YELLOW = new Color(Display.getDefault(), 255, 255, 192);\r
-    private static final Color COLOR_YELLOW = Display.getCurrent().getSystemColor(SWT.COLOR_YELLOW);\r
-    private static final Color COLOR_LIGHT_MAGENTA = new Color(Display.getDefault(), 255, 192, 255);\r
-    private static final Color COLOR_MAGENTA = Display.getCurrent().getSystemColor(SWT.COLOR_MAGENTA);\r
-    private static final Color COLOR_LIGHT_RED = new Color(Display.getDefault(), 255, 192, 192);\r
-    private static final Color COLOR_TEXT_BACKGROUND = Display.getCurrent().getSystemColor(SWT.COLOR_WHITE);\r
-    private static final Color COLOR_WIDGET_BACKGROUND = Display.getCurrent().getSystemColor(SWT.COLOR_WIDGET_BACKGROUND);\r
-\r
-    private final ISelection selection;\r
-    private CustomTxtTraceDefinition definition;\r
-    private String editDefinitionName;\r
-    private String defaultDescription;\r
-    private Line selectedLine;\r
-    private Composite container;\r
-    private Text logtypeText;\r
-    private Text timestampOutputFormatText;\r
-    private Text timestampPreviewText;\r
-    private ScrolledComposite treeScrolledComposite;\r
-    private ScrolledComposite lineScrolledComposite;\r
-    private TreeViewer treeViewer;\r
-    private Composite treeContainer;\r
-    private Composite lineContainer;\r
-    private StyledText inputText;\r
-    private Font fixedFont;\r
-    private UpdateListener updateListener;\r
-    private Browser helpBrowser;\r
-\r
-    // variables used recursively through line traversal\r
-    private String timeStampFormat;\r
-    private boolean timestampFound;\r
-\r
-    protected CustomTxtParserInputWizardPage(ISelection selection, CustomTxtTraceDefinition definition) {\r
-        super("CustomParserWizardPage"); //$NON-NLS-1$\r
-        if (definition == null) {\r
-            setTitle(Messages.CustomTxtParserInputWizardPage_windowTitleNew);\r
-            defaultDescription = Messages.CustomTxtParserInputWizardPage_descriptionNew;\r
-        } else {\r
-            setTitle(Messages.CustomTxtParserInputWizardPage_windowTitleEdit);\r
-            defaultDescription = Messages.CustomTxtParserInputWizardPage_desccriptionEdit;\r
-        }\r
-        setDescription(defaultDescription);\r
-        this.selection = selection;\r
-        this.definition = definition;\r
-        if (definition != null) {\r
-            this.editDefinitionName = definition.definitionName;\r
-        }\r
-    }\r
-\r
-       @Override\r
-    public void createControl(Composite parent) {\r
-        container = new Composite(parent, SWT.NULL);\r
-        container.setLayout(new GridLayout());\r
-\r
-        updateListener = new UpdateListener();\r
-\r
-        Composite headerComposite = new Composite(container, SWT.FILL);\r
-        GridLayout headerLayout = new GridLayout(5, false);\r
-        headerLayout.marginHeight = 0;\r
-        headerLayout.marginWidth = 0;\r
-        headerComposite.setLayout(headerLayout);\r
-        headerComposite.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));\r
-\r
-        Label logtypeLabel = new Label(headerComposite, SWT.NULL);\r
-        logtypeLabel.setText(Messages.CustomTxtParserInputWizardPage_logType);\r
-\r
-        logtypeText = new Text(headerComposite, SWT.BORDER | SWT.SINGLE);\r
-        logtypeText.setLayoutData(new GridData(120, SWT.DEFAULT));\r
-\r
-        Label timestampFormatLabel = new Label(headerComposite, SWT.NULL);\r
-        timestampFormatLabel.setText(Messages.CustomTxtParserInputWizardPage_timestampFormat);\r
-\r
-        timestampOutputFormatText = new Text(headerComposite, SWT.BORDER | SWT.SINGLE);\r
-        timestampOutputFormatText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));\r
-        timestampOutputFormatText.setText(DEFAULT_TIMESTAMP_FORMAT);\r
-\r
-        Button dateFormatHelpButton = new Button(headerComposite, SWT.PUSH);\r
-        dateFormatHelpButton.setImage(helpImage);\r
-        dateFormatHelpButton.setToolTipText(Messages.CustomTxtParserInputWizardPage_dateFormatHelp);\r
-        dateFormatHelpButton.addSelectionListener(new SelectionAdapter() {\r
-            @Override\r
-                       public void widgetSelected(SelectionEvent e) {\r
-                openHelpShell(SIMPLE_DATE_FORMAT_URL);\r
-            }\r
-        });\r
-\r
-        Label timestampPreviewLabel = new Label(headerComposite, SWT.NULL);\r
-        timestampPreviewLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 3, 1));\r
-        timestampPreviewLabel.setText(Messages.CustomTxtParserInputWizardPage_preview);\r
-\r
-        timestampPreviewText = new Text(headerComposite, SWT.BORDER | SWT.SINGLE | SWT.READ_ONLY);\r
-        timestampPreviewText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1));\r
-        timestampPreviewText.setText(Messages.CustomTxtParserInputWizardPage_noMatchingTimestamp);\r
-\r
-        Composite buttonBar = new Composite(container, SWT.NONE);\r
-        GridLayout buttonBarLayout = new GridLayout(5, false);\r
-        buttonBarLayout.marginHeight = 0;\r
-        buttonBarLayout.marginWidth = 0;\r
-        buttonBar.setLayout(buttonBarLayout);\r
-\r
-        Button removeButton = new Button(buttonBar, SWT.PUSH);\r
-        removeButton.setImage(deleteImage);\r
-        removeButton.setToolTipText(Messages.CustomTxtParserInputWizardPage_removeLine);\r
-        removeButton.addSelectionListener(new SelectionAdapter() {\r
-               @Override\r
-            public void widgetSelected(SelectionEvent e) {\r
-                if (treeViewer.getSelection().isEmpty() || selectedLine == null) {\r
-                    return;\r
-                }\r
-                removeLine();\r
-                InputLine inputLine = (InputLine) ((IStructuredSelection) treeViewer.getSelection()).getFirstElement();\r
-                if (inputLine.parentInput == null) {\r
-                    definition.inputs.remove(inputLine);\r
-                } else {\r
-                    inputLine.parentInput.childrenInputs.remove(inputLine);\r
-                }\r
-                treeViewer.refresh();\r
-                validate();\r
-                updatePreviews();\r
-            }\r
-        });\r
-        Button addNextButton = new Button(buttonBar, SWT.PUSH);\r
-        addNextButton.setImage(addNextImage);\r
-        addNextButton.setToolTipText(Messages.CustomTxtParserInputWizardPage_addNextLine);\r
-        addNextButton.addSelectionListener(new SelectionAdapter() {\r
-               @Override\r
-            public void widgetSelected(SelectionEvent e) {\r
-                InputLine inputLine = new InputLine(Cardinality.ZERO_OR_MORE, "", null); //$NON-NLS-1$\r
-                if (((List<?>) treeViewer.getInput()).size() == 0) {\r
-                    definition.inputs.add(inputLine);\r
-                } else if (treeViewer.getSelection().isEmpty()) {\r
-                    return;\r
-                } else {\r
-                    InputLine previousInputLine = (InputLine) ((IStructuredSelection) treeViewer.getSelection()).getFirstElement();\r
-                    if (previousInputLine.parentInput == null) {\r
-                        for (int i = 0; i < definition.inputs.size(); i++) {\r
-                            if (definition.inputs.get(i).equals(previousInputLine)) {\r
-                                definition.inputs.add(i + 1, inputLine);\r
-                            }\r
-                        }\r
-                    } else {\r
-                        previousInputLine.addNext(inputLine);\r
-                    }\r
-                }\r
-                treeViewer.refresh();\r
-                treeViewer.setSelection(new StructuredSelection(inputLine), true);\r
-            }\r
-        });\r
-        Button addChildButton = new Button(buttonBar, SWT.PUSH);\r
-        addChildButton.setImage(addChildImage);\r
-        addChildButton.setToolTipText(Messages.CustomTxtParserInputWizardPage_addChildLine);\r
-        addChildButton.addSelectionListener(new SelectionAdapter() {\r
-               @Override\r
-               public void widgetSelected(SelectionEvent e) {\r
-                InputLine inputLine = new InputLine(Cardinality.ZERO_OR_MORE, "", null); //$NON-NLS-1$\r
-                if (((List<?>) treeViewer.getInput()).size() == 0) {\r
-                    definition.inputs.add(inputLine);\r
-                } else if (treeViewer.getSelection().isEmpty()) {\r
-                    return;\r
-                } else {\r
-                    InputLine parentInputLine = (InputLine) ((IStructuredSelection) treeViewer.getSelection()).getFirstElement();\r
-                    parentInputLine.addChild(inputLine);\r
-                }\r
-                treeViewer.refresh();\r
-                treeViewer.setSelection(new StructuredSelection(inputLine), true);\r
-            }\r
-        });\r
-        Button moveUpButton = new Button(buttonBar, SWT.PUSH);\r
-        moveUpButton.setImage(moveUpImage);\r
-        moveUpButton.setToolTipText(Messages.CustomTxtParserInputWizardPage_moveUp);\r
-        moveUpButton.addSelectionListener(new SelectionAdapter() {\r
-               @Override\r
-            public void widgetSelected(SelectionEvent e) {\r
-                if (treeViewer.getSelection().isEmpty()) {\r
-                    return;\r
-                }\r
-                InputLine inputLine = (InputLine) ((IStructuredSelection) treeViewer.getSelection()).getFirstElement();\r
-                if (inputLine.parentInput == null) {\r
-                    for (int i = 1; i < definition.inputs.size(); i++) {\r
-                        if (definition.inputs.get(i).equals(inputLine)) {\r
-                            definition.inputs.add(i - 1 , definition.inputs.remove(i));\r
-                            break;\r
-                        }\r
-                    }\r
-                } else {\r
-                    inputLine.moveUp();\r
-                }\r
-                treeViewer.refresh();\r
-                validate();\r
-                updatePreviews();\r
-            }\r
-        });\r
-        Button moveDownButton = new Button(buttonBar, SWT.PUSH);\r
-        moveDownButton.setImage(moveDownImage);\r
-        moveDownButton.setToolTipText(Messages.CustomTxtParserInputWizardPage_moveDown);\r
-        moveDownButton.addSelectionListener(new SelectionAdapter() {\r
-               @Override\r
-            public void widgetSelected(SelectionEvent e) {\r
-                if (treeViewer.getSelection().isEmpty()) {\r
-                    return;\r
-                }\r
-                InputLine inputLine = (InputLine) ((IStructuredSelection) treeViewer.getSelection()).getFirstElement();\r
-                if (inputLine.parentInput == null) {\r
-                    for (int i = 0; i < definition.inputs.size() - 1; i++) {\r
-                        if (definition.inputs.get(i).equals(inputLine)) {\r
-                            definition.inputs.add(i + 1 , definition.inputs.remove(i));\r
-                            break;\r
-                        }\r
-                    }\r
-                } else {\r
-                    inputLine.moveDown();\r
-                }\r
-                treeViewer.refresh();\r
-                validate();\r
-                updatePreviews();\r
-            }\r
-        });\r
-\r
-        SashForm vSash = new SashForm(container, SWT.VERTICAL);\r
-        vSash.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));\r
-        vSash.setBackground(vSash.getDisplay().getSystemColor(SWT.COLOR_GRAY));\r
-\r
-        SashForm hSash = new SashForm(vSash, SWT.HORIZONTAL);\r
-        hSash.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));\r
-\r
-        treeScrolledComposite = new ScrolledComposite(hSash, SWT.V_SCROLL | SWT.H_SCROLL);\r
-        GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true);\r
-        gd.heightHint = 200;\r
-        gd.widthHint = 200;\r
-        treeScrolledComposite.setLayoutData(gd);\r
-        treeContainer = new Composite(treeScrolledComposite, SWT.NONE);\r
-        treeContainer.setLayout(new FillLayout());\r
-        treeScrolledComposite.setContent(treeContainer);\r
-        treeScrolledComposite.setExpandHorizontal(true);\r
-        treeScrolledComposite.setExpandVertical(true);\r
-\r
-        treeViewer = new TreeViewer(treeContainer, SWT.SINGLE | SWT.BORDER);\r
-        treeViewer.setContentProvider(new InputLineTreeNodeContentProvider());\r
-        treeViewer.setLabelProvider(new InputLineTreeLabelProvider());\r
-        treeViewer.addSelectionChangedListener(new InputLineTreeSelectionChangedListener());\r
-        treeContainer.layout();\r
-\r
-        treeScrolledComposite.setMinSize(treeContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).x, treeContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).y);\r
-\r
-        lineScrolledComposite = new ScrolledComposite(hSash, SWT.V_SCROLL);\r
-        lineScrolledComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));\r
-        lineContainer = new Composite(lineScrolledComposite, SWT.NONE);\r
-        GridLayout linesLayout = new GridLayout();\r
-        linesLayout.marginHeight = 1;\r
-        linesLayout.marginWidth = 0;\r
-        lineContainer.setLayout(linesLayout);\r
-        lineScrolledComposite.setContent(lineContainer);\r
-        lineScrolledComposite.setExpandHorizontal(true);\r
-        lineScrolledComposite.setExpandVertical(true);\r
-\r
-        if (definition == null) {\r
-            definition = new CustomTxtTraceDefinition();\r
-            definition.inputs.add(new InputLine(Cardinality.ZERO_OR_MORE, DEFAULT_REGEX,\r
-                    Arrays.asList(new InputData(CustomTraceDefinition.TAG_MESSAGE, CustomTraceDefinition.ACTION_SET))));\r
-        }\r
-        loadDefinition(definition);\r
-        treeViewer.expandAll();\r
-        lineContainer.layout();\r
-\r
-        logtypeText.addModifyListener(updateListener);\r
-        timestampOutputFormatText.addModifyListener(updateListener);\r
-\r
-        lineScrolledComposite.setMinSize(lineContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).x, lineContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).y-1);\r
-\r
-        hSash.setWeights(new int[] {1, 2});\r
-\r
-        Composite sashBottom = new Composite(vSash, SWT.NONE);\r
-        GridLayout sashBottomLayout = new GridLayout(3, false);\r
-        sashBottomLayout.marginHeight = 0;\r
-        sashBottomLayout.marginWidth = 0;\r
-        sashBottom.setLayout(sashBottomLayout);\r
-\r
-        Label previewLabel = new Label(sashBottom, SWT.NULL);\r
-        previewLabel.setText(Messages.CustomTxtParserInputWizardPage_previewInput);\r
-        previewLabel.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));\r
-\r
-        Button highlightAllButton = new Button(sashBottom, SWT.PUSH);\r
-        highlightAllButton.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false));\r
-        highlightAllButton.setText(Messages.CustomTxtParserInputWizardPage_highlightAll);\r
-        highlightAllButton.addSelectionListener(new SelectionAdapter() {\r
-               @Override\r
-            public void widgetSelected(SelectionEvent e) {\r
-                updatePreviews(true);\r
-            }\r
-        });\r
-\r
-        Button legendButton = new Button(sashBottom, SWT.PUSH);\r
-        legendButton.setImage(helpImage);\r
-        legendButton.setToolTipText(Messages.CustomTxtParserInputWizardPage_previewLegend);\r
-        legendButton.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false));\r
-        legendButton.addSelectionListener(new SelectionAdapter() {\r
-               @Override\r
-            public void widgetSelected(SelectionEvent e) {\r
-                openLegend();\r
-            }\r
-        });\r
-\r
-        inputText = new StyledText(sashBottom, SWT.MULTI | SWT.V_SCROLL | SWT.H_SCROLL);\r
-        if (fixedFont == null) {\r
-            if (System.getProperty("os.name").contains("Windows")) { //$NON-NLS-1$  //$NON-NLS-2$\r
-                fixedFont = new Font(Display.getCurrent(), new FontData("Courier New", 10, SWT.NORMAL)); //$NON-NLS-1$\r
-            } else {\r
-                fixedFont = new Font(Display.getCurrent(), new FontData("Monospace", 10, SWT.NORMAL)); //$NON-NLS-1$\r
-            }\r
-        }\r
-        inputText.setFont(fixedFont);\r
-        gd = new GridData(SWT.FILL, SWT.FILL, true, true, 3, 1);\r
-        gd.heightHint = inputText.computeSize(SWT.DEFAULT, inputText.getLineHeight() * 4).y;\r
-        gd.widthHint = 800;\r
-        inputText.setLayoutData(gd);\r
-        inputText.setText(getSelectionText());\r
-        inputText.addModifyListener(updateListener);\r
-\r
-        vSash.setWeights(new int[] {hSash.computeSize(SWT.DEFAULT, SWT.DEFAULT).y, sashBottom.computeSize(SWT.DEFAULT, SWT.DEFAULT).y});\r
-\r
-        setControl(container);\r
-\r
-        validate();\r
-        updatePreviews();\r
-    }\r
-\r
-    private static class InputLineTreeNodeContentProvider implements ITreeContentProvider {\r
-\r
-       @Override\r
-        public Object[] getElements(Object inputElement) {\r
-            return ((List<?>) inputElement).toArray();\r
-        }\r
-\r
-       @Override\r
-        public Object[] getChildren(Object parentElement) {\r
-            InputLine inputLine = (InputLine) parentElement;\r
-            if (inputLine.childrenInputs == null) {\r
-                return new InputLine[0];\r
-            }\r
-            return inputLine.childrenInputs.toArray();\r
-        }\r
-\r
-       @Override\r
-        public boolean hasChildren(Object element) {\r
-            InputLine inputLine = (InputLine) element;\r
-            return (inputLine.childrenInputs != null && inputLine.childrenInputs.size() > 0);\r
-        }\r
-\r
-       @Override\r
-        public void dispose() {\r
-        }\r
-\r
-       @Override\r
-        public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {\r
-        }\r
-\r
-       @Override\r
-        public Object getParent(Object element) {\r
-            InputLine inputLine = (InputLine) element;\r
-            return inputLine.parentInput;\r
-        }\r
-    }\r
-\r
-    private class InputLineTreeLabelProvider extends ColumnLabelProvider {\r
-\r
-        @Override\r
-        public Image getImage(Object element) {\r
-            return lineImage;\r
-        }\r
-\r
-        @Override\r
-        public String getText(Object element) {\r
-            InputLine inputLine = (InputLine) element;\r
-            if (inputLine.parentInput == null) {\r
-                return "Root Line " + getName(inputLine) + " " + inputLine.cardinality.toString() + " : " + inputLine.getRegex(); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$\r
-            }\r
-            return "Line " + getName(inputLine) + " " + inputLine.cardinality.toString() + " : " + inputLine.getRegex(); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$\r
-        }\r
-    }\r
-\r
-    private class InputLineTreeSelectionChangedListener implements ISelectionChangedListener {\r
-       @Override\r
-        public void selectionChanged(SelectionChangedEvent event) {\r
-            if (selectedLine != null) {\r
-                selectedLine.dispose();\r
-            }\r
-            if (!(event.getSelection().isEmpty()) && event.getSelection() instanceof IStructuredSelection) {\r
-                IStructuredSelection selection = (IStructuredSelection) event.getSelection();\r
-                InputLine inputLine = (InputLine) selection.getFirstElement();\r
-                selectedLine = new Line(lineContainer, getName(inputLine), inputLine);\r
-                lineContainer.layout();\r
-                lineScrolledComposite.setMinSize(lineContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).x, lineContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).y-1);\r
-                container.layout();\r
-                validate();\r
-                updatePreviews();\r
-            }\r
-        }\r
-    }\r
-\r
-    /* (non-Javadoc)\r
-     * @see org.eclipse.jface.dialogs.DialogPage#dispose()\r
-     */\r
-    @Override\r
-    public void dispose() {\r
-        if (fixedFont != null) {\r
-            fixedFont.dispose();\r
-            fixedFont = null;\r
-        }\r
-        super.dispose();\r
-    }\r
-\r
-    private void loadDefinition(CustomTxtTraceDefinition def) {\r
-        logtypeText.setText(def.definitionName);\r
-        timestampOutputFormatText.setText(def.timeStampOutputFormat);\r
-        treeViewer.setInput(def.inputs);\r
-        if (def.inputs.size() > 0) {\r
-            InputLine inputLine = def.inputs.get(0);\r
-            treeViewer.setSelection(new StructuredSelection(inputLine));\r
-        }\r
-    }\r
-\r
-    private String getName(InputLine inputLine) {\r
-        if (inputLine.parentInput == null) {\r
-            return Integer.toString(definition.inputs.indexOf(inputLine)+1);\r
-        }\r
-        return getName(inputLine.parentInput) + "." + Integer.toString(inputLine.parentInput.childrenInputs.indexOf(inputLine)+1); //$NON-NLS-1$\r
-    }\r
-\r
-    public List<String> getInputNames() {\r
-        List<String> inputs = new ArrayList<String>();\r
-        for (InputLine inputLine : definition.inputs) {\r
-            for (String inputName : getInputNames(inputLine)) {\r
-                if (!inputs.contains(inputName)) {\r
-                    inputs.add(inputName);\r
-                }\r
-            }\r
-        }\r
-        return inputs;\r
-    }\r
-\r
-    public List<String> getInputNames(InputLine inputLine) {\r
-        List<String> inputs = new ArrayList<String>();\r
-        if (inputLine.columns != null) {\r
-            for (InputData inputData : inputLine.columns) {\r
-                String inputName = inputData.name;\r
-                if (!inputs.contains(inputName)) {\r
-                    inputs.add(inputName);\r
-                }\r
-            }\r
-        }\r
-        if (inputLine.childrenInputs != null) {\r
-            for (InputLine childInputLine : inputLine.childrenInputs) {\r
-                for (String inputName : getInputNames(childInputLine)) {\r
-                    if (!inputs.contains(inputName)) {\r
-                        inputs.add(inputName);\r
-                    }\r
-                }\r
-            }\r
-        }\r
-        return inputs;\r
-    }\r
-\r
-    private void removeLine() {\r
-        selectedLine.dispose();\r
-        selectedLine = null;\r
-        lineContainer.layout();\r
-        lineScrolledComposite.setMinSize(lineContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).x, lineContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).y-1);\r
-        container.layout();\r
-    }\r
-\r
-    private String getSelectionText() {\r
-        if (this.selection instanceof IStructuredSelection) {\r
-            Object selection = ((IStructuredSelection)this.selection).getFirstElement();\r
-            if (selection instanceof IFile) {\r
-                IFile file = (IFile)selection;\r
-                BufferedReader reader = null;\r
-                try {\r
-                    reader = new BufferedReader(new InputStreamReader(file.getContents()));\r
-                    StringBuilder sb = new StringBuilder();\r
-                    String line = null;\r
-                    while ((line = reader.readLine()) != null) {\r
-                        sb.append(line + "\n"); //$NON-NLS-1$\r
-                    }\r
-                    return sb.toString();\r
-                } catch (CoreException e) {\r
-                    return ""; //$NON-NLS-1$\r
-                } catch (IOException e) {\r
-                    return ""; //$NON-NLS-1$\r
-                } finally {\r
-                    if (reader != null) {\r
-                        try {\r
-                            reader.close();\r
-                        } catch (IOException e) {\r
-                        }\r
-                    }\r
-                }\r
-            }\r
-        }\r
-        return ""; //$NON-NLS-1$\r
-    }\r
-\r
-    private void updatePreviews() {\r
-        updatePreviews(false);\r
-    }\r
-\r
-    private void updatePreviews(boolean updateAll) {\r
-        if (inputText == null) {\r
-            // early update during construction\r
-            return;\r
-        }\r
-        inputText.setStyleRanges(new StyleRange[] {});\r
-\r
-        Scanner scanner = new Scanner(inputText.getText());\r
-        scanner.useDelimiter("\n"); //$NON-NLS-1$\r
-        int rawPos = 0;\r
-        String skip; // skip starting delimiters\r
-        if ((skip = scanner.findWithinHorizon("\\A\n+", 0)) != null) { //$NON-NLS-1$\r
-            rawPos += skip.length();\r
-        }\r
-\r
-        timeStampFormat = null;\r
-        if (selectedLine != null) {\r
-            for (InputGroup input : selectedLine.inputs) {\r
-                input.previewText.setText(Messages.CustomTxtParserInputWizardPage_noMathcingLine);\r
-            }\r
-        }\r
-\r
-        Map<String, String> data = new HashMap<String, String>();\r
-        int rootLineMatches = 0;\r
-        String firstEntryTimeStamp = null;\r
-        String firstEntryTimeStampInputFormat = null;\r
-        String log = null;\r
-    event:\r
-        while (scanner.hasNext()) {\r
-            if (rootLineMatches > 0 && !updateAll) {\r
-                break;\r
-            }\r
-            if (log == null) {\r
-                log = scanner.next();\r
-            }\r
-            int length = log.length();\r
-            for (InputLine rootInputLine : definition.inputs) {\r
-                Pattern pattern;\r
-                try {\r
-                    pattern = rootInputLine.getPattern();\r
-                } catch (PatternSyntaxException e) {\r
-                    continue;\r
-                }\r
-                Matcher matcher = pattern.matcher(log);\r
-                if (matcher.find()) {\r
-                    rootLineMatches++;\r
-                    inputText.setStyleRange(new StyleRange(rawPos, length,\r
-                            COLOR_BLACK, COLOR_YELLOW, SWT.ITALIC));\r
-                    data = new HashMap<String, String>();\r
-                    timeStampFormat = null;\r
-                    updatePreviewLine(rootInputLine, matcher, data, rawPos, rootLineMatches);\r
-                    if (rootLineMatches == 1) {\r
-                        firstEntryTimeStamp = data.get(CustomTraceDefinition.TAG_TIMESTAMP);\r
-                        firstEntryTimeStampInputFormat = timeStampFormat;\r
-                    }\r
-                    HashMap<InputLine, Integer> countMap = new HashMap<InputLine, Integer>();\r
-                    InputLine currentInput = null;\r
-                    if (rootInputLine.childrenInputs != null && rootInputLine.childrenInputs.size() > 0) {\r
-                        currentInput = rootInputLine.childrenInputs.get(0);\r
-                        countMap.put(currentInput, 0);\r
-                    }\r
-                    rawPos += length + 1; // +1 for \n\r
-                    while (scanner.hasNext()) {\r
-                        log = scanner.next();\r
-                        length = log.length();\r
-                        boolean processed = false;\r
-                        if (currentInput == null) {\r
-                            for (InputLine input : definition.inputs) {\r
-                                matcher = input.getPattern().matcher(log);\r
-                                if (matcher.find()) {\r
-                                    continue event;\r
-                                }\r
-                            }\r
-                        } else {\r
-                            if (countMap.get(currentInput) >= currentInput.getMinCount()) {\r
-                                List<InputLine> nextInputs = currentInput.getNextInputs(countMap);\r
-                                if (nextInputs.size() == 0 || nextInputs.get(nextInputs.size() - 1).getMinCount() == 0) {\r
-                                    for (InputLine input : definition.inputs) {\r
-                                        matcher = input.getPattern().matcher(log);\r
-                                        if (matcher.find()) {\r
-                                            continue event;\r
-                                        }\r
-                                    }\r
-                                }\r
-                                for (InputLine input : nextInputs) {\r
-                                    matcher = input.getPattern().matcher(log);\r
-                                    if (matcher.find()) {\r
-                                        inputText.setStyleRange(new StyleRange(rawPos, length,\r
-                                                COLOR_BLACK, COLOR_LIGHT_YELLOW, SWT.ITALIC));\r
-                                        currentInput = input;\r
-                                        updatePreviewLine(currentInput, matcher, data, rawPos, rootLineMatches);\r
-                                        if (countMap.get(currentInput) == null) {\r
-                                            countMap.put(currentInput, 1);\r
-                                        } else {\r
-                                            countMap.put(currentInput, countMap.get(currentInput) + 1);\r
-                                        }\r
-                                        Iterator<InputLine> iter = countMap.keySet().iterator();\r
-                                        while (iter.hasNext()) {\r
-                                            InputLine inputLine = iter.next();\r
-                                            if (inputLine.level > currentInput.level) {\r
-                                                iter.remove();\r
-                                            }\r
-                                        }\r
-                                        if (currentInput.childrenInputs != null && currentInput.childrenInputs.size() > 0) {\r
-                                            currentInput = currentInput.childrenInputs.get(0);\r
-                                            countMap.put(currentInput, 0);\r
-                                        } else {\r
-                                            if (countMap.get(currentInput) >= currentInput.getMaxCount()) {\r
-                                                if (currentInput.getNextInputs(countMap).size() > 0) {\r
-                                                    currentInput = currentInput.getNextInputs(countMap).get(0);\r
-                                                    if (countMap.get(currentInput) == null) {\r
-                                                        countMap.put(currentInput, 0);\r
-                                                    }\r
-                                                    iter = countMap.keySet().iterator();\r
-                                                    while (iter.hasNext()) {\r
-                                                        InputLine inputLine = iter.next();\r
-                                                        if (inputLine.level > currentInput.level) {\r
-                                                            iter.remove();\r
-                                                        }\r
-                                                    }\r
-                                                } else {\r
-                                                    currentInput = null;\r
-                                                }\r
-                                            }\r
-                                        }\r
-                                        processed = true;\r
-                                        break;\r
-                                    }\r
-                                }\r
-                            }\r
-                            if (! processed) {\r
-                                matcher = currentInput.getPattern().matcher(log);\r
-                                if (matcher.find()) {\r
-                                    inputText.setStyleRange(new StyleRange(rawPos, length,\r
-                                            COLOR_BLACK, COLOR_LIGHT_YELLOW, SWT.ITALIC));\r
-                                    updatePreviewLine(currentInput, matcher, data, rawPos, rootLineMatches);\r
-                                    countMap.put(currentInput, countMap.get(currentInput) + 1);\r
-                                    if (currentInput.childrenInputs != null && currentInput.childrenInputs.size() > 0) {\r
-                                        currentInput = currentInput.childrenInputs.get(0);\r
-                                        countMap.put(currentInput, 0);\r
-                                    } else {\r
-                                        if (countMap.get(currentInput) >= currentInput.getMaxCount()) {\r
-                                            if (currentInput.getNextInputs(countMap).size() > 0) {\r
-                                                currentInput = currentInput.getNextInputs(countMap).get(0);\r
-                                                if (countMap.get(currentInput) == null) {\r
-                                                    countMap.put(currentInput, 0);\r
-                                                }\r
-                                                Iterator<InputLine> iter = countMap.keySet().iterator();\r
-                                                while (iter.hasNext()) {\r
-                                                    InputLine inputLine = iter.next();\r
-                                                    if (inputLine.level > currentInput.level) {\r
-                                                        iter.remove();\r
-                                                    }\r
-                                                }\r
-                                            } else {\r
-                                                currentInput = null;\r
-                                            }\r
-                                        }\r
-                                    }\r
-                                }\r
-                            }\r
-                        }\r
-                        rawPos += length + 1; // +1 for \n\r
-                    }\r
-\r
-                    break;\r
-                }\r
-            }\r
-            rawPos += length + 1; // +1 for \n\r
-            log = null;\r
-        }\r
-        scanner.close();\r
-        if (rootLineMatches == 1) {\r
-            firstEntryTimeStamp = data.get(CustomTraceDefinition.TAG_TIMESTAMP);\r
-            firstEntryTimeStampInputFormat = timeStampFormat;\r
-        }\r
-        if (firstEntryTimeStamp == null) {\r
-            timestampPreviewText.setText(Messages.CustomTxtParserInputWizardPage_noTimestampGroup);\r
-            if (selectedLine != null) {\r
-                for (InputGroup group : selectedLine.inputs) {\r
-                    if (group.tagCombo.getText().equals(CustomTraceDefinition.TAG_TIMESTAMP)) {\r
-                        timestampPreviewText.setText(Messages.CustomTxtParserInputWizardPage_noMatchingTimestamp);\r
-                        break;\r
-                    }\r
-                }\r
-            }\r
-        } else {\r
-            try {\r
-                SimpleDateFormat dateFormat = new SimpleDateFormat(firstEntryTimeStampInputFormat);\r
-                Date date = dateFormat.parse(firstEntryTimeStamp);\r
-                dateFormat = new SimpleDateFormat(timestampOutputFormatText.getText().trim());\r
-                timestampPreviewText.setText(dateFormat.format(date));\r
-            } catch (ParseException e) {\r
-                timestampPreviewText.setText("*parse exception* [" + firstEntryTimeStamp + "] <> [" + firstEntryTimeStampInputFormat + "]"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$\r
-            } catch (IllegalArgumentException e) {\r
-                timestampPreviewText.setText("*parse exception* [Illegal Argument]"); //$NON-NLS-1$\r
-            }\r
-\r
-        }\r
-    }\r
-\r
-    private void updatePreviewLine(InputLine line, Matcher matcher, Map<String, String> data, int rawPos, int rootLineMatches) {\r
-        for (int i = 0; i < line.columns.size(); i++) {\r
-            InputData input = line.columns.get(i);\r
-            if (i < matcher.groupCount() && matcher.group(i+1) != null) {\r
-                if (line.parentInput == null) {\r
-                    inputText.setStyleRange(new StyleRange(rawPos + matcher.start(i+1), matcher.end(i+1) - matcher.start(i+1),\r
-                            COLOR_BLACK, COLOR_GREEN, SWT.BOLD));\r
-                } else {\r
-                    inputText.setStyleRange(new StyleRange(rawPos + matcher.start(i+1), matcher.end(i+1) - matcher.start(i+1),\r
-                            COLOR_BLACK, COLOR_LIGHT_GREEN, SWT.BOLD));\r
-                }\r
-                String value = matcher.group(i+1).trim();\r
-                if (selectedLine != null && selectedLine.inputLine.equals(line) && rootLineMatches == 1) {\r
-                    if (selectedLine.inputs.get(i).previewText.getText().equals(Messages.CustomTxtParserInputWizardPage_noMatchingLine)) {\r
-                        selectedLine.inputs.get(i).previewText.setText(value);\r
-                    }\r
-                }\r
-                if (value.length() == 0) {\r
-                    continue;\r
-                }\r
-                if (input.action == CustomTraceDefinition.ACTION_SET) {\r
-                    data.put(input.name, value);\r
-                    if (input.name.equals(CustomTraceDefinition.TAG_TIMESTAMP)) {\r
-                        timeStampFormat = input.format;\r
-                    }\r
-                } else if (input.action == CustomTraceDefinition.ACTION_APPEND) {\r
-                    String s = data.get(input.name);\r
-                    if (s != null) {\r
-                        data.put(input.name, s + value);\r
-                    } else {\r
-                        data.put(input.name, value);\r
-                    }\r
-                    if (input.name.equals(CustomTraceDefinition.TAG_TIMESTAMP)) {\r
-                        if (timeStampFormat != null) {\r
-                            timeStampFormat += input.format;\r
-                        } else {\r
-                            timeStampFormat = input.format;\r
-                        }\r
-                    }\r
-                } else if (input.action == CustomTraceDefinition.ACTION_APPEND_WITH_SEPARATOR) {\r
-                    String s = data.get(input.name);\r
-                    if (s != null) {\r
-                        data.put(input.name, s + " | " + value); //$NON-NLS-1$\r
-                    } else {\r
-                        data.put(input.name, value);\r
-                    }\r
-                    if (input.name.equals(CustomTraceDefinition.TAG_TIMESTAMP)) {\r
-                        if (timeStampFormat != null) {\r
-                            timeStampFormat += " | " + input.format; //$NON-NLS-1$\r
-                        } else {\r
-                            timeStampFormat = input.format;\r
-                        }\r
-                    }\r
-                }\r
-            } else {\r
-                if (selectedLine != null && selectedLine.inputLine.equals(line) && rootLineMatches == 1) {\r
-                    if (selectedLine.inputs.get(i).previewText.getText().equals(Messages.CustomTxtParserInputWizardPage_noMatchingLine)) {\r
-                        selectedLine.inputs.get(i).previewText.setText(Messages.CustomTxtParserInputWizardPage_noMatchingGroup);\r
-                    }\r
-                }\r
-            }\r
-        }\r
-        // highlight the matching groups that have no corresponponding input\r
-        for (int i = line.columns.size(); i < matcher.groupCount(); i++) {\r
-            if (matcher.group(i+1) != null) {\r
-                if (line.parentInput == null) {\r
-                    inputText.setStyleRange(new StyleRange(rawPos + matcher.start(i+1), matcher.end(i+1) - matcher.start(i+1),\r
-                            COLOR_BLACK, COLOR_MAGENTA));\r
-                } else {\r
-                    inputText.setStyleRange(new StyleRange(rawPos + matcher.start(i+1), matcher.end(i+1) - matcher.start(i+1),\r
-                            COLOR_BLACK, COLOR_LIGHT_MAGENTA));\r
-                }\r
-            }\r
-        }\r
-    }\r
-\r
-    private void openHelpShell(String url) {\r
-        if (helpBrowser != null && !helpBrowser.isDisposed()) {\r
-            helpBrowser.getShell().setActive();\r
-            if (!helpBrowser.getUrl().equals(url)) {\r
-                helpBrowser.setUrl(url);\r
-            }\r
-            return;\r
-        }\r
-        final Shell helpShell = new Shell(getShell(), SWT.SHELL_TRIM);\r
-        helpShell.setLayout(new FillLayout());\r
-        helpBrowser = new Browser(helpShell, SWT.NONE);\r
-        helpBrowser.addTitleListener(new TitleListener() {\r
-               @Override\r
-           public void changed(TitleEvent event) {\r
-               helpShell.setText(event.title);\r
-           }\r
-        });\r
-        helpBrowser.setBounds(0,0,600,400);\r
-        helpShell.pack();\r
-        helpShell.open();\r
-        helpBrowser.setUrl(url);\r
-    }\r
-\r
-    private void openLegend() {\r
-        final String CG = Messages.CustomTxtParserInputWizardPage_capturedGroup;\r
-        final String UCG = Messages.CustomTxtParserInputWizardPage_unidentifiedCaptureGroup;\r
-        final String UT = Messages.CustomTxtParserInputWizardPage_uncapturedText;\r
-        int line1start = 0;\r
-        String line1 = Messages.CustomTxtParserInputWizardPage_nonMatchingLine;\r
-        int line2start = line1start + line1.length();\r
-        String line2 = Messages.CustomTxtParserInputWizardPage_matchingLineRoot + CG + " " + UCG + " " + UT + " \n";  //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$\r
-        int line3start = line2start + line2.length();\r
-        String line3 = Messages.CustomTxtParserInputWizardPage_matchingOtherLine + CG + " " + UCG + " " + UT + " \n"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$\r
-        int line4start = line3start + line3.length();\r
-        String line4 = Messages.CustomTxtParserInputWizardPage_matchingOtherLine + CG + " " + UCG + " " + UT + " \n"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$\r
-        int line5start = line4start + line4.length();\r
-        String line5 = Messages.CustomTxtParserInputWizardPage_nonMatchingLine;\r
-        int line6start = line5start + line5.length();\r
-        String line6 = Messages.CustomTxtParserInputWizardPage_matchingRootLine + CG + " " + UCG + " " + UT + " \n"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$\r
-\r
-        final Shell legendShell = new Shell(getShell(), SWT.DIALOG_TRIM);\r
-        legendShell.setLayout(new FillLayout());\r
-        StyledText legendText = new StyledText(legendShell, SWT.MULTI);\r
-        legendText.setFont(fixedFont);\r
-        legendText.setText(line1 + line2 + line3 + line4 + line5 + line6);\r
-        legendText.setStyleRange(new StyleRange(line2start, line2.length(), COLOR_BLACK, COLOR_YELLOW, SWT.ITALIC));\r
-        legendText.setStyleRange(new StyleRange(line3start, line3.length(), COLOR_BLACK, COLOR_LIGHT_YELLOW, SWT.ITALIC));\r
-        legendText.setStyleRange(new StyleRange(line4start, line4.length(), COLOR_BLACK, COLOR_LIGHT_YELLOW, SWT.ITALIC));\r
-        legendText.setStyleRange(new StyleRange(line6start, line6.length(), COLOR_BLACK, COLOR_YELLOW, SWT.ITALIC));\r
-        legendText.setStyleRange(new StyleRange(line2start + line2.indexOf(CG), CG.length(), COLOR_BLACK, COLOR_GREEN, SWT.BOLD));\r
-        legendText.setStyleRange(new StyleRange(line2start + line2.indexOf(UCG), UCG.length(), COLOR_BLACK, COLOR_MAGENTA));\r
-        legendText.setStyleRange(new StyleRange(line3start + line3.indexOf(CG), CG.length(), COLOR_BLACK, COLOR_LIGHT_GREEN, SWT.BOLD));\r
-        legendText.setStyleRange(new StyleRange(line3start + line3.indexOf(UCG), UCG.length(), COLOR_BLACK, COLOR_LIGHT_MAGENTA));\r
-        legendText.setStyleRange(new StyleRange(line4start + line4.indexOf(CG), CG.length(), COLOR_BLACK, COLOR_LIGHT_GREEN, SWT.BOLD));\r
-        legendText.setStyleRange(new StyleRange(line4start + line4.indexOf(UCG), UCG.length(), COLOR_BLACK, COLOR_LIGHT_MAGENTA));\r
-        legendText.setStyleRange(new StyleRange(line6start + line6.indexOf(CG), CG.length(), COLOR_BLACK, COLOR_GREEN, SWT.BOLD));\r
-        legendText.setStyleRange(new StyleRange(line6start + line6.indexOf(UCG), UCG.length(), COLOR_BLACK, COLOR_MAGENTA));\r
-        legendShell.setText(Messages.CustomTxtParserInputWizardPage_previewLegend);\r
-        legendShell.pack();\r
-        legendShell.open();\r
-    }\r
-\r
-    private class UpdateListener implements ModifyListener, SelectionListener {\r
-\r
-       @Override\r
-        public void modifyText(ModifyEvent e) {\r
-            validate();\r
-            updatePreviews();\r
-        }\r
-\r
-       @Override\r
-        public void widgetDefaultSelected(SelectionEvent e) {\r
-            validate();\r
-            updatePreviews();\r
-        }\r
-\r
-       @Override\r
-        public void widgetSelected(SelectionEvent e) {\r
-            validate();\r
-            updatePreviews();\r
-        }\r
-\r
-    }\r
-\r
-    private class Line {\r
-        private static final String INFINITY_STRING = "\u221E"; //$NON-NLS-1$\r
-        InputLine inputLine;\r
-        Group group;\r
-        Composite labelComposite;\r
-        Text regexText;\r
-        Composite cardinalityContainer;\r
-        Combo cardinalityCombo;\r
-        Label cardinalityMinLabel;\r
-        Text cardinalityMinText;\r
-        Label cardinalityMaxLabel;\r
-        Text cardinalityMaxText;\r
-        Button infiniteButton;\r
-        List<InputGroup> inputs = new ArrayList<InputGroup>();\r
-        Button addGroupButton;\r
-        Label addGroupLabel;\r
-\r
-        public Line(Composite parent, String name, InputLine inputLine) {\r
-            this.inputLine = inputLine;\r
-\r
-            group = new Group(parent, SWT.NONE);\r
-            group.setText(name);\r
-            group.setLayout(new GridLayout(2, false));\r
-            group.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));\r
-\r
-            labelComposite = new Composite(group, SWT.FILL);\r
-            GridLayout labelLayout = new GridLayout(1, false);\r
-            labelLayout.marginWidth = 0;\r
-            labelLayout.marginHeight = 0;\r
-            labelComposite.setLayout(labelLayout);\r
-            labelComposite.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false));\r
-\r
-            Label label = new Label(labelComposite, SWT.NULL);\r
-            label.setText(Messages.CustomTxtParserInputWizardPage_regularExpression);\r
-\r
-            Composite regexContainer = new Composite(group, SWT.NONE);\r
-            GridLayout regexLayout = new GridLayout(2, false);\r
-            regexLayout.marginHeight = 0;\r
-            regexLayout.marginWidth = 0;\r
-            regexContainer.setLayout(regexLayout);\r
-            regexContainer.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));\r
-\r
-            regexText = new Text(regexContainer, SWT.BORDER | SWT.SINGLE);\r
-            GridData gd = new GridData(SWT.FILL, SWT.CENTER, true, false);\r
-            gd.widthHint = 0;\r
-            regexText.setLayoutData(gd);\r
-            regexText.setText(inputLine.getRegex());\r
-            regexText.addModifyListener(updateListener);\r
-\r
-            Button regexHelpButton = new Button(regexContainer, SWT.PUSH);\r
-            regexHelpButton.setImage(helpImage);\r
-            regexHelpButton.setToolTipText(Messages.CustomTxtParserInputWizardPage_regularExpressionHelp);\r
-            regexHelpButton.addSelectionListener(new SelectionAdapter() {\r
-               @Override\r
-               public void widgetSelected(SelectionEvent e) {\r
-                    openHelpShell(PATTERN_URL);\r
-                }\r
-            });\r
-\r
-            label = new Label(group, SWT.NONE);\r
-            label.setText(Messages.CustomTxtParserInputWizardPage_cardinality);\r
-            label.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false));\r
-\r
-            cardinalityContainer = new Composite(group, SWT.NONE);\r
-            GridLayout cardinalityLayout = new GridLayout(6, false);\r
-            cardinalityLayout.marginHeight = 0;\r
-            cardinalityLayout.marginWidth = 0;\r
-            cardinalityContainer.setLayout(cardinalityLayout);\r
-            cardinalityContainer.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));\r
-\r
-            cardinalityCombo = new Combo(cardinalityContainer, SWT.DROP_DOWN | SWT.READ_ONLY);\r
-            cardinalityCombo.setItems(new String[] {\r
-                    Cardinality.ZERO_OR_MORE.toString(),\r
-                    Cardinality.ONE_OR_MORE.toString(),\r
-                    Cardinality.ZERO_OR_ONE.toString(),\r
-                    Cardinality.ONE.toString(),\r
-                    "(?,?)"}); //$NON-NLS-1$\r
-            cardinalityCombo.addSelectionListener(new SelectionListener(){\r
-               @Override\r
-                public void widgetDefaultSelected(SelectionEvent e) {}\r
-               @Override\r
-                public void widgetSelected(SelectionEvent e) {\r
-                    switch (cardinalityCombo.getSelectionIndex()) {\r
-                    case 4: //(?,?)\r
-                        cardinalityMinLabel.setVisible(true);\r
-                        cardinalityMinText.setVisible(true);\r
-                        cardinalityMaxLabel.setVisible(true);\r
-                        cardinalityMaxText.setVisible(true);\r
-                        infiniteButton.setVisible(true);\r
-                        break;\r
-                    default:\r
-                        cardinalityMinLabel.setVisible(false);\r
-                        cardinalityMinText.setVisible(false);\r
-                        cardinalityMaxLabel.setVisible(false);\r
-                        cardinalityMaxText.setVisible(false);\r
-                        infiniteButton.setVisible(false);\r
-                        break;\r
-                    }\r
-                    cardinalityContainer.layout();\r
-                    validate();\r
-                    updatePreviews();\r
-                }});\r
-\r
-            cardinalityMinLabel = new Label(cardinalityContainer, SWT.NONE);\r
-            cardinalityMinLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false));\r
-            cardinalityMinLabel.setText(Messages.CustomTxtParserInputWizardPage_min);\r
-            cardinalityMinLabel.setVisible(false);\r
-\r
-            cardinalityMinText = new Text(cardinalityContainer, SWT.BORDER | SWT.SINGLE);\r
-            gd = new GridData(SWT.CENTER, SWT.CENTER, false, false);\r
-            gd.widthHint = 20;\r
-            cardinalityMinText.setLayoutData(gd);\r
-            cardinalityMinText.setVisible(false);\r
-\r
-            cardinalityMaxLabel = new Label(cardinalityContainer, SWT.NONE);\r
-            cardinalityMaxLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false));\r
-            cardinalityMaxLabel.setText(Messages.CustomTxtParserInputWizardPage_max);\r
-            cardinalityMaxLabel.setVisible(false);\r
-\r
-            cardinalityMaxText = new Text(cardinalityContainer, SWT.BORDER | SWT.SINGLE);\r
-            gd = new GridData(SWT.CENTER, SWT.CENTER, false, false);\r
-            gd.widthHint = 20;\r
-            cardinalityMaxText.setLayoutData(gd);\r
-            cardinalityMaxText.setVisible(false);\r
-\r
-            infiniteButton = new Button(cardinalityContainer, SWT.PUSH);\r
-            infiniteButton.setText(INFINITY_STRING);\r
-            infiniteButton.setVisible(false);\r
-            infiniteButton.addSelectionListener(new SelectionAdapter(){\r
-                @Override\r
-                public void widgetSelected(SelectionEvent e) {\r
-                    cardinalityMaxText.setText(INFINITY_STRING);\r
-                }});\r
-\r
-            if (inputLine.cardinality.equals(Cardinality.ZERO_OR_MORE)) {\r
-                cardinalityCombo.select(0);\r
-            } else if (inputLine.cardinality.equals(Cardinality.ONE_OR_MORE)) {\r
-                cardinalityCombo.select(1);\r
-            } else if (inputLine.cardinality.equals(Cardinality.ZERO_OR_ONE)) {\r
-                cardinalityCombo.select(2);\r
-            } else if (inputLine.cardinality.equals(Cardinality.ONE)) {\r
-                cardinalityCombo.select(3);\r
-            } else {\r
-                cardinalityCombo.select(4);\r
-                cardinalityMinLabel.setVisible(true);\r
-                cardinalityMinText.setVisible(true);\r
-                if (inputLine.getMinCount() >= 0) {\r
-                    cardinalityMinText.setText(Integer.toString(inputLine.getMinCount()));\r
-                }\r
-                cardinalityMaxLabel.setVisible(true);\r
-                cardinalityMaxText.setVisible(true);\r
-                if (inputLine.getMaxCount() == Cardinality.INF) {\r
-                    cardinalityMaxText.setText(INFINITY_STRING);\r
-                } else if (inputLine.getMaxCount() >= 0) {\r
-                    cardinalityMaxText.setText(Integer.toString(inputLine.getMaxCount()));\r
-                }\r
-                infiniteButton.setVisible(true);\r
-            }\r
-\r
-            VerifyListener digitsListener = new VerifyListener() {\r
-               @Override\r
-                public void verifyText(VerifyEvent e) {\r
-                    if (e.text.equals(INFINITY_STRING)) {\r
-                        e.doit = e.widget == cardinalityMaxText && e.start == 0 && e.end == ((Text) e.widget).getText().length();\r
-                    } else {\r
-                        if (((Text) e.widget).getText().equals(INFINITY_STRING)) {\r
-                            e.doit = e.start == 0 && e.end == ((Text) e.widget).getText().length();\r
-                        }\r
-                        for (int i = 0; i < e.text.length(); i++) {\r
-                            if (!Character.isDigit(e.text.charAt(i))) {\r
-                                e.doit = false;\r
-                                break;\r
-                            }\r
-                        }\r
-                    }\r
-                }};\r
-\r
-            cardinalityMinText.addModifyListener(updateListener);\r
-            cardinalityMaxText.addModifyListener(updateListener);\r
-            cardinalityMinText.addVerifyListener(digitsListener);\r
-            cardinalityMaxText.addVerifyListener(digitsListener);\r
-\r
-            if (inputLine.columns != null) {\r
-                for (InputData inputData : inputLine.columns) {\r
-                    InputGroup inputGroup = new InputGroup(group, this, inputs.size()+1);\r
-                    if (inputData.name.equals(CustomTraceDefinition.TAG_TIMESTAMP)) {\r
-                        inputGroup.tagCombo.select(0);\r
-                        inputGroup.tagText.setText(inputData.format);\r
-                        inputGroup.tagLabel.setText(Messages.CustomTxtParserInputWizardPage_format);\r
-                        inputGroup.tagLabel.setVisible(true);\r
-                        inputGroup.tagText.setVisible(true);\r
-                        inputGroup.tagText.addModifyListener(updateListener);\r
-                    } else if (inputData.name.equals(CustomTraceDefinition.TAG_MESSAGE)) {\r
-                        inputGroup.tagCombo.select(1);\r
-                    } else {\r
-                        inputGroup.tagCombo.select(2);\r
-                        inputGroup.tagText.setText(inputData.name);\r
-                        inputGroup.tagLabel.setText(Messages.CustomTxtParserInputWizardPage_name);\r
-                        inputGroup.tagLabel.setVisible(true);\r
-                        inputGroup.tagText.setVisible(true);\r
-                        inputGroup.tagText.addModifyListener(updateListener);\r
-                    }\r
-                    inputGroup.actionCombo.select(inputData.action);\r
-                    inputs.add(inputGroup);\r
-                }\r
-            }\r
-\r
-            createAddGroupButton();\r
-        }\r
-\r
-        private void createAddGroupButton() {\r
-            addGroupButton = new Button(group, SWT.PUSH);\r
-            addGroupButton.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false));\r
-            addGroupButton.setImage(addImage);\r
-            addGroupButton.setToolTipText(Messages.CustomTxtParserInputWizardPage_addGroup);\r
-            addGroupButton.addSelectionListener(new SelectionAdapter() {\r
-               @Override\r
-                public void widgetSelected(SelectionEvent e) {\r
-                    removeAddGroupButton();\r
-                    inputs.add(new InputGroup(group, Line.this, inputs.size()+1));\r
-                    createAddGroupButton();\r
-                    lineContainer.layout();\r
-                    lineScrolledComposite.setMinSize(lineContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).x, lineContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).y-1);\r
-                    group.getParent().layout();\r
-                    validate();\r
-                    updatePreviews();\r
-                }\r
-            });\r
-\r
-            addGroupLabel = new Label(group, SWT.NULL);\r
-            addGroupLabel.setText(Messages.CustomTxtParserInputWizardPage_newGroup);\r
-        }\r
-\r
-        private void removeAddGroupButton() {\r
-            addGroupButton.dispose();\r
-            addGroupLabel.dispose();\r
-        }\r
-\r
-        private void removeInput(int inputNumber) {\r
-            if (--inputNumber < inputs.size()) {\r
-                inputs.remove(inputNumber).dispose();\r
-                for (int i = inputNumber; i < inputs.size(); i++) {\r
-                    inputs.get(i).setInputNumber(i+1);\r
-                }\r
-                lineContainer.layout();\r
-                lineScrolledComposite.setMinSize(lineContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).x, lineContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).y-1);\r
-                group.getParent().layout();\r
-            }\r
-        }\r
-\r
-//        private void setName(String name) {\r
-//            this.name = name;\r
-//            group.setText("Line " + name);\r
-//        }\r
-\r
-        private void dispose() {\r
-            group.dispose();\r
-        }\r
-\r
-        private void extractInputs() {\r
-            inputLine.setRegex(selectedLine.regexText.getText());\r
-            switch (cardinalityCombo.getSelectionIndex()) {\r
-            case 0:\r
-                inputLine.cardinality = Cardinality.ZERO_OR_MORE;\r
-                break;\r
-            case 1:\r
-                inputLine.cardinality = Cardinality.ONE_OR_MORE;\r
-                break;\r
-            case 2:\r
-                inputLine.cardinality = Cardinality.ZERO_OR_ONE;\r
-                break;\r
-            case 3:\r
-                inputLine.cardinality = Cardinality.ONE;\r
-                break;\r
-            case 4: //(?,?)\r
-                int min, max;\r
-                try {\r
-                    min = Integer.parseInt(cardinalityMinText.getText());\r
-                } catch (NumberFormatException e) {\r
-                    min = -1;\r
-                }\r
-                try {\r
-                    if (cardinalityMaxText.getText().equals(INFINITY_STRING)) {\r
-                        max = Cardinality.INF;\r
-                    } else {\r
-                        max = Integer.parseInt(cardinalityMaxText.getText());\r
-                    }\r
-                } catch (NumberFormatException e) {\r
-                    max = -1;\r
-                }\r
-                inputLine.cardinality = new Cardinality(min, max);\r
-                break;\r
-            default:\r
-                inputLine.cardinality = Cardinality.ZERO_OR_MORE;\r
-                break;\r
-            }\r
-            inputLine.columns = new ArrayList<InputData>(inputs.size());\r
-            for (int i = 0; i < inputs.size(); i++) {\r
-                InputGroup group = inputs.get(i);\r
-                InputData inputData = new InputData();\r
-                if (group.tagCombo.getText().equals(CustomTraceDefinition.TAG_OTHER)) {\r
-                    inputData.name = group.tagText.getText().trim();\r
-                } else {\r
-                    inputData.name = group.tagCombo.getText();\r
-                    if (group.tagCombo.getText().equals(CustomTraceDefinition.TAG_TIMESTAMP)) {\r
-                        inputData.format = group.tagText.getText().trim();\r
-                    }\r
-                }\r
-                inputData.action = group.actionCombo.getSelectionIndex();\r
-                inputLine.columns.add(inputData);\r
-            }\r
-        }\r
-    }\r
-\r
-    private class InputGroup {\r
-        Line line;\r
-        int inputNumber;\r
-\r
-        // children of parent (must be disposed)\r
-        Composite labelComposite;\r
-        Composite tagComposite;\r
-        Label previewLabel;\r
-        Text previewText;\r
-\r
-        // children of labelComposite\r
-        Label inputLabel;\r
-\r
-        // children of tagComposite\r
-        Combo tagCombo;\r
-        Label tagLabel;\r
-        Text tagText;\r
-        Combo actionCombo;\r
-\r
-        public InputGroup(Composite parent, Line line, int inputNumber) {\r
-            this.line = line;\r
-            this.inputNumber = inputNumber;\r
-\r
-            labelComposite = new Composite(parent, SWT.FILL);\r
-            GridLayout labelLayout = new GridLayout(2, false);\r
-            labelLayout.marginWidth = 0;\r
-            labelLayout.marginHeight = 0;\r
-            labelComposite.setLayout(labelLayout);\r
-            labelComposite.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false));\r
-\r
-            Button deleteButton = new Button(labelComposite, SWT.PUSH);\r
-            deleteButton.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false));\r
-            deleteButton.setImage(deleteImage);\r
-            deleteButton.setToolTipText(Messages.CustomTxtParserInputWizardPage_removeGroup);\r
-            deleteButton.addSelectionListener(new SelectionAdapter() {\r
-               @Override\r
-                public void widgetSelected(SelectionEvent e) {\r
-                    InputGroup.this.line.removeInput(InputGroup.this.inputNumber);\r
-                    validate();\r
-                    updatePreviews();\r
-                }\r
-            });\r
-\r
-            inputLabel = new Label(labelComposite, SWT.NULL);\r
-            inputLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false));\r
-            inputLabel.setText(Messages.CustomTxtParserInputWizardPage_group + inputNumber + ":"); //$NON-NLS-1$\r
-\r
-            tagComposite = new Composite(parent, SWT.FILL);\r
-            GridLayout tagLayout = new GridLayout(4, false);\r
-            tagLayout.marginWidth = 0;\r
-            tagLayout.marginHeight = 0;\r
-            tagComposite.setLayout(tagLayout);\r
-            tagComposite.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));\r
-\r
-            tagCombo = new Combo(tagComposite, SWT.DROP_DOWN | SWT.READ_ONLY);\r
-            tagCombo.setItems(new String[] {CustomTraceDefinition.TAG_TIMESTAMP,\r
-                                            CustomTraceDefinition.TAG_MESSAGE,\r
-                                            CustomTraceDefinition.TAG_OTHER});\r
-            tagCombo.select(1);\r
-            tagCombo.addSelectionListener(new SelectionListener(){\r
-               @Override\r
-                public void widgetDefaultSelected(SelectionEvent e) {}\r
-               @Override\r
-                public void widgetSelected(SelectionEvent e) {\r
-                    tagText.removeModifyListener(updateListener);\r
-                    switch (tagCombo.getSelectionIndex()) {\r
-                    case 0: //Time Stamp\r
-                        tagLabel.setText(Messages.CustomTxtParserInputWizardPage_format);\r
-                        tagLabel.setVisible(true);\r
-                        tagText.setVisible(true);\r
-                        tagText.addModifyListener(updateListener);\r
-                        break;\r
-                    case 1: //Message\r
-                        tagLabel.setVisible(false);\r
-                        tagText.setVisible(false);\r
-                        break;\r
-                    case 2: //Other\r
-                        tagLabel.setText(Messages.CustomTxtParserInputWizardPage_name);\r
-                        tagLabel.setVisible(true);\r
-                        tagText.setVisible(true);\r
-                        tagText.addModifyListener(updateListener);\r
-                        break;\r
-                    case 3: //Continue\r
-                        tagLabel.setVisible(false);\r
-                        tagText.setVisible(false);\r
-                        break;\r
-                    default:\r
-                        break;\r
-                    }\r
-                    tagComposite.layout();\r
-                    validate();\r
-                    updatePreviews();\r
-                }});\r
-\r
-            tagLabel = new Label(tagComposite, SWT.NULL);\r
-            tagLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false));\r
-            tagLabel.setVisible(false);\r
-\r
-            tagText = new Text(tagComposite, SWT.BORDER | SWT.SINGLE);\r
-            GridData gd = new GridData(SWT.FILL, SWT.CENTER, true, false);\r
-            gd.widthHint = 0;\r
-            tagText.setLayoutData(gd);\r
-            tagText.setVisible(false);\r
-\r
-            actionCombo = new Combo(tagComposite, SWT.DROP_DOWN | SWT.READ_ONLY);\r
-            actionCombo.setItems(new String[] {Messages.CustomTxtParserInputWizardPage_set, Messages.CustomTxtParserInputWizardPage_append, Messages.CustomTxtParserInputWizardPage_appendWith});\r
-            actionCombo.select(0);\r
-            actionCombo.addSelectionListener(updateListener);\r
-\r
-            previewLabel = new Label(parent, SWT.NULL);\r
-            previewLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false));\r
-            previewLabel.setText(Messages.CustomTxtParserInputWizardPage_preview);\r
-\r
-            previewText = new Text(parent, SWT.BORDER | SWT.SINGLE | SWT.READ_ONLY);\r
-            gd = new GridData(SWT.FILL, SWT.CENTER, true, false);\r
-            gd.widthHint = 0;\r
-            previewText.setLayoutData(gd);\r
-            previewText.setText(Messages.CustomTxtParserInputWizardPage_noMatch);\r
-            previewText.setBackground(COLOR_WIDGET_BACKGROUND);\r
-        }\r
-\r
-        private void dispose() {\r
-            labelComposite.dispose();\r
-            tagComposite.dispose();\r
-            previewLabel.dispose();\r
-            previewText.dispose();\r
-        }\r
-\r
-        private void setInputNumber(int inputNumber) {\r
-            this.inputNumber = inputNumber;\r
-            inputLabel.setText(Messages.CustomTxtParserInputWizardPage_group + inputNumber + ":"); //$NON-NLS-1$\r
-            labelComposite.layout();\r
-        }\r
-    }\r
-\r
-    private void validate() {\r
-\r
-        definition.definitionName = logtypeText.getText().trim();\r
-        definition.timeStampOutputFormat = timestampOutputFormatText.getText().trim();\r
-\r
-        if (selectedLine != null) {\r
-            selectedLine.extractInputs();\r
-            treeViewer.refresh();\r
-        }\r
-\r
-        StringBuffer errors = new StringBuffer();\r
-\r
-        if (definition.definitionName.length() == 0) {\r
-            errors.append("Enter a name for the new log type. "); //$NON-NLS-1$\r
-            logtypeText.setBackground(COLOR_LIGHT_RED);\r
-        } else {\r
-            logtypeText.setBackground(COLOR_TEXT_BACKGROUND);\r
-            for (CustomTxtTraceDefinition def : CustomTxtTraceDefinition.loadAll()) {\r
-                if (definition.definitionName.equals(def.definitionName)) {\r
-                    if (editDefinitionName == null || ! editDefinitionName.equals(definition.definitionName)) {\r
-                        errors.append("The log type name already exists. "); //$NON-NLS-1$\r
-                        logtypeText.setBackground(COLOR_LIGHT_RED);\r
-                        break;\r
-                    }\r
-                }\r
-            }\r
-        }\r
-\r
-        timestampFound = false;\r
-        for (int i = 0; i < definition.inputs.size(); i++) {\r
-\r
-            InputLine inputLine = definition.inputs.get(i);\r
-            String name = Integer.toString(i+1);\r
-            errors.append(validateLine(inputLine, name));\r
-        }\r
-        if (timestampFound) {\r
-            if (definition.timeStampOutputFormat.length() == 0) {\r
-                errors.append("Enter the output format for the Time Stamp field. "); //$NON-NLS-1$\r
-                timestampOutputFormatText.setBackground(COLOR_LIGHT_RED);\r
-            } else {\r
-                try {\r
-                    new SimpleDateFormat(definition.timeStampOutputFormat);\r
-                    timestampOutputFormatText.setBackground(COLOR_TEXT_BACKGROUND);\r
-                } catch (IllegalArgumentException e) {\r
-                    errors.append("Enter a valid output format for the Time Stamp field. "); //$NON-NLS-1$\r
-                    timestampOutputFormatText.setBackground(COLOR_LIGHT_RED);\r
-                }\r
-            }\r
-\r
-        } else {\r
-            timestampOutputFormatText.setBackground(COLOR_TEXT_BACKGROUND);\r
-//            timestampPreviewText.setBackground(COLOR_WIDGET_BACKGROUND);\r
-//            errors.append("Identify a Time Stamp group (Line "+name+"). ");\r
-//            timestampPreviewText.setText("*no timestamp group*");\r
-//            timestampPreviewText.setBackground(COLOR_LIGHT_RED);\r
-        }\r
-\r
-        if (errors.length() == 0) {\r
-            setDescription(defaultDescription);\r
-            setPageComplete(true);\r
-        } else {\r
-            setDescription(errors.toString());\r
-            setPageComplete(false);\r
-        }\r
-    }\r
-\r
-    public StringBuffer validateLine(InputLine inputLine, String name) {\r
-        StringBuffer errors = new StringBuffer();\r
-        Line line = null;\r
-        if (selectedLine != null && selectedLine.inputLine.equals(inputLine)) {\r
-            line = selectedLine;\r
-        }\r
-        try {\r
-            Pattern.compile(inputLine.getRegex());\r
-            if (line != null) {\r
-                line.regexText.setBackground(COLOR_TEXT_BACKGROUND);\r
-            }\r
-        } catch (PatternSyntaxException e) {\r
-            errors.append("Enter a valid regular expression (Line "+name+"). "); //$NON-NLS-1$ //$NON-NLS-2$\r
-            if (line != null) {\r
-                line.regexText.setBackground(COLOR_LIGHT_RED);\r
-            }\r
-        }\r
-        if (inputLine.getMinCount() == -1) {\r
-            errors.append("Enter a minimum value for cardinality (Line "+name+"). "); //$NON-NLS-1$ //$NON-NLS-2$\r
-            if (line != null) {\r
-                line.cardinalityMinText.setBackground(COLOR_LIGHT_RED);\r
-            }\r
-        } else {\r
-            if (line != null) {\r
-                line.cardinalityMinText.setBackground(COLOR_TEXT_BACKGROUND);\r
-            }\r
-        }\r
-        if (inputLine.getMaxCount() == -1) {\r
-            errors.append("Enter a maximum value for cardinality (Line "+name+"). "); //$NON-NLS-1$ //$NON-NLS-2$\r
-            if (line != null) {\r
-                line.cardinalityMaxText.setBackground(COLOR_LIGHT_RED);\r
-            }\r
-        } else if (inputLine.getMinCount() > inputLine.getMaxCount()) {\r
-            errors.append("Enter correct (min <= max) values for cardinality (Line "+name+"). "); //$NON-NLS-1$ //$NON-NLS-2$\r
-            if (line != null) {\r
-                line.cardinalityMinText.setBackground(COLOR_LIGHT_RED);\r
-            }\r
-            if (line != null) {\r
-                line.cardinalityMaxText.setBackground(COLOR_LIGHT_RED);\r
-            }\r
-        } else {\r
-            if (line != null) {\r
-                line.cardinalityMaxText.setBackground(COLOR_TEXT_BACKGROUND);\r
-            }\r
-        }\r
-        for (int i = 0; inputLine.columns != null && i < inputLine.columns.size(); i++) {\r
-            InputData inputData = inputLine.columns.get(i);\r
-            InputGroup group = null;\r
-            if (line != null) {\r
-                group = line.inputs.get(i);\r
-            }\r
-            if (inputData.name.equals(CustomTraceDefinition.TAG_TIMESTAMP)) {\r
-                timestampFound = true;\r
-                if (inputData.format.length() == 0) {\r
-                    errors.append("Enter the input format for the Time Stamp (Line "+name+" Group "+(i+1)+"). "); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$\r
-                    if (group != null) {\r
-                        group.tagText.setBackground(COLOR_LIGHT_RED);\r
-                    }\r
-                } else {\r
-                    try {\r
-                        new SimpleDateFormat(inputData.format);\r
-                        if (group != null) {\r
-                            group.tagText.setBackground(COLOR_TEXT_BACKGROUND);\r
-                        }\r
-                    } catch (IllegalArgumentException e) {\r
-                        errors.append("Enter a valid input format for the Time Stamp (Line "+name+" Group "+(i+1)+"). "); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$\r
-                        if (group != null) {\r
-                            group.tagText.setBackground(COLOR_LIGHT_RED);\r
-                        }\r
-                    }\r
-                }\r
-            } else if (inputData.name.length() == 0) {\r
-                errors.append("Enter a name for the data group (Line "+name+" Group "+(i+1)+"). "); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$\r
-                if (group != null) {\r
-                    group.tagText.setBackground(COLOR_LIGHT_RED);\r
-                }\r
-            } else {\r
-                if (group != null) {\r
-                    group.tagText.setBackground(COLOR_TEXT_BACKGROUND);\r
-                }\r
-            }\r
-        }\r
-        for (int i = 0; inputLine.childrenInputs != null && i < inputLine.childrenInputs.size(); i++) {\r
-            errors.append(validateLine(inputLine.childrenInputs.get(i), name+"."+(i+1))); //$NON-NLS-1$\r
-        }\r
-        return errors;\r
-    }\r
-\r
-    public CustomTxtTraceDefinition getDefinition() {\r
-        return definition;\r
-    }\r
-\r
-    public char[] getInputText() {\r
-        return inputText.getText().toCharArray();\r
-    }\r
-}\r
+package org.eclipse.linuxtools.internal.tmf.ui.parsers.wizards;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Scanner;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.regex.PatternSyntaxException;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jface.viewers.ColumnLabelProvider;
+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.SelectionChangedEvent;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.wizard.WizardPage;
+import org.eclipse.linuxtools.internal.tmf.ui.Activator;
+import org.eclipse.linuxtools.internal.tmf.ui.Messages;
+import org.eclipse.linuxtools.internal.tmf.ui.parsers.custom.CustomTraceDefinition;
+import org.eclipse.linuxtools.internal.tmf.ui.parsers.custom.CustomTxtTraceDefinition;
+import org.eclipse.linuxtools.internal.tmf.ui.parsers.custom.CustomTxtTraceDefinition.Cardinality;
+import org.eclipse.linuxtools.internal.tmf.ui.parsers.custom.CustomTxtTraceDefinition.InputData;
+import org.eclipse.linuxtools.internal.tmf.ui.parsers.custom.CustomTxtTraceDefinition.InputLine;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.browser.Browser;
+import org.eclipse.swt.browser.TitleEvent;
+import org.eclipse.swt.browser.TitleListener;
+import org.eclipse.swt.custom.SashForm;
+import org.eclipse.swt.custom.ScrolledComposite;
+import org.eclipse.swt.custom.StyleRange;
+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.events.VerifyEvent;
+import org.eclipse.swt.events.VerifyListener;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.FontData;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
+
+public class CustomTxtParserInputWizardPage extends WizardPage {
+
+    private static final String DEFAULT_REGEX = "\\s*(.*\\S)"; //$NON-NLS-1$
+    private static final String DEFAULT_TIMESTAMP_FORMAT = "yyyy-MM-dd HH:mm:ss.SSS"; //$NON-NLS-1$
+    private static final String SIMPLE_DATE_FORMAT_URL = "http://java.sun.com/javase/6/docs/api/java/text/SimpleDateFormat.html#skip-navbar_top"; //$NON-NLS-1$
+    private static final String PATTERN_URL = "http://java.sun.com/javase/6/docs/api/java/util/regex/Pattern.html#sum"; //$NON-NLS-1$
+    private static final Image lineImage = Activator.getDefault().getImageFromPath("/icons/elcl16/line_icon.gif"); //$NON-NLS-1$
+    private static final Image addImage = Activator.getDefault().getImageFromPath("/icons/elcl16/add_button.gif"); //$NON-NLS-1$
+    private static final Image addNextImage = Activator.getDefault().getImageFromPath("/icons/elcl16/addnext_button.gif"); //$NON-NLS-1$
+    private static final Image addChildImage = Activator.getDefault().getImageFromPath("/icons/elcl16/addchild_button.gif"); //$NON-NLS-1$
+    private static final Image deleteImage = Activator.getDefault().getImageFromPath("/icons/elcl16/delete_button.gif"); //$NON-NLS-1$
+    private static final Image moveUpImage = Activator.getDefault().getImageFromPath("/icons/elcl16/moveup_button.gif"); //$NON-NLS-1$
+    private static final Image moveDownImage = Activator.getDefault().getImageFromPath("/icons/elcl16/movedown_button.gif"); //$NON-NLS-1$
+    private static final Image helpImage = Activator.getDefault().getImageFromPath("/icons/elcl16/help_button.gif"); //$NON-NLS-1$
+    private static final Color COLOR_BLACK = Display.getCurrent().getSystemColor(SWT.COLOR_BLACK);
+    private static final Color COLOR_LIGHT_GREEN = new Color(Display.getDefault(), 192, 255, 192);
+    private static final Color COLOR_GREEN = Display.getCurrent().getSystemColor(SWT.COLOR_GREEN);
+    private static final Color COLOR_LIGHT_YELLOW = new Color(Display.getDefault(), 255, 255, 192);
+    private static final Color COLOR_YELLOW = Display.getCurrent().getSystemColor(SWT.COLOR_YELLOW);
+    private static final Color COLOR_LIGHT_MAGENTA = new Color(Display.getDefault(), 255, 192, 255);
+    private static final Color COLOR_MAGENTA = Display.getCurrent().getSystemColor(SWT.COLOR_MAGENTA);
+    private static final Color COLOR_LIGHT_RED = new Color(Display.getDefault(), 255, 192, 192);
+    private static final Color COLOR_TEXT_BACKGROUND = Display.getCurrent().getSystemColor(SWT.COLOR_WHITE);
+    private static final Color COLOR_WIDGET_BACKGROUND = Display.getCurrent().getSystemColor(SWT.COLOR_WIDGET_BACKGROUND);
+
+    private final ISelection selection;
+    private CustomTxtTraceDefinition definition;
+    private String editDefinitionName;
+    private String defaultDescription;
+    private Line selectedLine;
+    private Composite container;
+    private Text logtypeText;
+    private Text timestampOutputFormatText;
+    private Text timestampPreviewText;
+    private ScrolledComposite treeScrolledComposite;
+    private ScrolledComposite lineScrolledComposite;
+    private TreeViewer treeViewer;
+    private Composite treeContainer;
+    private Composite lineContainer;
+    private StyledText inputText;
+    private Font fixedFont;
+    private UpdateListener updateListener;
+    private Browser helpBrowser;
+
+    // variables used recursively through line traversal
+    private String timeStampFormat;
+    private boolean timestampFound;
+
+    protected CustomTxtParserInputWizardPage(ISelection selection, CustomTxtTraceDefinition definition) {
+        super("CustomParserWizardPage"); //$NON-NLS-1$
+        if (definition == null) {
+            setTitle(Messages.CustomTxtParserInputWizardPage_windowTitleNew);
+            defaultDescription = Messages.CustomTxtParserInputWizardPage_descriptionNew;
+        } else {
+            setTitle(Messages.CustomTxtParserInputWizardPage_windowTitleEdit);
+            defaultDescription = Messages.CustomTxtParserInputWizardPage_desccriptionEdit;
+        }
+        setDescription(defaultDescription);
+        this.selection = selection;
+        this.definition = definition;
+        if (definition != null) {
+            this.editDefinitionName = definition.definitionName;
+        }
+    }
+
+       @Override
+    public void createControl(Composite parent) {
+        container = new Composite(parent, SWT.NULL);
+        container.setLayout(new GridLayout());
+
+        updateListener = new UpdateListener();
+
+        Composite headerComposite = new Composite(container, SWT.FILL);
+        GridLayout headerLayout = new GridLayout(5, false);
+        headerLayout.marginHeight = 0;
+        headerLayout.marginWidth = 0;
+        headerComposite.setLayout(headerLayout);
+        headerComposite.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
+
+        Label logtypeLabel = new Label(headerComposite, SWT.NULL);
+        logtypeLabel.setText(Messages.CustomTxtParserInputWizardPage_logType);
+
+        logtypeText = new Text(headerComposite, SWT.BORDER | SWT.SINGLE);
+        logtypeText.setLayoutData(new GridData(120, SWT.DEFAULT));
+
+        Label timestampFormatLabel = new Label(headerComposite, SWT.NULL);
+        timestampFormatLabel.setText(Messages.CustomTxtParserInputWizardPage_timestampFormat);
+
+        timestampOutputFormatText = new Text(headerComposite, SWT.BORDER | SWT.SINGLE);
+        timestampOutputFormatText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
+        timestampOutputFormatText.setText(DEFAULT_TIMESTAMP_FORMAT);
+
+        Button dateFormatHelpButton = new Button(headerComposite, SWT.PUSH);
+        dateFormatHelpButton.setImage(helpImage);
+        dateFormatHelpButton.setToolTipText(Messages.CustomTxtParserInputWizardPage_dateFormatHelp);
+        dateFormatHelpButton.addSelectionListener(new SelectionAdapter() {
+            @Override
+                       public void widgetSelected(SelectionEvent e) {
+                openHelpShell(SIMPLE_DATE_FORMAT_URL);
+            }
+        });
+
+        Label timestampPreviewLabel = new Label(headerComposite, SWT.NULL);
+        timestampPreviewLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 3, 1));
+        timestampPreviewLabel.setText(Messages.CustomTxtParserInputWizardPage_preview);
+
+        timestampPreviewText = new Text(headerComposite, SWT.BORDER | SWT.SINGLE | SWT.READ_ONLY);
+        timestampPreviewText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1));
+        timestampPreviewText.setText(Messages.CustomTxtParserInputWizardPage_noMatchingTimestamp);
+
+        Composite buttonBar = new Composite(container, SWT.NONE);
+        GridLayout buttonBarLayout = new GridLayout(5, false);
+        buttonBarLayout.marginHeight = 0;
+        buttonBarLayout.marginWidth = 0;
+        buttonBar.setLayout(buttonBarLayout);
+
+        Button removeButton = new Button(buttonBar, SWT.PUSH);
+        removeButton.setImage(deleteImage);
+        removeButton.setToolTipText(Messages.CustomTxtParserInputWizardPage_removeLine);
+        removeButton.addSelectionListener(new SelectionAdapter() {
+               @Override
+            public void widgetSelected(SelectionEvent e) {
+                if (treeViewer.getSelection().isEmpty() || selectedLine == null) {
+                    return;
+                }
+                removeLine();
+                InputLine inputLine = (InputLine) ((IStructuredSelection) treeViewer.getSelection()).getFirstElement();
+                if (inputLine.parentInput == null) {
+                    definition.inputs.remove(inputLine);
+                } else {
+                    inputLine.parentInput.childrenInputs.remove(inputLine);
+                }
+                treeViewer.refresh();
+                validate();
+                updatePreviews();
+            }
+        });
+        Button addNextButton = new Button(buttonBar, SWT.PUSH);
+        addNextButton.setImage(addNextImage);
+        addNextButton.setToolTipText(Messages.CustomTxtParserInputWizardPage_addNextLine);
+        addNextButton.addSelectionListener(new SelectionAdapter() {
+               @Override
+            public void widgetSelected(SelectionEvent e) {
+                InputLine inputLine = new InputLine(Cardinality.ZERO_OR_MORE, "", null); //$NON-NLS-1$
+                if (((List<?>) treeViewer.getInput()).size() == 0) {
+                    definition.inputs.add(inputLine);
+                } else if (treeViewer.getSelection().isEmpty()) {
+                    return;
+                } else {
+                    InputLine previousInputLine = (InputLine) ((IStructuredSelection) treeViewer.getSelection()).getFirstElement();
+                    if (previousInputLine.parentInput == null) {
+                        for (int i = 0; i < definition.inputs.size(); i++) {
+                            if (definition.inputs.get(i).equals(previousInputLine)) {
+                                definition.inputs.add(i + 1, inputLine);
+                            }
+                        }
+                    } else {
+                        previousInputLine.addNext(inputLine);
+                    }
+                }
+                treeViewer.refresh();
+                treeViewer.setSelection(new StructuredSelection(inputLine), true);
+            }
+        });
+        Button addChildButton = new Button(buttonBar, SWT.PUSH);
+        addChildButton.setImage(addChildImage);
+        addChildButton.setToolTipText(Messages.CustomTxtParserInputWizardPage_addChildLine);
+        addChildButton.addSelectionListener(new SelectionAdapter() {
+               @Override
+               public void widgetSelected(SelectionEvent e) {
+                InputLine inputLine = new InputLine(Cardinality.ZERO_OR_MORE, "", null); //$NON-NLS-1$
+                if (((List<?>) treeViewer.getInput()).size() == 0) {
+                    definition.inputs.add(inputLine);
+                } else if (treeViewer.getSelection().isEmpty()) {
+                    return;
+                } else {
+                    InputLine parentInputLine = (InputLine) ((IStructuredSelection) treeViewer.getSelection()).getFirstElement();
+                    parentInputLine.addChild(inputLine);
+                }
+                treeViewer.refresh();
+                treeViewer.setSelection(new StructuredSelection(inputLine), true);
+            }
+        });
+        Button moveUpButton = new Button(buttonBar, SWT.PUSH);
+        moveUpButton.setImage(moveUpImage);
+        moveUpButton.setToolTipText(Messages.CustomTxtParserInputWizardPage_moveUp);
+        moveUpButton.addSelectionListener(new SelectionAdapter() {
+               @Override
+            public void widgetSelected(SelectionEvent e) {
+                if (treeViewer.getSelection().isEmpty()) {
+                    return;
+                }
+                InputLine inputLine = (InputLine) ((IStructuredSelection) treeViewer.getSelection()).getFirstElement();
+                if (inputLine.parentInput == null) {
+                    for (int i = 1; i < definition.inputs.size(); i++) {
+                        if (definition.inputs.get(i).equals(inputLine)) {
+                            definition.inputs.add(i - 1 , definition.inputs.remove(i));
+                            break;
+                        }
+                    }
+                } else {
+                    inputLine.moveUp();
+                }
+                treeViewer.refresh();
+                validate();
+                updatePreviews();
+            }
+        });
+        Button moveDownButton = new Button(buttonBar, SWT.PUSH);
+        moveDownButton.setImage(moveDownImage);
+        moveDownButton.setToolTipText(Messages.CustomTxtParserInputWizardPage_moveDown);
+        moveDownButton.addSelectionListener(new SelectionAdapter() {
+               @Override
+            public void widgetSelected(SelectionEvent e) {
+                if (treeViewer.getSelection().isEmpty()) {
+                    return;
+                }
+                InputLine inputLine = (InputLine) ((IStructuredSelection) treeViewer.getSelection()).getFirstElement();
+                if (inputLine.parentInput == null) {
+                    for (int i = 0; i < definition.inputs.size() - 1; i++) {
+                        if (definition.inputs.get(i).equals(inputLine)) {
+                            definition.inputs.add(i + 1 , definition.inputs.remove(i));
+                            break;
+                        }
+                    }
+                } else {
+                    inputLine.moveDown();
+                }
+                treeViewer.refresh();
+                validate();
+                updatePreviews();
+            }
+        });
+
+        SashForm vSash = new SashForm(container, SWT.VERTICAL);
+        vSash.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+        vSash.setBackground(vSash.getDisplay().getSystemColor(SWT.COLOR_GRAY));
+
+        SashForm hSash = new SashForm(vSash, SWT.HORIZONTAL);
+        hSash.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+
+        treeScrolledComposite = new ScrolledComposite(hSash, SWT.V_SCROLL | SWT.H_SCROLL);
+        GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true);
+        gd.heightHint = 200;
+        gd.widthHint = 200;
+        treeScrolledComposite.setLayoutData(gd);
+        treeContainer = new Composite(treeScrolledComposite, SWT.NONE);
+        treeContainer.setLayout(new FillLayout());
+        treeScrolledComposite.setContent(treeContainer);
+        treeScrolledComposite.setExpandHorizontal(true);
+        treeScrolledComposite.setExpandVertical(true);
+
+        treeViewer = new TreeViewer(treeContainer, SWT.SINGLE | SWT.BORDER);
+        treeViewer.setContentProvider(new InputLineTreeNodeContentProvider());
+        treeViewer.setLabelProvider(new InputLineTreeLabelProvider());
+        treeViewer.addSelectionChangedListener(new InputLineTreeSelectionChangedListener());
+        treeContainer.layout();
+
+        treeScrolledComposite.setMinSize(treeContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).x, treeContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).y);
+
+        lineScrolledComposite = new ScrolledComposite(hSash, SWT.V_SCROLL);
+        lineScrolledComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+        lineContainer = new Composite(lineScrolledComposite, SWT.NONE);
+        GridLayout linesLayout = new GridLayout();
+        linesLayout.marginHeight = 1;
+        linesLayout.marginWidth = 0;
+        lineContainer.setLayout(linesLayout);
+        lineScrolledComposite.setContent(lineContainer);
+        lineScrolledComposite.setExpandHorizontal(true);
+        lineScrolledComposite.setExpandVertical(true);
+
+        if (definition == null) {
+            definition = new CustomTxtTraceDefinition();
+            definition.inputs.add(new InputLine(Cardinality.ZERO_OR_MORE, DEFAULT_REGEX,
+                    Arrays.asList(new InputData(CustomTraceDefinition.TAG_MESSAGE, CustomTraceDefinition.ACTION_SET))));
+        }
+        loadDefinition(definition);
+        treeViewer.expandAll();
+        lineContainer.layout();
+
+        logtypeText.addModifyListener(updateListener);
+        timestampOutputFormatText.addModifyListener(updateListener);
+
+        lineScrolledComposite.setMinSize(lineContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).x, lineContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).y-1);
+
+        hSash.setWeights(new int[] {1, 2});
+
+        Composite sashBottom = new Composite(vSash, SWT.NONE);
+        GridLayout sashBottomLayout = new GridLayout(3, false);
+        sashBottomLayout.marginHeight = 0;
+        sashBottomLayout.marginWidth = 0;
+        sashBottom.setLayout(sashBottomLayout);
+
+        Label previewLabel = new Label(sashBottom, SWT.NULL);
+        previewLabel.setText(Messages.CustomTxtParserInputWizardPage_previewInput);
+        previewLabel.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
+
+        Button highlightAllButton = new Button(sashBottom, SWT.PUSH);
+        highlightAllButton.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false));
+        highlightAllButton.setText(Messages.CustomTxtParserInputWizardPage_highlightAll);
+        highlightAllButton.addSelectionListener(new SelectionAdapter() {
+               @Override
+            public void widgetSelected(SelectionEvent e) {
+                updatePreviews(true);
+            }
+        });
+
+        Button legendButton = new Button(sashBottom, SWT.PUSH);
+        legendButton.setImage(helpImage);
+        legendButton.setToolTipText(Messages.CustomTxtParserInputWizardPage_previewLegend);
+        legendButton.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false));
+        legendButton.addSelectionListener(new SelectionAdapter() {
+               @Override
+            public void widgetSelected(SelectionEvent e) {
+                openLegend();
+            }
+        });
+
+        inputText = new StyledText(sashBottom, SWT.MULTI | SWT.V_SCROLL | SWT.H_SCROLL);
+        if (fixedFont == null) {
+            if (System.getProperty("os.name").contains("Windows")) { //$NON-NLS-1$  //$NON-NLS-2$
+                fixedFont = new Font(Display.getCurrent(), new FontData("Courier New", 10, SWT.NORMAL)); //$NON-NLS-1$
+            } else {
+                fixedFont = new Font(Display.getCurrent(), new FontData("Monospace", 10, SWT.NORMAL)); //$NON-NLS-1$
+            }
+        }
+        inputText.setFont(fixedFont);
+        gd = new GridData(SWT.FILL, SWT.FILL, true, true, 3, 1);
+        gd.heightHint = inputText.computeSize(SWT.DEFAULT, inputText.getLineHeight() * 4).y;
+        gd.widthHint = 800;
+        inputText.setLayoutData(gd);
+        inputText.setText(getSelectionText());
+        inputText.addModifyListener(updateListener);
+
+        vSash.setWeights(new int[] {hSash.computeSize(SWT.DEFAULT, SWT.DEFAULT).y, sashBottom.computeSize(SWT.DEFAULT, SWT.DEFAULT).y});
+
+        setControl(container);
+
+        validate();
+        updatePreviews();
+    }
+
+    private static class InputLineTreeNodeContentProvider implements ITreeContentProvider {
+
+       @Override
+        public Object[] getElements(Object inputElement) {
+            return ((List<?>) inputElement).toArray();
+        }
+
+       @Override
+        public Object[] getChildren(Object parentElement) {
+            InputLine inputLine = (InputLine) parentElement;
+            if (inputLine.childrenInputs == null) {
+                return new InputLine[0];
+            }
+            return inputLine.childrenInputs.toArray();
+        }
+
+       @Override
+        public boolean hasChildren(Object element) {
+            InputLine inputLine = (InputLine) element;
+            return (inputLine.childrenInputs != null && inputLine.childrenInputs.size() > 0);
+        }
+
+       @Override
+        public void dispose() {
+        }
+
+       @Override
+        public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+        }
+
+       @Override
+        public Object getParent(Object element) {
+            InputLine inputLine = (InputLine) element;
+            return inputLine.parentInput;
+        }
+    }
+
+    private class InputLineTreeLabelProvider extends ColumnLabelProvider {
+
+        @Override
+        public Image getImage(Object element) {
+            return lineImage;
+        }
+
+        @Override
+        public String getText(Object element) {
+            InputLine inputLine = (InputLine) element;
+            if (inputLine.parentInput == null) {
+                return "Root Line " + getName(inputLine) + " " + inputLine.cardinality.toString() + " : " + inputLine.getRegex(); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+            }
+            return "Line " + getName(inputLine) + " " + inputLine.cardinality.toString() + " : " + inputLine.getRegex(); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+        }
+    }
+
+    private class InputLineTreeSelectionChangedListener implements ISelectionChangedListener {
+       @Override
+        public void selectionChanged(SelectionChangedEvent event) {
+            if (selectedLine != null) {
+                selectedLine.dispose();
+            }
+            if (!(event.getSelection().isEmpty()) && event.getSelection() instanceof IStructuredSelection) {
+                IStructuredSelection selection = (IStructuredSelection) event.getSelection();
+                InputLine inputLine = (InputLine) selection.getFirstElement();
+                selectedLine = new Line(lineContainer, getName(inputLine), inputLine);
+                lineContainer.layout();
+                lineScrolledComposite.setMinSize(lineContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).x, lineContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).y-1);
+                container.layout();
+                validate();
+                updatePreviews();
+            }
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see org.eclipse.jface.dialogs.DialogPage#dispose()
+     */
+    @Override
+    public void dispose() {
+        if (fixedFont != null) {
+            fixedFont.dispose();
+            fixedFont = null;
+        }
+        super.dispose();
+    }
+
+    private void loadDefinition(CustomTxtTraceDefinition def) {
+        logtypeText.setText(def.definitionName);
+        timestampOutputFormatText.setText(def.timeStampOutputFormat);
+        treeViewer.setInput(def.inputs);
+        if (def.inputs.size() > 0) {
+            InputLine inputLine = def.inputs.get(0);
+            treeViewer.setSelection(new StructuredSelection(inputLine));
+        }
+    }
+
+    private String getName(InputLine inputLine) {
+        if (inputLine.parentInput == null) {
+            return Integer.toString(definition.inputs.indexOf(inputLine)+1);
+        }
+        return getName(inputLine.parentInput) + "." + Integer.toString(inputLine.parentInput.childrenInputs.indexOf(inputLine)+1); //$NON-NLS-1$
+    }
+
+    public List<String> getInputNames() {
+        List<String> inputs = new ArrayList<String>();
+        for (InputLine inputLine : definition.inputs) {
+            for (String inputName : getInputNames(inputLine)) {
+                if (!inputs.contains(inputName)) {
+                    inputs.add(inputName);
+                }
+            }
+        }
+        return inputs;
+    }
+
+    public List<String> getInputNames(InputLine inputLine) {
+        List<String> inputs = new ArrayList<String>();
+        if (inputLine.columns != null) {
+            for (InputData inputData : inputLine.columns) {
+                String inputName = inputData.name;
+                if (!inputs.contains(inputName)) {
+                    inputs.add(inputName);
+                }
+            }
+        }
+        if (inputLine.childrenInputs != null) {
+            for (InputLine childInputLine : inputLine.childrenInputs) {
+                for (String inputName : getInputNames(childInputLine)) {
+                    if (!inputs.contains(inputName)) {
+                        inputs.add(inputName);
+                    }
+                }
+            }
+        }
+        return inputs;
+    }
+
+    private void removeLine() {
+        selectedLine.dispose();
+        selectedLine = null;
+        lineContainer.layout();
+        lineScrolledComposite.setMinSize(lineContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).x, lineContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).y-1);
+        container.layout();
+    }
+
+    private String getSelectionText() {
+        if (this.selection instanceof IStructuredSelection) {
+            Object selection = ((IStructuredSelection)this.selection).getFirstElement();
+            if (selection instanceof IFile) {
+                IFile file = (IFile)selection;
+                BufferedReader reader = null;
+                try {
+                    reader = new BufferedReader(new InputStreamReader(file.getContents()));
+                    StringBuilder sb = new StringBuilder();
+                    String line = null;
+                    while ((line = reader.readLine()) != null) {
+                        sb.append(line + "\n"); //$NON-NLS-1$
+                    }
+                    return sb.toString();
+                } catch (CoreException e) {
+                    return ""; //$NON-NLS-1$
+                } catch (IOException e) {
+                    return ""; //$NON-NLS-1$
+                } finally {
+                    if (reader != null) {
+                        try {
+                            reader.close();
+                        } catch (IOException e) {
+                        }
+                    }
+                }
+            }
+        }
+        return ""; //$NON-NLS-1$
+    }
+
+    private void updatePreviews() {
+        updatePreviews(false);
+    }
+
+    private void updatePreviews(boolean updateAll) {
+        if (inputText == null) {
+            // early update during construction
+            return;
+        }
+        inputText.setStyleRanges(new StyleRange[] {});
+
+        Scanner scanner = new Scanner(inputText.getText());
+        scanner.useDelimiter("\n"); //$NON-NLS-1$
+        int rawPos = 0;
+        String skip; // skip starting delimiters
+        if ((skip = scanner.findWithinHorizon("\\A\n+", 0)) != null) { //$NON-NLS-1$
+            rawPos += skip.length();
+        }
+
+        timeStampFormat = null;
+        if (selectedLine != null) {
+            for (InputGroup input : selectedLine.inputs) {
+                input.previewText.setText(Messages.CustomTxtParserInputWizardPage_noMathcingLine);
+            }
+        }
+
+        Map<String, String> data = new HashMap<String, String>();
+        int rootLineMatches = 0;
+        String firstEntryTimeStamp = null;
+        String firstEntryTimeStampInputFormat = null;
+        String log = null;
+    event:
+        while (scanner.hasNext()) {
+            if (rootLineMatches > 0 && !updateAll) {
+                break;
+            }
+            if (log == null) {
+                log = scanner.next();
+            }
+            int length = log.length();
+            for (InputLine rootInputLine : definition.inputs) {
+                Pattern pattern;
+                try {
+                    pattern = rootInputLine.getPattern();
+                } catch (PatternSyntaxException e) {
+                    continue;
+                }
+                Matcher matcher = pattern.matcher(log);
+                if (matcher.find()) {
+                    rootLineMatches++;
+                    inputText.setStyleRange(new StyleRange(rawPos, length,
+                            COLOR_BLACK, COLOR_YELLOW, SWT.ITALIC));
+                    data = new HashMap<String, String>();
+                    timeStampFormat = null;
+                    updatePreviewLine(rootInputLine, matcher, data, rawPos, rootLineMatches);
+                    if (rootLineMatches == 1) {
+                        firstEntryTimeStamp = data.get(CustomTraceDefinition.TAG_TIMESTAMP);
+                        firstEntryTimeStampInputFormat = timeStampFormat;
+                    }
+                    HashMap<InputLine, Integer> countMap = new HashMap<InputLine, Integer>();
+                    InputLine currentInput = null;
+                    if (rootInputLine.childrenInputs != null && rootInputLine.childrenInputs.size() > 0) {
+                        currentInput = rootInputLine.childrenInputs.get(0);
+                        countMap.put(currentInput, 0);
+                    }
+                    rawPos += length + 1; // +1 for \n
+                    while (scanner.hasNext()) {
+                        log = scanner.next();
+                        length = log.length();
+                        boolean processed = false;
+                        if (currentInput == null) {
+                            for (InputLine input : definition.inputs) {
+                                matcher = input.getPattern().matcher(log);
+                                if (matcher.find()) {
+                                    continue event;
+                                }
+                            }
+                        } else {
+                            if (countMap.get(currentInput) >= currentInput.getMinCount()) {
+                                List<InputLine> nextInputs = currentInput.getNextInputs(countMap);
+                                if (nextInputs.size() == 0 || nextInputs.get(nextInputs.size() - 1).getMinCount() == 0) {
+                                    for (InputLine input : definition.inputs) {
+                                        matcher = input.getPattern().matcher(log);
+                                        if (matcher.find()) {
+                                            continue event;
+                                        }
+                                    }
+                                }
+                                for (InputLine input : nextInputs) {
+                                    matcher = input.getPattern().matcher(log);
+                                    if (matcher.find()) {
+                                        inputText.setStyleRange(new StyleRange(rawPos, length,
+                                                COLOR_BLACK, COLOR_LIGHT_YELLOW, SWT.ITALIC));
+                                        currentInput = input;
+                                        updatePreviewLine(currentInput, matcher, data, rawPos, rootLineMatches);
+                                        if (countMap.get(currentInput) == null) {
+                                            countMap.put(currentInput, 1);
+                                        } else {
+                                            countMap.put(currentInput, countMap.get(currentInput) + 1);
+                                        }
+                                        Iterator<InputLine> iter = countMap.keySet().iterator();
+                                        while (iter.hasNext()) {
+                                            InputLine inputLine = iter.next();
+                                            if (inputLine.level > currentInput.level) {
+                                                iter.remove();
+                                            }
+                                        }
+                                        if (currentInput.childrenInputs != null && currentInput.childrenInputs.size() > 0) {
+                                            currentInput = currentInput.childrenInputs.get(0);
+                                            countMap.put(currentInput, 0);
+                                        } else {
+                                            if (countMap.get(currentInput) >= currentInput.getMaxCount()) {
+                                                if (currentInput.getNextInputs(countMap).size() > 0) {
+                                                    currentInput = currentInput.getNextInputs(countMap).get(0);
+                                                    if (countMap.get(currentInput) == null) {
+                                                        countMap.put(currentInput, 0);
+                                                    }
+                                                    iter = countMap.keySet().iterator();
+                                                    while (iter.hasNext()) {
+                                                        InputLine inputLine = iter.next();
+                                                        if (inputLine.level > currentInput.level) {
+                                                            iter.remove();
+                                                        }
+                                                    }
+                                                } else {
+                                                    currentInput = null;
+                                                }
+                                            }
+                                        }
+                                        processed = true;
+                                        break;
+                                    }
+                                }
+                            }
+                            if (! processed) {
+                                matcher = currentInput.getPattern().matcher(log);
+                                if (matcher.find()) {
+                                    inputText.setStyleRange(new StyleRange(rawPos, length,
+                                            COLOR_BLACK, COLOR_LIGHT_YELLOW, SWT.ITALIC));
+                                    updatePreviewLine(currentInput, matcher, data, rawPos, rootLineMatches);
+                                    countMap.put(currentInput, countMap.get(currentInput) + 1);
+                                    if (currentInput.childrenInputs != null && currentInput.childrenInputs.size() > 0) {
+                                        currentInput = currentInput.childrenInputs.get(0);
+                                        countMap.put(currentInput, 0);
+                                    } else {
+                                        if (countMap.get(currentInput) >= currentInput.getMaxCount()) {
+                                            if (currentInput.getNextInputs(countMap).size() > 0) {
+                                                currentInput = currentInput.getNextInputs(countMap).get(0);
+                                                if (countMap.get(currentInput) == null) {
+                                                    countMap.put(currentInput, 0);
+                                                }
+                                                Iterator<InputLine> iter = countMap.keySet().iterator();
+                                                while (iter.hasNext()) {
+                                                    InputLine inputLine = iter.next();
+                                                    if (inputLine.level > currentInput.level) {
+                                                        iter.remove();
+                                                    }
+                                                }
+                                            } else {
+                                                currentInput = null;
+                                            }
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                        rawPos += length + 1; // +1 for \n
+                    }
+
+                    break;
+                }
+            }
+            rawPos += length + 1; // +1 for \n
+            log = null;
+        }
+        scanner.close();
+        if (rootLineMatches == 1) {
+            firstEntryTimeStamp = data.get(CustomTraceDefinition.TAG_TIMESTAMP);
+            firstEntryTimeStampInputFormat = timeStampFormat;
+        }
+        if (firstEntryTimeStamp == null) {
+            timestampPreviewText.setText(Messages.CustomTxtParserInputWizardPage_noTimestampGroup);
+            if (selectedLine != null) {
+                for (InputGroup group : selectedLine.inputs) {
+                    if (group.tagCombo.getText().equals(CustomTraceDefinition.TAG_TIMESTAMP)) {
+                        timestampPreviewText.setText(Messages.CustomTxtParserInputWizardPage_noMatchingTimestamp);
+                        break;
+                    }
+                }
+            }
+        } else {
+            try {
+                SimpleDateFormat dateFormat = new SimpleDateFormat(firstEntryTimeStampInputFormat);
+                Date date = dateFormat.parse(firstEntryTimeStamp);
+                dateFormat = new SimpleDateFormat(timestampOutputFormatText.getText().trim());
+                timestampPreviewText.setText(dateFormat.format(date));
+            } catch (ParseException e) {
+                timestampPreviewText.setText("*parse exception* [" + firstEntryTimeStamp + "] <> [" + firstEntryTimeStampInputFormat + "]"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+            } catch (IllegalArgumentException e) {
+                timestampPreviewText.setText("*parse exception* [Illegal Argument]"); //$NON-NLS-1$
+            }
+
+        }
+    }
+
+    private void updatePreviewLine(InputLine line, Matcher matcher, Map<String, String> data, int rawPos, int rootLineMatches) {
+        for (int i = 0; i < line.columns.size(); i++) {
+            InputData input = line.columns.get(i);
+            if (i < matcher.groupCount() && matcher.group(i+1) != null) {
+                if (line.parentInput == null) {
+                    inputText.setStyleRange(new StyleRange(rawPos + matcher.start(i+1), matcher.end(i+1) - matcher.start(i+1),
+                            COLOR_BLACK, COLOR_GREEN, SWT.BOLD));
+                } else {
+                    inputText.setStyleRange(new StyleRange(rawPos + matcher.start(i+1), matcher.end(i+1) - matcher.start(i+1),
+                            COLOR_BLACK, COLOR_LIGHT_GREEN, SWT.BOLD));
+                }
+                String value = matcher.group(i+1).trim();
+                if (selectedLine != null && selectedLine.inputLine.equals(line) && rootLineMatches == 1) {
+                    if (selectedLine.inputs.get(i).previewText.getText().equals(Messages.CustomTxtParserInputWizardPage_noMatchingLine)) {
+                        selectedLine.inputs.get(i).previewText.setText(value);
+                    }
+                }
+                if (value.length() == 0) {
+                    continue;
+                }
+                if (input.action == CustomTraceDefinition.ACTION_SET) {
+                    data.put(input.name, value);
+                    if (input.name.equals(CustomTraceDefinition.TAG_TIMESTAMP)) {
+                        timeStampFormat = input.format;
+                    }
+                } else if (input.action == CustomTraceDefinition.ACTION_APPEND) {
+                    String s = data.get(input.name);
+                    if (s != null) {
+                        data.put(input.name, s + value);
+                    } else {
+                        data.put(input.name, value);
+                    }
+                    if (input.name.equals(CustomTraceDefinition.TAG_TIMESTAMP)) {
+                        if (timeStampFormat != null) {
+                            timeStampFormat += input.format;
+                        } else {
+                            timeStampFormat = input.format;
+                        }
+                    }
+                } else if (input.action == CustomTraceDefinition.ACTION_APPEND_WITH_SEPARATOR) {
+                    String s = data.get(input.name);
+                    if (s != null) {
+                        data.put(input.name, s + " | " + value); //$NON-NLS-1$
+                    } else {
+                        data.put(input.name, value);
+                    }
+                    if (input.name.equals(CustomTraceDefinition.TAG_TIMESTAMP)) {
+                        if (timeStampFormat != null) {
+                            timeStampFormat += " | " + input.format; //$NON-NLS-1$
+                        } else {
+                            timeStampFormat = input.format;
+                        }
+                    }
+                }
+            } else {
+                if (selectedLine != null && selectedLine.inputLine.equals(line) && rootLineMatches == 1) {
+                    if (selectedLine.inputs.get(i).previewText.getText().equals(Messages.CustomTxtParserInputWizardPage_noMatchingLine)) {
+                        selectedLine.inputs.get(i).previewText.setText(Messages.CustomTxtParserInputWizardPage_noMatchingGroup);
+                    }
+                }
+            }
+        }
+        // highlight the matching groups that have no corresponponding input
+        for (int i = line.columns.size(); i < matcher.groupCount(); i++) {
+            if (matcher.group(i+1) != null) {
+                if (line.parentInput == null) {
+                    inputText.setStyleRange(new StyleRange(rawPos + matcher.start(i+1), matcher.end(i+1) - matcher.start(i+1),
+                            COLOR_BLACK, COLOR_MAGENTA));
+                } else {
+                    inputText.setStyleRange(new StyleRange(rawPos + matcher.start(i+1), matcher.end(i+1) - matcher.start(i+1),
+                            COLOR_BLACK, COLOR_LIGHT_MAGENTA));
+                }
+            }
+        }
+    }
+
+    private void openHelpShell(String url) {
+        if (helpBrowser != null && !helpBrowser.isDisposed()) {
+            helpBrowser.getShell().setActive();
+            if (!helpBrowser.getUrl().equals(url)) {
+                helpBrowser.setUrl(url);
+            }
+            return;
+        }
+        final Shell helpShell = new Shell(getShell(), SWT.SHELL_TRIM);
+        helpShell.setLayout(new FillLayout());
+        helpBrowser = new Browser(helpShell, SWT.NONE);
+        helpBrowser.addTitleListener(new TitleListener() {
+               @Override
+           public void changed(TitleEvent event) {
+               helpShell.setText(event.title);
+           }
+        });
+        helpBrowser.setBounds(0,0,600,400);
+        helpShell.pack();
+        helpShell.open();
+        helpBrowser.setUrl(url);
+    }
+
+    private void openLegend() {
+        final String CG = Messages.CustomTxtParserInputWizardPage_capturedGroup;
+        final String UCG = Messages.CustomTxtParserInputWizardPage_unidentifiedCaptureGroup;
+        final String UT = Messages.CustomTxtParserInputWizardPage_uncapturedText;
+        int line1start = 0;
+        String line1 = Messages.CustomTxtParserInputWizardPage_nonMatchingLine;
+        int line2start = line1start + line1.length();
+        String line2 = Messages.CustomTxtParserInputWizardPage_matchingLineRoot + CG + " " + UCG + " " + UT + " \n";  //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+        int line3start = line2start + line2.length();
+        String line3 = Messages.CustomTxtParserInputWizardPage_matchingOtherLine + CG + " " + UCG + " " + UT + " \n"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+        int line4start = line3start + line3.length();
+        String line4 = Messages.CustomTxtParserInputWizardPage_matchingOtherLine + CG + " " + UCG + " " + UT + " \n"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+        int line5start = line4start + line4.length();
+        String line5 = Messages.CustomTxtParserInputWizardPage_nonMatchingLine;
+        int line6start = line5start + line5.length();
+        String line6 = Messages.CustomTxtParserInputWizardPage_matchingRootLine + CG + " " + UCG + " " + UT + " \n"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+
+        final Shell legendShell = new Shell(getShell(), SWT.DIALOG_TRIM);
+        legendShell.setLayout(new FillLayout());
+        StyledText legendText = new StyledText(legendShell, SWT.MULTI);
+        legendText.setFont(fixedFont);
+        legendText.setText(line1 + line2 + line3 + line4 + line5 + line6);
+        legendText.setStyleRange(new StyleRange(line2start, line2.length(), COLOR_BLACK, COLOR_YELLOW, SWT.ITALIC));
+        legendText.setStyleRange(new StyleRange(line3start, line3.length(), COLOR_BLACK, COLOR_LIGHT_YELLOW, SWT.ITALIC));
+        legendText.setStyleRange(new StyleRange(line4start, line4.length(), COLOR_BLACK, COLOR_LIGHT_YELLOW, SWT.ITALIC));
+        legendText.setStyleRange(new StyleRange(line6start, line6.length(), COLOR_BLACK, COLOR_YELLOW, SWT.ITALIC));
+        legendText.setStyleRange(new StyleRange(line2start + line2.indexOf(CG), CG.length(), COLOR_BLACK, COLOR_GREEN, SWT.BOLD));
+        legendText.setStyleRange(new StyleRange(line2start + line2.indexOf(UCG), UCG.length(), COLOR_BLACK, COLOR_MAGENTA));
+        legendText.setStyleRange(new StyleRange(line3start + line3.indexOf(CG), CG.length(), COLOR_BLACK, COLOR_LIGHT_GREEN, SWT.BOLD));
+        legendText.setStyleRange(new StyleRange(line3start + line3.indexOf(UCG), UCG.length(), COLOR_BLACK, COLOR_LIGHT_MAGENTA));
+        legendText.setStyleRange(new StyleRange(line4start + line4.indexOf(CG), CG.length(), COLOR_BLACK, COLOR_LIGHT_GREEN, SWT.BOLD));
+        legendText.setStyleRange(new StyleRange(line4start + line4.indexOf(UCG), UCG.length(), COLOR_BLACK, COLOR_LIGHT_MAGENTA));
+        legendText.setStyleRange(new StyleRange(line6start + line6.indexOf(CG), CG.length(), COLOR_BLACK, COLOR_GREEN, SWT.BOLD));
+        legendText.setStyleRange(new StyleRange(line6start + line6.indexOf(UCG), UCG.length(), COLOR_BLACK, COLOR_MAGENTA));
+        legendShell.setText(Messages.CustomTxtParserInputWizardPage_previewLegend);
+        legendShell.pack();
+        legendShell.open();
+    }
+
+    private class UpdateListener implements ModifyListener, SelectionListener {
+
+       @Override
+        public void modifyText(ModifyEvent e) {
+            validate();
+            updatePreviews();
+        }
+
+       @Override
+        public void widgetDefaultSelected(SelectionEvent e) {
+            validate();
+            updatePreviews();
+        }
+
+       @Override
+        public void widgetSelected(SelectionEvent e) {
+            validate();
+            updatePreviews();
+        }
+
+    }
+
+    private class Line {
+        private static final String INFINITY_STRING = "\u221E"; //$NON-NLS-1$
+        InputLine inputLine;
+        Group group;
+        Composite labelComposite;
+        Text regexText;
+        Composite cardinalityContainer;
+        Combo cardinalityCombo;
+        Label cardinalityMinLabel;
+        Text cardinalityMinText;
+        Label cardinalityMaxLabel;
+        Text cardinalityMaxText;
+        Button infiniteButton;
+        List<InputGroup> inputs = new ArrayList<InputGroup>();
+        Button addGroupButton;
+        Label addGroupLabel;
+
+        public Line(Composite parent, String name, InputLine inputLine) {
+            this.inputLine = inputLine;
+
+            group = new Group(parent, SWT.NONE);
+            group.setText(name);
+            group.setLayout(new GridLayout(2, false));
+            group.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
+
+            labelComposite = new Composite(group, SWT.FILL);
+            GridLayout labelLayout = new GridLayout(1, false);
+            labelLayout.marginWidth = 0;
+            labelLayout.marginHeight = 0;
+            labelComposite.setLayout(labelLayout);
+            labelComposite.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false));
+
+            Label label = new Label(labelComposite, SWT.NULL);
+            label.setText(Messages.CustomTxtParserInputWizardPage_regularExpression);
+
+            Composite regexContainer = new Composite(group, SWT.NONE);
+            GridLayout regexLayout = new GridLayout(2, false);
+            regexLayout.marginHeight = 0;
+            regexLayout.marginWidth = 0;
+            regexContainer.setLayout(regexLayout);
+            regexContainer.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
+
+            regexText = new Text(regexContainer, SWT.BORDER | SWT.SINGLE);
+            GridData gd = new GridData(SWT.FILL, SWT.CENTER, true, false);
+            gd.widthHint = 0;
+            regexText.setLayoutData(gd);
+            regexText.setText(inputLine.getRegex());
+            regexText.addModifyListener(updateListener);
+
+            Button regexHelpButton = new Button(regexContainer, SWT.PUSH);
+            regexHelpButton.setImage(helpImage);
+            regexHelpButton.setToolTipText(Messages.CustomTxtParserInputWizardPage_regularExpressionHelp);
+            regexHelpButton.addSelectionListener(new SelectionAdapter() {
+               @Override
+               public void widgetSelected(SelectionEvent e) {
+                    openHelpShell(PATTERN_URL);
+                }
+            });
+
+            label = new Label(group, SWT.NONE);
+            label.setText(Messages.CustomTxtParserInputWizardPage_cardinality);
+            label.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false));
+
+            cardinalityContainer = new Composite(group, SWT.NONE);
+            GridLayout cardinalityLayout = new GridLayout(6, false);
+            cardinalityLayout.marginHeight = 0;
+            cardinalityLayout.marginWidth = 0;
+            cardinalityContainer.setLayout(cardinalityLayout);
+            cardinalityContainer.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
+
+            cardinalityCombo = new Combo(cardinalityContainer, SWT.DROP_DOWN | SWT.READ_ONLY);
+            cardinalityCombo.setItems(new String[] {
+                    Cardinality.ZERO_OR_MORE.toString(),
+                    Cardinality.ONE_OR_MORE.toString(),
+                    Cardinality.ZERO_OR_ONE.toString(),
+                    Cardinality.ONE.toString(),
+                    "(?,?)"}); //$NON-NLS-1$
+            cardinalityCombo.addSelectionListener(new SelectionListener(){
+               @Override
+                public void widgetDefaultSelected(SelectionEvent e) {}
+               @Override
+                public void widgetSelected(SelectionEvent e) {
+                    switch (cardinalityCombo.getSelectionIndex()) {
+                    case 4: //(?,?)
+                        cardinalityMinLabel.setVisible(true);
+                        cardinalityMinText.setVisible(true);
+                        cardinalityMaxLabel.setVisible(true);
+                        cardinalityMaxText.setVisible(true);
+                        infiniteButton.setVisible(true);
+                        break;
+                    default:
+                        cardinalityMinLabel.setVisible(false);
+                        cardinalityMinText.setVisible(false);
+                        cardinalityMaxLabel.setVisible(false);
+                        cardinalityMaxText.setVisible(false);
+                        infiniteButton.setVisible(false);
+                        break;
+                    }
+                    cardinalityContainer.layout();
+                    validate();
+                    updatePreviews();
+                }});
+
+            cardinalityMinLabel = new Label(cardinalityContainer, SWT.NONE);
+            cardinalityMinLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false));
+            cardinalityMinLabel.setText(Messages.CustomTxtParserInputWizardPage_min);
+            cardinalityMinLabel.setVisible(false);
+
+            cardinalityMinText = new Text(cardinalityContainer, SWT.BORDER | SWT.SINGLE);
+            gd = new GridData(SWT.CENTER, SWT.CENTER, false, false);
+            gd.widthHint = 20;
+            cardinalityMinText.setLayoutData(gd);
+            cardinalityMinText.setVisible(false);
+
+            cardinalityMaxLabel = new Label(cardinalityContainer, SWT.NONE);
+            cardinalityMaxLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false));
+            cardinalityMaxLabel.setText(Messages.CustomTxtParserInputWizardPage_max);
+            cardinalityMaxLabel.setVisible(false);
+
+            cardinalityMaxText = new Text(cardinalityContainer, SWT.BORDER | SWT.SINGLE);
+            gd = new GridData(SWT.CENTER, SWT.CENTER, false, false);
+            gd.widthHint = 20;
+            cardinalityMaxText.setLayoutData(gd);
+            cardinalityMaxText.setVisible(false);
+
+            infiniteButton = new Button(cardinalityContainer, SWT.PUSH);
+            infiniteButton.setText(INFINITY_STRING);
+            infiniteButton.setVisible(false);
+            infiniteButton.addSelectionListener(new SelectionAdapter(){
+                @Override
+                public void widgetSelected(SelectionEvent e) {
+                    cardinalityMaxText.setText(INFINITY_STRING);
+                }});
+
+            if (inputLine.cardinality.equals(Cardinality.ZERO_OR_MORE)) {
+                cardinalityCombo.select(0);
+            } else if (inputLine.cardinality.equals(Cardinality.ONE_OR_MORE)) {
+                cardinalityCombo.select(1);
+            } else if (inputLine.cardinality.equals(Cardinality.ZERO_OR_ONE)) {
+                cardinalityCombo.select(2);
+            } else if (inputLine.cardinality.equals(Cardinality.ONE)) {
+                cardinalityCombo.select(3);
+            } else {
+                cardinalityCombo.select(4);
+                cardinalityMinLabel.setVisible(true);
+                cardinalityMinText.setVisible(true);
+                if (inputLine.getMinCount() >= 0) {
+                    cardinalityMinText.setText(Integer.toString(inputLine.getMinCount()));
+                }
+                cardinalityMaxLabel.setVisible(true);
+                cardinalityMaxText.setVisible(true);
+                if (inputLine.getMaxCount() == Cardinality.INF) {
+                    cardinalityMaxText.setText(INFINITY_STRING);
+                } else if (inputLine.getMaxCount() >= 0) {
+                    cardinalityMaxText.setText(Integer.toString(inputLine.getMaxCount()));
+                }
+                infiniteButton.setVisible(true);
+            }
+
+            VerifyListener digitsListener = new VerifyListener() {
+               @Override
+                public void verifyText(VerifyEvent e) {
+                    if (e.text.equals(INFINITY_STRING)) {
+                        e.doit = e.widget == cardinalityMaxText && e.start == 0 && e.end == ((Text) e.widget).getText().length();
+                    } else {
+                        if (((Text) e.widget).getText().equals(INFINITY_STRING)) {
+                            e.doit = e.start == 0 && e.end == ((Text) e.widget).getText().length();
+                        }
+                        for (int i = 0; i < e.text.length(); i++) {
+                            if (!Character.isDigit(e.text.charAt(i))) {
+                                e.doit = false;
+                                break;
+                            }
+                        }
+                    }
+                }};
+
+            cardinalityMinText.addModifyListener(updateListener);
+            cardinalityMaxText.addModifyListener(updateListener);
+            cardinalityMinText.addVerifyListener(digitsListener);
+            cardinalityMaxText.addVerifyListener(digitsListener);
+
+            if (inputLine.columns != null) {
+                for (InputData inputData : inputLine.columns) {
+                    InputGroup inputGroup = new InputGroup(group, this, inputs.size()+1);
+                    if (inputData.name.equals(CustomTraceDefinition.TAG_TIMESTAMP)) {
+                        inputGroup.tagCombo.select(0);
+                        inputGroup.tagText.setText(inputData.format);
+                        inputGroup.tagLabel.setText(Messages.CustomTxtParserInputWizardPage_format);
+                        inputGroup.tagLabel.setVisible(true);
+                        inputGroup.tagText.setVisible(true);
+                        inputGroup.tagText.addModifyListener(updateListener);
+                    } else if (inputData.name.equals(CustomTraceDefinition.TAG_MESSAGE)) {
+                        inputGroup.tagCombo.select(1);
+                    } else {
+                        inputGroup.tagCombo.select(2);
+                        inputGroup.tagText.setText(inputData.name);
+                        inputGroup.tagLabel.setText(Messages.CustomTxtParserInputWizardPage_name);
+                        inputGroup.tagLabel.setVisible(true);
+                        inputGroup.tagText.setVisible(true);
+                        inputGroup.tagText.addModifyListener(updateListener);
+                    }
+                    inputGroup.actionCombo.select(inputData.action);
+                    inputs.add(inputGroup);
+                }
+            }
+
+            createAddGroupButton();
+        }
+
+        private void createAddGroupButton() {
+            addGroupButton = new Button(group, SWT.PUSH);
+            addGroupButton.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false));
+            addGroupButton.setImage(addImage);
+            addGroupButton.setToolTipText(Messages.CustomTxtParserInputWizardPage_addGroup);
+            addGroupButton.addSelectionListener(new SelectionAdapter() {
+               @Override
+                public void widgetSelected(SelectionEvent e) {
+                    removeAddGroupButton();
+                    inputs.add(new InputGroup(group, Line.this, inputs.size()+1));
+                    createAddGroupButton();
+                    lineContainer.layout();
+                    lineScrolledComposite.setMinSize(lineContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).x, lineContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).y-1);
+                    group.getParent().layout();
+                    validate();
+                    updatePreviews();
+                }
+            });
+
+            addGroupLabel = new Label(group, SWT.NULL);
+            addGroupLabel.setText(Messages.CustomTxtParserInputWizardPage_newGroup);
+        }
+
+        private void removeAddGroupButton() {
+            addGroupButton.dispose();
+            addGroupLabel.dispose();
+        }
+
+        private void removeInput(int inputNumber) {
+            if (--inputNumber < inputs.size()) {
+                inputs.remove(inputNumber).dispose();
+                for (int i = inputNumber; i < inputs.size(); i++) {
+                    inputs.get(i).setInputNumber(i+1);
+                }
+                lineContainer.layout();
+                lineScrolledComposite.setMinSize(lineContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).x, lineContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT).y-1);
+                group.getParent().layout();
+            }
+        }
+
+//        private void setName(String name) {
+//            this.name = name;
+//            group.setText("Line " + name);
+//        }
+
+        private void dispose() {
+            group.dispose();
+        }
+
+        private void extractInputs() {
+            inputLine.setRegex(selectedLine.regexText.getText());
+            switch (cardinalityCombo.getSelectionIndex()) {
+            case 0:
+                inputLine.cardinality = Cardinality.ZERO_OR_MORE;
+                break;
+            case 1:
+                inputLine.cardinality = Cardinality.ONE_OR_MORE;
+                break;
+            case 2:
+                inputLine.cardinality = Cardinality.ZERO_OR_ONE;
+                break;
+            case 3:
+                inputLine.cardinality = Cardinality.ONE;
+                break;
+            case 4: //(?,?)
+                int min, max;
+                try {
+                    min = Integer.parseInt(cardinalityMinText.getText());
+                } catch (NumberFormatException e) {
+                    min = -1;
+                }
+                try {
+                    if (cardinalityMaxText.getText().equals(INFINITY_STRING)) {
+                        max = Cardinality.INF;
+                    } else {
+                        max = Integer.parseInt(cardinalityMaxText.getText());
+                    }
+                } catch (NumberFormatException e) {
+                    max = -1;
+                }
+                inputLine.cardinality = new Cardinality(min, max);
+                break;
+            default:
+                inputLine.cardinality = Cardinality.ZERO_OR_MORE;
+                break;
+            }
+            inputLine.columns = new ArrayList<InputData>(inputs.size());
+            for (int i = 0; i < inputs.size(); i++) {
+                InputGroup group = inputs.get(i);
+                InputData inputData = new InputData();
+                if (group.tagCombo.getText().equals(CustomTraceDefinition.TAG_OTHER)) {
+                    inputData.name = group.tagText.getText().trim();
+                } else {
+                    inputData.name = group.tagCombo.getText();
+                    if (group.tagCombo.getText().equals(CustomTraceDefinition.TAG_TIMESTAMP)) {
+                        inputData.format = group.tagText.getText().trim();
+                    }
+                }
+                inputData.action = group.actionCombo.getSelectionIndex();
+                inputLine.columns.add(inputData);
+            }
+        }
+    }
+
+    private class InputGroup {
+        Line line;
+        int inputNumber;
+
+        // children of parent (must be disposed)
+        Composite labelComposite;
+        Composite tagComposite;
+        Label previewLabel;
+        Text previewText;
+
+        // children of labelComposite
+        Label inputLabel;
+
+        // children of tagComposite
+        Combo tagCombo;
+        Label tagLabel;
+        Text tagText;
+        Combo actionCombo;
+
+        public InputGroup(Composite parent, Line line, int inputNumber) {
+            this.line = line;
+            this.inputNumber = inputNumber;
+
+            labelComposite = new Composite(parent, SWT.FILL);
+            GridLayout labelLayout = new GridLayout(2, false);
+            labelLayout.marginWidth = 0;
+            labelLayout.marginHeight = 0;
+            labelComposite.setLayout(labelLayout);
+            labelComposite.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false));
+
+            Button deleteButton = new Button(labelComposite, SWT.PUSH);
+            deleteButton.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false));
+            deleteButton.setImage(deleteImage);
+            deleteButton.setToolTipText(Messages.CustomTxtParserInputWizardPage_removeGroup);
+            deleteButton.addSelectionListener(new SelectionAdapter() {
+               @Override
+                public void widgetSelected(SelectionEvent e) {
+                    InputGroup.this.line.removeInput(InputGroup.this.inputNumber);
+                    validate();
+                    updatePreviews();
+                }
+            });
+
+            inputLabel = new Label(labelComposite, SWT.NULL);
+            inputLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false));
+            inputLabel.setText(Messages.CustomTxtParserInputWizardPage_group + inputNumber + ":"); //$NON-NLS-1$
+
+            tagComposite = new Composite(parent, SWT.FILL);
+            GridLayout tagLayout = new GridLayout(4, false);
+            tagLayout.marginWidth = 0;
+            tagLayout.marginHeight = 0;
+            tagComposite.setLayout(tagLayout);
+            tagComposite.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
+
+            tagCombo = new Combo(tagComposite, SWT.DROP_DOWN | SWT.READ_ONLY);
+            tagCombo.setItems(new String[] {CustomTraceDefinition.TAG_TIMESTAMP,
+                                            CustomTraceDefinition.TAG_MESSAGE,
+                                            CustomTraceDefinition.TAG_OTHER});
+            tagCombo.select(1);
+            tagCombo.addSelectionListener(new SelectionListener(){
+               @Override
+                public void widgetDefaultSelected(SelectionEvent e) {}
+               @Override
+                public void widgetSelected(SelectionEvent e) {
+                    tagText.removeModifyListener(updateListener);
+                    switch (tagCombo.getSelectionIndex()) {
+                    case 0: //Time Stamp
+                        tagLabel.setText(Messages.CustomTxtParserInputWizardPage_format);
+                        tagLabel.setVisible(true);
+                        tagText.setVisible(true);
+                        tagText.addModifyListener(updateListener);
+                        break;
+                    case 1: //Message
+                        tagLabel.setVisible(false);
+                        tagText.setVisible(false);
+                        break;
+                    case 2: //Other
+                        tagLabel.setText(Messages.CustomTxtParserInputWizardPage_name);
+                        tagLabel.setVisible(true);
+                        tagText.setVisible(true);
+                        tagText.addModifyListener(updateListener);
+                        break;
+                    case 3: //Continue
+                        tagLabel.setVisible(false);
+                        tagText.setVisible(false);
+                        break;
+                    default:
+                        break;
+                    }
+                    tagComposite.layout();
+                    validate();
+                    updatePreviews();
+                }});
+
+            tagLabel = new Label(tagComposite, SWT.NULL);
+            tagLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false));
+            tagLabel.setVisible(false);
+
+            tagText = new Text(tagComposite, SWT.BORDER | SWT.SINGLE);
+            GridData gd = new GridData(SWT.FILL, SWT.CENTER, true, false);
+            gd.widthHint = 0;
+            tagText.setLayoutData(gd);
+            tagText.setVisible(false);
+
+            actionCombo = new Combo(tagComposite, SWT.DROP_DOWN | SWT.READ_ONLY);
+            actionCombo.setItems(new String[] {Messages.CustomTxtParserInputWizardPage_set, Messages.CustomTxtParserInputWizardPage_append, Messages.CustomTxtParserInputWizardPage_appendWith});
+            actionCombo.select(0);
+            actionCombo.addSelectionListener(updateListener);
+
+            previewLabel = new Label(parent, SWT.NULL);
+            previewLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false));
+            previewLabel.setText(Messages.CustomTxtParserInputWizardPage_preview);
+
+            previewText = new Text(parent, SWT.BORDER | SWT.SINGLE | SWT.READ_ONLY);
+            gd = new GridData(SWT.FILL, SWT.CENTER, true, false);
+            gd.widthHint = 0;
+            previewText.setLayoutData(gd);
+            previewText.setText(Messages.CustomTxtParserInputWizardPage_noMatch);
+            previewText.setBackground(COLOR_WIDGET_BACKGROUND);
+        }
+
+        private void dispose() {
+            labelComposite.dispose();
+            tagComposite.dispose();
+            previewLabel.dispose();
+            previewText.dispose();
+        }
+
+        private void setInputNumber(int inputNumber) {
+            this.inputNumber = inputNumber;
+            inputLabel.setText(Messages.CustomTxtParserInputWizardPage_group + inputNumber + ":"); //$NON-NLS-1$
+            labelComposite.layout();
+        }
+    }
+
+    private void validate() {
+
+        definition.definitionName = logtypeText.getText().trim();
+        definition.timeStampOutputFormat = timestampOutputFormatText.getText().trim();
+
+        if (selectedLine != null) {
+            selectedLine.extractInputs();
+            treeViewer.refresh();
+        }
+
+        StringBuffer errors = new StringBuffer();
+
+        if (definition.definitionName.length() == 0) {
+            errors.append("Enter a name for the new log type. "); //$NON-NLS-1$
+            logtypeText.setBackground(COLOR_LIGHT_RED);
+        } else {
+            logtypeText.setBackground(COLOR_TEXT_BACKGROUND);
+            for (CustomTxtTraceDefinition def : CustomTxtTraceDefinition.loadAll()) {
+                if (definition.definitionName.equals(def.definitionName)) {
+                    if (editDefinitionName == null || ! editDefinitionName.equals(definition.definitionName)) {
+                        errors.append("The log type name already exists. "); //$NON-NLS-1$
+                        logtypeText.setBackground(COLOR_LIGHT_RED);
+                        break;
+                    }
+                }
+            }
+        }
+
+        timestampFound = false;
+        for (int i = 0; i < definition.inputs.size(); i++) {
+
+            InputLine inputLine = definition.inputs.get(i);
+            String name = Integer.toString(i+1);
+            errors.append(validateLine(inputLine, name));
+        }
+        if (timestampFound) {
+            if (definition.timeStampOutputFormat.length() == 0) {
+                errors.append("Enter the output format for the Time Stamp field. "); //$NON-NLS-1$
+                timestampOutputFormatText.setBackground(COLOR_LIGHT_RED);
+            } else {
+                try {
+                    new SimpleDateFormat(definition.timeStampOutputFormat);
+                    timestampOutputFormatText.setBackground(COLOR_TEXT_BACKGROUND);
+                } catch (IllegalArgumentException e) {
+                    errors.append("Enter a valid output format for the Time Stamp field. "); //$NON-NLS-1$
+                    timestampOutputFormatText.setBackground(COLOR_LIGHT_RED);
+                }
+            }
+
+        } else {
+            timestampOutputFormatText.setBackground(COLOR_TEXT_BACKGROUND);
+//            timestampPreviewText.setBackground(COLOR_WIDGET_BACKGROUND);
+//            errors.append("Identify a Time Stamp group (Line "+name+"). ");
+//            timestampPreviewText.setText("*no timestamp group*");
+//            timestampPreviewText.setBackground(COLOR_LIGHT_RED);
+        }
+
+        if (errors.length() == 0) {
+            setDescription(defaultDescription);
+            setPageComplete(true);
+        } else {
+            setDescription(errors.toString());
+            setPageComplete(false);
+        }
+    }
+
+    public StringBuffer validateLine(InputLine inputLine, String name) {
+        StringBuffer errors = new StringBuffer();
+        Line line = null;
+        if (selectedLine != null && selectedLine.inputLine.equals(inputLine)) {
+            line = selectedLine;
+        }
+        try {
+            Pattern.compile(inputLine.getRegex());
+            if (line != null) {
+                line.regexText.setBackground(COLOR_TEXT_BACKGROUND);
+            }
+        } catch (PatternSyntaxException e) {
+            errors.append("Enter a valid regular expression (Line "+name+"). "); //$NON-NLS-1$ //$NON-NLS-2$
+            if (line != null) {
+                line.regexText.setBackground(COLOR_LIGHT_RED);
+            }
+        }
+        if (inputLine.getMinCount() == -1) {
+            errors.append("Enter a minimum value for cardinality (Line "+name+"). "); //$NON-NLS-1$ //$NON-NLS-2$
+            if (line != null) {
+                line.cardinalityMinText.setBackground(COLOR_LIGHT_RED);
+            }
+        } else {
+            if (line != null) {
+                line.cardinalityMinText.setBackground(COLOR_TEXT_BACKGROUND);
+            }
+        }
+        if (inputLine.getMaxCount() == -1) {
+            errors.append("Enter a maximum value for cardinality (Line "+name+"). "); //$NON-NLS-1$ //$NON-NLS-2$
+            if (line != null) {
+                line.cardinalityMaxText.setBackground(COLOR_LIGHT_RED);
+            }
+        } else if (inputLine.getMinCount() > inputLine.getMaxCount()) {
+            errors.append("Enter correct (min <= max) values for cardinality (Line "+name+"). "); //$NON-NLS-1$ //$NON-NLS-2$
+            if (line != null) {
+                line.cardinalityMinText.setBackground(COLOR_LIGHT_RED);
+            }
+            if (line != null) {
+                line.cardinalityMaxText.setBackground(COLOR_LIGHT_RED);
+            }
+        } else {
+            if (line != null) {
+                line.cardinalityMaxText.setBackground(COLOR_TEXT_BACKGROUND);
+            }
+        }
+        for (int i = 0; inputLine.columns != null && i < inputLine.columns.size(); i++) {
+            InputData inputData = inputLine.columns.get(i);
+            InputGroup group = null;
+            if (line != null) {
+                group = line.inputs.get(i);
+            }
+            if (inputData.name.equals(CustomTraceDefinition.TAG_TIMESTAMP)) {
+                timestampFound = true;
+                if (inputData.format.length() == 0) {
+                    errors.append("Enter the input format for the Time Stamp (Line "+name+" Group "+(i+1)+"). "); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+                    if (group != null) {
+                        group.tagText.setBackground(COLOR_LIGHT_RED);
+                    }
+                } else {
+                    try {
+                        new SimpleDateFormat(inputData.format);
+                        if (group != null) {
+                            group.tagText.setBackground(COLOR_TEXT_BACKGROUND);
+                        }
+                    } catch (IllegalArgumentException e) {
+                        errors.append("Enter a valid input format for the Time Stamp (Line "+name+" Group "+(i+1)+"). "); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+                        if (group != null) {
+                            group.tagText.setBackground(COLOR_LIGHT_RED);
+                        }
+                    }
+                }
+            } else if (inputData.name.length() == 0) {
+                errors.append("Enter a name for the data group (Line "+name+" Group "+(i+1)+"). "); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+                if (group != null) {
+                    group.tagText.setBackground(COLOR_LIGHT_RED);
+                }
+            } else {
+                if (group != null) {
+                    group.tagText.setBackground(COLOR_TEXT_BACKGROUND);
+                }
+            }
+        }
+        for (int i = 0; inputLine.childrenInputs != null && i < inputLine.childrenInputs.size(); i++) {
+            errors.append(validateLine(inputLine.childrenInputs.get(i), name+"."+(i+1))); //$NON-NLS-1$
+        }
+        return errors;
+    }
+
+    public CustomTxtTraceDefinition getDefinition() {
+        return definition;
+    }
+
+    public char[] getInputText() {
+        return inputText.getText().toCharArray();
+    }
+}
This page took 0.104888 seconds and 5 git commands to generate.