protected JPanel buildMainPanel() {
		initialBuild = true;

		mainPanel = new JPanel(new BorderLayout(10, 5));

		comboModel = new DefaultComboBoxModel<>();
		populateComboBox();

		comboBox = new GhidraComboBox<>(comboModel);
		comboItemListener = e -> selectionChanged(e);
		comboBox.getAccessibleContext().setAccessibleName("Parse Configurations");
		comboBox.addItemListener(comboItemListener);

		JPanel cPanel = new JPanel(new BorderLayout());
		cPanel.setBorder(BorderFactory.createTitledBorder("Parse Configuration"));
		cPanel.add(comboBox);
		cPanel.getAccessibleContext().setAccessibleName("Configuration");
		JPanel comboPanel = new JPanel(new BorderLayout());
		comboPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
		comboPanel.getAccessibleContext().setAccessibleName("Configurations");
		comboPanel.add(cPanel);

		// enable edits, add to bottom, ordered
		pathPanel = new PathnameTablePanel(null, true, false, true);
		pathPanel.setBorder(BorderFactory.createTitledBorder("Source files to parse"));
		pathPanel.getAccessibleContext().setAccessibleName("Path");
		String importDir = Preferences.getProperty(LAST_IMPORT_C_DIRECTORY);
		if (importDir == null) {
			importDir = Preferences.getProperty(Preferences.LAST_PATH_DIRECTORY);
			if (importDir != null) {
				Preferences.setProperty(LAST_IMPORT_C_DIRECTORY, importDir);
			}
		}
		pathPanel.setFileChooserProperties("Choose Source Files", LAST_IMPORT_C_DIRECTORY,
			GhidraFileChooserMode.FILES_AND_DIRECTORIES, true,
			new ExtensionFileFilter(new String[] { "h" }, "C Header Files"));

		// Set default render to display red if file would not be found
		// Using include paths
		pathPanel.getTable().setDefaultRenderer(String.class, new GTableCellRenderer() {
			@Override
			public Component getTableCellRendererComponent(GTableCellRenderingData data) {

				JLabel label = (JLabel) super.getTableCellRendererComponent(data);
				label.getAccessibleContext().setAccessibleName("Path Data");
				Object value = data.getValue();

				String pathName = (String) value;
				pathName = (pathName == null ? "" : pathName.trim());

				if (pathName.length() == 0 || pathName.startsWith("#")) {
					return label;
				}

				boolean fileExists = true;
				File file = new File(pathName);
				fileExists = file.exists();

				// file not found directly, see if one of the include paths will find the file
				if (!fileExists) {
					fileExists = doesFileExist(pathName, fileExists);
				}

				label.setText(pathName.toString());
				if (!fileExists) {
					label.setForeground(getErrorForegroundColor(data.isSelected()));
				}
				return label;
			}
		});

		tableListener = e -> {
			ComboBoxItem item = (ComboBoxItem) comboBox.getSelectedItem();
			item.isChanged = !initialBuild;
			notifyContextChanged();
		};
		tableModel = pathPanel.getTable().getModel();
		tableModel.addTableModelListener(tableListener);

		// enable edits, add to bottom, ordered
		includePathPanel = new PathnameTablePanel(null, true, false, true);
		includePathPanel.setBorder(BorderFactory.createTitledBorder("Include paths"));
		includePathPanel.setFileChooserProperties("Choose Source Files", LAST_IMPORT_C_DIRECTORY,
			GhidraFileChooserMode.FILES_AND_DIRECTORIES, true,
			new ExtensionFileFilter(new String[] { "h" }, "C Header Files"));

		parsePathTableListener = e -> {
			ComboBoxItem item = (ComboBoxItem) comboBox.getSelectedItem();
			item.isChanged = !initialBuild;
			notifyContextChanged();
			pathPanel.getTable().repaint();
		};
		parsePathTableModel = includePathPanel.getTable().getModel();
		parsePathTableModel.addTableModelListener(parsePathTableListener);

		JPanel optionsPanel = new JPanel(new BorderLayout());
		optionsPanel.getAccessibleContext().setAccessibleName("Options");
		optionsPanel.setBorder(BorderFactory.createTitledBorder("Parse Options"));

		// create options field
		// initialize it with windows options
		parseOptionsField = new JTextArea(5, 70);
		JScrollPane pane = new JScrollPane(parseOptionsField);
		pane.getViewport().setPreferredSize(new Dimension(300, 200));
		pane.getAccessibleContext().setAccessibleName("Options");
		optionsPanel.add(pane, BorderLayout.CENTER);

		JPanel archPanel = new JPanel(new BorderLayout());
		archPanel.setBorder(BorderFactory.createTitledBorder("Program Architecture:"));
		archPanel.getAccessibleContext().setAccessibleName("Program Architecture");
		archPanel.add(new GLabel(" ", SwingConstants.RIGHT));
		languagePanel = buildLanguagePanel();
		archPanel.add(languagePanel);

		// create Parse Button

		parseButton = new JButton("Parse to Program");
		parseButton.addActionListener(ev -> doParse(false));
		parseButton.setToolTipText("Parse files and add data types to current program");
		parseButton.getAccessibleContext().setAccessibleName("Parse to Program");
		addButton(parseButton);

		parseToFileButton = new JButton("Parse to File...");
		parseToFileButton.addActionListener(ev -> doParse(true));
		parseToFileButton.setToolTipText("Parse files and output to archive file");
		parseToFileButton.getAccessibleContext().setAccessibleName("Parse to File");
		addButton(parseToFileButton);

		mainPanel.add(comboPanel, BorderLayout.NORTH);

		includePathPanel.setPreferredSize(new Dimension(pathPanel.getPreferredSize().width, 200));
		JSplitPane optionsPane =
			new JSplitPane(JSplitPane.VERTICAL_SPLIT, includePathPanel, optionsPanel);
		optionsPane.getAccessibleContext().setAccessibleName("Include Path and Options");
		optionsPane.setResizeWeight(0.50);

		pathPanel.setPreferredSize(new Dimension(pathPanel.getPreferredSize().width, 200));
		JSplitPane outerPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, pathPanel, optionsPane);
		outerPane.getAccessibleContext().setAccessibleName("Path and Options");
		outerPane.setResizeWeight(0.50);

		mainPanel.add(outerPane, BorderLayout.CENTER);

		mainPanel.add(archPanel, BorderLayout.SOUTH);

		setHelpLocation(new HelpLocation(plugin.getName(), "Parse_C_Source"));

		loadProfile();

		initialBuild = false;
		mainPanel.getAccessibleContext().setAccessibleName("Parse");
		return mainPanel;
	}
Dialog that shows files used for parsing C header files. The profile has a list of source header
files to parse, followed by parse options (compiler directives). Ghidra supplies a Windows
profile by default in core/parserprofiles. The user can do "save as" on this default profile to
create new profiles that will be written to the user's {@code <home>/userprofiles} directory. The
CParserPlugin creates this directory if it doesn't exist.
<p>
The data types resulting from the parse operation can either be added to the data type manager in
the current program, or written to an archive data file.
Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/cparser/ParseDialog.java