Index: /trunk/src/org/openstreetmap/josm/gui/dialogs/SearchDialog.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/dialogs/SearchDialog.java	(revision 16267)
+++ /trunk/src/org/openstreetmap/josm/gui/dialogs/SearchDialog.java	(revision 16268)
@@ -292,5 +292,5 @@
                 GBC.eol());
         hintPanel.add(new SearchKeywordRow(hcbSearchString)
-                .addKeyword("<i>key</i>", null, tr("matches if ''key'' exists"))
+                .addKeyword("<i>key:</i>", null, tr("matches if ''key'' exists"))
                 .addKeyword("<i>key</i>=<i>value</i>", null, tr("''key'' with exactly ''value''"))
                 .addKeyword("<i>key</i>~<i>regexp</i>", null, tr("value of ''key'' matching the regular expression ''regexp''"))
Index: /trunk/test/unit/org/openstreetmap/josm/data/osm/search/SearchCompilerTest.java
===================================================================
--- /trunk/test/unit/org/openstreetmap/josm/data/osm/search/SearchCompilerTest.java	(revision 16267)
+++ /trunk/test/unit/org/openstreetmap/josm/data/osm/search/SearchCompilerTest.java	(revision 16268)
@@ -540,4 +540,18 @@
 
     /**
+     * Test whether a key exists.
+     * @throws SearchParseError never
+     */
+    @Test
+    public void testKeyExists15943() throws SearchParseError {
+        Match matcher = SearchCompiler.compile("surface:");
+        assertTrue(matcher.match(new Tag("surface", "")));
+        assertTrue(matcher.match(new Tag("surface", "wood")));
+        assertFalse(matcher.match(new Tag("surface:source", "xxx")));
+        assertFalse(matcher.match(new Tag("foo", "bar")));
+        assertFalse(matcher.match(new Tag("name", "foo:surface:bar")));
+    }
+
+    /**
      * Unit test of {@link SearchCompiler.ExactKeyValue.Mode} enum.
      */
