Index: trunk/src/org/openstreetmap/josm/data/protobuf/ProtobufParser.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/protobuf/ProtobufParser.java	(revision 18825)
+++ trunk/src/org/openstreetmap/josm/data/protobuf/ProtobufParser.java	(revision 18826)
@@ -52,6 +52,5 @@
      * @param start    The start position in the byte array
      * @param end      The end position in the byte array (exclusive - [start, end) )
-     * @return t
-     * he number from the byte array. Depending upon length of time the number will be stored, narrowing may be helpful.
+     * @return the number from the byte array. Depending upon length of time the number will be stored, narrowing may be helpful.
      * @since 18695
      */
@@ -101,5 +100,5 @@
      */
     public static long decodeZigZag(long signed) {
-        return (signed >> 1) ^ -(signed & 1);
+        return (signed >>> 1) ^ -(signed & 1);
     }
 
Index: trunk/src/org/openstreetmap/josm/io/OsmPbfReader.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/OsmPbfReader.java	(revision 18825)
+++ trunk/src/org/openstreetmap/josm/io/OsmPbfReader.java	(revision 18826)
@@ -632,5 +632,5 @@
                 switch (protobufRecord.getField()) {
                     case 1:
-                        id = protobufRecord.asUnsignedVarInt().intValue();
+                        id = protobufRecord.asUnsignedVarInt().longValue();
                         break;
                     case 2:
@@ -699,5 +699,5 @@
                 switch (protobufRecord.getField()) {
                     case 1:
-                        id = protobufRecord.asUnsignedVarInt().intValue();
+                        id = protobufRecord.asUnsignedVarInt().longValue();
                         break;
                     case 2:
@@ -838,7 +838,4 @@
      */
     private static void setOsmPrimitiveData(PrimitiveBlockRecord primitiveBlockRecord, PrimitiveData primitive, Info info) {
-        if (info.changeset() != null) {
-            primitive.setChangesetId(Math.toIntExact(info.changeset()));
-        }
         primitive.setVisible(info.isVisible());
         if (info.timestamp() != null) {
@@ -852,4 +849,7 @@
         if (info.version() > 0) {
             primitive.setVersion(info.version());
+        }
+        if (info.changeset() != null) {
+            primitive.setChangesetId(Math.toIntExact(info.changeset()));
         }
     }
Index: trunk/test/unit/org/openstreetmap/josm/data/protobuf/ProtobufParserTest.java
===================================================================
--- trunk/test/unit/org/openstreetmap/josm/data/protobuf/ProtobufParserTest.java	(revision 18825)
+++ trunk/test/unit/org/openstreetmap/josm/data/protobuf/ProtobufParserTest.java	(revision 18826)
@@ -4,5 +4,10 @@
 import static org.junit.jupiter.api.Assertions.assertEquals;
 
+import java.util.stream.Stream;
+
 import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
 
 /**
@@ -49,3 +54,35 @@
         assertEquals(4_294_967_297L, ProtobufParser.encodeZigZag(Integer.MIN_VALUE - 1L).longValue());
     }
+
+    static Stream<Arguments> testDecode() {
+        return Stream.of(
+                Arguments.of(21L, 42L),
+                Arguments.of(9223372036854775785L, -46L)
+        );
+    }
+
+    @ParameterizedTest
+    @MethodSource
+    void testDecode(long expected, long toDecode) {
+        assertEquals(expected, ProtobufParser.decodeZigZag(toDecode));
+    }
+
+    static Stream<Arguments> testDecodeVarInt() {
+        return Stream.of(
+                Arguments.of(1, new int[] {0x01}),
+                Arguments.of(150, new int[] {0x96, 0x01}),
+                Arguments.of(9223372036854775806L, new int[] {0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F}),
+                Arguments.of(Long.MAX_VALUE, new int[] {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F})
+        );
+    }
+
+    @ParameterizedTest
+    @MethodSource
+    void testDecodeVarInt(long expected, int[] bytes) {
+        // Drop most significant bit
+        for (int i = 0; i < bytes.length; i++) {
+            bytes[i] = bytes[i] & 0x7F;
+        }
+        assertEquals(expected, ProtobufParser.convertByteArray(ProtobufTest.toByteArray(bytes), (byte) 7, 0, bytes.length));
+    }
 }
Index: trunk/test/unit/org/openstreetmap/josm/gui/io/importexport/OsmPbfImporterTest.java
===================================================================
--- trunk/test/unit/org/openstreetmap/josm/gui/io/importexport/OsmPbfImporterTest.java	(revision 18825)
+++ trunk/test/unit/org/openstreetmap/josm/gui/io/importexport/OsmPbfImporterTest.java	(revision 18826)
@@ -5,4 +5,5 @@
 import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
 import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
 import static org.junit.jupiter.api.Assertions.assertSame;
 import static org.junit.jupiter.api.Assertions.assertThrows;
@@ -18,4 +19,6 @@
 import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
 import org.openstreetmap.josm.TestUtils;
 import org.openstreetmap.josm.data.coor.ILatLon;
@@ -23,4 +26,5 @@
 import org.openstreetmap.josm.data.osm.AbstractPrimitive;
 import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.data.osm.OsmPrimitiveType;
 import org.openstreetmap.josm.data.osm.Relation;
 import org.openstreetmap.josm.data.osm.Way;
@@ -130,3 +134,35 @@
         }
     }
+
+    @Test
+    void testIdParsing() throws IOException, IllegalDataException {
+        final DataSet dataSet;
+        try (InputStream inputStream = TestUtils.getRegressionDataStream(23165, "largeIds.osm.pbf")) {
+            dataSet = importer.parseDataSet(inputStream, NullProgressMonitor.INSTANCE);
+        }
+        assertNotNull(dataSet.getPrimitiveById(9223372036854775806L, OsmPrimitiveType.NODE));
+        assertNotNull(dataSet.getPrimitiveById(9223372036854775806L, OsmPrimitiveType.WAY));
+        assertNotNull(dataSet.getPrimitiveById(9223372036854775806L, OsmPrimitiveType.RELATION));
+    }
+
+    @ParameterizedTest
+    @ValueSource(strings = {"Downloads/24165.osm.pbf", "workspace/tasking-manager/frontend/24165.osmosis.osm.pbf",
+    "workspace/tasking-manager/frontend/24165.osmium.osm.pbf"})
+    void test23165(String path) throws IOException {
+        try (InputStream is = Files.newInputStream(Paths.get("/Users/tsmock", path))) {
+            DataSet ds = assertDoesNotThrow(() -> importer.parseDataSet(is, NullProgressMonitor.INSTANCE));
+            assertNotNull(ds.getPrimitiveById(22319993769L, OsmPrimitiveType.NODE));
+            assertNotNull(ds.getPrimitiveById(32920002105L, OsmPrimitiveType.NODE));
+            assertNotNull(ds.getPrimitiveById(29706529395L, OsmPrimitiveType.NODE));
+            assertNotNull(ds.getPrimitiveById(23842321089L, OsmPrimitiveType.NODE));
+            assertNotNull(ds.getPrimitiveById(31341235510L, OsmPrimitiveType.NODE));
+            assertNotNull(ds.getPrimitiveById(30053292843L, OsmPrimitiveType.NODE));
+            assertNotNull(ds.getPrimitiveById(28917983832L, OsmPrimitiveType.NODE));
+            assertNotNull(ds.getPrimitiveById(29875275836L, OsmPrimitiveType.NODE));
+            assertNotNull(ds.getPrimitiveById(32694472600L, OsmPrimitiveType.NODE));
+            assertNotNull(ds.getPrimitiveById(22545520445L, OsmPrimitiveType.NODE));
+            assertNotNull(ds.getPrimitiveById(23222110547L, OsmPrimitiveType.NODE));
+            assertNotNull(ds.getPrimitiveById(2147640293L, OsmPrimitiveType.WAY));
+        }
+    }
 }
