=UTF-8
diff --git a/unittest/org.eclipse.cdt.unittest.feature/.settings/org.eclipse.core.runtime.prefs b/unittest/org.eclipse.cdt.unittest.feature/.settings/org.eclipse.core.runtime.prefs
new file mode 100644
index 00000000000..5a0ad22d2a7
--- /dev/null
+++ b/unittest/org.eclipse.cdt.unittest.feature/.settings/org.eclipse.core.runtime.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+line.separator=\n
diff --git a/unittest/org.eclipse.cdt.unittest.feature/about.html b/unittest/org.eclipse.cdt.unittest.feature/about.html
new file mode 100644
index 00000000000..164f781a8fd
--- /dev/null
+++ b/unittest/org.eclipse.cdt.unittest.feature/about.html
@@ -0,0 +1,36 @@
+
+
+
+
+About
+
+
+ About This Content
+
+ November 30, 2017
+ License
+
+
+ The Eclipse Foundation makes available all content in this plug-in
+ ("Content"). Unless otherwise indicated below, the Content
+ is provided to you under the terms and conditions of the Eclipse
+ Public License Version 2.0 ("EPL"). A copy of the EPL is
+ available at http://www.eclipse.org/legal/epl-2.0.
+ For purposes of the EPL, "Program" will mean the Content.
+
+
+
+ If you did not receive this Content directly from the Eclipse
+ Foundation, the Content is being redistributed by another party
+ ("Redistributor") and different terms and conditions may
+ apply to your use of any object code in the Content. Check the
+ Redistributor's license that was provided with the Content. If no such
+ license exists, contact the Redistributor. Unless otherwise indicated
+ below, the terms and conditions of the EPL still apply to any source
+ code in the Content and such source code may be obtained at http://www.eclipse.org.
+
+
+
+
\ No newline at end of file
diff --git a/unittest/org.eclipse.cdt.unittest.feature/about.ini b/unittest/org.eclipse.cdt.unittest.feature/about.ini
new file mode 100644
index 00000000000..e07a7bb377e
--- /dev/null
+++ b/unittest/org.eclipse.cdt.unittest.feature/about.ini
@@ -0,0 +1,24 @@
+# about.ini
+# contains information about a feature
+# java.io.Properties file (ISO 8859-1 with "\" escapes)
+# "%key" are externalized strings defined in about.properties
+# This file does not need to be translated.
+
+# Property "aboutText" contains blurb for "About" dialog (translated)
+aboutText=%blurb
+
+# Property "windowImage" contains path to window icon (16x16)
+# needed for primary features only
+
+# Property "featureImage" contains path to feature image (32x32)
+featureImage=cdt_logo_icon32.png
+
+# Property "aboutImage" contains path to product image (500x330 or 115x164)
+# needed for primary features only
+
+# Property "appName" contains name of the application (translated)
+# needed for primary features only
+
+# Property "welcomePerspective" contains the id of the perspective in which the
+# welcome page is to be opened.
+# optional
diff --git a/unittest/org.eclipse.cdt.unittest.feature/about.mappings b/unittest/org.eclipse.cdt.unittest.feature/about.mappings
new file mode 100644
index 00000000000..936a8039c3e
--- /dev/null
+++ b/unittest/org.eclipse.cdt.unittest.feature/about.mappings
@@ -0,0 +1,9 @@
+# about.mappings
+# contains fill-ins for about.properties
+# java.io.Properties file (ISO 8859-1 with "\" escapes)
+# This file does not need to be translated.
+
+# The following should contain the build version.
+# e.g. "0=20200106-1728"
+# This value will be added automatically via the build scripts
+0=${buildId}
diff --git a/unittest/org.eclipse.cdt.unittest.feature/about.properties b/unittest/org.eclipse.cdt.unittest.feature/about.properties
new file mode 100644
index 00000000000..bdbe81c1e03
--- /dev/null
+++ b/unittest/org.eclipse.cdt.unittest.feature/about.properties
@@ -0,0 +1,32 @@
+###############################################################################
+# Copyright (c) 2020 Contributors to the Eclipse Foundation
+#
+# See the NOTICE file(s) distributed with this work for additional
+# information regarding copyright ownership.
+#
+# This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License 2.0
+# which accompanies this distribution, and is available at
+# https://www.eclipse.org/legal/epl-2.0/
+#
+# SPDX-License-Identifier: EPL-2.0
+###############################################################################
+# about.properties
+# contains externalized strings for about.ini
+# java.io.Properties file (ISO 8859-1 with "\" escapes)
+# fill-ins are supplied by about.mappings
+# This file should be translated.
+# NOTE TO TRANSLATOR: Please do not translate the featureVersion variable.
+
+
+blurb=C/C++ Test runner client for UnitTest View\n\
+\n\
+Version: {featureVersion}\n\
+Build id: {0}\n\
+\n\
+Copyright (c) 2020 Contributors to the Eclipse Foundation
+\n\
+See the NOTICE file(s) distributed with this work for additional\n\
+information regarding copyright ownership.\n\
+\n\
+Visit http://www.eclipse.org/cdt
diff --git a/unittest/org.eclipse.cdt.unittest.feature/build.properties b/unittest/org.eclipse.cdt.unittest.feature/build.properties
new file mode 100644
index 00000000000..2aed40631e7
--- /dev/null
+++ b/unittest/org.eclipse.cdt.unittest.feature/build.properties
@@ -0,0 +1,23 @@
+###############################################################################
+# Copyright (c) 2020 Red Hat, Inc.
+#
+# This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License 2.0
+# which accompanies this distribution, and is available at
+# https://www.eclipse.org/legal/epl-2.0/
+#
+# SPDX-License-Identifier: EPL-2.0
+#
+# Contributors:
+# Red Hat Inc. - initial API and implementation
+###############################################################################
+bin.includes = feature.xml,\
+ feature.properties,\
+ about.html,\
+ about.ini,\
+ about.mappings,\
+ about.properties,\
+ cdt_logo_icon32.png
+src.includes = feature.xml,\
+ feature.properties,\
+ about.html
\ No newline at end of file
diff --git a/unittest/org.eclipse.cdt.unittest.feature/cdt_logo_icon32.png b/unittest/org.eclipse.cdt.unittest.feature/cdt_logo_icon32.png
new file mode 100644
index 00000000000..470ca81b327
Binary files /dev/null and b/unittest/org.eclipse.cdt.unittest.feature/cdt_logo_icon32.png differ
diff --git a/unittest/org.eclipse.cdt.unittest.feature/feature.properties b/unittest/org.eclipse.cdt.unittest.feature/feature.properties
new file mode 100644
index 00000000000..0730fa2d6b7
--- /dev/null
+++ b/unittest/org.eclipse.cdt.unittest.feature/feature.properties
@@ -0,0 +1,22 @@
+#################################################################################
+# Copyright (c) 2020 Red Hat, Inc.
+#
+# This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License 2.0
+# which accompanies this distribution, and is available at
+# https://www.eclipse.org/legal/epl-2.0/
+#
+# SPDX-License-Identifier: EPL-2.0
+#
+# Contributors:
+# Red Hat Inc. - initial API and implementation
+#################################################################################
+featureName=C/C++ Test runner client for UnitTest View
+description=Support for running C/C++ unit tests using UnitTest View
+providerName=Eclipse CDT
+copyright=\
+Copyright (c) 2020 Red Hat, Inc. and others.\n\
+This program and the accompanying materials\n\
+are made available under the terms of the Eclipse Public License 2.0\n\
+which accompanies this distribution, and is available at\n\
+https://www.eclipse.org/legal/epl-2.0/
diff --git a/unittest/org.eclipse.cdt.unittest.feature/feature.xml b/unittest/org.eclipse.cdt.unittest.feature/feature.xml
new file mode 100644
index 00000000000..a4fe16c492b
--- /dev/null
+++ b/unittest/org.eclipse.cdt.unittest.feature/feature.xml
@@ -0,0 +1,51 @@
+
+
+
+
+ %description
+
+
+
+ %copyright
+
+
+
+ %license
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/unittest/org.eclipse.cdt.unittest/.classpath b/unittest/org.eclipse.cdt.unittest/.classpath
new file mode 100644
index 00000000000..4a00becd81d
--- /dev/null
+++ b/unittest/org.eclipse.cdt.unittest/.classpath
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/unittest/org.eclipse.cdt.unittest/.project b/unittest/org.eclipse.cdt.unittest/.project
new file mode 100644
index 00000000000..846548d65f9
--- /dev/null
+++ b/unittest/org.eclipse.cdt.unittest/.project
@@ -0,0 +1,34 @@
+
+
+ org.eclipse.cdt.unittest
+
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+ org.eclipse.pde.ManifestBuilder
+
+
+
+
+ org.eclipse.pde.SchemaBuilder
+
+
+
+
+ org.eclipse.pde.api.tools.apiAnalysisBuilder
+
+
+
+
+
+ org.eclipse.jdt.core.javanature
+ org.eclipse.pde.PluginNature
+ org.eclipse.pde.api.tools.apiAnalysisNature
+
+
diff --git a/unittest/org.eclipse.cdt.unittest/.settings/org.eclipse.core.resources.prefs b/unittest/org.eclipse.cdt.unittest/.settings/org.eclipse.core.resources.prefs
new file mode 100644
index 00000000000..99f26c0203a
--- /dev/null
+++ b/unittest/org.eclipse.cdt.unittest/.settings/org.eclipse.core.resources.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+encoding/=UTF-8
diff --git a/unittest/org.eclipse.cdt.unittest/.settings/org.eclipse.core.runtime.prefs b/unittest/org.eclipse.cdt.unittest/.settings/org.eclipse.core.runtime.prefs
new file mode 100644
index 00000000000..5a0ad22d2a7
--- /dev/null
+++ b/unittest/org.eclipse.cdt.unittest/.settings/org.eclipse.core.runtime.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+line.separator=\n
diff --git a/unittest/org.eclipse.cdt.unittest/.settings/org.eclipse.jdt.core.prefs b/unittest/org.eclipse.cdt.unittest/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 00000000000..e3a8104f9ca
--- /dev/null
+++ b/unittest/org.eclipse.cdt.unittest/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,486 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.builder.cleanOutputFolder=clean
+org.eclipse.jdt.core.builder.duplicateResourceTask=warning
+org.eclipse.jdt.core.builder.invalidClasspath=abort
+org.eclipse.jdt.core.builder.recreateModifiedClassFileInOutputFolder=ignore
+org.eclipse.jdt.core.builder.resourceCopyExclusionFilter=*.launch, *.xtend
+org.eclipse.jdt.core.circularClasspath=error
+org.eclipse.jdt.core.classpath.exclusionPatterns=enabled
+org.eclipse.jdt.core.classpath.mainOnlyProjectHasTestOnlyDependency=error
+org.eclipse.jdt.core.classpath.multipleOutputLocations=enabled
+org.eclipse.jdt.core.classpath.outputOverlappingAnotherSource=error
+org.eclipse.jdt.core.codeComplete.argumentPrefixes=
+org.eclipse.jdt.core.codeComplete.argumentSuffixes=
+org.eclipse.jdt.core.codeComplete.fieldPrefixes=
+org.eclipse.jdt.core.codeComplete.fieldSuffixes=
+org.eclipse.jdt.core.codeComplete.localPrefixes=
+org.eclipse.jdt.core.codeComplete.localSuffixes=
+org.eclipse.jdt.core.codeComplete.staticFieldPrefixes=
+org.eclipse.jdt.core.codeComplete.staticFieldSuffixes=
+org.eclipse.jdt.core.codeComplete.staticFinalFieldPrefixes=
+org.eclipse.jdt.core.codeComplete.staticFinalFieldSuffixes=
+org.eclipse.jdt.core.compiler.annotation.inheritNullAnnotations=disabled
+org.eclipse.jdt.core.compiler.annotation.missingNonNullByDefaultAnnotation=ignore
+org.eclipse.jdt.core.compiler.annotation.nonnull=org.eclipse.jdt.annotation.NonNull
+org.eclipse.jdt.core.compiler.annotation.nonnull.secondary=
+org.eclipse.jdt.core.compiler.annotation.nonnullbydefault=org.eclipse.jdt.annotation.NonNullByDefault
+org.eclipse.jdt.core.compiler.annotation.nonnullbydefault.secondary=
+org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jdt.annotation.Nullable
+org.eclipse.jdt.core.compiler.annotation.nullable.secondary=
+org.eclipse.jdt.core.compiler.annotation.nullanalysis=disabled
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.methodParameters=generate
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=11
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=11
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.doc.comment.support=enabled
+org.eclipse.jdt.core.compiler.maxProblemPerUnit=100
+org.eclipse.jdt.core.compiler.problem.APILeak=warning
+org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.autoboxing=ignore
+org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning
+org.eclipse.jdt.core.compiler.problem.deadCode=warning
+org.eclipse.jdt.core.compiler.problem.deprecation=warning
+org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled
+org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled
+org.eclipse.jdt.core.compiler.problem.discouragedReference=warning
+org.eclipse.jdt.core.compiler.problem.emptyStatement=warning
+org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.problem.explicitlyClosedAutoCloseable=ignore
+org.eclipse.jdt.core.compiler.problem.fallthroughCase=warning
+org.eclipse.jdt.core.compiler.problem.fatalOptionalError=enabled
+org.eclipse.jdt.core.compiler.problem.fieldHiding=warning
+org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning
+org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=error
+org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning
+org.eclipse.jdt.core.compiler.problem.includeNullInfoFromAsserts=disabled
+org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning
+org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=warning
+org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore
+org.eclipse.jdt.core.compiler.problem.invalidJavadoc=ignore
+org.eclipse.jdt.core.compiler.problem.invalidJavadocTags=enabled
+org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsDeprecatedRef=disabled
+org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsNotVisibleRef=enabled
+org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsVisibility=protected
+org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore
+org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=error
+org.eclipse.jdt.core.compiler.problem.missingDefaultCase=ignore
+org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=warning
+org.eclipse.jdt.core.compiler.problem.missingEnumCaseDespiteDefault=disabled
+org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=ignore
+org.eclipse.jdt.core.compiler.problem.missingJavadocComments=ignore
+org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsOverriding=disabled
+org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsVisibility=public
+org.eclipse.jdt.core.compiler.problem.missingJavadocTagDescription=return_tag
+org.eclipse.jdt.core.compiler.problem.missingJavadocTags=ignore
+org.eclipse.jdt.core.compiler.problem.missingJavadocTagsMethodTypeParameters=disabled
+org.eclipse.jdt.core.compiler.problem.missingJavadocTagsOverriding=disabled
+org.eclipse.jdt.core.compiler.problem.missingJavadocTagsVisibility=protected
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=warning
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled
+org.eclipse.jdt.core.compiler.problem.missingSerialVersion=ignore
+org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore
+org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning
+org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning
+org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=warning
+org.eclipse.jdt.core.compiler.problem.nonnullParameterAnnotationDropped=warning
+org.eclipse.jdt.core.compiler.problem.nonnullTypeVariableFromLegacyInvocation=warning
+org.eclipse.jdt.core.compiler.problem.nullAnnotationInferenceConflict=error
+org.eclipse.jdt.core.compiler.problem.nullReference=error
+org.eclipse.jdt.core.compiler.problem.nullSpecViolation=error
+org.eclipse.jdt.core.compiler.problem.nullUncheckedConversion=warning
+org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning
+org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore
+org.eclipse.jdt.core.compiler.problem.pessimisticNullAnalysisForFreeTypeVariables=warning
+org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=warning
+org.eclipse.jdt.core.compiler.problem.potentialNullReference=warning
+org.eclipse.jdt.core.compiler.problem.potentiallyUnclosedCloseable=ignore
+org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning
+org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation=warning
+org.eclipse.jdt.core.compiler.problem.redundantNullCheck=warning
+org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=ignore
+org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=warning
+org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore
+org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore
+org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning
+org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
+org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning
+org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled
+org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
+org.eclipse.jdt.core.compiler.problem.syntacticNullAnalysisForFields=disabled
+org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore
+org.eclipse.jdt.core.compiler.problem.terminalDeprecation=warning
+org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
+org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=enabled
+org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
+org.eclipse.jdt.core.compiler.problem.unclosedCloseable=warning
+org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore
+org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.unlikelyCollectionMethodArgumentType=warning
+org.eclipse.jdt.core.compiler.problem.unlikelyCollectionMethodArgumentTypeStrict=disabled
+org.eclipse.jdt.core.compiler.problem.unlikelyEqualsArgumentType=info
+org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore
+org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=warning
+org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
+org.eclipse.jdt.core.compiler.problem.unstableAutoModuleName=warning
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled
+org.eclipse.jdt.core.compiler.problem.unusedExceptionParameter=ignore
+org.eclipse.jdt.core.compiler.problem.unusedImport=warning
+org.eclipse.jdt.core.compiler.problem.unusedLabel=warning
+org.eclipse.jdt.core.compiler.problem.unusedLocal=warning
+org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=ignore
+org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore
+org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled
+org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning
+org.eclipse.jdt.core.compiler.problem.unusedTypeParameter=ignore
+org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
+org.eclipse.jdt.core.compiler.release=enabled
+org.eclipse.jdt.core.compiler.source=11
+org.eclipse.jdt.core.formatter.align_assignment_statements_on_columns=false
+org.eclipse.jdt.core.formatter.align_fields_grouping_blank_lines=2147483647
+org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
+org.eclipse.jdt.core.formatter.align_variable_declarations_on_columns=false
+org.eclipse.jdt.core.formatter.align_with_spaces=false
+org.eclipse.jdt.core.formatter.alignment_for_additive_operator=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_assignment=0
+org.eclipse.jdt.core.formatter.alignment_for_bitwise_operator=16
+org.eclipse.jdt.core.formatter.alignment_for_compact_if=16
+org.eclipse.jdt.core.formatter.alignment_for_compact_loops=16
+org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80
+org.eclipse.jdt.core.formatter.alignment_for_enum_constants=16
+org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16
+org.eclipse.jdt.core.formatter.alignment_for_expressions_in_for_loop_header=0
+org.eclipse.jdt.core.formatter.alignment_for_logical_operator=16
+org.eclipse.jdt.core.formatter.alignment_for_method_declaration=0
+org.eclipse.jdt.core.formatter.alignment_for_module_statements=16
+org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16
+org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator=16
+org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0
+org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=80
+org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16
+org.eclipse.jdt.core.formatter.alignment_for_string_concatenation=16
+org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_type_arguments=0
+org.eclipse.jdt.core.formatter.alignment_for_type_parameters=0
+org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch=16
+org.eclipse.jdt.core.formatter.blank_lines_after_imports=1
+org.eclipse.jdt.core.formatter.blank_lines_after_package=1
+org.eclipse.jdt.core.formatter.blank_lines_before_field=0
+org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0
+org.eclipse.jdt.core.formatter.blank_lines_before_imports=1
+org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1
+org.eclipse.jdt.core.formatter.blank_lines_before_method=1
+org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1
+org.eclipse.jdt.core.formatter.blank_lines_before_package=0
+org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1
+org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1
+org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_lambda_body=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.comment.align_tags_descriptions_grouped=true
+org.eclipse.jdt.core.formatter.comment.align_tags_names_descriptions=false
+org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=false
+org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=false
+org.eclipse.jdt.core.formatter.comment.count_line_length_from_starting_position=true
+org.eclipse.jdt.core.formatter.comment.format_block_comments=false
+org.eclipse.jdt.core.formatter.comment.format_header=false
+org.eclipse.jdt.core.formatter.comment.format_html=true
+org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=false
+org.eclipse.jdt.core.formatter.comment.format_line_comments=false
+org.eclipse.jdt.core.formatter.comment.format_source_code=true
+org.eclipse.jdt.core.formatter.comment.indent_parameter_description=false
+org.eclipse.jdt.core.formatter.comment.indent_root_tags=false
+org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert
+org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=do not insert
+org.eclipse.jdt.core.formatter.comment.line_length=80
+org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries=true
+org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries=true
+org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments=false
+org.eclipse.jdt.core.formatter.compact_else_if=true
+org.eclipse.jdt.core.formatter.continuation_indentation=2
+org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2
+org.eclipse.jdt.core.formatter.disabling_tag=@formatter\:off
+org.eclipse.jdt.core.formatter.enabling_tag=@formatter\:on
+org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false
+org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column=false
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true
+org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true
+org.eclipse.jdt.core.formatter.indent_empty_lines=false
+org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true
+org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true
+org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true
+org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false
+org.eclipse.jdt.core.formatter.indentation.size=4
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_enum_constant=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_label=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_type_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_after_additive_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert
+org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_bitwise_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert
+org.eclipse.jdt.core.formatter.insert_space_after_lambda_arrow=insert
+org.eclipse.jdt.core.formatter.insert_space_after_logical_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_multiplicative_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_relational_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources=insert
+org.eclipse.jdt.core.formatter.insert_space_after_shift_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_string_concatenation=insert
+org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_additive_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert
+org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_bitwise_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_lambda_arrow=insert
+org.eclipse.jdt.core.formatter.insert_space_before_logical_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_multiplicative_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert
+org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert
+org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert
+org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_relational_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_shift_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_string_concatenation=insert
+org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.join_lines_in_comments=true
+org.eclipse.jdt.core.formatter.join_wrapped_lines=true
+org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false
+org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false
+org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false
+org.eclipse.jdt.core.formatter.keep_simple_do_while_body_on_same_line=false
+org.eclipse.jdt.core.formatter.keep_simple_for_body_on_same_line=false
+org.eclipse.jdt.core.formatter.keep_simple_while_body_on_same_line=false
+org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false
+org.eclipse.jdt.core.formatter.lineSplit=120
+org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false
+org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false
+org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0
+org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1
+org.eclipse.jdt.core.formatter.parentheses_positions_in_annotation=common_lines
+org.eclipse.jdt.core.formatter.parentheses_positions_in_catch_clause=common_lines
+org.eclipse.jdt.core.formatter.parentheses_positions_in_enum_constant_declaration=common_lines
+org.eclipse.jdt.core.formatter.parentheses_positions_in_for_statment=common_lines
+org.eclipse.jdt.core.formatter.parentheses_positions_in_if_while_statement=common_lines
+org.eclipse.jdt.core.formatter.parentheses_positions_in_lambda_declaration=common_lines
+org.eclipse.jdt.core.formatter.parentheses_positions_in_method_delcaration=common_lines
+org.eclipse.jdt.core.formatter.parentheses_positions_in_method_invocation=common_lines
+org.eclipse.jdt.core.formatter.parentheses_positions_in_switch_statement=common_lines
+org.eclipse.jdt.core.formatter.parentheses_positions_in_try_clause=common_lines
+org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true
+org.eclipse.jdt.core.formatter.tabulation.char=tab
+org.eclipse.jdt.core.formatter.tabulation.size=4
+org.eclipse.jdt.core.formatter.use_on_off_tags=true
+org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false
+org.eclipse.jdt.core.formatter.wrap_before_additive_operator=true
+org.eclipse.jdt.core.formatter.wrap_before_assignment_operator=false
+org.eclipse.jdt.core.formatter.wrap_before_bitwise_operator=true
+org.eclipse.jdt.core.formatter.wrap_before_conditional_operator=true
+org.eclipse.jdt.core.formatter.wrap_before_logical_operator=true
+org.eclipse.jdt.core.formatter.wrap_before_multiplicative_operator=true
+org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch=true
+org.eclipse.jdt.core.formatter.wrap_before_string_concatenation=true
+org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=true
+org.eclipse.jdt.core.incompatibleJDKLevel=ignore
+org.eclipse.jdt.core.incompleteClasspath=error
+org.eclipse.jdt.core.javaFormatter=org.eclipse.jdt.core.defaultJavaFormatter
diff --git a/unittest/org.eclipse.cdt.unittest/.settings/org.eclipse.jdt.launching.prefs b/unittest/org.eclipse.cdt.unittest/.settings/org.eclipse.jdt.launching.prefs
new file mode 100644
index 00000000000..f8a131b56e0
--- /dev/null
+++ b/unittest/org.eclipse.cdt.unittest/.settings/org.eclipse.jdt.launching.prefs
@@ -0,0 +1,3 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.launching.PREF_COMPILER_COMPLIANCE_DOES_NOT_MATCH_JRE=warning
+org.eclipse.jdt.launching.PREF_STRICTLY_COMPATIBLE_JRE_NOT_AVAILABLE=warning
diff --git a/unittest/org.eclipse.cdt.unittest/.settings/org.eclipse.jdt.ui.prefs b/unittest/org.eclipse.cdt.unittest/.settings/org.eclipse.jdt.ui.prefs
new file mode 100644
index 00000000000..e44576346c4
--- /dev/null
+++ b/unittest/org.eclipse.cdt.unittest/.settings/org.eclipse.jdt.ui.prefs
@@ -0,0 +1,133 @@
+cleanup.add_default_serial_version_id=true
+cleanup.add_generated_serial_version_id=false
+cleanup.add_missing_annotations=true
+cleanup.add_missing_deprecated_annotations=true
+cleanup.add_missing_methods=false
+cleanup.add_missing_nls_tags=false
+cleanup.add_missing_override_annotations=true
+cleanup.add_missing_override_annotations_interface_methods=true
+cleanup.add_serial_version_id=false
+cleanup.always_use_blocks=true
+cleanup.always_use_parentheses_in_expressions=false
+cleanup.always_use_this_for_non_static_field_access=false
+cleanup.always_use_this_for_non_static_method_access=false
+cleanup.convert_functional_interfaces=false
+cleanup.convert_to_enhanced_for_loop=false
+cleanup.correct_indentation=false
+cleanup.format_source_code=true
+cleanup.format_source_code_changes_only=false
+cleanup.insert_inferred_type_arguments=false
+cleanup.make_local_variable_final=true
+cleanup.make_parameters_final=false
+cleanup.make_private_fields_final=true
+cleanup.make_type_abstract_if_missing_method=false
+cleanup.make_variable_declarations_final=false
+cleanup.never_use_blocks=false
+cleanup.never_use_parentheses_in_expressions=true
+cleanup.organize_imports=true
+cleanup.qualify_static_field_accesses_with_declaring_class=false
+cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
+cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
+cleanup.qualify_static_member_accesses_with_declaring_class=false
+cleanup.qualify_static_method_accesses_with_declaring_class=false
+cleanup.remove_private_constructors=true
+cleanup.remove_redundant_modifiers=false
+cleanup.remove_redundant_semicolons=true
+cleanup.remove_redundant_type_arguments=true
+cleanup.remove_trailing_whitespaces=true
+cleanup.remove_trailing_whitespaces_all=true
+cleanup.remove_trailing_whitespaces_ignore_empty=false
+cleanup.remove_unnecessary_casts=true
+cleanup.remove_unnecessary_nls_tags=false
+cleanup.remove_unused_imports=true
+cleanup.remove_unused_local_variables=false
+cleanup.remove_unused_private_fields=true
+cleanup.remove_unused_private_members=false
+cleanup.remove_unused_private_methods=true
+cleanup.remove_unused_private_types=true
+cleanup.sort_members=false
+cleanup.sort_members_all=false
+cleanup.use_anonymous_class_creation=false
+cleanup.use_blocks=false
+cleanup.use_blocks_only_for_return_and_throw=false
+cleanup.use_lambda=true
+cleanup.use_parentheses_in_expressions=false
+cleanup.use_this_for_non_static_field_access=false
+cleanup.use_this_for_non_static_field_access_only_if_necessary=true
+cleanup.use_this_for_non_static_method_access=false
+cleanup.use_this_for_non_static_method_access_only_if_necessary=true
+cleanup_profile=_CDT
+cleanup_settings_version=2
+eclipse.preferences.version=1
+editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
+formatter_profile=_CDT
+formatter_settings_version=14
+internal.default.compliance=user
+org.eclipse.jdt.ui.exception.name=e
+org.eclipse.jdt.ui.gettersetter.use.is=true
+org.eclipse.jdt.ui.ignorelowercasenames=true
+org.eclipse.jdt.ui.importorder=java;javax;org;com;
+org.eclipse.jdt.ui.keywordthis=false
+org.eclipse.jdt.ui.ondemandthreshold=1000
+org.eclipse.jdt.ui.overrideannotation=true
+org.eclipse.jdt.ui.staticondemandthreshold=1000
+org.eclipse.jdt.ui.text.custom_code_templates=
+sp_cleanup.add_default_serial_version_id=true
+sp_cleanup.add_generated_serial_version_id=false
+sp_cleanup.add_missing_annotations=true
+sp_cleanup.add_missing_deprecated_annotations=true
+sp_cleanup.add_missing_methods=false
+sp_cleanup.add_missing_nls_tags=false
+sp_cleanup.add_missing_override_annotations=true
+sp_cleanup.add_missing_override_annotations_interface_methods=true
+sp_cleanup.add_serial_version_id=false
+sp_cleanup.always_use_blocks=true
+sp_cleanup.always_use_parentheses_in_expressions=false
+sp_cleanup.always_use_this_for_non_static_field_access=false
+sp_cleanup.always_use_this_for_non_static_method_access=false
+sp_cleanup.convert_functional_interfaces=false
+sp_cleanup.convert_to_enhanced_for_loop=false
+sp_cleanup.correct_indentation=false
+sp_cleanup.format_source_code=true
+sp_cleanup.format_source_code_changes_only=false
+sp_cleanup.insert_inferred_type_arguments=false
+sp_cleanup.make_local_variable_final=true
+sp_cleanup.make_parameters_final=false
+sp_cleanup.make_private_fields_final=true
+sp_cleanup.make_type_abstract_if_missing_method=false
+sp_cleanup.make_variable_declarations_final=false
+sp_cleanup.never_use_blocks=false
+sp_cleanup.never_use_parentheses_in_expressions=true
+sp_cleanup.on_save_use_additional_actions=true
+sp_cleanup.organize_imports=true
+sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
+sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
+sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
+sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
+sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_redundant_modifiers=false
+sp_cleanup.remove_redundant_semicolons=true
+sp_cleanup.remove_redundant_type_arguments=true
+sp_cleanup.remove_trailing_whitespaces=true
+sp_cleanup.remove_trailing_whitespaces_all=true
+sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
+sp_cleanup.remove_unnecessary_casts=true
+sp_cleanup.remove_unnecessary_nls_tags=false
+sp_cleanup.remove_unused_imports=true
+sp_cleanup.remove_unused_local_variables=false
+sp_cleanup.remove_unused_private_fields=true
+sp_cleanup.remove_unused_private_members=false
+sp_cleanup.remove_unused_private_methods=true
+sp_cleanup.remove_unused_private_types=true
+sp_cleanup.sort_members=false
+sp_cleanup.sort_members_all=false
+sp_cleanup.use_anonymous_class_creation=false
+sp_cleanup.use_blocks=false
+sp_cleanup.use_blocks_only_for_return_and_throw=false
+sp_cleanup.use_lambda=true
+sp_cleanup.use_parentheses_in_expressions=false
+sp_cleanup.use_this_for_non_static_field_access=false
+sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
+sp_cleanup.use_this_for_non_static_method_access=false
+sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
diff --git a/unittest/org.eclipse.cdt.unittest/.settings/org.eclipse.pde.api.tools.prefs b/unittest/org.eclipse.cdt.unittest/.settings/org.eclipse.pde.api.tools.prefs
new file mode 100644
index 00000000000..ec9fbf321d0
--- /dev/null
+++ b/unittest/org.eclipse.cdt.unittest/.settings/org.eclipse.pde.api.tools.prefs
@@ -0,0 +1,184 @@
+ANNOTATION_ELEMENT_TYPE_ADDED_CLASS_BOUND=Error
+ANNOTATION_ELEMENT_TYPE_ADDED_FIELD=Error
+ANNOTATION_ELEMENT_TYPE_ADDED_INTERFACE_BOUND=Error
+ANNOTATION_ELEMENT_TYPE_ADDED_INTERFACE_BOUNDS=Error
+ANNOTATION_ELEMENT_TYPE_ADDED_METHOD=Error
+ANNOTATION_ELEMENT_TYPE_ADDED_METHOD_WITHOUT_DEFAULT_VALUE=Error
+ANNOTATION_ELEMENT_TYPE_ADDED_TYPE_MEMBER=Error
+ANNOTATION_ELEMENT_TYPE_ADDED_TYPE_PARAMETER=Error
+ANNOTATION_ELEMENT_TYPE_CHANGED_CLASS_BOUND=Error
+ANNOTATION_ELEMENT_TYPE_CHANGED_CONTRACTED_SUPERINTERFACES_SET=Error
+ANNOTATION_ELEMENT_TYPE_CHANGED_INTERFACE_BOUND=Error
+ANNOTATION_ELEMENT_TYPE_CHANGED_INTERFACE_BOUNDS=Error
+ANNOTATION_ELEMENT_TYPE_CHANGED_RESTRICTIONS=Error
+ANNOTATION_ELEMENT_TYPE_CHANGED_TO_CLASS=Error
+ANNOTATION_ELEMENT_TYPE_CHANGED_TO_ENUM=Error
+ANNOTATION_ELEMENT_TYPE_CHANGED_TO_INTERFACE=Error
+ANNOTATION_ELEMENT_TYPE_CHANGED_TYPE_CONVERSION=Error
+ANNOTATION_ELEMENT_TYPE_REMOVED_CLASS_BOUND=Error
+ANNOTATION_ELEMENT_TYPE_REMOVED_FIELD=Error
+ANNOTATION_ELEMENT_TYPE_REMOVED_INTERFACE_BOUND=Error
+ANNOTATION_ELEMENT_TYPE_REMOVED_METHOD=Error
+ANNOTATION_ELEMENT_TYPE_REMOVED_METHOD_WITHOUT_DEFAULT_VALUE=Error
+ANNOTATION_ELEMENT_TYPE_REMOVED_METHOD_WITH_DEFAULT_VALUE=Error
+ANNOTATION_ELEMENT_TYPE_REMOVED_TYPE_MEMBER=Error
+ANNOTATION_ELEMENT_TYPE_REMOVED_TYPE_PARAMETER=Error
+ANNOTATION_ELEMENT_TYPE_REMOVED_TYPE_PARAMETERS=Error
+API_COMPONENT_ELEMENT_TYPE_REMOVED_API_TYPE=Error
+API_COMPONENT_ELEMENT_TYPE_REMOVED_REEXPORTED_API_TYPE=Error
+API_COMPONENT_ELEMENT_TYPE_REMOVED_REEXPORTED_TYPE=Error
+API_COMPONENT_ELEMENT_TYPE_REMOVED_TYPE=Error
+API_USE_SCAN_FIELD_SEVERITY=Error
+API_USE_SCAN_METHOD_SEVERITY=Error
+API_USE_SCAN_TYPE_SEVERITY=Error
+CLASS_ELEMENT_TYPE_ADDED_CLASS_BOUND=Error
+CLASS_ELEMENT_TYPE_ADDED_FIELD=Error
+CLASS_ELEMENT_TYPE_ADDED_INTERFACE_BOUND=Error
+CLASS_ELEMENT_TYPE_ADDED_INTERFACE_BOUNDS=Error
+CLASS_ELEMENT_TYPE_ADDED_METHOD=Error
+CLASS_ELEMENT_TYPE_ADDED_RESTRICTIONS=Error
+CLASS_ELEMENT_TYPE_ADDED_TYPE_PARAMETER=Error
+CLASS_ELEMENT_TYPE_CHANGED_CLASS_BOUND=Error
+CLASS_ELEMENT_TYPE_CHANGED_CONTRACTED_SUPERCLASS_SET=Error
+CLASS_ELEMENT_TYPE_CHANGED_CONTRACTED_SUPERINTERFACES_SET=Error
+CLASS_ELEMENT_TYPE_CHANGED_DECREASE_ACCESS=Error
+CLASS_ELEMENT_TYPE_CHANGED_INTERFACE_BOUND=Error
+CLASS_ELEMENT_TYPE_CHANGED_NON_ABSTRACT_TO_ABSTRACT=Error
+CLASS_ELEMENT_TYPE_CHANGED_NON_FINAL_TO_FINAL=Error
+CLASS_ELEMENT_TYPE_CHANGED_RESTRICTIONS=Error
+CLASS_ELEMENT_TYPE_CHANGED_SUPERCLASS=Error
+CLASS_ELEMENT_TYPE_CHANGED_TO_ANNOTATION=Error
+CLASS_ELEMENT_TYPE_CHANGED_TO_ENUM=Error
+CLASS_ELEMENT_TYPE_CHANGED_TO_INTERFACE=Error
+CLASS_ELEMENT_TYPE_CHANGED_TYPE_CONVERSION=Error
+CLASS_ELEMENT_TYPE_REMOVED_CLASS_BOUND=Error
+CLASS_ELEMENT_TYPE_REMOVED_CONSTRUCTOR=Error
+CLASS_ELEMENT_TYPE_REMOVED_FIELD=Error
+CLASS_ELEMENT_TYPE_REMOVED_INTERFACE_BOUND=Error
+CLASS_ELEMENT_TYPE_REMOVED_INTERFACE_BOUNDS=Error
+CLASS_ELEMENT_TYPE_REMOVED_METHOD=Error
+CLASS_ELEMENT_TYPE_REMOVED_SUPERCLASS=Error
+CLASS_ELEMENT_TYPE_REMOVED_TYPE_MEMBER=Error
+CLASS_ELEMENT_TYPE_REMOVED_TYPE_PARAMETER=Error
+CLASS_ELEMENT_TYPE_REMOVED_TYPE_PARAMETERS=Error
+CONSTRUCTOR_ELEMENT_TYPE_ADDED_CLASS_BOUND=Error
+CONSTRUCTOR_ELEMENT_TYPE_ADDED_INTERFACE_BOUND=Error
+CONSTRUCTOR_ELEMENT_TYPE_ADDED_INTERFACE_BOUNDS=Error
+CONSTRUCTOR_ELEMENT_TYPE_ADDED_TYPE_PARAMETER=Error
+CONSTRUCTOR_ELEMENT_TYPE_CHANGED_CLASS_BOUND=Error
+CONSTRUCTOR_ELEMENT_TYPE_CHANGED_DECREASE_ACCESS=Error
+CONSTRUCTOR_ELEMENT_TYPE_CHANGED_INTERFACE_BOUND=Error
+CONSTRUCTOR_ELEMENT_TYPE_CHANGED_NON_ABSTRACT_TO_ABSTRACT=Error
+CONSTRUCTOR_ELEMENT_TYPE_CHANGED_NON_FINAL_TO_FINAL=Error
+CONSTRUCTOR_ELEMENT_TYPE_CHANGED_NON_STATIC_TO_STATIC=Error
+CONSTRUCTOR_ELEMENT_TYPE_CHANGED_STATIC_TO_NON_STATIC=Error
+CONSTRUCTOR_ELEMENT_TYPE_CHANGED_TYPE_PARAMETER=Error
+CONSTRUCTOR_ELEMENT_TYPE_CHANGED_VARARGS_TO_ARRAY=Error
+CONSTRUCTOR_ELEMENT_TYPE_REMOVED_ANNOTATION_DEFAULT_VALUE=Error
+CONSTRUCTOR_ELEMENT_TYPE_REMOVED_CLASS_BOUND=Error
+CONSTRUCTOR_ELEMENT_TYPE_REMOVED_INTERFACE_BOUND=Error
+CONSTRUCTOR_ELEMENT_TYPE_REMOVED_INTERFACE_BOUNDS=Error
+CONSTRUCTOR_ELEMENT_TYPE_REMOVED_TYPE_PARAMETER=Error
+CONSTRUCTOR_ELEMENT_TYPE_REMOVED_TYPE_PARAMETERS=Error
+ENUM_ELEMENT_TYPE_CHANGED_CONTRACTED_SUPERINTERFACES_SET=Error
+ENUM_ELEMENT_TYPE_CHANGED_RESTRICTIONS=Error
+ENUM_ELEMENT_TYPE_CHANGED_TO_ANNOTATION=Error
+ENUM_ELEMENT_TYPE_CHANGED_TO_CLASS=Error
+ENUM_ELEMENT_TYPE_CHANGED_TO_INTERFACE=Error
+ENUM_ELEMENT_TYPE_CHANGED_TYPE_CONVERSION=Error
+ENUM_ELEMENT_TYPE_REMOVED_ENUM_CONSTANT=Error
+ENUM_ELEMENT_TYPE_REMOVED_FIELD=Error
+ENUM_ELEMENT_TYPE_REMOVED_METHOD=Error
+ENUM_ELEMENT_TYPE_REMOVED_TYPE_MEMBER=Error
+FIELD_ELEMENT_TYPE_ADDED_VALUE=Error
+FIELD_ELEMENT_TYPE_CHANGED_DECREASE_ACCESS=Error
+FIELD_ELEMENT_TYPE_CHANGED_FINAL_TO_NON_FINAL_STATIC_CONSTANT=Error
+FIELD_ELEMENT_TYPE_CHANGED_NON_FINAL_TO_FINAL=Error
+FIELD_ELEMENT_TYPE_CHANGED_NON_STATIC_TO_STATIC=Error
+FIELD_ELEMENT_TYPE_CHANGED_STATIC_TO_NON_STATIC=Error
+FIELD_ELEMENT_TYPE_CHANGED_TYPE=Error
+FIELD_ELEMENT_TYPE_CHANGED_VALUE=Error
+FIELD_ELEMENT_TYPE_REMOVED_TYPE_ARGUMENT=Error
+FIELD_ELEMENT_TYPE_REMOVED_TYPE_ARGUMENTS=Error
+FIELD_ELEMENT_TYPE_REMOVED_VALUE=Error
+ILLEGAL_EXTEND=Warning
+ILLEGAL_IMPLEMENT=Warning
+ILLEGAL_INSTANTIATE=Warning
+ILLEGAL_OVERRIDE=Warning
+ILLEGAL_REFERENCE=Warning
+INTERFACE_ELEMENT_TYPE_ADDED_CLASS_BOUND=Error
+INTERFACE_ELEMENT_TYPE_ADDED_DEFAULT_METHOD=Error
+INTERFACE_ELEMENT_TYPE_ADDED_FIELD=Error
+INTERFACE_ELEMENT_TYPE_ADDED_INTERFACE_BOUND=Error
+INTERFACE_ELEMENT_TYPE_ADDED_INTERFACE_BOUNDS=Error
+INTERFACE_ELEMENT_TYPE_ADDED_METHOD=Error
+INTERFACE_ELEMENT_TYPE_ADDED_RESTRICTIONS=Error
+INTERFACE_ELEMENT_TYPE_ADDED_SUPER_INTERFACE_WITH_METHODS=Error
+INTERFACE_ELEMENT_TYPE_ADDED_TYPE_MEMBER=Error
+INTERFACE_ELEMENT_TYPE_ADDED_TYPE_PARAMETER=Error
+INTERFACE_ELEMENT_TYPE_ADDED_TYPE_PARAMETERS=Error
+INTERFACE_ELEMENT_TYPE_CHANGED_CLASS_BOUND=Error
+INTERFACE_ELEMENT_TYPE_CHANGED_CONTRACTED_SUPERINTERFACES_SET=Error
+INTERFACE_ELEMENT_TYPE_CHANGED_INTERFACE_BOUND=Error
+INTERFACE_ELEMENT_TYPE_CHANGED_INTERFACE_BOUNDS=Error
+INTERFACE_ELEMENT_TYPE_CHANGED_RESTRICTIONS=Error
+INTERFACE_ELEMENT_TYPE_CHANGED_TO_ANNOTATION=Error
+INTERFACE_ELEMENT_TYPE_CHANGED_TO_CLASS=Error
+INTERFACE_ELEMENT_TYPE_CHANGED_TO_ENUM=Error
+INTERFACE_ELEMENT_TYPE_CHANGED_TYPE_CONVERSION=Error
+INTERFACE_ELEMENT_TYPE_REMOVED_CLASS_BOUND=Error
+INTERFACE_ELEMENT_TYPE_REMOVED_FIELD=Error
+INTERFACE_ELEMENT_TYPE_REMOVED_INTERFACE_BOUND=Error
+INTERFACE_ELEMENT_TYPE_REMOVED_INTERFACE_BOUNDS=Error
+INTERFACE_ELEMENT_TYPE_REMOVED_METHOD=Error
+INTERFACE_ELEMENT_TYPE_REMOVED_TYPE_MEMBER=Error
+INTERFACE_ELEMENT_TYPE_REMOVED_TYPE_PARAMETER=Error
+INVALID_ANNOTATION=Ignore
+INVALID_JAVADOC_TAG=Error
+INVALID_REFERENCE_IN_SYSTEM_LIBRARIES=Warning
+LEAK_EXTEND=Warning
+LEAK_FIELD_DECL=Warning
+LEAK_IMPLEMENT=Warning
+LEAK_METHOD_PARAM=Warning
+LEAK_METHOD_RETURN_TYPE=Warning
+METHOD_ELEMENT_TYPE_ADDED_CLASS_BOUND=Error
+METHOD_ELEMENT_TYPE_ADDED_INTERFACE_BOUND=Error
+METHOD_ELEMENT_TYPE_ADDED_INTERFACE_BOUNDS=Error
+METHOD_ELEMENT_TYPE_ADDED_RESTRICTIONS=Error
+METHOD_ELEMENT_TYPE_ADDED_TYPE_PARAMETER=Error
+METHOD_ELEMENT_TYPE_CHANGED_CLASS_BOUND=Error
+METHOD_ELEMENT_TYPE_CHANGED_DECREASE_ACCESS=Error
+METHOD_ELEMENT_TYPE_CHANGED_INTERFACE_BOUND=Error
+METHOD_ELEMENT_TYPE_CHANGED_NON_ABSTRACT_TO_ABSTRACT=Error
+METHOD_ELEMENT_TYPE_CHANGED_NON_FINAL_TO_FINAL=Error
+METHOD_ELEMENT_TYPE_CHANGED_NON_STATIC_TO_STATIC=Error
+METHOD_ELEMENT_TYPE_CHANGED_STATIC_TO_NON_STATIC=Error
+METHOD_ELEMENT_TYPE_CHANGED_TYPE_PARAMETER=Error
+METHOD_ELEMENT_TYPE_CHANGED_VARARGS_TO_ARRAY=Error
+METHOD_ELEMENT_TYPE_REMOVED_ANNOTATION_DEFAULT_VALUE=Error
+METHOD_ELEMENT_TYPE_REMOVED_CLASS_BOUND=Error
+METHOD_ELEMENT_TYPE_REMOVED_INTERFACE_BOUND=Error
+METHOD_ELEMENT_TYPE_REMOVED_INTERFACE_BOUNDS=Error
+METHOD_ELEMENT_TYPE_REMOVED_TYPE_PARAMETER=Error
+METHOD_ELEMENT_TYPE_REMOVED_TYPE_PARAMETERS=Error
+MISSING_EE_DESCRIPTIONS=Warning
+TYPE_PARAMETER_ELEMENT_TYPE_ADDED_CLASS_BOUND=Error
+TYPE_PARAMETER_ELEMENT_TYPE_ADDED_INTERFACE_BOUND=Error
+TYPE_PARAMETER_ELEMENT_TYPE_CHANGED_CLASS_BOUND=Error
+TYPE_PARAMETER_ELEMENT_TYPE_CHANGED_INTERFACE_BOUND=Error
+TYPE_PARAMETER_ELEMENT_TYPE_REMOVED_CLASS_BOUND=Error
+TYPE_PARAMETER_ELEMENT_TYPE_REMOVED_INTERFACE_BOUND=Error
+UNUSED_PROBLEM_FILTERS=Warning
+automatically_removed_unused_problem_filters=false
+changed_execution_env=Error
+eclipse.preferences.version=1
+incompatible_api_component_version=Error
+incompatible_api_component_version_include_major_without_breaking_change=Disabled
+incompatible_api_component_version_include_minor_without_api_change=Disabled
+incompatible_api_component_version_report_major_without_breaking_change=Warning
+incompatible_api_component_version_report_minor_without_api_change=Warning
+invalid_since_tag_version=Error
+malformed_since_tag=Error
+missing_since_tag=Error
+report_api_breakage_when_major_version_incremented=Disabled
+report_resolution_errors_api_component=Warning
diff --git a/unittest/org.eclipse.cdt.unittest/.settings/org.eclipse.pde.prefs b/unittest/org.eclipse.cdt.unittest/.settings/org.eclipse.pde.prefs
new file mode 100644
index 00000000000..d2dc703ba9e
--- /dev/null
+++ b/unittest/org.eclipse.cdt.unittest/.settings/org.eclipse.pde.prefs
@@ -0,0 +1,35 @@
+compilers.f.unresolved-features=1
+compilers.f.unresolved-plugins=1
+compilers.incompatible-environment=1
+compilers.p.build=1
+compilers.p.build.bin.includes=1
+compilers.p.build.encodings=2
+compilers.p.build.java.compiler=2
+compilers.p.build.java.compliance=1
+compilers.p.build.missing.output=2
+compilers.p.build.output.library=1
+compilers.p.build.source.library=1
+compilers.p.build.src.includes=1
+compilers.p.deprecated=1
+compilers.p.discouraged-class=1
+compilers.p.internal=1
+compilers.p.missing-packages=2
+compilers.p.missing-version-export-package=2
+compilers.p.missing-version-import-package=2
+compilers.p.missing-version-require-bundle=2
+compilers.p.no-required-att=0
+compilers.p.no.automatic.module=1
+compilers.p.not-externalized-att=1
+compilers.p.service.component.without.lazyactivation=1
+compilers.p.unknown-attribute=1
+compilers.p.unknown-class=1
+compilers.p.unknown-element=1
+compilers.p.unknown-identifier=1
+compilers.p.unknown-resource=1
+compilers.p.unresolved-ex-points=0
+compilers.p.unresolved-import=0
+compilers.s.create-docs=false
+compilers.s.doc-folder=doc
+compilers.s.open-tags=1
+compilers.use-project=true
+eclipse.preferences.version=1
diff --git a/unittest/org.eclipse.cdt.unittest/META-INF/MANIFEST.MF b/unittest/org.eclipse.cdt.unittest/META-INF/MANIFEST.MF
new file mode 100644
index 00000000000..0fc18eeb6b2
--- /dev/null
+++ b/unittest/org.eclipse.cdt.unittest/META-INF/MANIFEST.MF
@@ -0,0 +1,30 @@
+Manifest-Version: 1.0
+Automatic-Module-Name: org.eclipse.cdt.unittest
+Bundle-ManifestVersion: 2
+Bundle-Name: %pluginName
+Bundle-SymbolicName: org.eclipse.cdt.unittest;singleton:=true
+Bundle-Version: 1.0.0.qualifier
+Bundle-Activator: org.eclipse.cdt.unittest.CDTUnitTestPlugin
+Bundle-ActivationPolicy: lazy
+Bundle-Vendor: %providerName
+Bundle-Localization: plugin
+Require-Bundle: org.eclipse.unittest.ui,
+ org.eclipse.cdt.testsrunner,
+ org.eclipse.cdt.debug.core,
+ org.eclipse.cdt.debug.ui,
+ org.eclipse.cdt.managedbuilder.core,
+ org.eclipse.cdt.launch,
+ org.eclipse.cdt.dsf.gdb,
+ org.eclipse.cdt.dsf.gdb.ui,
+ org.eclipse.cdt.core,
+ org.eclipse.cdt.ui,
+ org.eclipse.search,
+ org.eclipse.core.runtime;bundle-version="[3.11.0,4.0.0)",
+ org.eclipse.ui;bundle-version="[3.5.0,4.0.0)",
+ org.eclipse.debug.core;bundle-version="[3.5.0,4.0.0)",
+ org.eclipse.debug.ui;bundle-version="[3.5.0,4.0.0)",
+ org.eclipse.jface.text;bundle-version="[3.5.0,4.0.0)",
+ org.eclipse.ui.workbench.texteditor;bundle-version="[3.5.0,4.0.0)",
+ org.eclipse.core.filesystem,
+ org.eclipse.ui.ide;bundle-version="[3.5.0,4.0.0)"
+Bundle-RequiredExecutionEnvironment: JavaSE-11
diff --git a/unittest/org.eclipse.cdt.unittest/about.html b/unittest/org.eclipse.cdt.unittest/about.html
new file mode 100644
index 00000000000..164f781a8fd
--- /dev/null
+++ b/unittest/org.eclipse.cdt.unittest/about.html
@@ -0,0 +1,36 @@
+
+
+
+
+About
+
+
+ About This Content
+
+ November 30, 2017
+ License
+
+
+ The Eclipse Foundation makes available all content in this plug-in
+ ("Content"). Unless otherwise indicated below, the Content
+ is provided to you under the terms and conditions of the Eclipse
+ Public License Version 2.0 ("EPL"). A copy of the EPL is
+ available at http://www.eclipse.org/legal/epl-2.0.
+ For purposes of the EPL, "Program" will mean the Content.
+
+
+
+ If you did not receive this Content directly from the Eclipse
+ Foundation, the Content is being redistributed by another party
+ ("Redistributor") and different terms and conditions may
+ apply to your use of any object code in the Content. Check the
+ Redistributor's license that was provided with the Content. If no such
+ license exists, contact the Redistributor. Unless otherwise indicated
+ below, the terms and conditions of the EPL still apply to any source
+ code in the Content and such source code may be obtained at http://www.eclipse.org.
+
+
+
+
\ No newline at end of file
diff --git a/unittest/org.eclipse.cdt.unittest/about.ini b/unittest/org.eclipse.cdt.unittest/about.ini
new file mode 100644
index 00000000000..e07a7bb377e
--- /dev/null
+++ b/unittest/org.eclipse.cdt.unittest/about.ini
@@ -0,0 +1,24 @@
+# about.ini
+# contains information about a feature
+# java.io.Properties file (ISO 8859-1 with "\" escapes)
+# "%key" are externalized strings defined in about.properties
+# This file does not need to be translated.
+
+# Property "aboutText" contains blurb for "About" dialog (translated)
+aboutText=%blurb
+
+# Property "windowImage" contains path to window icon (16x16)
+# needed for primary features only
+
+# Property "featureImage" contains path to feature image (32x32)
+featureImage=cdt_logo_icon32.png
+
+# Property "aboutImage" contains path to product image (500x330 or 115x164)
+# needed for primary features only
+
+# Property "appName" contains name of the application (translated)
+# needed for primary features only
+
+# Property "welcomePerspective" contains the id of the perspective in which the
+# welcome page is to be opened.
+# optional
diff --git a/unittest/org.eclipse.cdt.unittest/about.mappings b/unittest/org.eclipse.cdt.unittest/about.mappings
new file mode 100644
index 00000000000..936a8039c3e
--- /dev/null
+++ b/unittest/org.eclipse.cdt.unittest/about.mappings
@@ -0,0 +1,9 @@
+# about.mappings
+# contains fill-ins for about.properties
+# java.io.Properties file (ISO 8859-1 with "\" escapes)
+# This file does not need to be translated.
+
+# The following should contain the build version.
+# e.g. "0=20200106-1728"
+# This value will be added automatically via the build scripts
+0=${buildId}
diff --git a/unittest/org.eclipse.cdt.unittest/about.properties b/unittest/org.eclipse.cdt.unittest/about.properties
new file mode 100644
index 00000000000..c03bbd2c411
--- /dev/null
+++ b/unittest/org.eclipse.cdt.unittest/about.properties
@@ -0,0 +1,32 @@
+###############################################################################
+# Copyright (c) 2020 Contributors to the Eclipse Foundation
+#
+# See the NOTICE file(s) distributed with this work for additional
+# information regarding copyright ownership.
+#
+# This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License 2.0
+# which accompanies this distribution, and is available at
+# https://www.eclipse.org/legal/epl-2.0/
+#
+# SPDX-License-Identifier: EPL-2.0
+###############################################################################
+# about.properties
+# contains externalized strings for about.ini
+# java.io.Properties file (ISO 8859-1 with "\" escapes)
+# fill-ins are supplied by about.mappings
+# This file should be translated.
+# NOTE TO TRANSLATOR: Please do not translate the featureVersion variable.
+
+
+blurb=C/C++ Test runner client for UnitTest View\n\
+\n\
+Version: {featureVersion}\n\
+Build id: {0}\n\
+\n\
+Copyright (c) 2012, 2020 Contributors to the Eclipse Foundation
+\n\
+See the NOTICE file(s) distributed with this work for additional\n\
+information regarding copyright ownership.\n\
+\n\
+Visit http://www.eclipse.org/cdt
diff --git a/unittest/org.eclipse.cdt.unittest/build.properties b/unittest/org.eclipse.cdt.unittest/build.properties
new file mode 100644
index 00000000000..d4235413cbb
--- /dev/null
+++ b/unittest/org.eclipse.cdt.unittest/build.properties
@@ -0,0 +1,29 @@
+###############################################################################
+# Copyright (c) 2020 IBM Corporation and others.
+#
+# This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License 2.0
+# which accompanies this distribution, and is available at
+# https://www.eclipse.org/legal/epl-2.0/
+#
+# SPDX-License-Identifier: EPL-2.0
+#
+# Contributors:
+# IBM Corporation - initial API and implementation
+###############################################################################
+bin.includes = plugin.xml,\
+ about.html,\
+ icons/,\
+ plugin.properties,\
+ .,\
+ META-INF/
+ about.ini,\
+ about.mappings,\
+ about.properties,\
+ cdt_logo_icon32.png
+
+source.. = src/
+
+src.includes = about.html
+
+javacWarnings..=-unavoidableGenericProblems
\ No newline at end of file
diff --git a/unittest/org.eclipse.cdt.unittest/cdt_logo_icon32.png b/unittest/org.eclipse.cdt.unittest/cdt_logo_icon32.png
new file mode 100644
index 00000000000..470ca81b327
Binary files /dev/null and b/unittest/org.eclipse.cdt.unittest/cdt_logo_icon32.png differ
diff --git a/unittest/org.eclipse.cdt.unittest/icons/eview16/cppunit.gif b/unittest/org.eclipse.cdt.unittest/icons/eview16/cppunit.gif
new file mode 100644
index 00000000000..883170d6d3d
Binary files /dev/null and b/unittest/org.eclipse.cdt.unittest/icons/eview16/cppunit.gif differ
diff --git a/unittest/org.eclipse.cdt.unittest/icons/obj16/test_notrun.gif b/unittest/org.eclipse.cdt.unittest/icons/obj16/test_notrun.gif
new file mode 100644
index 00000000000..8f73ccb15ba
Binary files /dev/null and b/unittest/org.eclipse.cdt.unittest/icons/obj16/test_notrun.gif differ
diff --git a/unittest/org.eclipse.cdt.unittest/plugin.properties b/unittest/org.eclipse.cdt.unittest/plugin.properties
new file mode 100644
index 00000000000..9a7bd96fd95
--- /dev/null
+++ b/unittest/org.eclipse.cdt.unittest/plugin.properties
@@ -0,0 +1,31 @@
+###############################################################################
+ # Copyright (c) 2020 Red Hat Inc. and others.
+ #
+ # This program and the accompanying materials
+ # are made available under the terms of the Eclipse Public License 2.0
+ # which accompanies this distribution, and is available at
+ # https://www.eclipse.org/legal/epl-2.0/
+ #
+ # SPDX-License-Identifier: EPL-2.0
+ #
+ # Contributors:
+ # Red Hat Inc. - initial API and implementation
+ ###############################################################################
+
+pluginName=C/C++ Test runner client for UnitTest View
+providerName=Eclipse.org
+
+CPPUnitLaunchConfigurationType.name=C/C++ Unit Test (generic Test view)
+
+CPPUnitLaunch.name=Run C/C++ Unit Test Launcher
+CPPUnitLaunch.description=Run C/C++ tests.
+CPPUnitLaunchDSF.name=GDB (DSF) C/C++ Unit Test Launcher
+CPPUnitLaunchDSF.description=Run C/C++ Tests under control of GDB debugger integrated using the Debugger Services Framework (DSF).
+
+MainLaunchTab.name=Main
+ArgumentsLaunchTab.name=Arguments
+CTestingLaunchTab.name=C/C++ Testing
+EnvironmentLaunchTab.name=Environment
+DebuggerLaunchTab.name=Debugger
+SourceLookupLaunchTab.name=Source
+CommonLaunchTab.name=Common
diff --git a/unittest/org.eclipse.cdt.unittest/plugin.xml b/unittest/org.eclipse.cdt.unittest/plugin.xml
new file mode 100644
index 00000000000..b2e5534d7fd
--- /dev/null
+++ b/unittest/org.eclipse.cdt.unittest/plugin.xml
@@ -0,0 +1,181 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/unittest/org.eclipse.cdt.unittest/src/org/eclipse/cdt/unittest/CDTUnitTestPlugin.java b/unittest/org.eclipse.cdt.unittest/src/org/eclipse/cdt/unittest/CDTUnitTestPlugin.java
new file mode 100644
index 00000000000..fe6901dd548
--- /dev/null
+++ b/unittest/org.eclipse.cdt.unittest/src/org/eclipse/cdt/unittest/CDTUnitTestPlugin.java
@@ -0,0 +1,89 @@
+/*******************************************************************************
+ * Copyright (c) 2020 Red Hat Inc. and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Red Hat Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.unittest;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Plugin;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.preferences.InstanceScope;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+
+/**
+ * The plug-in runtime class for the JUnit core plug-in.
+ */
+public class CDTUnitTestPlugin extends Plugin {
+
+ /**
+ * The single instance of this plug-in runtime class.
+ */
+ private static CDTUnitTestPlugin fgPlugin = null;
+
+ public static final String UNITTEST_PLUGIN_ID = "org.eclipse.unittest.ui"; //$NON-NLS-1$
+ public static final String PLUGIN_ID = "org.eclipse.cdt.unittest"; //$NON-NLS-1$
+
+ public static final String CDT_TEST_VIEW_SUPPORT_ID = "org.eclipse.cdt.unittest.loader"; //$NON-NLS-1$
+ public static final String CDT_DSF_DBG_TEST_VIEW_SUPPORT_ID = "org.eclipse.cdt.unittest.loader"; //$NON-NLS-1$
+
+ private BundleContext fBundleContext;
+
+ public CDTUnitTestPlugin() {
+ fgPlugin = this;
+ }
+
+ public static CDTUnitTestPlugin getDefault() {
+ return fgPlugin;
+ }
+
+ public static String getPluginId() {
+ return PLUGIN_ID;
+ }
+
+ public static void log(Throwable e) {
+ log(new Status(IStatus.ERROR, getPluginId(), IStatus.ERROR, "Error", e)); //$NON-NLS-1$
+ }
+
+ public static void log(IStatus status) {
+ getDefault().getLog().log(status);
+ }
+
+ @Override
+ public void start(BundleContext context) throws Exception {
+ super.start(context);
+ fBundleContext = context;
+ }
+
+ @Override
+ public void stop(BundleContext context) throws Exception {
+ try {
+ InstanceScope.INSTANCE.getNode(CDTUnitTestPlugin.UNITTEST_PLUGIN_ID).flush();
+ } finally {
+ super.stop(context);
+ }
+ fBundleContext = null;
+ }
+
+ /**
+ * Returns a service with the specified name or null
if none.
+ *
+ * @param serviceName name of service
+ * @return service object or null
if none
+ */
+ public Object getService(String serviceName) {
+ ServiceReference> reference = fBundleContext.getServiceReference(serviceName);
+ if (reference == null)
+ return null;
+ return fBundleContext.getService(reference);
+ }
+}
diff --git a/unittest/org.eclipse.cdt.unittest/src/org/eclipse/cdt/unittest/internal/launcher/CTestingTab.java b/unittest/org.eclipse.cdt.unittest/src/org/eclipse/cdt/unittest/internal/launcher/CTestingTab.java
new file mode 100644
index 00000000000..f7ea8f67ebd
--- /dev/null
+++ b/unittest/org.eclipse.cdt.unittest/src/org/eclipse/cdt/unittest/internal/launcher/CTestingTab.java
@@ -0,0 +1,208 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2020 Anton Gorenkov
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Anton Gorenkov - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.unittest.internal.launcher;
+
+import org.eclipse.cdt.launch.ui.CLaunchConfigurationTab;
+import org.eclipse.cdt.testsrunner.internal.TestsRunnerPlugin;
+import org.eclipse.cdt.testsrunner.internal.launcher.ITestsLaunchConfigurationConstants;
+import org.eclipse.cdt.testsrunner.internal.launcher.TestsRunnerProviderInfo;
+import org.eclipse.cdt.testsrunner.launcher.ITestsRunnerProviderInfo;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Label;
+
+import org.eclipse.core.runtime.CoreException;
+
+import org.eclipse.debug.core.DebugPlugin;
+import org.eclipse.debug.core.ILaunchConfiguration;
+import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
+
+/**
+ * A launch configuration tab that displays and edits different testing options
+ * (e.g. Tests Runner provider plug-in).
+ *
+ * This class may be instantiated. This class is not intended to be subclassed.
+ *
+ *
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+public class CTestingTab extends CLaunchConfigurationTab {
+
+ /**
+ * Tab identifier used for ordering of tabs added using the
+ * org.eclipse.debug.ui.launchConfigurationTabs
+ * extension point.
+ */
+ private static final String TAB_ID = "org.eclipse.cdt.testsrunner.testingTab"; //$NON-NLS-1$
+
+ private static final String TESTING_PROCESS_FACTORY_ID = "org.eclipse.cdt.unittest.testsrunner.TestingProcessFactory"; //$NON-NLS-1$
+
+ /** Shows the list of available Tests Runner provider plug-ins. */
+ private Combo testsRunnerProviderCombo;
+
+ /** Shows the description for the currently selected Tests Runner provider plug-in. */
+ private Label testsRunnerProviderDescriptionLabel;
+
+ @Override
+ public void createControl(Composite parent) {
+ Composite pageComposite = new Composite(parent, SWT.NONE);
+ GridLayout pageCompositeLayout = new GridLayout(2, false);
+ pageCompositeLayout.horizontalSpacing = 40;
+ pageComposite.setLayout(pageCompositeLayout);
+
+ // Create a tests runner selector
+ new Label(pageComposite, SWT.NONE).setText(LauncherMessages.CTestingTab_tests_runner_label);
+ testsRunnerProviderCombo = new Combo(pageComposite, SWT.READ_ONLY | SWT.DROP_DOWN);
+ testsRunnerProviderCombo.add(LauncherMessages.CTestingTab_tests_runner_is_not_set);
+ testsRunnerProviderCombo.setData("0", null); //$NON-NLS-1$
+
+ // Add all the tests runners
+ for (TestsRunnerProviderInfo testsRunnerProviderInfo : TestsRunnerPlugin.getDefault()
+ .getTestsRunnerProvidersManager().getTestsRunnersProviderInfo()) {
+ testsRunnerProviderCombo.setData(Integer.toString(testsRunnerProviderCombo.getItemCount()),
+ testsRunnerProviderInfo);
+ testsRunnerProviderCombo.add(testsRunnerProviderInfo.getName());
+ }
+
+ testsRunnerProviderCombo.addModifyListener(new ModifyListener() {
+
+ @Override
+ public void modifyText(ModifyEvent e) {
+ testsRunnerProviderDescriptionLabel.setText(getCurrentTestsRunnerDescription());
+ updateLaunchConfigurationDialog();
+ }
+ });
+
+ // Create a tests runner description label
+ testsRunnerProviderDescriptionLabel = new Label(pageComposite, SWT.WRAP);
+ GridData testsRunnerProviderLabelGD = new GridData(GridData.FILL_BOTH);
+ testsRunnerProviderLabelGD.horizontalSpan = 2;
+ testsRunnerProviderLabelGD.horizontalAlignment = GridData.FILL;
+ testsRunnerProviderDescriptionLabel.setLayoutData(testsRunnerProviderLabelGD);
+
+ GridData pageCompositeGD = new GridData(GridData.FILL_BOTH);
+ pageCompositeGD.horizontalAlignment = GridData.FILL;
+ pageCompositeGD.grabExcessHorizontalSpace = true;
+ pageComposite.setLayoutData(pageCompositeGD);
+ setControl(pageComposite);
+ }
+
+ /**
+ * Returns the information for the currently selected Tests Runner provider
+ * plug-in.
+ *
+ * @return Tests Runner provide plug-in information
+ */
+ private ITestsRunnerProviderInfo getCurrentTestsRunnerProviderInfo() {
+ return getTestsRunnerProviderInfo(testsRunnerProviderCombo.getSelectionIndex());
+ }
+
+ /**
+ * Returns the information for the Tests Runner provide plug-in specified by
+ * index.
+ *
+ * @param comboIndex index in combo widget
+ * @return Tests Runner provide plug-in information
+ */
+ private ITestsRunnerProviderInfo getTestsRunnerProviderInfo(int comboIndex) {
+ return (ITestsRunnerProviderInfo) testsRunnerProviderCombo.getData(Integer.toString(comboIndex));
+ }
+
+ /**
+ * Returns the description for the currently selected Tests Runner provide
+ * plug-in.
+ *
+ * @return the description
+ */
+ private String getCurrentTestsRunnerDescription() {
+ ITestsRunnerProviderInfo testsRunnerProvider = getCurrentTestsRunnerProviderInfo();
+ if (testsRunnerProvider != null) {
+ return testsRunnerProvider.getDescription();
+ } else {
+ return LauncherMessages.CTestingTab_no_tests_runner_label;
+ }
+ }
+
+ @Override
+ public boolean isValid(ILaunchConfiguration config) {
+ return getCurrentTestsRunnerProviderInfo() != null;
+ }
+
+ @Override
+ public void setDefaults(ILaunchConfigurationWorkingCopy config) {
+ config.setAttribute(ITestsLaunchConfigurationConstants.ATTR_TESTS_RUNNER, (String) null);
+ config.setAttribute(DebugPlugin.ATTR_PROCESS_FACTORY_ID, TESTING_PROCESS_FACTORY_ID);
+ }
+
+ @Override
+ public void initializeFrom(ILaunchConfiguration configuration) {
+ try {
+ String testsRunnerId = configuration.getAttribute(ITestsLaunchConfigurationConstants.ATTR_TESTS_RUNNER,
+ (String) null);
+ int comboIndex = 0;
+ for (int i = 1; i < testsRunnerProviderCombo.getItemCount(); i++) {
+ if (getTestsRunnerProviderInfo(i).getId().equals(testsRunnerId)) {
+ comboIndex = i;
+ break;
+ }
+ }
+ testsRunnerProviderCombo.select(comboIndex);
+
+ } catch (CoreException e) {
+ TestsRunnerPlugin.log(e);
+ }
+ }
+
+ @Override
+ public void performApply(ILaunchConfigurationWorkingCopy configuration) {
+ ITestsRunnerProviderInfo testsRunnerProvider = getCurrentTestsRunnerProviderInfo();
+ String testsRunnerProviderId = testsRunnerProvider != null ? testsRunnerProvider.getId() : null;
+ configuration.setAttribute(ITestsLaunchConfigurationConstants.ATTR_TESTS_RUNNER, testsRunnerProviderId);
+ configuration.setAttribute(DebugPlugin.ATTR_PROCESS_FACTORY_ID, TESTING_PROCESS_FACTORY_ID);
+ }
+
+ @Override
+ public String getId() {
+ return TAB_ID;
+ }
+
+ @Override
+ public String getName() {
+ return LauncherMessages.CTestingTab_tab_name;
+ }
+
+ @Override
+ public String getErrorMessage() {
+ String m = super.getErrorMessage();
+ if (m == null) {
+ if (getCurrentTestsRunnerProviderInfo() == null) {
+ return LauncherMessages.CTestingTab_no_tests_runner_error;
+ }
+ }
+ return m;
+ }
+
+ @Override
+ public Image getImage() {
+ return TestsRunnerPlugin.createAutoImage("obj16/test_notrun.gif"); //$NON-NLS-1$
+ }
+
+}
diff --git a/unittest/org.eclipse.cdt.unittest/src/org/eclipse/cdt/unittest/internal/launcher/DsfGdbRunTestsLaunchDelegate.java b/unittest/org.eclipse.cdt.unittest/src/org/eclipse/cdt/unittest/internal/launcher/DsfGdbRunTestsLaunchDelegate.java
new file mode 100644
index 00000000000..6d319b34fff
--- /dev/null
+++ b/unittest/org.eclipse.cdt.unittest/src/org/eclipse/cdt/unittest/internal/launcher/DsfGdbRunTestsLaunchDelegate.java
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2020 Anton Gorenkov.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Anton Gorenkov - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.unittest.internal.launcher;
+
+import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants;
+import org.eclipse.cdt.unittest.CDTUnitTestPlugin;
+import org.eclipse.cdt.unittest.launcher.BaseTestsLaunchDelegate;
+
+/**
+ * Launch delegate implementation that redirects its queries to DSF.
+ */
+public class DsfGdbRunTestsLaunchDelegate extends BaseTestsLaunchDelegate {
+
+ @Override
+ public String getPreferredDelegateId() {
+ return ICDTLaunchConfigurationConstants.PREFERRED_DEBUG_LOCAL_LAUNCH_DELEGATE;
+ }
+
+ @Override
+ public String getUnitTestViewSupportID() {
+ return CDTUnitTestPlugin.CDT_TEST_VIEW_SUPPORT_ID;
+ }
+
+}
diff --git a/unittest/org.eclipse.cdt.unittest/src/org/eclipse/cdt/unittest/internal/launcher/EmptyConfigurationTabGroup.java b/unittest/org.eclipse.cdt.unittest/src/org/eclipse/cdt/unittest/internal/launcher/EmptyConfigurationTabGroup.java
new file mode 100644
index 00000000000..80d6c37c65a
--- /dev/null
+++ b/unittest/org.eclipse.cdt.unittest/src/org/eclipse/cdt/unittest/internal/launcher/EmptyConfigurationTabGroup.java
@@ -0,0 +1,31 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2020 Anton Gorenkov
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Anton Gorenkov - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.unittest.internal.launcher;
+
+import org.eclipse.debug.ui.AbstractLaunchConfigurationTabGroup;
+import org.eclipse.debug.ui.ILaunchConfigurationDialog;
+import org.eclipse.debug.ui.ILaunchConfigurationTab;
+
+/**
+ * Represents an empty tab group. Actual tabs are added via the
+ * org.eclipse.debug.ui.launchConfigurationTabs
extension point.
+ */
+public class EmptyConfigurationTabGroup extends AbstractLaunchConfigurationTabGroup {
+
+ @Override
+ public void createTabs(ILaunchConfigurationDialog dialog, String mode) {
+ setTabs(new ILaunchConfigurationTab[0]);
+ }
+
+}
diff --git a/unittest/org.eclipse.cdt.unittest/src/org/eclipse/cdt/unittest/internal/launcher/LauncherMessages.java b/unittest/org.eclipse.cdt.unittest/src/org/eclipse/cdt/unittest/internal/launcher/LauncherMessages.java
new file mode 100644
index 00000000000..3ba3213c767
--- /dev/null
+++ b/unittest/org.eclipse.cdt.unittest/src/org/eclipse/cdt/unittest/internal/launcher/LauncherMessages.java
@@ -0,0 +1,37 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2020 Anton Gorenkov.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Anton Gorenkov - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.unittest.internal.launcher;
+
+import org.eclipse.osgi.util.NLS;
+
+public class LauncherMessages extends NLS {
+ private static final String BUNDLE_NAME = "org.eclipse.cdt.unittest.internal.launcher.LauncherMessages"; //$NON-NLS-1$
+
+ public static String BaseTestsLaunchDelegate_invalid_tests_runner;
+ public static String BaseTestsLaunchDelegate_tests_runner_load_failed;
+
+ public static String CTestingTab_no_tests_runner_error;
+ public static String CTestingTab_no_tests_runner_label;
+ public static String CTestingTab_tab_name;
+ public static String CTestingTab_tests_runner_is_not_set;
+ public static String CTestingTab_tests_runner_label;
+
+ static {
+ // initialize resource bundle
+ NLS.initializeMessages(BUNDLE_NAME, LauncherMessages.class);
+ }
+
+ private LauncherMessages() {
+ }
+}
diff --git a/unittest/org.eclipse.cdt.unittest/src/org/eclipse/cdt/unittest/internal/launcher/LauncherMessages.properties b/unittest/org.eclipse.cdt.unittest/src/org/eclipse/cdt/unittest/internal/launcher/LauncherMessages.properties
new file mode 100644
index 00000000000..ff7808b3f0b
--- /dev/null
+++ b/unittest/org.eclipse.cdt.unittest/src/org/eclipse/cdt/unittest/internal/launcher/LauncherMessages.properties
@@ -0,0 +1,21 @@
+###############################################################################
+# Copyright (c) 2011, 2020 Anton Gorenkov
+#
+# This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License 2.0
+# which accompanies this distribution, and is available at
+# https://www.eclipse.org/legal/epl-2.0/
+#
+# SPDX-License-Identifier: EPL-2.0
+#
+# Contributors:
+# Anton Gorenkov - Initial implementation
+###############################################################################
+BaseTestsLaunchDelegate_invalid_tests_runner=Tests Runner is not specified or invalid
+BaseTestsLaunchDelegate_tests_runner_load_failed=Tests Runner cannot be instantiated
+
+CTestingTab_no_tests_runner_error=Tests runner is not selected
+CTestingTab_no_tests_runner_label=Select a tests runner...
+CTestingTab_tab_name=C/C++ Testing
+CTestingTab_tests_runner_is_not_set=
+CTestingTab_tests_runner_label=Tests Runner
\ No newline at end of file
diff --git a/unittest/org.eclipse.cdt.unittest/src/org/eclipse/cdt/unittest/internal/launcher/RunTestsLaunchDelegate.java b/unittest/org.eclipse.cdt.unittest/src/org/eclipse/cdt/unittest/internal/launcher/RunTestsLaunchDelegate.java
new file mode 100644
index 00000000000..0ef05fcd0e6
--- /dev/null
+++ b/unittest/org.eclipse.cdt.unittest/src/org/eclipse/cdt/unittest/internal/launcher/RunTestsLaunchDelegate.java
@@ -0,0 +1,34 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2020 Anton Gorenkov.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Anton Gorenkov - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.unittest.internal.launcher;
+
+import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants;
+import org.eclipse.cdt.unittest.CDTUnitTestPlugin;
+import org.eclipse.cdt.unittest.launcher.BaseTestsLaunchDelegate;
+
+/**
+ * Launch delegate implementation that is used for Run mode.
+ */
+public class RunTestsLaunchDelegate extends BaseTestsLaunchDelegate {
+
+ @Override
+ public String getPreferredDelegateId() {
+ return ICDTLaunchConfigurationConstants.PREFERRED_RUN_LAUNCH_DELEGATE;
+ }
+
+ @Override
+ public String getUnitTestViewSupportID() {
+ return CDTUnitTestPlugin.CDT_TEST_VIEW_SUPPORT_ID;
+ }
+}
diff --git a/unittest/org.eclipse.cdt.unittest/src/org/eclipse/cdt/unittest/internal/launcher/TestingProcessFactory.java b/unittest/org.eclipse.cdt.unittest/src/org/eclipse/cdt/unittest/internal/launcher/TestingProcessFactory.java
new file mode 100644
index 00000000000..11556e38c57
--- /dev/null
+++ b/unittest/org.eclipse.cdt.unittest/src/org/eclipse/cdt/unittest/internal/launcher/TestingProcessFactory.java
@@ -0,0 +1,51 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2020 Anton Gorenkov, and others
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Anton Gorenkov - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.unittest.internal.launcher;
+
+import java.util.Collections;
+import java.util.Map;
+
+import org.eclipse.cdt.dsf.gdb.IGdbDebugConstants;
+import org.eclipse.cdt.dsf.gdb.launching.GDBProcess;
+import org.eclipse.cdt.dsf.gdb.launching.InferiorRuntimeProcess;
+
+import org.eclipse.debug.core.ILaunch;
+import org.eclipse.debug.core.IProcessFactory;
+import org.eclipse.debug.core.model.IProcess;
+import org.eclipse.debug.core.model.RuntimeProcess;
+
+/**
+ * Custom testing process factory allows to handle the output stream of the
+ * testing process and prevent it from output to Console.
+ */
+public class TestingProcessFactory implements IProcessFactory {
+
+ @Override
+ public IProcess newProcess(ILaunch launch, Process process, String label, Map attributes) {
+ // Mimic the behavior of DSF GDBProcessFactory.
+ if (attributes != null) {
+ Object processTypeCreationAttrValue = attributes.get(IGdbDebugConstants.PROCESS_TYPE_CREATION_ATTR);
+ if (IGdbDebugConstants.GDB_PROCESS_CREATION_VALUE.equals(processTypeCreationAttrValue)) {
+ return new GDBProcess(launch, process, label, attributes);
+ }
+
+ if (IGdbDebugConstants.INFERIOR_PROCESS_CREATION_VALUE.equals(processTypeCreationAttrValue)) {
+ return new InferiorRuntimeProcess(launch, process, label, attributes);
+ }
+ // Probably, it is CDI creating a new inferior process
+ }
+ return new RuntimeProcess(launch, process, label, Collections.emptyMap());
+ }
+
+}
diff --git a/unittest/org.eclipse.cdt.unittest/src/org/eclipse/cdt/unittest/launcher/BaseTestsLaunchDelegate.java b/unittest/org.eclipse.cdt.unittest/src/org/eclipse/cdt/unittest/launcher/BaseTestsLaunchDelegate.java
new file mode 100644
index 00000000000..49a8c8b41ac
--- /dev/null
+++ b/unittest/org.eclipse.cdt.unittest/src/org/eclipse/cdt/unittest/launcher/BaseTestsLaunchDelegate.java
@@ -0,0 +1,273 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2020 Anton Gorenkov.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Anton Gorenkov - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.unittest.launcher;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants;
+import org.eclipse.cdt.testsrunner.internal.TestsRunnerPlugin;
+import org.eclipse.cdt.testsrunner.internal.launcher.ITestsLaunchConfigurationConstants;
+import org.eclipse.cdt.testsrunner.internal.launcher.TestsRunnerProviderInfo;
+import org.eclipse.cdt.testsrunner.internal.ui.view.TestPathUtils;
+import org.eclipse.cdt.testsrunner.launcher.ITestsRunnerProvider;
+import org.eclipse.cdt.testsrunner.model.TestingException;
+import org.eclipse.cdt.unittest.CDTUnitTestPlugin;
+import org.eclipse.cdt.unittest.internal.launcher.LauncherMessages;
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.debug.core.DebugPlugin;
+import org.eclipse.debug.core.ILaunch;
+import org.eclipse.debug.core.ILaunchConfiguration;
+import org.eclipse.debug.core.ILaunchConfigurationType;
+import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
+import org.eclipse.debug.core.ILaunchDelegate;
+import org.eclipse.debug.core.ILaunchManager;
+import org.eclipse.debug.core.model.ILaunchConfigurationDelegate2;
+import org.eclipse.debug.core.model.LaunchConfigurationDelegate;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.ui.IViewPart;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.unittest.ui.ConfigureViewerSupport;
+
+/**
+ * Launch delegate implementation that redirects its queries to the preferred
+ * launch delegate, correcting the arguments attribute (to take into account
+ * auto generated test module parameters) and setting up the custom process
+ * factory (to handle testing process IO streams).
+ */
+public abstract class BaseTestsLaunchDelegate extends LaunchConfigurationDelegate {
+
+ /** Stores the changes made to the launch configuration. */
+ private Map changesToLaunchConfiguration = new HashMap<>();
+
+ @Override
+ public ILaunch getLaunch(ILaunchConfiguration config, String mode) throws CoreException {
+ activateTestResultView();
+ return getPreferredDelegate(config, mode).getLaunch(config, mode);
+ }
+
+ @Override
+ public boolean buildForLaunch(ILaunchConfiguration config, String mode, IProgressMonitor monitor)
+ throws CoreException {
+ return getPreferredDelegate(config, mode).buildForLaunch(config, mode, monitor);
+ }
+
+ @Override
+ public boolean finalLaunchCheck(ILaunchConfiguration config, String mode, IProgressMonitor monitor)
+ throws CoreException {
+ return getPreferredDelegate(config, mode).finalLaunchCheck(config, mode, monitor);
+ }
+
+ @Override
+ public boolean preLaunchCheck(ILaunchConfiguration config, String mode, IProgressMonitor monitor)
+ throws CoreException {
+ return getPreferredDelegate(config, mode).preLaunchCheck(config, mode, monitor);
+ }
+
+ @Override
+ public void launch(ILaunchConfiguration config, String mode, ILaunch launch, IProgressMonitor monitor)
+ throws CoreException {
+
+ if (mode.equals(ILaunchManager.RUN_MODE) || mode.equals(ILaunchManager.DEBUG_MODE)) {
+
+ // NOTE: The modified working copy of launch configuration cannot be passed directly
+ // to the preferred delegate because in this case the LaunchHistory will not work
+ // properly (and the rerun last launched configuration action will fail). So we
+ // just modify the existing configuration and revert all the changes back after
+ // the launch is done.
+
+ try {
+ // Changes launch configuration a bit and redirect it to the preferred C/C++ Application Launch delegate
+ updatedLaunchConfiguration(config);
+ getPreferredDelegate(config, mode).launch(config, mode, launch, monitor);
+ } finally {
+ revertChangedToLaunchConfiguration(config);
+ }
+ // activateTestingView();
+ }
+ }
+
+ /**
+ * Revert the changes to launch configuration previously made with
+ * updatedLaunchConfigurationAttribute()
.
+ *
+ * @param config launch configuration to revert
+ * @throws CoreException in case of error
+ */
+ private void revertChangedToLaunchConfiguration(ILaunchConfiguration config) throws CoreException {
+ ILaunchConfigurationWorkingCopy configWC = config.getWorkingCopy();
+ for (Map.Entry changeEntry : changesToLaunchConfiguration.entrySet()) {
+ configWC.setAttribute(changeEntry.getKey(), changeEntry.getValue());
+ }
+ configWC.doSave();
+ changesToLaunchConfiguration.clear();
+ }
+
+ /**
+ * Saves the current value of the specified attribute (to be reverted later)
+ * and update its value in launch configuration.
+ *
+ * @param config launch configuration which attribute should be updated
+ * @param attributeName attribute name
+ * @param value new value of the specified attribute
+ * @throws CoreException in case of error
+ */
+ private void updatedLaunchConfigurationAttribute(ILaunchConfigurationWorkingCopy config, String attributeName,
+ String value) throws CoreException {
+ changesToLaunchConfiguration.put(attributeName, config.getAttribute(attributeName, "")); //$NON-NLS-1$
+ config.setAttribute(attributeName, value);
+ }
+
+ /**
+ * Makes the necessary changes to the launch configuration before passing it
+ * to the underlying delegate. Currently, updates the program arguments with
+ * the value that was obtained from Tests Runner provider plug-in.
+ *
+ * @param config launch configuration
+ * @throws CoreException in case of error
+ */
+ private void updatedLaunchConfiguration(ILaunchConfiguration config) throws CoreException {
+ changesToLaunchConfiguration.clear();
+ ILaunchConfigurationWorkingCopy configWC = config.getWorkingCopy();
+ new ConfigureViewerSupport(getUnitTestViewSupportID()).apply(configWC);
+ setProgramArguments(configWC);
+ configWC.doSave();
+ }
+
+ /**
+ * Updates the program arguments with the value that was obtained from Tests
+ * Runner provider plug-in.
+ *
+ * @param config launch configuration
+ * @throws CoreException in case of error
+ */
+ private void setProgramArguments(ILaunchConfigurationWorkingCopy config) throws CoreException {
+ List packedTestsFilter = config.getAttribute(ITestsLaunchConfigurationConstants.ATTR_TESTS_FILTER,
+ Collections.emptyList());
+ String[][] testsFilter = TestPathUtils
+ .unpackTestPaths(packedTestsFilter.toArray(new String[packedTestsFilter.size()]));
+
+ // Configure test module run parameters with a Tests Runner
+ String[] params = null;
+ try {
+ params = getTestsRunner(config).getAdditionalLaunchParameters(testsFilter);
+
+ } catch (TestingException e) {
+ throw new CoreException(
+ new Status(IStatus.ERROR, TestsRunnerPlugin.getUniqueIdentifier(), e.getLocalizedMessage(), null));
+ }
+
+ // Rewrite ATTR_PROGRAM_ARGUMENTS attribute of launch configuration
+ if (params != null && params.length >= 1) {
+ StringBuilder sb = new StringBuilder();
+ sb.append(config.getAttribute(ICDTLaunchConfigurationConstants.ATTR_PROGRAM_ARGUMENTS, "")); //$NON-NLS-1$
+ for (String param : params) {
+ sb.append(' ');
+ sb.append(param);
+ }
+ updatedLaunchConfigurationAttribute(config, ICDTLaunchConfigurationConstants.ATTR_PROGRAM_ARGUMENTS,
+ sb.toString());
+ }
+ }
+
+ /**
+ * Resolves Tests Runner provider plug-in interface by the value written in
+ * launch configuration.
+ *
+ * @param config launch configuration
+ * @return an {@link ITestsRunnerProvider} instance
+ * @throws CoreException in case of error
+ */
+ public static ITestsRunnerProvider getTestsRunner(ILaunchConfiguration config) throws CoreException {
+ TestsRunnerProviderInfo testsRunnerProviderInfo = TestsRunnerPlugin.getDefault()
+ .getTestsRunnerProvidersManager().getTestsRunnerProviderInfo(config);
+ if (testsRunnerProviderInfo == null) {
+ throw new CoreException(new Status(IStatus.ERROR, TestsRunnerPlugin.getUniqueIdentifier(),
+ LauncherMessages.BaseTestsLaunchDelegate_invalid_tests_runner, null));
+ }
+ ITestsRunnerProvider testsRunnerProvider = testsRunnerProviderInfo.instantiateTestsRunnerProvider();
+ if (testsRunnerProvider == null) {
+ throw new CoreException(new Status(IStatus.ERROR, TestsRunnerPlugin.getUniqueIdentifier(),
+ LauncherMessages.BaseTestsLaunchDelegate_tests_runner_load_failed, null));
+ }
+ return testsRunnerProvider;
+ }
+
+ /**
+ * Resolves the preferred launch delegate for the specified configuration to
+ * launch C/C++ Local Application in the specified mode. The preferred
+ * launch delegate ID is taken from getPreferredDelegateId()
.
+ *
+ * @param config launch configuration
+ * @param mode mode
+ * @return launch delegate
+ * @throws CoreException in case of error
+ */
+ private ILaunchConfigurationDelegate2 getPreferredDelegate(ILaunchConfiguration config, String mode)
+ throws CoreException {
+ ILaunchManager launchMgr = DebugPlugin.getDefault().getLaunchManager();
+ ILaunchConfigurationType localCfg = launchMgr
+ .getLaunchConfigurationType(ICDTLaunchConfigurationConstants.ID_LAUNCH_C_APP);
+ Set modes = config.getModes();
+ modes.add(mode);
+ String preferredDelegateId = getPreferredDelegateId();
+ for (ILaunchDelegate delegate : localCfg.getDelegates(modes)) {
+ if (preferredDelegateId.equals(delegate.getId())) {
+ return (ILaunchConfigurationDelegate2) delegate.getDelegate();
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Returns the launch delegate id which should be used to redirect the
+ * launch.
+ *
+ * @return launch delegate ID
+ */
+ public abstract String getPreferredDelegateId();
+
+ /**
+ * Returns the default test View Support identifier
+ *
+ * @return default test View Support identifier
+ */
+ public abstract String getUnitTestViewSupportID();
+
+ /**
+ * Activates the view showing testing results.
+ */
+ private void activateTestResultView() {
+ Assert.isNotNull(Platform.getBundle("org.eclipse.unittest.ui")); //$NON-NLS-1$
+ Display.getDefault().syncExec(() -> {
+ try {
+ IWorkbenchWindow activeWindow = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
+ IViewPart view = activeWindow.getActivePage().showView("org.eclipse.unittest.ui.ResultView"); //$NON-NLS-1$
+ PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().activate(view);
+ } catch (PartInitException e) {
+ CDTUnitTestPlugin.log(e);
+ }
+ });
+ }
+}
diff --git a/unittest/org.eclipse.cdt.unittest/src/org/eclipse/cdt/unittest/launcher/CDTMessages.java b/unittest/org.eclipse.cdt.unittest/src/org/eclipse/cdt/unittest/launcher/CDTMessages.java
new file mode 100644
index 00000000000..b6b82112abd
--- /dev/null
+++ b/unittest/org.eclipse.cdt.unittest/src/org/eclipse/cdt/unittest/launcher/CDTMessages.java
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ * Copyright (c) 2020 Red Hat Inc. and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Red Hat Inc. - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.cdt.unittest.launcher;
+
+import org.eclipse.osgi.util.NLS;
+
+public class CDTMessages extends NLS {
+ private static final String BUNDLE_NAME = "org.eclipse.cdt.unittest.launcher.CDTMessages"; //$NON-NLS-1$
+ public static String TestingSession_finished_status;
+ public static String TestingSession_name_format;
+ public static String TestingSession_starting_status;
+ public static String TestingSession_stopped_status;
+ static {
+ // initialize resource bundle
+ NLS.initializeMessages(BUNDLE_NAME, CDTMessages.class);
+ }
+
+ private CDTMessages() {
+ }
+}
diff --git a/unittest/org.eclipse.cdt.unittest/src/org/eclipse/cdt/unittest/launcher/CDTMessages.properties b/unittest/org.eclipse.cdt.unittest/src/org/eclipse/cdt/unittest/launcher/CDTMessages.properties
new file mode 100644
index 00000000000..dd9bee2bc6b
--- /dev/null
+++ b/unittest/org.eclipse.cdt.unittest/src/org/eclipse/cdt/unittest/launcher/CDTMessages.properties
@@ -0,0 +1,19 @@
+###############################################################################
+ # Copyright (c) 2020 Red Hat Inc. and others.
+ #
+ # This program and the accompanying materials
+ # are made available under the terms of the Eclipse Public License 2.0
+ # which accompanies this distribution, and is available at
+ # https://www.eclipse.org/legal/epl-2.0/
+ #
+ # SPDX-License-Identifier: EPL-2.0
+ #
+ # Contributors:
+ # Red Hat Inc. - initial API and implementation
+ ###############################################################################
+
+# From CDT Model
+TestingSession_name_format={0} ({1})
+TestingSession_finished_status=Finished after {0}
+TestingSession_starting_status=Starting...
+TestingSession_stopped_status=Testing was stopped by user
diff --git a/unittest/org.eclipse.cdt.unittest/src/org/eclipse/cdt/unittest/launcher/CDTTestRunnerClient.java b/unittest/org.eclipse.cdt.unittest/src/org/eclipse/cdt/unittest/launcher/CDTTestRunnerClient.java
new file mode 100644
index 00000000000..6005ca06989
--- /dev/null
+++ b/unittest/org.eclipse.cdt.unittest/src/org/eclipse/cdt/unittest/launcher/CDTTestRunnerClient.java
@@ -0,0 +1,408 @@
+/*******************************************************************************
+ * Copyright (c) 2020 Red Hat Inc. and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Red Hat Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.unittest.launcher;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Deque;
+import java.util.LinkedList;
+import java.util.List;
+
+import org.eclipse.cdt.dsf.gdb.launching.InferiorRuntimeProcess;
+import org.eclipse.cdt.testsrunner.internal.launcher.TestsRunnerProvidersManager;
+import org.eclipse.cdt.testsrunner.internal.model.TestCase;
+import org.eclipse.cdt.testsrunner.internal.model.TestSuite;
+import org.eclipse.cdt.testsrunner.launcher.ITestsRunnerProvider;
+import org.eclipse.cdt.testsrunner.model.ITestCase;
+import org.eclipse.cdt.testsrunner.model.ITestItem;
+import org.eclipse.cdt.testsrunner.model.ITestItem.Status;
+import org.eclipse.cdt.testsrunner.model.ITestMessage.Level;
+import org.eclipse.cdt.testsrunner.model.ITestModelUpdater;
+import org.eclipse.cdt.testsrunner.model.ITestSuite;
+import org.eclipse.cdt.testsrunner.model.TestingException;
+import org.eclipse.cdt.unittest.CDTUnitTestPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.ICoreRunnable;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.debug.core.DebugPlugin;
+import org.eclipse.debug.core.ILaunch;
+import org.eclipse.debug.core.ILaunchListener;
+import org.eclipse.debug.core.model.IProcess;
+import org.eclipse.debug.core.model.IStreamMonitor;
+import org.eclipse.unittest.launcher.ITestRunnerClient;
+import org.eclipse.unittest.model.ITestCaseElement;
+import org.eclipse.unittest.model.ITestElement;
+import org.eclipse.unittest.model.ITestElement.FailureTrace;
+import org.eclipse.unittest.model.ITestRunSession;
+import org.eclipse.unittest.model.ITestSuiteElement;
+
+public class CDTTestRunnerClient implements ITestRunnerClient {
+ static private final String NL = System.lineSeparator();
+
+ class TestModelUpdaterAdapter implements ITestModelUpdater {
+ class TestElementReference {
+ String parentId;
+ String id;
+ String name;
+ boolean isSuite;
+ private long startTime;
+ private long testingTime;
+
+ public TestElementReference(String parentId, String id, String name, boolean isSuite) {
+ this.parentId = parentId;
+ this.id = id;
+ this.name = name;
+ this.isSuite = isSuite;
+ this.startTime = System.currentTimeMillis();
+ }
+
+ @Override
+ public String toString() {
+ return new StringBuilder().append("TestElementReference: ") //$NON-NLS-1$
+ .append("parentId = ").append(parentId).append(NL) //$NON-NLS-1$
+ .append("id = ").append(id).append(NL) //$NON-NLS-1$
+ .append("name = ").append(name).append(NL) //$NON-NLS-1$
+ .append("isSuite = ").append(isSuite).append(NL) //$NON-NLS-1$
+ .append("startTime = ").append(startTime).append(NL) //$NON-NLS-1$
+ .append("testingTime = ").append(testingTime).append(NL) //$NON-NLS-1$
+ .toString();
+ }
+ }
+
+ Deque testElementRefs = new LinkedList<>();
+
+ String fCurrentTestCase;
+ String fCurrentTestSuite;
+ int fTestId = 0;
+ /**
+ * The failed trace that is currently reported from the RemoteTestRunner
+ */
+ final StringBuilder fFailedTrace = new StringBuilder();
+
+ @Override
+ public void enterTestSuite(String name) {
+ if (fDebug) {
+ System.out.println("TestModelUpdaterAdapter.enterTestSuite: name = " + name); //$NON-NLS-1$
+ }
+ TestElementReference pRef = testElementRefs.isEmpty() ? null : testElementRefs.peek();
+
+ TestElementReference cRef = new TestElementReference(pRef == null ? String.valueOf("-1") : pRef.id, //$NON-NLS-1$
+ String.valueOf(fTestId++), name, true);
+ testElementRefs.push(cRef);
+
+ this.fCurrentTestSuite = cRef.id;
+
+ fTestRunSession.newTestSuite(cRef.id, cRef.name, null, getTestSuite(cRef.parentId), cRef.name, null);
+ }
+
+ @Override
+ public void exitTestSuite() {
+ if (fDebug) {
+ System.out.println("TestModelUpdaterAdapter.exitTestSuite"); //$NON-NLS-1$
+ }
+ TestElementReference cRef = testElementRefs.pop();
+ while (cRef != null && !cRef.isSuite) {
+ logUnexpectedTest(cRef.id, cRef);
+ cRef = testElementRefs.pop();
+ }
+ }
+
+ @Override
+ public void enterTestCase(String name) {
+ if (fDebug) {
+ System.out.println("TestModelUpdaterAdapter.enterTestCase: name = " + name); //$NON-NLS-1$
+ }
+
+ TestElementReference pRef = testElementRefs.isEmpty() ? null : testElementRefs.peek();
+
+ String parentId = String.valueOf("-1"); //$NON-NLS-1$
+ if (pRef != null) {
+ parentId = pRef.isSuite ? pRef.id : pRef.parentId;
+ }
+
+ TestElementReference cRef = new TestElementReference(parentId, String.valueOf(fTestId++), name, false);
+ testElementRefs.push(cRef);
+
+ this.fCurrentTestCase = cRef.id;
+ fFailedTrace.setLength(0);
+
+ ITestElement test = fTestRunSession.newTestCase(cRef.id, cRef.name, getTestSuite(cRef.parentId), cRef.name,
+ null);
+ fTestRunSession.notifyTestStarted(test);
+ }
+
+ private ITestSuiteElement getTestSuite(String parentId) {
+ ITestElement parent = fTestRunSession.getTestElement(parentId);
+ if (parent instanceof ITestSuiteElement) {
+ return (ITestSuiteElement) parent;
+ }
+ return null;
+ }
+
+ @Override
+ public void setTestStatus(Status status) {
+ if (fDebug) {
+ System.out.println("TestModelUpdaterAdapter.setTestStatus: status = " + status.toString()); //$NON-NLS-1$
+ }
+
+ if (status.isError()) {
+ TestElementReference cRef = testElementRefs.isEmpty() ? null : testElementRefs.peek();
+ if (cRef != null) {
+ ITestElement test = fTestRunSession.getTestElement(cRef.id);
+ if (test != null) {
+ fTestRunSession.notifyTestFailed(test,
+ status == Status.Aborted ? ITestElement.Result.ERROR : ITestElement.Result.FAILURE,
+ false, new FailureTrace(fFailedTrace.toString(), "", "")); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ } else {
+ logUnexpectedTest(fCurrentTestCase, null);
+ }
+ }
+ }
+
+ @Override
+ public void setTestingTime(int testingTime) {
+ if (fDebug) {
+ System.out.println("TestModelUpdaterAdapter.setTestingTime: testingTime = " + testingTime); //$NON-NLS-1$
+ }
+
+ TestElementReference cRef = testElementRefs.isEmpty() ? null : testElementRefs.peek();
+ if (cRef != null) {
+ cRef.testingTime = testingTime;
+ } else {
+ logUnexpectedTest(fCurrentTestCase, null);
+ }
+ }
+
+ @Override
+ public void exitTestCase() {
+ if (fDebug) {
+ System.out.println("TestModelUpdaterAdapter.exitTestCase"); //$NON-NLS-1$
+ }
+
+ TestElementReference cRef = testElementRefs.isEmpty() ? null : testElementRefs.peek();
+
+ if (cRef != null && !cRef.isSuite) {
+ testElementRefs.pop(); // Renove test case ref
+ ITestElement testElement = fTestRunSession.getTestElement(cRef.id);
+ fTestRunSession.notifyTestEnded(testElement, false);
+ } else {
+ logUnexpectedTest(cRef == null ? "null" : cRef.id, cRef); //$NON-NLS-1$
+ }
+
+ }
+
+ @Override
+ public void addTestMessage(String file, int line, Level level, String text) {
+ if (fDebug) {
+ System.out.println("TestModelUpdaterAdapter.addTestMessage: file = " + file + //$NON-NLS-1$
+ ", line = " + line + //$NON-NLS-1$
+ ", level = " + level.toString() + //$NON-NLS-1$
+ ", text = " + text); //$NON-NLS-1$
+ }
+
+ fFailedTrace.append(level.toString()).append(": ").append(text).append("\r\n") //$NON-NLS-1$ //$NON-NLS-2$
+ .append(CDTTestViewSupport.FRAME_PREFIX).append(file).append(':').append(line).append("\r\n"); //$NON-NLS-1$
+ }
+
+ @Override
+ public ITestSuite currentTestSuite() {
+ if (fDebug) {
+ System.out.println("TestModelUpdaterAdapter.currentTestSuite"); //$NON-NLS-1$
+ }
+
+ ITestElement testElement = fTestRunSession.getTestElement(fCurrentTestSuite);
+ if (testElement instanceof ITestSuiteElement) {
+ return convertFromTestSuiteElement((ITestSuiteElement) testElement);
+ } else {
+ return convertFromTestSuiteElement(testElement.getParent());
+ }
+ }
+
+ @Override
+ public ITestCase currentTestCase() {
+ if (fDebug) {
+ System.out.println("TestModelUpdaterAdapter.currentTestCase"); //$NON-NLS-1$
+ }
+
+ ITestElement testElement = fTestRunSession.getTestElement(fCurrentTestCase);
+ if (testElement instanceof ITestCaseElement) {
+ return convertFromTestCaseElement((ITestCaseElement) testElement);
+ }
+ return null;
+ }
+
+ private void logUnexpectedTest(String testId, TestElementReference testElement) {
+ CDTUnitTestPlugin
+ .log(new Exception("Unexpected TestElement type for testId '" + testId + "': " + testElement)); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ }
+
+ private final ITestRunSession fTestRunSession;
+ private ITestsRunnerProvider fTestsRunnerProvider;
+ private IProcess process;
+ private ILaunchListener fFindProcessListener;
+ protected boolean fDebug = false;
+ private InputStream fStream;
+
+ public CDTTestRunnerClient(ITestRunSession session) {
+ this.fTestRunSession = session;
+ }
+
+ @Override
+ public void startMonitoring() {
+ ILaunch launch = this.fTestRunSession.getLaunch();
+ fFindProcessListener = new ILaunchListener() {
+ @Override
+ public void launchRemoved(@SuppressWarnings("hiding") ILaunch launch) {
+ // Nothing to do
+ }
+
+ @Override
+ public void launchChanged(ILaunch aLaunch) {
+ if (aLaunch.equals(launch) && process == null) {
+ process = connectProcess(launch);
+ }
+ }
+
+ @Override
+ public void launchAdded(@SuppressWarnings("hiding") ILaunch launch) {
+ // Nothing to do
+ }
+ };
+ DebugPlugin.getDefault().getLaunchManager().addLaunchListener(fFindProcessListener);
+ try {
+ fTestsRunnerProvider = new TestsRunnerProvidersManager()
+ .getTestsRunnerProviderInfo(launch.getLaunchConfiguration()).instantiateTestsRunnerProvider();
+ process = connectProcess(launch);
+ } catch (CoreException e) {
+ CDTUnitTestPlugin.log(e);
+ }
+ }
+
+ private IProcess connectProcess(ILaunch launch) {
+ if (this.process != null) {
+ return this.process;
+ }
+ this.process = Arrays.stream(launch.getProcesses()).filter(InferiorRuntimeProcess.class::isInstance).findAny()
+ .orElse(null);
+ if (this.process != null) {
+ DebugPlugin.getDefault().getLaunchManager().removeLaunchListener(fFindProcessListener);
+ fStream = toInputStream(process);
+ Job.createSystem("Monitor test process", (ICoreRunnable) monitor -> run(fStream)).schedule(); //$NON-NLS-1$
+ }
+ return this.process;
+ }
+
+ private static InputStream toInputStream(IProcess process) {
+ IStreamMonitor monitor = process.getStreamsProxy().getOutputStreamMonitor();
+ if (monitor == null) {
+ return null;
+ }
+ List content = Collections.synchronizedList(new LinkedList<>());
+ monitor.addListener((text, progresMonitor) -> text.chars().forEach(content::add));
+ byte[] initialContent = monitor.getContents().getBytes();
+ for (int i = initialContent.length - 1; i >= 0; i--) {
+ content.add(0, Integer.valueOf(initialContent[i]));
+ }
+ return new InputStream() {
+ @Override
+ public int read() throws IOException {
+ while (!process.isTerminated() || !content.isEmpty()) {
+ if (!content.isEmpty()) {
+ return content.remove(0).intValue();
+ }
+ try {
+ Thread.sleep(20, 0);
+ } catch (InterruptedException e) {
+ return -1;
+ }
+ }
+ return -1;
+ }
+
+ @Override
+ public int read(byte[] b, int off, int len) throws IOException {
+ if (process.isTerminated() && available() == 0) {
+ return -1;
+ }
+ if (len == 0) {
+ return 0;
+ }
+ int i = 0;
+ do {
+ b[off + i] = (byte) read();
+ i++;
+ } while (available() > 0 && i < len && off + i < b.length);
+ return i;
+ }
+
+ @Override
+ public int available() throws IOException {
+ return content.size();
+ }
+ };
+ }
+
+ public void run(InputStream iStream) {
+ if (iStream == null) {
+ return;
+ }
+ fTestRunSession.notifyTestSessionStarted(null);
+ try {
+ fTestsRunnerProvider.run(new TestModelUpdaterAdapter(), iStream);
+ fTestRunSession.notifyTestSessionCompleted(fTestRunSession.getDuration());
+ } catch (TestingException e) {
+ fTestRunSession.notifyTestSessionAborted(null, e);
+ }
+ }
+
+ @Override
+ public void stopTest() {
+ stopMonitoring();
+ }
+
+ ITestItem convertFromTestElement(final ITestElement element) {
+ if (element instanceof ITestSuiteElement) {
+ return convertFromTestSuiteElement(((ITestSuiteElement) element));
+ }
+ if (element instanceof ITestCaseElement) {
+ return convertFromTestCaseElement((ITestCaseElement) element);
+ }
+ return null;
+ }
+
+ ITestCase convertFromTestCaseElement(final ITestCaseElement element) {
+ if (element == null) {
+ return null;
+ }
+ return new TestCase(element.getTestName(), (TestSuite) convertFromTestSuiteElement(element.getParent()));
+ }
+
+ ITestSuite convertFromTestSuiteElement(ITestSuiteElement testSuiteElement) {
+ if (testSuiteElement == null) {
+ return null;
+ }
+ return new TestSuite(testSuiteElement.getTestName(),
+ (TestSuite) convertFromTestSuiteElement(testSuiteElement.getParent()));
+ }
+
+ @Override
+ public void stopMonitoring() {
+ DebugPlugin.getDefault().getLaunchManager().removeLaunchListener(fFindProcessListener);
+ }
+
+}
diff --git a/unittest/org.eclipse.cdt.unittest/src/org/eclipse/cdt/unittest/launcher/CDTTestViewSupport.java b/unittest/org.eclipse.cdt.unittest/src/org/eclipse/cdt/unittest/launcher/CDTTestViewSupport.java
new file mode 100644
index 00000000000..f511720bf06
--- /dev/null
+++ b/unittest/org.eclipse.cdt.unittest/src/org/eclipse/cdt/unittest/launcher/CDTTestViewSupport.java
@@ -0,0 +1,148 @@
+/*******************************************************************************
+ * Copyright (c) 2020 Red Hat Inc. and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Red Hat Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.unittest.launcher;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import org.eclipse.cdt.testsrunner.internal.launcher.ITestsLaunchConfigurationConstants;
+import org.eclipse.cdt.unittest.CDTUnitTestPlugin;
+import org.eclipse.cdt.unittest.ui.OpenEditorAtLineAction;
+import org.eclipse.cdt.unittest.ui.OpenTestAction;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.text.StringMatcher;
+import org.eclipse.debug.core.ILaunchConfiguration;
+import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.unittest.launcher.ITestRunnerClient;
+import org.eclipse.unittest.model.ITestCaseElement;
+import org.eclipse.unittest.model.ITestElement;
+import org.eclipse.unittest.model.ITestRunSession;
+import org.eclipse.unittest.model.ITestSuiteElement;
+import org.eclipse.unittest.ui.ITestViewSupport;
+
+public class CDTTestViewSupport implements ITestViewSupport {
+ /**
+ * The delimiter between parts of serialized test path. Should not be met in
+ * test paths names.
+ */
+ private static final String TEST_PATH_PART_DELIMITER = "\n"; //$NON-NLS-1$
+ public static final String FRAME_PREFIX = " at "; //$NON-NLS-1$
+
+ @Override
+ public Collection getTraceExclusionFilterPatterns() {
+ return Collections.emptySet();
+ }
+
+ @Override
+ public IAction getOpenTestAction(Shell shell, ITestCaseElement testCase) {
+ return new OpenTestAction(shell, testCase.getParent(), testCase);
+ }
+
+ @Override
+ public IAction getOpenTestAction(Shell shell, ITestSuiteElement testSuite) {
+ return new OpenTestAction(shell, testSuite);
+ }
+
+ @Override
+ public IAction createOpenEditorAction(Shell shell, ITestElement failure, String traceLine) {
+ try {
+ String testName = traceLine;
+ int indexOfFramePrefix = testName.indexOf(FRAME_PREFIX);
+ if (indexOfFramePrefix == -1) {
+ return null;
+ }
+ testName = testName.substring(indexOfFramePrefix);
+ testName = testName.substring(FRAME_PREFIX.length(), testName.lastIndexOf(':')).trim();
+
+ String lineNumber = traceLine;
+ lineNumber = lineNumber.substring(lineNumber.indexOf(':') + 1);
+ int line = Integer.parseInt(lineNumber);
+ return new OpenEditorAtLineAction(shell, testName, failure.getTestRunSession(), line);
+ } catch (NumberFormatException | IndexOutOfBoundsException e) {
+ CDTUnitTestPlugin.log(e);
+ }
+ return null;
+ }
+
+ @Override
+ public Runnable createShowStackTraceInConsoleViewActionDelegate(ITestElement failedTest) {
+ return null;
+ }
+
+ @Override
+ public ILaunchConfiguration getRerunLaunchConfiguration(List tests) {
+ if (tests.isEmpty()) {
+ return null;
+ }
+ ILaunchConfiguration origin = tests.get(0).getTestRunSession().getLaunch().getLaunchConfiguration();
+ ILaunchConfigurationWorkingCopy res;
+ try {
+ res = origin.copy(origin.getName() + "\uD83D\uDD03"); //$NON-NLS-1$
+ res.setAttribute(ITestsLaunchConfigurationConstants.ATTR_TESTS_FILTER,
+ tests.stream().map(CDTTestViewSupport::packTestPaths).collect(Collectors.toList()));
+ return res;
+ } catch (CoreException e) {
+ CDTUnitTestPlugin.log(e);
+ return null;
+ }
+ }
+
+ /**
+ * Pack the paths to specified test items to string list.
+ * @param testElement test element to pack
+ *
+ * @return string list
+ */
+ private static String packTestPaths(ITestElement testElement) {
+ List testPath = new ArrayList<>();
+
+ // Collect test path parts (in reverse order)
+ testPath.clear();
+ ITestElement element = testElement;
+ while (element != null && !(element instanceof ITestRunSession)) {
+ // Exclude root test suite
+ if (element.getParent() != null) {
+ testPath.add(element.getTestName());
+ }
+ element = element.getParent();
+ }
+ // Join path parts into the only string
+ StringBuilder sb = new StringBuilder();
+ boolean needDelimiter = false;
+ for (int pathPartIdx = testPath.size() - 1; pathPartIdx >= 0; pathPartIdx--) {
+ if (needDelimiter) {
+ sb.append(TEST_PATH_PART_DELIMITER);
+ } else {
+ needDelimiter = true;
+ }
+ sb.append(testPath.get(pathPartIdx));
+ }
+ return sb.toString();
+ }
+
+ @Override
+ public String getDisplayName() {
+ return "C/C++ Unit Tests"; //$NON-NLS-1$
+ }
+
+ @Override
+ public ITestRunnerClient newTestRunnerClient(ITestRunSession session) {
+ return new CDTTestRunnerClient(session);
+ }
+}
diff --git a/unittest/org.eclipse.cdt.unittest/src/org/eclipse/cdt/unittest/ui/ActionsMessages.java b/unittest/org.eclipse.cdt.unittest/src/org/eclipse/cdt/unittest/ui/ActionsMessages.java
new file mode 100644
index 00000000000..21e773c7344
--- /dev/null
+++ b/unittest/org.eclipse.cdt.unittest/src/org/eclipse/cdt/unittest/ui/ActionsMessages.java
@@ -0,0 +1,37 @@
+/*******************************************************************************
+ * Copyright (c) 2020 Red Hat Inc. and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Red Hat Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.unittest.ui;
+
+import org.eclipse.osgi.util.NLS;
+
+public class ActionsMessages extends NLS {
+ private static final String BUNDLE_NAME = "org.eclipse.cdt.unittest.ui.ActionsMessages"; //$NON-NLS-1$
+
+ public static String OpenInEditorAction_text;
+ public static String OpenInEditorAction_tooltip;
+ public static String OpenEditorAction_action_label;
+ public static String OpenEditorAction_error_cannotopen_title;
+ public static String OpenEditorAction_error_cannotopen_message;
+ public static String OpenEditorAction_errorOpenEditor;
+ public static String OpenEditorAction_UpdateElementsJob_name;
+ public static String OpenEditorAction_UpdateElementsJob_inProgress;
+
+ static {
+ // initialize resource bundle
+ NLS.initializeMessages(BUNDLE_NAME, ActionsMessages.class);
+ }
+
+ private ActionsMessages() {
+ }
+}
diff --git a/unittest/org.eclipse.cdt.unittest/src/org/eclipse/cdt/unittest/ui/ActionsMessages.properties b/unittest/org.eclipse.cdt.unittest/src/org/eclipse/cdt/unittest/ui/ActionsMessages.properties
new file mode 100644
index 00000000000..9e68aa1b0a2
--- /dev/null
+++ b/unittest/org.eclipse.cdt.unittest/src/org/eclipse/cdt/unittest/ui/ActionsMessages.properties
@@ -0,0 +1,23 @@
+###############################################################################
+ # Copyright (c) 2020 Red Hat Inc. and others.
+ #
+ # This program and the accompanying materials
+ # are made available under the terms of the Eclipse Public License 2.0
+ # which accompanies this distribution, and is available at
+ # https://www.eclipse.org/legal/epl-2.0/
+ #
+ # SPDX-License-Identifier: EPL-2.0
+ #
+ # Contributors:
+ # Red Hat Inc. - initial API and implementation
+ ###############################################################################
+
+OpenInEditorAction_text=&Go to File
+OpenInEditorAction_tooltip=Show File Referred By the Message
+
+OpenEditorAction_action_label=&Go to File
+OpenEditorAction_error_cannotopen_title=Cannot Open Editor
+OpenEditorAction_error_cannotopen_message=Test class not found in selected project
+OpenEditorAction_errorOpenEditor=Error opening editor for file \"{0}\"
+OpenEditorAction_UpdateElementsJob_name=Updating element list
+OpenEditorAction_UpdateElementsJob_inProgress=Updating element list...
diff --git a/unittest/org.eclipse.cdt.unittest/src/org/eclipse/cdt/unittest/ui/OpenEditorAtLineAction.java b/unittest/org.eclipse.cdt.unittest/src/org/eclipse/cdt/unittest/ui/OpenEditorAtLineAction.java
new file mode 100644
index 00000000000..035895a0150
--- /dev/null
+++ b/unittest/org.eclipse.cdt.unittest/src/org/eclipse/cdt/unittest/ui/OpenEditorAtLineAction.java
@@ -0,0 +1,186 @@
+/*******************************************************************************
+ * Copyright (c) 2020 Red Hat Inc. and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Red Hat Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.unittest.ui;
+
+import java.net.URI;
+
+import org.eclipse.cdt.debug.core.CDebugCorePlugin;
+import org.eclipse.cdt.debug.ui.CDebugUIPlugin;
+import org.eclipse.cdt.unittest.CDTUnitTestPlugin;
+import org.eclipse.unittest.model.ITestRunSession;
+
+import org.eclipse.swt.widgets.Shell;
+
+import org.eclipse.core.filesystem.URIUtil;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.resources.ResourcesPlugin;
+
+import org.eclipse.jface.action.Action;
+
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.ide.IDE;
+
+import org.eclipse.ui.texteditor.IDocumentProvider;
+import org.eclipse.ui.texteditor.ITextEditor;
+
+import org.eclipse.debug.core.DebugPlugin;
+import org.eclipse.debug.core.ILaunch;
+import org.eclipse.debug.core.ILaunchConfiguration;
+import org.eclipse.debug.core.model.IPersistableSourceLocator;
+import org.eclipse.debug.core.model.ISourceLocator;
+import org.eclipse.debug.core.sourcelookup.AbstractSourceLookupDirector;
+import org.eclipse.debug.core.sourcelookup.ISourceLookupParticipant;
+import org.eclipse.debug.core.sourcelookup.containers.LocalFileStorage;
+
+import org.eclipse.debug.ui.DebugUITools;
+import org.eclipse.debug.ui.IDebugModelPresentation;
+import org.eclipse.debug.ui.sourcelookup.ISourceLookupResult;
+
+/**
+ * Opens the editor in place where the currently selected message is pointed to.
+ */
+public class OpenEditorAtLineAction extends Action {
+ @SuppressWarnings("unused")
+ private Shell shell;
+ private String fileName;
+ private int line;
+ private ITestRunSession fTestRunSession;
+
+ public OpenEditorAtLineAction(Shell shell, String fileName, ITestRunSession testRunSession, int line) {
+ super(ActionsMessages.OpenInEditorAction_text);
+ this.shell = shell;
+ this.fileName = fileName;
+ this.fTestRunSession = testRunSession;
+ this.line = line;
+ setToolTipText(ActionsMessages.OpenInEditorAction_tooltip);
+ }
+
+ @Override
+ public void run() {
+ ILaunch launch = fTestRunSession != null ? fTestRunSession.getLaunch() : null;
+ if (launch == null)
+ return;
+ lookupSource(fileName, line, launch);
+ }
+
+ // NOTE: This method is copied from Linux Tools Project (http://www.eclipse.org/linuxtools).
+ // Valgrind Support Plugin is implementing similar functionality so it is just reused.
+ // See also org.eclipse.linuxtools.valgrind.ui/src/org/eclipse/linuxtools/internal/valgrind/ui/CoreMessagesViewer.java
+ private void lookupSource(String file, int lineNumber, ILaunch launch) {
+ ISourceLocator locator = launch.getSourceLocator();
+ if (locator instanceof AbstractSourceLookupDirector) {
+ AbstractSourceLookupDirector director = (AbstractSourceLookupDirector) locator;
+ ISourceLookupParticipant[] participants = director.getParticipants();
+ if (participants.length == 0) {
+ // source locator likely disposed, try recreating it
+ IPersistableSourceLocator sourceLocator;
+ ILaunchConfiguration config = launch.getLaunchConfiguration();
+ if (config != null) {
+ try {
+ String id = config.getAttribute(ILaunchConfiguration.ATTR_SOURCE_LOCATOR_ID, (String) null);
+ if (id == null) {
+ sourceLocator = CDebugUIPlugin.createDefaultSourceLocator();
+ sourceLocator.initializeDefaults(config);
+ } else {
+ sourceLocator = DebugPlugin.getDefault().getLaunchManager().newSourceLocator(id);
+ String memento = config.getAttribute(ILaunchConfiguration.ATTR_SOURCE_LOCATOR_MEMENTO,
+ (String) null);
+ if (memento == null) {
+ sourceLocator.initializeDefaults(config);
+ } else {
+ sourceLocator.initializeFromMemento(memento);
+ }
+ }
+
+ // replace old source locator
+ locator = sourceLocator;
+ launch.setSourceLocator(sourceLocator);
+ } catch (CoreException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+ ISourceLookupResult result = DebugUITools.lookupSource(file, locator);
+ try {
+ openEditorAndSelect(result, lineNumber);
+ } catch (PartInitException | BadLocationException e) {
+ CDTUnitTestPlugin.log(e);
+ }
+ }
+
+ // NOTE: This method is copied from Linux Tools Project (http://www.eclipse.org/linuxtools).
+ // Valgrind Support Plugin is implementing similar functionality so it is just reused.
+ // See also org.eclipse.linuxtools.valgrind.ui/src/org/eclipse/linuxtools/internal/valgrind/ui/CoreMessagesViewer.java
+ private void openEditorAndSelect(ISourceLookupResult result, int lineNumber)
+ throws PartInitException, BadLocationException {
+ IEditorInput input = result.getEditorInput();
+ String editorID = result.getEditorId();
+
+ if (input == null || editorID == null) {
+ // Consult the CDT DebugModelPresentation
+ Object sourceElement = result.getSourceElement();
+ if (sourceElement != null) {
+ // Resolve IResource in case we get a LocalFileStorage object
+ if (sourceElement instanceof LocalFileStorage) {
+ IPath filePath = ((LocalFileStorage) sourceElement).getFullPath();
+ URI fileURI = URIUtil.toURI(filePath);
+ IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
+ IFile[] files = root.findFilesForLocationURI(fileURI);
+ if (files.length > 0) {
+ // Take the first match
+ sourceElement = files[0];
+ }
+ }
+
+ IDebugModelPresentation pres = DebugUITools
+ .newDebugModelPresentation(CDebugCorePlugin.getUniqueIdentifier());
+ input = pres.getEditorInput(sourceElement);
+ editorID = pres.getEditorId(input, sourceElement);
+ pres.dispose();
+ }
+ }
+ if (input != null && editorID != null) {
+ // Open the editor
+ IWorkbenchPage activePage = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
+
+ IEditorPart editor = IDE.openEditor(activePage, input, editorID);
+ // Select the line
+ if (editor instanceof ITextEditor) {
+ ITextEditor textEditor = (ITextEditor) editor;
+
+ if (lineNumber > 0) {
+ IDocumentProvider provider = textEditor.getDocumentProvider();
+ IDocument document = provider.getDocument(textEditor.getEditorInput());
+
+ IRegion lineRegion = document.getLineInformation(lineNumber - 1); //zero-indexed
+ textEditor.selectAndReveal(lineRegion.getOffset(), lineRegion.getLength());
+ }
+ }
+ }
+ }
+}
diff --git a/unittest/org.eclipse.cdt.unittest/src/org/eclipse/cdt/unittest/ui/OpenTestAction.java b/unittest/org.eclipse.cdt.unittest/src/org/eclipse/cdt/unittest/ui/OpenTestAction.java
new file mode 100644
index 00000000000..8af6936f465
--- /dev/null
+++ b/unittest/org.eclipse.cdt.unittest/src/org/eclipse/cdt/unittest/ui/OpenTestAction.java
@@ -0,0 +1,330 @@
+/*******************************************************************************
+ * Copyright (c) 2020 Red Hat Inc. and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Red Hat Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.unittest.ui;
+
+import java.util.HashSet;
+
+import org.eclipse.cdt.core.CCorePlugin;
+import org.eclipse.cdt.core.browser.ITypeInfo;
+import org.eclipse.cdt.core.browser.ITypeReference;
+import org.eclipse.cdt.core.browser.IndexTypeInfo;
+import org.eclipse.cdt.core.browser.QualifiedTypeName;
+import org.eclipse.cdt.core.dom.ast.IBinding;
+import org.eclipse.cdt.core.index.IIndex;
+import org.eclipse.cdt.core.index.IIndexBinding;
+import org.eclipse.cdt.core.index.IIndexMacro;
+import org.eclipse.cdt.core.index.IIndexManager;
+import org.eclipse.cdt.core.index.IndexFilter;
+import org.eclipse.cdt.core.model.CModelException;
+import org.eclipse.cdt.core.model.CoreModel;
+import org.eclipse.cdt.core.model.ICElement;
+import org.eclipse.cdt.core.model.ITranslationUnit;
+import org.eclipse.cdt.internal.core.browser.IndexModelUtil;
+import org.eclipse.cdt.internal.ui.search.CSearchUtil;
+import org.eclipse.cdt.internal.ui.util.EditorUtility;
+import org.eclipse.cdt.unittest.CDTUnitTestPlugin;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.unittest.model.ITestCaseElement;
+import org.eclipse.unittest.model.ITestElement;
+import org.eclipse.unittest.model.ITestSuiteElement;
+
+import org.eclipse.swt.widgets.Shell;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.jobs.Job;
+
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.dialogs.MessageDialog;
+
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.PartInitException;
+
+import org.eclipse.ui.texteditor.ITextEditor;
+
+public class OpenTestAction extends Action {
+ protected String fClassName;
+ protected String fMethodName;
+ protected Shell shell;
+ private String fSearchPrefix;
+
+ /**
+ * Job to update the element list in the background.
+ */
+ private class UpdateElementsJob extends Job {
+ /**
+ * The last used prefix to query the index. null
means
+ * the query result should be empty.
+ */
+ private volatile char[] fCurrentPrefix;
+ private Object[] result;
+
+ public UpdateElementsJob(String name) {
+ super(name);
+ setSystem(true);
+ setUser(false);
+ setPriority(Job.LONG);
+ }
+
+ public Object[] runQuery(String prefix) {
+ fCurrentPrefix = toPrefixChars(prefix);
+ result = null;
+ schedule();
+ try {
+ join();
+ } catch (InterruptedException e) {
+ return null;
+ }
+ return result;
+ }
+
+ @Override
+ public IStatus run(final IProgressMonitor monitor) {
+ monitor.beginTask(ActionsMessages.OpenEditorAction_UpdateElementsJob_inProgress, IProgressMonitor.UNKNOWN);
+ final ITypeInfo[] elements = getElementsByPrefix(fCurrentPrefix, monitor);
+ if (elements != null && !monitor.isCanceled()) {
+ result = elements;
+ monitor.done();
+ return Status.OK_STATUS;
+ }
+ return Status.CANCEL_STATUS;
+ }
+
+ private char[] toPrefixChars(String filterPrefix) {
+ filterPrefix = CSearchUtil.adjustSearchStringForOperators(filterPrefix);
+ return toPrefix(filterPrefix);
+ }
+
+ private char[] toPrefix(String userFilter) {
+ QualifiedTypeName qualifiedName = new QualifiedTypeName(userFilter);
+ if (qualifiedName.segmentCount() > 1) {
+ userFilter = qualifiedName.lastSegment();
+ }
+ if (userFilter.endsWith("<")) { //$NON-NLS-1$
+ userFilter = userFilter.substring(0, userFilter.length() - 1);
+ }
+ int asterisk = userFilter.indexOf("*"); //$NON-NLS-1$
+ int questionMark = userFilter.indexOf("?"); //$NON-NLS-1$
+ int prefixEnd = asterisk < 0 ? questionMark
+ : questionMark < 0 ? asterisk : Math.min(asterisk, questionMark);
+ return (prefixEnd == -1 ? userFilter : userFilter.substring(0, prefixEnd)).toCharArray();
+ }
+
+ /**
+ * Queries the elements for the given prefix.
+ * @param prefix a prefix
+ * @param monitor a progress monitor
+ * @return an array of {@link ITypeInfo}s
+ */
+ protected ITypeInfo[] getElementsByPrefix(char[] prefix, IProgressMonitor monitor) {
+ if (monitor.isCanceled()) {
+ return null;
+ }
+ HashSet types = new HashSet<>();
+ if (prefix != null) {
+ final IndexFilter filter = new IndexFilter() {
+ @Override
+ public boolean acceptBinding(IBinding binding) throws CoreException {
+ if (isVisibleType(IndexModelUtil.getElementType(binding))) {
+ return IndexFilter.ALL_DECLARED.acceptBinding(binding);
+ }
+ return false;
+ }
+ };
+ try {
+ IIndex index = CCorePlugin.getIndexManager().getIndex(
+ CoreModel.getDefault().getCModel().getCProjects(),
+ IIndexManager.ADD_EXTENSION_FRAGMENTS_NAVIGATION);
+ index.acquireReadLock();
+ try {
+ IIndexBinding[] bindings = index.findBindingsForPrefix(prefix, false, filter, monitor);
+ for (int i = 0; i < bindings.length; i++) {
+ if (i % 0x1000 == 0 && monitor.isCanceled()) {
+ return null;
+ }
+ final IndexTypeInfo typeinfo = IndexTypeInfo.create(index, bindings[i]);
+ types.add(typeinfo);
+ }
+
+ if (isVisibleType(ICElement.C_MACRO)) {
+ IIndexMacro[] macros = index.findMacrosForPrefix(prefix, IndexFilter.ALL_DECLARED, monitor);
+ for (int i = 0; i < macros.length; i++) {
+ if (i % 0x1000 == 0 && monitor.isCanceled()) {
+ return null;
+ }
+ final IndexTypeInfo typeinfo = IndexTypeInfo.create(index, macros[i]);
+ types.add(typeinfo);
+ }
+ }
+ } finally {
+ index.releaseReadLock();
+ }
+ } catch (CoreException | InterruptedException e) {
+ CDTUnitTestPlugin.log(e);
+ }
+ }
+ return types.toArray(new ITypeInfo[types.size()]);
+ }
+
+ /**
+ * Answer whether the given type is a class or a struct.
+ *
+ * @param type the type constant, see {@link ICElement}
+ * @return true
if the given type is visible,
+ * false
otherwise
+ */
+ protected boolean isVisibleType(int type) {
+ return ICElement.C_CLASS == type || ICElement.C_STRUCT == type;
+ }
+ }
+
+ public OpenTestAction(Shell shell, ITestSuiteElement testSuite) {
+ this(shell, testSuite, null);
+ }
+
+ public OpenTestAction(Shell shell, ITestSuiteElement testSuite, ITestCaseElement testCase) {
+ super(ActionsMessages.OpenEditorAction_action_label);
+ this.shell = shell;
+ this.fClassName = getClassName(testSuite);
+ this.fMethodName = testCase != null ? getTestMethodName(testCase) : "*"; //$NON-NLS-1$
+ this.fSearchPrefix = new StringBuilder(fClassName).append('_').append(fMethodName).append("_Test").toString(); //$NON-NLS-1$
+ }
+
+ /*
+ * @see IAction#run()
+ */
+ @Override
+ public void run() {
+ UpdateElementsJob searchJob = new UpdateElementsJob(ActionsMessages.OpenEditorAction_UpdateElementsJob_name);
+ Object[] result = searchJob.runQuery(fSearchPrefix);
+
+ Object infoObject = result != null && result.length > 0 ? result[0] : null;
+ ITypeInfo info = infoObject instanceof ITypeInfo ? (ITypeInfo) infoObject : null;
+ ITypeReference location = info != null ? info.getResolvedReference() : null;
+
+ if (location == null) {
+ MessageDialog.openError(getShell(), ActionsMessages.OpenEditorAction_error_cannotopen_title,
+ ActionsMessages.OpenEditorAction_error_cannotopen_message);
+ } else if (!openTypeInEditor(location)) {
+ // Error opening editor.
+ String title = ActionsMessages.OpenEditorAction_error_cannotopen_title;
+ String message = NLS.bind(ActionsMessages.OpenEditorAction_errorOpenEditor, location.getPath().toString());
+ MessageDialog.openError(getShell(), title, message);
+ }
+ }
+
+ protected Shell getShell() {
+ return shell;
+ }
+
+ /**
+ * Opens an editor and displays the selected type.
+ *
+ * @param location a location reference
+ * @return true if successfully displayed.
+ */
+ private boolean openTypeInEditor(ITypeReference location) {
+ ICElement[] cElements = location.getCElements();
+ try {
+ if (cElements != null && cElements.length > 0) {
+ IEditorPart editor = EditorUtility.openInEditor(cElements[0]);
+ EditorUtility.revealInEditor(editor, cElements[0]);
+ return true;
+ }
+ ITranslationUnit unit = location.getTranslationUnit();
+ IEditorPart editorPart = null;
+
+ if (unit != null)
+ editorPart = EditorUtility.openInEditor(unit);
+ if (editorPart == null) {
+ // Open as external file.
+ editorPart = EditorUtility.openInEditor(location.getLocation(), null);
+ }
+
+ // Highlight the type in the editor.
+ if (editorPart != null && editorPart instanceof ITextEditor) {
+ ITextEditor editor = (ITextEditor) editorPart;
+ if (location.isLineNumber()) {
+ IDocument document = editor.getDocumentProvider().getDocument(editor.getEditorInput());
+ try {
+ int startOffset = document.getLineOffset(location.getOffset() - 1);
+ int length = document.getLineLength(location.getOffset() - 1);
+ editor.selectAndReveal(startOffset, length);
+ return true;
+ } catch (BadLocationException ble) {
+ return false;
+ }
+ }
+ editor.selectAndReveal(location.getOffset(), location.getLength());
+ return true;
+ }
+ } catch (CModelException ex) {
+ CDTUnitTestPlugin.log(ex);
+ return false;
+ } catch (PartInitException ex) {
+ CDTUnitTestPlugin.log(ex);
+ return false;
+ }
+
+ return false;
+ }
+
+ public String getClassName(ITestElement test) {
+ return extractClassName(test.getTestName());
+ }
+
+ private static String extractClassName(String testNameString) {
+ testNameString = extractRawClassName(testNameString);
+ testNameString = testNameString.replace('$', '.'); // see bug 178503
+ return testNameString;
+ }
+
+ /**
+ * Extracts and returns a raw class name from a test element name
+ *
+ * @param testNameString a test element name
+ *
+ * @return an extracted raw class name
+ */
+ public static String extractRawClassName(String testNameString) {
+ if (testNameString.startsWith("[") && testNameString.endsWith("]")) { //$NON-NLS-1$ //$NON-NLS-2$
+ // a group of parameterized tests, see
+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=102512
+ return testNameString;
+ }
+ int index = testNameString.lastIndexOf('(');
+ if (index < 0)
+ return testNameString;
+ int end = testNameString.lastIndexOf(')');
+ testNameString = testNameString.substring(index + 1, end > index ? end : testNameString.length());
+ return testNameString;
+ }
+
+ private String getTestMethodName(ITestElement test) {
+ String testName = test.getTestName();
+ int index = testName.lastIndexOf('(');
+ if (index > 0)
+ return testName.substring(0, index);
+ index = testName.indexOf('@');
+ if (index > 0)
+ return testName.substring(0, index);
+ return testName;
+ }
+
+}
diff --git a/unittest/pom.xml b/unittest/pom.xml
new file mode 100644
index 00000000000..2c7c97a374b
--- /dev/null
+++ b/unittest/pom.xml
@@ -0,0 +1,15 @@
+
+
+ 4.0.0
+
+
+ org.eclipse.cdt
+ cdt-parent
+ 10.2.0-SNAPSHOT
+
+
+ org.eclipse.cdt.unittest-parent
+ pom
+