Index: trunk/src/org/openstreetmap/josm/gui/download/OverpassQueryWizardDialog.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/download/OverpassQueryWizardDialog.java	(revision 17335)
+++ trunk/src/org/openstreetmap/josm/gui/download/OverpassQueryWizardDialog.java	(revision 17336)
@@ -91,5 +91,5 @@
     private Optional<String> tryParseSearchTerm(String searchTerm) {
         try {
-            return Optional.of(SearchCompilerQueryWizard.getInstance().constructQuery(searchTerm));
+            return Optional.of(SearchCompilerQueryWizard.constructQuery(searchTerm));
         } catch (UncheckedParseException | IllegalStateException ex) {
             Logging.error(ex);
Index: trunk/src/org/openstreetmap/josm/tools/SearchCompilerQueryWizard.java
===================================================================
--- trunk/src/org/openstreetmap/josm/tools/SearchCompilerQueryWizard.java	(revision 17335)
+++ trunk/src/org/openstreetmap/josm/tools/SearchCompilerQueryWizard.java	(revision 17336)
@@ -26,15 +26,4 @@
 public final class SearchCompilerQueryWizard {
 
-    private static final SearchCompilerQueryWizard instance = new SearchCompilerQueryWizard();
-
-    /**
-     * Replies the unique instance of this class.
-     *
-     * @return the unique instance of this class
-     */
-    public static SearchCompilerQueryWizard getInstance() {
-        return instance;
-    }
-
     private SearchCompilerQueryWizard() {
         // private constructor for utility class
@@ -47,5 +36,5 @@
      * @throws UncheckedParseException when the parsing fails
      */
-    public String constructQuery(final String search) {
+    public static String constructQuery(final String search) {
         try {
             Matcher matcher = Pattern.compile("\\s+GLOBAL\\s*$", Pattern.CASE_INSENSITIVE).matcher(search);
@@ -74,5 +63,5 @@
                 }
             }
-            
+
             final Match match = SearchCompiler.compile(search);
             return constructQuery(match, "[bbox:{{bbox}}];", "");
@@ -82,5 +71,5 @@
     }
 
-    private String constructQuery(final Match match, final String bounds, final String queryLineSuffix) {
+    private static String constructQuery(final Match match, final String bounds, final String queryLineSuffix) {
         final List<Match> normalized = normalizeToDNF(match);
         final List<String> queryLines = new ArrayList<>();
@@ -136,4 +125,6 @@
                 case EXACT:
                     return "[" + quote(key) + (negated ? "!=" : "=") + quote(value) + "]";
+                case ANY_KEY: // *=value
+                    // fall through
                 case EXACT_REGEXP:
                     final Matcher matcher = Pattern.compile("/(?<regex>.*)/(?<flags>i)?").matcher(value);
@@ -141,4 +132,6 @@
                             ? quote(matcher.group("regex")) + Optional.ofNullable(matcher.group("flags")).map(f -> "," + f).orElse("")
                             : quote(value);
+                    if (mode == SearchCompiler.ExactKeyValue.Mode.ANY_KEY)
+                        return "[~\"^.*$\"" + (negated ? "!~" : "~") + valueQuery + "]";
                     return "[" + quote(key) + (negated ? "!~" : "~") + valueQuery + "]";
                 case MISSING_KEY:
Index: trunk/test/unit/org/openstreetmap/josm/io/OverpassDownloadReaderTest.java
===================================================================
--- trunk/test/unit/org/openstreetmap/josm/io/OverpassDownloadReaderTest.java	(revision 17335)
+++ trunk/test/unit/org/openstreetmap/josm/io/OverpassDownloadReaderTest.java	(revision 17336)
@@ -59,5 +59,5 @@
 
     private String getExpandedQuery(String search) {
-        final String query = SearchCompilerQueryWizard.getInstance().constructQuery(search);
+        final String query = SearchCompilerQueryWizard.constructQuery(search);
         final String request = new OverpassDownloadReader(new Bounds(1, 2, 3, 4), null, query)
                 .getRequestForBbox(1, 2, 3, 4)
Index: trunk/test/unit/org/openstreetmap/josm/tools/SearchCompilerQueryWizardTest.java
===================================================================
--- trunk/test/unit/org/openstreetmap/josm/tools/SearchCompilerQueryWizardTest.java	(revision 17335)
+++ trunk/test/unit/org/openstreetmap/josm/tools/SearchCompilerQueryWizardTest.java	(revision 17336)
@@ -24,5 +24,5 @@
 
     private static String constructQuery(String s) {
-        return SearchCompilerQueryWizard.getInstance().constructQuery(s);
+        return SearchCompilerQueryWizard.constructQuery(s);
     }
 
@@ -241,3 +241,14 @@
                 "type:relation and type=multipolygon and -landuse=* and -\"area:highway\"=*");
     }
+
+    /**
+     * Test for ticket <a href="https://josm.openstreetmap.de/ticket/20037>#20037</a>
+     */
+    @Test
+    void testTicket20037() {
+        assertQueryEquals(
+                "  node[~\"^.*$\"~\"forward\"];\n" +
+                "  node[~\"^.*$\"~\"backward\"];\n",
+                "type:node AND (*=forward OR *=backward)");
+    }
 }
