From ab8cf544184ea13a31a80450f6f4c41f35699f40 Mon Sep 17 00:00:00 2001
From: Dai MIKURUBE <dmikurube@treasure-data.com>
Date: Tue, 18 May 2021 18:56:10 +0900
Subject: [PATCH 1/5] Add a subproject msgpack-value

---
 build.sbt           | 26 +++++++++++++++++++++++++-
 msgpack-value/.keep |  0
 2 files changed, 25 insertions(+), 1 deletion(-)
 create mode 100644 msgpack-value/.keep

diff --git a/build.sbt b/build.sbt
index eae3cd51a..4761e53d0 100644
--- a/build.sbt
+++ b/build.sbt
@@ -59,6 +59,29 @@ lazy val root = Project(id = "msgpack-java", base = file("."))
   )
   .aggregate(msgpackCore, msgpackJackson)
 
+lazy val msgpackValue = Project(id = "msgpack-value", base = file("msgpack-value"))
+  .enablePlugins(SbtOsgi)
+  .settings(
+    buildSettings,
+    description := "Value classes of the MessagePack for Java",
+    OsgiKeys.bundleSymbolicName := "org.msgpack.msgpack-value",
+    OsgiKeys.exportPackage := Seq(
+      // TODO enumerate used packages automatically
+      "org.msgpack.core",
+      "org.msgpack.value",
+    ),
+    libraryDependencies ++= Seq(
+      // msgpack-value should have no external dependencies
+      junitInterface,
+      "org.scalatest"     %% "scalatest"    % "3.0.3"  % "test",
+      "org.scalacheck"    %% "scalacheck"   % "1.13.5" % "test",
+      "org.xerial"        %% "xerial-core"  % "3.6.0"  % "test",
+      "org.msgpack"       % "msgpack"       % "0.6.12" % "test",
+      "commons-codec"     % "commons-codec" % "1.10"   % "test",
+      "com.typesafe.akka" %% "akka-actor"   % "2.5.7"  % "test"
+    )
+  )
+
 lazy val msgpackCore = Project(id = "msgpack-core", base = file("msgpack-core"))
   .enablePlugins(SbtOsgi)
   .settings(
@@ -75,7 +98,7 @@ lazy val msgpackCore = Project(id = "msgpack-core", base = file("msgpack-core"))
     ),
     testFrameworks += new TestFramework("wvlet.airspec.Framework"),
     libraryDependencies ++= Seq(
-      // msgpack-core should have no external dependencies
+      // msgpack-core should have no external dependencies except for msgpack-value
       junitInterface,
       "org.wvlet.airframe" %% "airframe-json" % AIRFRAME_VERSION % "test",
       "org.wvlet.airframe" %% "airspec"       % AIRFRAME_VERSION % "test",
@@ -88,6 +111,7 @@ lazy val msgpackCore = Project(id = "msgpack-core", base = file("msgpack-core"))
       "org.scala-lang.modules" %% "scala-collection-compat" % "2.4.3"  % "test"
     )
   )
+  .dependsOn(msgpackValue)
 
 lazy val msgpackJackson =
   Project(id = "msgpack-jackson", base = file("msgpack-jackson"))
diff --git a/msgpack-value/.keep b/msgpack-value/.keep
new file mode 100644
index 000000000..e69de29bb

From 5ac4ab2b8b377b7e2e4071cd8641f88cc3c4bfb2 Mon Sep 17 00:00:00 2001
From: Dai MIKURUBE <dmikurube@treasure-data.com>
Date: Tue, 18 May 2021 18:56:36 +0900
Subject: [PATCH 2/5] Move value classes to project msgpack-value

---
 msgpack-value/.keep                                               | 0
 .../src/main/java/org/msgpack/value/ArrayValue.java               | 0
 .../src/main/java/org/msgpack/value/BinaryValue.java              | 0
 .../src/main/java/org/msgpack/value/BooleanValue.java             | 0
 .../src/main/java/org/msgpack/value/ExtensionValue.java           | 0
 .../src/main/java/org/msgpack/value/FloatValue.java               | 0
 .../src/main/java/org/msgpack/value/ImmutableArrayValue.java      | 0
 .../src/main/java/org/msgpack/value/ImmutableBinaryValue.java     | 0
 .../src/main/java/org/msgpack/value/ImmutableBooleanValue.java    | 0
 .../src/main/java/org/msgpack/value/ImmutableExtensionValue.java  | 0
 .../src/main/java/org/msgpack/value/ImmutableFloatValue.java      | 0
 .../src/main/java/org/msgpack/value/ImmutableIntegerValue.java    | 0
 .../src/main/java/org/msgpack/value/ImmutableMapValue.java        | 0
 .../src/main/java/org/msgpack/value/ImmutableNilValue.java        | 0
 .../src/main/java/org/msgpack/value/ImmutableNumberValue.java     | 0
 .../src/main/java/org/msgpack/value/ImmutableRawValue.java        | 0
 .../src/main/java/org/msgpack/value/ImmutableStringValue.java     | 0
 .../src/main/java/org/msgpack/value/ImmutableTimestampValue.java  | 0
 .../src/main/java/org/msgpack/value/ImmutableValue.java           | 0
 .../src/main/java/org/msgpack/value/IntegerValue.java             | 0
 .../src/main/java/org/msgpack/value/MapValue.java                 | 0
 .../src/main/java/org/msgpack/value/NilValue.java                 | 0
 .../src/main/java/org/msgpack/value/NumberValue.java              | 0
 .../src/main/java/org/msgpack/value/RawValue.java                 | 0
 .../src/main/java/org/msgpack/value/StringValue.java              | 0
 .../src/main/java/org/msgpack/value/TimestampValue.java           | 0
 .../src/main/java/org/msgpack/value/Value.java                    | 0
 .../src/main/java/org/msgpack/value/ValueType.java                | 0
 28 files changed, 0 insertions(+), 0 deletions(-)
 delete mode 100644 msgpack-value/.keep
 rename {msgpack-core => msgpack-value}/src/main/java/org/msgpack/value/ArrayValue.java (100%)
 rename {msgpack-core => msgpack-value}/src/main/java/org/msgpack/value/BinaryValue.java (100%)
 rename {msgpack-core => msgpack-value}/src/main/java/org/msgpack/value/BooleanValue.java (100%)
 rename {msgpack-core => msgpack-value}/src/main/java/org/msgpack/value/ExtensionValue.java (100%)
 rename {msgpack-core => msgpack-value}/src/main/java/org/msgpack/value/FloatValue.java (100%)
 rename {msgpack-core => msgpack-value}/src/main/java/org/msgpack/value/ImmutableArrayValue.java (100%)
 rename {msgpack-core => msgpack-value}/src/main/java/org/msgpack/value/ImmutableBinaryValue.java (100%)
 rename {msgpack-core => msgpack-value}/src/main/java/org/msgpack/value/ImmutableBooleanValue.java (100%)
 rename {msgpack-core => msgpack-value}/src/main/java/org/msgpack/value/ImmutableExtensionValue.java (100%)
 rename {msgpack-core => msgpack-value}/src/main/java/org/msgpack/value/ImmutableFloatValue.java (100%)
 rename {msgpack-core => msgpack-value}/src/main/java/org/msgpack/value/ImmutableIntegerValue.java (100%)
 rename {msgpack-core => msgpack-value}/src/main/java/org/msgpack/value/ImmutableMapValue.java (100%)
 rename {msgpack-core => msgpack-value}/src/main/java/org/msgpack/value/ImmutableNilValue.java (100%)
 rename {msgpack-core => msgpack-value}/src/main/java/org/msgpack/value/ImmutableNumberValue.java (100%)
 rename {msgpack-core => msgpack-value}/src/main/java/org/msgpack/value/ImmutableRawValue.java (100%)
 rename {msgpack-core => msgpack-value}/src/main/java/org/msgpack/value/ImmutableStringValue.java (100%)
 rename {msgpack-core => msgpack-value}/src/main/java/org/msgpack/value/ImmutableTimestampValue.java (100%)
 rename {msgpack-core => msgpack-value}/src/main/java/org/msgpack/value/ImmutableValue.java (100%)
 rename {msgpack-core => msgpack-value}/src/main/java/org/msgpack/value/IntegerValue.java (100%)
 rename {msgpack-core => msgpack-value}/src/main/java/org/msgpack/value/MapValue.java (100%)
 rename {msgpack-core => msgpack-value}/src/main/java/org/msgpack/value/NilValue.java (100%)
 rename {msgpack-core => msgpack-value}/src/main/java/org/msgpack/value/NumberValue.java (100%)
 rename {msgpack-core => msgpack-value}/src/main/java/org/msgpack/value/RawValue.java (100%)
 rename {msgpack-core => msgpack-value}/src/main/java/org/msgpack/value/StringValue.java (100%)
 rename {msgpack-core => msgpack-value}/src/main/java/org/msgpack/value/TimestampValue.java (100%)
 rename {msgpack-core => msgpack-value}/src/main/java/org/msgpack/value/Value.java (100%)
 rename {msgpack-core => msgpack-value}/src/main/java/org/msgpack/value/ValueType.java (100%)

diff --git a/msgpack-value/.keep b/msgpack-value/.keep
deleted file mode 100644
index e69de29bb..000000000
diff --git a/msgpack-core/src/main/java/org/msgpack/value/ArrayValue.java b/msgpack-value/src/main/java/org/msgpack/value/ArrayValue.java
similarity index 100%
rename from msgpack-core/src/main/java/org/msgpack/value/ArrayValue.java
rename to msgpack-value/src/main/java/org/msgpack/value/ArrayValue.java
diff --git a/msgpack-core/src/main/java/org/msgpack/value/BinaryValue.java b/msgpack-value/src/main/java/org/msgpack/value/BinaryValue.java
similarity index 100%
rename from msgpack-core/src/main/java/org/msgpack/value/BinaryValue.java
rename to msgpack-value/src/main/java/org/msgpack/value/BinaryValue.java
diff --git a/msgpack-core/src/main/java/org/msgpack/value/BooleanValue.java b/msgpack-value/src/main/java/org/msgpack/value/BooleanValue.java
similarity index 100%
rename from msgpack-core/src/main/java/org/msgpack/value/BooleanValue.java
rename to msgpack-value/src/main/java/org/msgpack/value/BooleanValue.java
diff --git a/msgpack-core/src/main/java/org/msgpack/value/ExtensionValue.java b/msgpack-value/src/main/java/org/msgpack/value/ExtensionValue.java
similarity index 100%
rename from msgpack-core/src/main/java/org/msgpack/value/ExtensionValue.java
rename to msgpack-value/src/main/java/org/msgpack/value/ExtensionValue.java
diff --git a/msgpack-core/src/main/java/org/msgpack/value/FloatValue.java b/msgpack-value/src/main/java/org/msgpack/value/FloatValue.java
similarity index 100%
rename from msgpack-core/src/main/java/org/msgpack/value/FloatValue.java
rename to msgpack-value/src/main/java/org/msgpack/value/FloatValue.java
diff --git a/msgpack-core/src/main/java/org/msgpack/value/ImmutableArrayValue.java b/msgpack-value/src/main/java/org/msgpack/value/ImmutableArrayValue.java
similarity index 100%
rename from msgpack-core/src/main/java/org/msgpack/value/ImmutableArrayValue.java
rename to msgpack-value/src/main/java/org/msgpack/value/ImmutableArrayValue.java
diff --git a/msgpack-core/src/main/java/org/msgpack/value/ImmutableBinaryValue.java b/msgpack-value/src/main/java/org/msgpack/value/ImmutableBinaryValue.java
similarity index 100%
rename from msgpack-core/src/main/java/org/msgpack/value/ImmutableBinaryValue.java
rename to msgpack-value/src/main/java/org/msgpack/value/ImmutableBinaryValue.java
diff --git a/msgpack-core/src/main/java/org/msgpack/value/ImmutableBooleanValue.java b/msgpack-value/src/main/java/org/msgpack/value/ImmutableBooleanValue.java
similarity index 100%
rename from msgpack-core/src/main/java/org/msgpack/value/ImmutableBooleanValue.java
rename to msgpack-value/src/main/java/org/msgpack/value/ImmutableBooleanValue.java
diff --git a/msgpack-core/src/main/java/org/msgpack/value/ImmutableExtensionValue.java b/msgpack-value/src/main/java/org/msgpack/value/ImmutableExtensionValue.java
similarity index 100%
rename from msgpack-core/src/main/java/org/msgpack/value/ImmutableExtensionValue.java
rename to msgpack-value/src/main/java/org/msgpack/value/ImmutableExtensionValue.java
diff --git a/msgpack-core/src/main/java/org/msgpack/value/ImmutableFloatValue.java b/msgpack-value/src/main/java/org/msgpack/value/ImmutableFloatValue.java
similarity index 100%
rename from msgpack-core/src/main/java/org/msgpack/value/ImmutableFloatValue.java
rename to msgpack-value/src/main/java/org/msgpack/value/ImmutableFloatValue.java
diff --git a/msgpack-core/src/main/java/org/msgpack/value/ImmutableIntegerValue.java b/msgpack-value/src/main/java/org/msgpack/value/ImmutableIntegerValue.java
similarity index 100%
rename from msgpack-core/src/main/java/org/msgpack/value/ImmutableIntegerValue.java
rename to msgpack-value/src/main/java/org/msgpack/value/ImmutableIntegerValue.java
diff --git a/msgpack-core/src/main/java/org/msgpack/value/ImmutableMapValue.java b/msgpack-value/src/main/java/org/msgpack/value/ImmutableMapValue.java
similarity index 100%
rename from msgpack-core/src/main/java/org/msgpack/value/ImmutableMapValue.java
rename to msgpack-value/src/main/java/org/msgpack/value/ImmutableMapValue.java
diff --git a/msgpack-core/src/main/java/org/msgpack/value/ImmutableNilValue.java b/msgpack-value/src/main/java/org/msgpack/value/ImmutableNilValue.java
similarity index 100%
rename from msgpack-core/src/main/java/org/msgpack/value/ImmutableNilValue.java
rename to msgpack-value/src/main/java/org/msgpack/value/ImmutableNilValue.java
diff --git a/msgpack-core/src/main/java/org/msgpack/value/ImmutableNumberValue.java b/msgpack-value/src/main/java/org/msgpack/value/ImmutableNumberValue.java
similarity index 100%
rename from msgpack-core/src/main/java/org/msgpack/value/ImmutableNumberValue.java
rename to msgpack-value/src/main/java/org/msgpack/value/ImmutableNumberValue.java
diff --git a/msgpack-core/src/main/java/org/msgpack/value/ImmutableRawValue.java b/msgpack-value/src/main/java/org/msgpack/value/ImmutableRawValue.java
similarity index 100%
rename from msgpack-core/src/main/java/org/msgpack/value/ImmutableRawValue.java
rename to msgpack-value/src/main/java/org/msgpack/value/ImmutableRawValue.java
diff --git a/msgpack-core/src/main/java/org/msgpack/value/ImmutableStringValue.java b/msgpack-value/src/main/java/org/msgpack/value/ImmutableStringValue.java
similarity index 100%
rename from msgpack-core/src/main/java/org/msgpack/value/ImmutableStringValue.java
rename to msgpack-value/src/main/java/org/msgpack/value/ImmutableStringValue.java
diff --git a/msgpack-core/src/main/java/org/msgpack/value/ImmutableTimestampValue.java b/msgpack-value/src/main/java/org/msgpack/value/ImmutableTimestampValue.java
similarity index 100%
rename from msgpack-core/src/main/java/org/msgpack/value/ImmutableTimestampValue.java
rename to msgpack-value/src/main/java/org/msgpack/value/ImmutableTimestampValue.java
diff --git a/msgpack-core/src/main/java/org/msgpack/value/ImmutableValue.java b/msgpack-value/src/main/java/org/msgpack/value/ImmutableValue.java
similarity index 100%
rename from msgpack-core/src/main/java/org/msgpack/value/ImmutableValue.java
rename to msgpack-value/src/main/java/org/msgpack/value/ImmutableValue.java
diff --git a/msgpack-core/src/main/java/org/msgpack/value/IntegerValue.java b/msgpack-value/src/main/java/org/msgpack/value/IntegerValue.java
similarity index 100%
rename from msgpack-core/src/main/java/org/msgpack/value/IntegerValue.java
rename to msgpack-value/src/main/java/org/msgpack/value/IntegerValue.java
diff --git a/msgpack-core/src/main/java/org/msgpack/value/MapValue.java b/msgpack-value/src/main/java/org/msgpack/value/MapValue.java
similarity index 100%
rename from msgpack-core/src/main/java/org/msgpack/value/MapValue.java
rename to msgpack-value/src/main/java/org/msgpack/value/MapValue.java
diff --git a/msgpack-core/src/main/java/org/msgpack/value/NilValue.java b/msgpack-value/src/main/java/org/msgpack/value/NilValue.java
similarity index 100%
rename from msgpack-core/src/main/java/org/msgpack/value/NilValue.java
rename to msgpack-value/src/main/java/org/msgpack/value/NilValue.java
diff --git a/msgpack-core/src/main/java/org/msgpack/value/NumberValue.java b/msgpack-value/src/main/java/org/msgpack/value/NumberValue.java
similarity index 100%
rename from msgpack-core/src/main/java/org/msgpack/value/NumberValue.java
rename to msgpack-value/src/main/java/org/msgpack/value/NumberValue.java
diff --git a/msgpack-core/src/main/java/org/msgpack/value/RawValue.java b/msgpack-value/src/main/java/org/msgpack/value/RawValue.java
similarity index 100%
rename from msgpack-core/src/main/java/org/msgpack/value/RawValue.java
rename to msgpack-value/src/main/java/org/msgpack/value/RawValue.java
diff --git a/msgpack-core/src/main/java/org/msgpack/value/StringValue.java b/msgpack-value/src/main/java/org/msgpack/value/StringValue.java
similarity index 100%
rename from msgpack-core/src/main/java/org/msgpack/value/StringValue.java
rename to msgpack-value/src/main/java/org/msgpack/value/StringValue.java
diff --git a/msgpack-core/src/main/java/org/msgpack/value/TimestampValue.java b/msgpack-value/src/main/java/org/msgpack/value/TimestampValue.java
similarity index 100%
rename from msgpack-core/src/main/java/org/msgpack/value/TimestampValue.java
rename to msgpack-value/src/main/java/org/msgpack/value/TimestampValue.java
diff --git a/msgpack-core/src/main/java/org/msgpack/value/Value.java b/msgpack-value/src/main/java/org/msgpack/value/Value.java
similarity index 100%
rename from msgpack-core/src/main/java/org/msgpack/value/Value.java
rename to msgpack-value/src/main/java/org/msgpack/value/Value.java
diff --git a/msgpack-core/src/main/java/org/msgpack/value/ValueType.java b/msgpack-value/src/main/java/org/msgpack/value/ValueType.java
similarity index 100%
rename from msgpack-core/src/main/java/org/msgpack/value/ValueType.java
rename to msgpack-value/src/main/java/org/msgpack/value/ValueType.java

From f2da506a7e9193eeb48d9661c785f0fda92083eb Mon Sep 17 00:00:00 2001
From: Dai MIKURUBE <dmikurube@treasure-data.com>
Date: Tue, 18 May 2021 18:56:53 +0900
Subject: [PATCH 3/5] Clone org.msgpack.core.MessagePack.Code to
 org.msgpack.value.MessagePackCode

---
 .../java/org/msgpack/core/MessageFormat.java  |  74 ++++-----
 .../java/org/msgpack/core/MessagePack.java    |  95 +++++------
 .../java/org/msgpack/core/MessagePacker.java  |  70 ++++----
 .../org/msgpack/core/MessageUnpacker.java     | 154 +++++++++---------
 .../impl/ImmutableTimestampValueImpl.java     |   2 +-
 .../msgpack/core/InvalidDataReadTest.scala    |   3 +-
 .../org/msgpack/core/MessageFormatTest.scala  |  70 ++++----
 .../msgpack/core/MessageUnpackerTest.scala    |   5 +-
 .../org/msgpack/value/ValueTypeTest.scala     |   2 +-
 .../dataformat/MessagePackGeneratorTest.java  |   5 +-
 .../org/msgpack/value/MessagePackCode.java    | 111 +++++++++++++
 11 files changed, 354 insertions(+), 237 deletions(-)
 create mode 100644 msgpack-value/src/main/java/org/msgpack/value/MessagePackCode.java

diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessageFormat.java b/msgpack-core/src/main/java/org/msgpack/core/MessageFormat.java
index d57c446f2..3c3463323 100644
--- a/msgpack-core/src/main/java/org/msgpack/core/MessageFormat.java
+++ b/msgpack-core/src/main/java/org/msgpack/core/MessageFormat.java
@@ -17,7 +17,7 @@
 
 import org.msgpack.core.annotations.VisibleForTesting;
 import org.msgpack.value.ValueType;
-import org.msgpack.core.MessagePack.Code;
+import org.msgpack.value.MessagePackCode;
 
 /**
  * Describes the list of the message format types defined in the MessagePack specification.
@@ -117,82 +117,82 @@ public static MessageFormat valueOf(final byte b)
     @VisibleForTesting
     static MessageFormat toMessageFormat(final byte b)
     {
-        if (Code.isPosFixInt(b)) {
+        if (MessagePackCode.isPosFixInt(b)) {
             return POSFIXINT;
         }
-        if (Code.isNegFixInt(b)) {
+        if (MessagePackCode.isNegFixInt(b)) {
             return NEGFIXINT;
         }
-        if (Code.isFixStr(b)) {
+        if (MessagePackCode.isFixStr(b)) {
             return FIXSTR;
         }
-        if (Code.isFixedArray(b)) {
+        if (MessagePackCode.isFixedArray(b)) {
             return FIXARRAY;
         }
-        if (Code.isFixedMap(b)) {
+        if (MessagePackCode.isFixedMap(b)) {
             return FIXMAP;
         }
         switch (b) {
-            case Code.NIL:
+            case MessagePackCode.NIL:
                 return NIL;
-            case Code.FALSE:
-            case Code.TRUE:
+            case MessagePackCode.FALSE:
+            case MessagePackCode.TRUE:
                 return BOOLEAN;
-            case Code.BIN8:
+            case MessagePackCode.BIN8:
                 return BIN8;
-            case Code.BIN16:
+            case MessagePackCode.BIN16:
                 return BIN16;
-            case Code.BIN32:
+            case MessagePackCode.BIN32:
                 return BIN32;
-            case Code.EXT8:
+            case MessagePackCode.EXT8:
                 return EXT8;
-            case Code.EXT16:
+            case MessagePackCode.EXT16:
                 return EXT16;
-            case Code.EXT32:
+            case MessagePackCode.EXT32:
                 return EXT32;
-            case Code.FLOAT32:
+            case MessagePackCode.FLOAT32:
                 return FLOAT32;
-            case Code.FLOAT64:
+            case MessagePackCode.FLOAT64:
                 return FLOAT64;
-            case Code.UINT8:
+            case MessagePackCode.UINT8:
                 return UINT8;
-            case Code.UINT16:
+            case MessagePackCode.UINT16:
                 return UINT16;
-            case Code.UINT32:
+            case MessagePackCode.UINT32:
                 return UINT32;
-            case Code.UINT64:
+            case MessagePackCode.UINT64:
                 return UINT64;
-            case Code.INT8:
+            case MessagePackCode.INT8:
                 return INT8;
-            case Code.INT16:
+            case MessagePackCode.INT16:
                 return INT16;
-            case Code.INT32:
+            case MessagePackCode.INT32:
                 return INT32;
-            case Code.INT64:
+            case MessagePackCode.INT64:
                 return INT64;
-            case Code.FIXEXT1:
+            case MessagePackCode.FIXEXT1:
                 return FIXEXT1;
-            case Code.FIXEXT2:
+            case MessagePackCode.FIXEXT2:
                 return FIXEXT2;
-            case Code.FIXEXT4:
+            case MessagePackCode.FIXEXT4:
                 return FIXEXT4;
-            case Code.FIXEXT8:
+            case MessagePackCode.FIXEXT8:
                 return FIXEXT8;
-            case Code.FIXEXT16:
+            case MessagePackCode.FIXEXT16:
                 return FIXEXT16;
-            case Code.STR8:
+            case MessagePackCode.STR8:
                 return STR8;
-            case Code.STR16:
+            case MessagePackCode.STR16:
                 return STR16;
-            case Code.STR32:
+            case MessagePackCode.STR32:
                 return STR32;
-            case Code.ARRAY16:
+            case MessagePackCode.ARRAY16:
                 return ARRAY16;
-            case Code.ARRAY32:
+            case MessagePackCode.ARRAY32:
                 return ARRAY32;
-            case Code.MAP16:
+            case MessagePackCode.MAP16:
                 return MAP16;
-            case Code.MAP32:
+            case MessagePackCode.MAP32:
                 return MAP32;
             default:
                 return NEVER_USED;
diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessagePack.java b/msgpack-core/src/main/java/org/msgpack/core/MessagePack.java
index edd449b34..daaa01036 100644
--- a/msgpack-core/src/main/java/org/msgpack/core/MessagePack.java
+++ b/msgpack-core/src/main/java/org/msgpack/core/MessagePack.java
@@ -23,6 +23,7 @@
 import org.msgpack.core.buffer.MessageBufferInput;
 import org.msgpack.core.buffer.MessageBufferOutput;
 import org.msgpack.core.buffer.OutputStreamBufferOutput;
+import org.msgpack.value.MessagePackCode;
 
 import java.io.InputStream;
 import java.io.OutputStream;
@@ -81,92 +82,94 @@ public class MessagePack
 
     /**
      * The prefix code set of MessagePack format. See also https://github.com/msgpack/msgpack/blob/master/spec.md for details.
+     *
+     * @deprecated It is here only for compatibility. Use {@link org.msgpack.value.MessagePackCode} instead.
      */
+    @Deprecated
     public static final class Code
     {
         public static final boolean isFixInt(byte b)
         {
-            int v = b & 0xFF;
-            return v <= 0x7f || v >= 0xe0;
+            return MessagePackCode.isFixInt(b);
         }
 
         public static final boolean isPosFixInt(byte b)
         {
-            return (b & POSFIXINT_MASK) == 0;
+            return MessagePackCode.isPosFixInt(b);
         }
 
         public static final boolean isNegFixInt(byte b)
         {
-            return (b & NEGFIXINT_PREFIX) == NEGFIXINT_PREFIX;
+            return MessagePackCode.isNegFixInt(b);
         }
 
         public static final boolean isFixStr(byte b)
         {
-            return (b & (byte) 0xe0) == Code.FIXSTR_PREFIX;
+            return MessagePackCode.isFixStr(b);
         }
 
         public static final boolean isFixedArray(byte b)
         {
-            return (b & (byte) 0xf0) == Code.FIXARRAY_PREFIX;
+            return MessagePackCode.isFixedArray(b);
         }
 
         public static final boolean isFixedMap(byte b)
         {
-            return (b & (byte) 0xf0) == Code.FIXMAP_PREFIX;
+            return MessagePackCode.isFixedMap(b);
         }
 
         public static final boolean isFixedRaw(byte b)
         {
-            return (b & (byte) 0xe0) == Code.FIXSTR_PREFIX;
+            return MessagePackCode.isFixedRaw(b);
         }
 
-        public static final byte POSFIXINT_MASK = (byte) 0x80;
+        public static final byte POSFIXINT_MASK = MessagePackCode.POSFIXINT_MASK;
 
-        public static final byte FIXMAP_PREFIX = (byte) 0x80;
-        public static final byte FIXARRAY_PREFIX = (byte) 0x90;
-        public static final byte FIXSTR_PREFIX = (byte) 0xa0;
+        public static final byte FIXMAP_PREFIX = MessagePackCode.FIXMAP_PREFIX;
+        public static final byte FIXARRAY_PREFIX = MessagePackCode.FIXARRAY_PREFIX;
+        public static final byte FIXSTR_PREFIX = MessagePackCode.FIXSTR_PREFIX;
 
-        public static final byte NIL = (byte) 0xc0;
-        public static final byte NEVER_USED = (byte) 0xc1;
-        public static final byte FALSE = (byte) 0xc2;
-        public static final byte TRUE = (byte) 0xc3;
-        public static final byte BIN8 = (byte) 0xc4;
-        public static final byte BIN16 = (byte) 0xc5;
-        public static final byte BIN32 = (byte) 0xc6;
-        public static final byte EXT8 = (byte) 0xc7;
-        public static final byte EXT16 = (byte) 0xc8;
-        public static final byte EXT32 = (byte) 0xc9;
-        public static final byte FLOAT32 = (byte) 0xca;
-        public static final byte FLOAT64 = (byte) 0xcb;
-        public static final byte UINT8 = (byte) 0xcc;
-        public static final byte UINT16 = (byte) 0xcd;
-        public static final byte UINT32 = (byte) 0xce;
-        public static final byte UINT64 = (byte) 0xcf;
+        public static final byte NIL = MessagePackCode.NIL;
+        public static final byte NEVER_USED = MessagePackCode.NEVER_USED;
+        public static final byte FALSE = MessagePackCode.FALSE;
+        public static final byte TRUE = MessagePackCode.TRUE;
+        public static final byte BIN8 = MessagePackCode.BIN8;
+        public static final byte BIN16 = MessagePackCode.BIN16;
+        public static final byte BIN32 = MessagePackCode.BIN32;
+        public static final byte EXT8 = MessagePackCode.EXT8;
+        public static final byte EXT16 = MessagePackCode.EXT16;
+        public static final byte EXT32 = MessagePackCode.EXT32;
+        public static final byte FLOAT32 = MessagePackCode.FLOAT32;
+        public static final byte FLOAT64 = MessagePackCode.FLOAT64;
+        public static final byte UINT8 = MessagePackCode.UINT8;
+        public static final byte UINT16 = MessagePackCode.UINT16;
+        public static final byte UINT32 = MessagePackCode.UINT32;
+        public static final byte UINT64 = MessagePackCode.UINT64;
 
-        public static final byte INT8 = (byte) 0xd0;
-        public static final byte INT16 = (byte) 0xd1;
-        public static final byte INT32 = (byte) 0xd2;
-        public static final byte INT64 = (byte) 0xd3;
+        public static final byte INT8 = MessagePackCode.INT8;
+        public static final byte INT16 = MessagePackCode.INT16;
+        public static final byte INT32 = MessagePackCode.INT32;
+        public static final byte INT64 = MessagePackCode.INT64;
 
-        public static final byte FIXEXT1 = (byte) 0xd4;
-        public static final byte FIXEXT2 = (byte) 0xd5;
-        public static final byte FIXEXT4 = (byte) 0xd6;
-        public static final byte FIXEXT8 = (byte) 0xd7;
-        public static final byte FIXEXT16 = (byte) 0xd8;
+        public static final byte FIXEXT1 = MessagePackCode.FIXEXT1;
+        public static final byte FIXEXT2 = MessagePackCode.FIXEXT2;
+        public static final byte FIXEXT4 = MessagePackCode.FIXEXT4;
+        public static final byte FIXEXT8 = MessagePackCode.FIXEXT8;
+        public static final byte FIXEXT16 = MessagePackCode.FIXEXT16;
 
-        public static final byte STR8 = (byte) 0xd9;
-        public static final byte STR16 = (byte) 0xda;
-        public static final byte STR32 = (byte) 0xdb;
+        public static final byte STR8 = MessagePackCode.STR8;
+        public static final byte STR16 = MessagePackCode.STR16;
+        public static final byte STR32 = MessagePackCode.STR32;
 
-        public static final byte ARRAY16 = (byte) 0xdc;
-        public static final byte ARRAY32 = (byte) 0xdd;
+        public static final byte ARRAY16 = MessagePackCode.ARRAY16;
+        public static final byte ARRAY32 = MessagePackCode.ARRAY32;
 
-        public static final byte MAP16 = (byte) 0xde;
-        public static final byte MAP32 = (byte) 0xdf;
+        public static final byte MAP16 = MessagePackCode.MAP16;
+        public static final byte MAP32 = MessagePackCode.MAP32;
 
-        public static final byte NEGFIXINT_PREFIX = (byte) 0xe0;
+        public static final byte NEGFIXINT_PREFIX = MessagePackCode.NEGFIXINT_PREFIX;
 
-        public static final byte EXT_TIMESTAMP = (byte) -1;
+        public static final byte EXT_TIMESTAMP = MessagePackCode.EXT_TIMESTAMP;
     }
 
     private MessagePack()
diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessagePacker.java b/msgpack-core/src/main/java/org/msgpack/core/MessagePacker.java
index 4cf789d9f..c5f0d186a 100644
--- a/msgpack-core/src/main/java/org/msgpack/core/MessagePacker.java
+++ b/msgpack-core/src/main/java/org/msgpack/core/MessagePacker.java
@@ -34,41 +34,41 @@
 import java.nio.charset.CodingErrorAction;
 import java.time.Instant;
 
-import static org.msgpack.core.MessagePack.Code.ARRAY16;
-import static org.msgpack.core.MessagePack.Code.ARRAY32;
-import static org.msgpack.core.MessagePack.Code.BIN16;
-import static org.msgpack.core.MessagePack.Code.BIN32;
-import static org.msgpack.core.MessagePack.Code.BIN8;
-import static org.msgpack.core.MessagePack.Code.EXT16;
-import static org.msgpack.core.MessagePack.Code.EXT32;
-import static org.msgpack.core.MessagePack.Code.EXT8;
-import static org.msgpack.core.MessagePack.Code.EXT_TIMESTAMP;
-import static org.msgpack.core.MessagePack.Code.FALSE;
-import static org.msgpack.core.MessagePack.Code.FIXARRAY_PREFIX;
-import static org.msgpack.core.MessagePack.Code.FIXEXT1;
-import static org.msgpack.core.MessagePack.Code.FIXEXT16;
-import static org.msgpack.core.MessagePack.Code.FIXEXT2;
-import static org.msgpack.core.MessagePack.Code.FIXEXT4;
-import static org.msgpack.core.MessagePack.Code.FIXEXT8;
-import static org.msgpack.core.MessagePack.Code.FIXMAP_PREFIX;
-import static org.msgpack.core.MessagePack.Code.FIXSTR_PREFIX;
-import static org.msgpack.core.MessagePack.Code.FLOAT32;
-import static org.msgpack.core.MessagePack.Code.FLOAT64;
-import static org.msgpack.core.MessagePack.Code.INT16;
-import static org.msgpack.core.MessagePack.Code.INT32;
-import static org.msgpack.core.MessagePack.Code.INT64;
-import static org.msgpack.core.MessagePack.Code.INT8;
-import static org.msgpack.core.MessagePack.Code.MAP16;
-import static org.msgpack.core.MessagePack.Code.MAP32;
-import static org.msgpack.core.MessagePack.Code.NIL;
-import static org.msgpack.core.MessagePack.Code.STR16;
-import static org.msgpack.core.MessagePack.Code.STR32;
-import static org.msgpack.core.MessagePack.Code.STR8;
-import static org.msgpack.core.MessagePack.Code.TRUE;
-import static org.msgpack.core.MessagePack.Code.UINT16;
-import static org.msgpack.core.MessagePack.Code.UINT32;
-import static org.msgpack.core.MessagePack.Code.UINT64;
-import static org.msgpack.core.MessagePack.Code.UINT8;
+import static org.msgpack.value.MessagePackCode.ARRAY16;
+import static org.msgpack.value.MessagePackCode.ARRAY32;
+import static org.msgpack.value.MessagePackCode.BIN16;
+import static org.msgpack.value.MessagePackCode.BIN32;
+import static org.msgpack.value.MessagePackCode.BIN8;
+import static org.msgpack.value.MessagePackCode.EXT16;
+import static org.msgpack.value.MessagePackCode.EXT32;
+import static org.msgpack.value.MessagePackCode.EXT8;
+import static org.msgpack.value.MessagePackCode.EXT_TIMESTAMP;
+import static org.msgpack.value.MessagePackCode.FALSE;
+import static org.msgpack.value.MessagePackCode.FIXARRAY_PREFIX;
+import static org.msgpack.value.MessagePackCode.FIXEXT1;
+import static org.msgpack.value.MessagePackCode.FIXEXT16;
+import static org.msgpack.value.MessagePackCode.FIXEXT2;
+import static org.msgpack.value.MessagePackCode.FIXEXT4;
+import static org.msgpack.value.MessagePackCode.FIXEXT8;
+import static org.msgpack.value.MessagePackCode.FIXMAP_PREFIX;
+import static org.msgpack.value.MessagePackCode.FIXSTR_PREFIX;
+import static org.msgpack.value.MessagePackCode.FLOAT32;
+import static org.msgpack.value.MessagePackCode.FLOAT64;
+import static org.msgpack.value.MessagePackCode.INT16;
+import static org.msgpack.value.MessagePackCode.INT32;
+import static org.msgpack.value.MessagePackCode.INT64;
+import static org.msgpack.value.MessagePackCode.INT8;
+import static org.msgpack.value.MessagePackCode.MAP16;
+import static org.msgpack.value.MessagePackCode.MAP32;
+import static org.msgpack.value.MessagePackCode.NIL;
+import static org.msgpack.value.MessagePackCode.STR16;
+import static org.msgpack.value.MessagePackCode.STR32;
+import static org.msgpack.value.MessagePackCode.STR8;
+import static org.msgpack.value.MessagePackCode.TRUE;
+import static org.msgpack.value.MessagePackCode.UINT16;
+import static org.msgpack.value.MessagePackCode.UINT32;
+import static org.msgpack.value.MessagePackCode.UINT64;
+import static org.msgpack.value.MessagePackCode.UINT8;
 import static org.msgpack.core.Preconditions.checkNotNull;
 
 /**
diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java b/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java
index b43204beb..3381631c7 100644
--- a/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java
+++ b/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java
@@ -15,10 +15,10 @@
 //
 package org.msgpack.core;
 
-import org.msgpack.core.MessagePack.Code;
 import org.msgpack.core.buffer.MessageBuffer;
 import org.msgpack.core.buffer.MessageBufferInput;
 import org.msgpack.value.ImmutableValue;
+import org.msgpack.value.MessagePackCode;
 import org.msgpack.value.Value;
 import org.msgpack.value.ValueFactory;
 import org.msgpack.value.Variable;
@@ -34,7 +34,7 @@
 import java.nio.charset.CodingErrorAction;
 import java.time.Instant;
 
-import static org.msgpack.core.MessagePack.Code.EXT_TIMESTAMP;
+import static org.msgpack.value.MessagePackCode.EXT_TIMESTAMP;
 import static org.msgpack.core.Preconditions.checkNotNull;
 
 /**
@@ -744,7 +744,7 @@ public void unpackNil()
             throws IOException
     {
         byte b = readByte();
-        if (b == Code.NIL) {
+        if (b == MessagePackCode.NIL) {
             return;
         }
         throw unexpected("Nil", b);
@@ -768,7 +768,7 @@ public boolean tryUnpackNil()
             throw new MessageInsufficientBufferException();
         }
         byte b = buffer.getByte(position);
-        if (b == Code.NIL) {
+        if (b == MessagePackCode.NIL) {
             readByte();
             return true;
         }
@@ -786,10 +786,10 @@ public boolean unpackBoolean()
             throws IOException
     {
         byte b = readByte();
-        if (b == Code.FALSE) {
+        if (b == MessagePackCode.FALSE) {
             return false;
         }
-        else if (b == Code.TRUE) {
+        else if (b == MessagePackCode.TRUE) {
             return true;
         }
         throw unexpected("boolean", b);
@@ -809,50 +809,50 @@ public byte unpackByte()
             throws IOException
     {
         byte b = readByte();
-        if (Code.isFixInt(b)) {
+        if (MessagePackCode.isFixInt(b)) {
             return b;
         }
         switch (b) {
-            case Code.UINT8: // unsigned int 8
+            case MessagePackCode.UINT8: // unsigned int 8
                 byte u8 = readByte();
                 if (u8 < (byte) 0) {
                     throw overflowU8(u8);
                 }
                 return u8;
-            case Code.UINT16: // unsigned int 16
+            case MessagePackCode.UINT16: // unsigned int 16
                 short u16 = readShort();
                 if (u16 < 0 || u16 > Byte.MAX_VALUE) {
                     throw overflowU16(u16);
                 }
                 return (byte) u16;
-            case Code.UINT32: // unsigned int 32
+            case MessagePackCode.UINT32: // unsigned int 32
                 int u32 = readInt();
                 if (u32 < 0 || u32 > Byte.MAX_VALUE) {
                     throw overflowU32(u32);
                 }
                 return (byte) u32;
-            case Code.UINT64: // unsigned int 64
+            case MessagePackCode.UINT64: // unsigned int 64
                 long u64 = readLong();
                 if (u64 < 0L || u64 > Byte.MAX_VALUE) {
                     throw overflowU64(u64);
                 }
                 return (byte) u64;
-            case Code.INT8: // signed int 8
+            case MessagePackCode.INT8: // signed int 8
                 byte i8 = readByte();
                 return i8;
-            case Code.INT16: // signed int 16
+            case MessagePackCode.INT16: // signed int 16
                 short i16 = readShort();
                 if (i16 < Byte.MIN_VALUE || i16 > Byte.MAX_VALUE) {
                     throw overflowI16(i16);
                 }
                 return (byte) i16;
-            case Code.INT32: // signed int 32
+            case MessagePackCode.INT32: // signed int 32
                 int i32 = readInt();
                 if (i32 < Byte.MIN_VALUE || i32 > Byte.MAX_VALUE) {
                     throw overflowI32(i32);
                 }
                 return (byte) i32;
-            case Code.INT64: // signed int 64
+            case MessagePackCode.INT64: // signed int 64
                 long i64 = readLong();
                 if (i64 < Byte.MIN_VALUE || i64 > Byte.MAX_VALUE) {
                     throw overflowI64(i64);
@@ -876,44 +876,44 @@ public short unpackShort()
             throws IOException
     {
         byte b = readByte();
-        if (Code.isFixInt(b)) {
+        if (MessagePackCode.isFixInt(b)) {
             return (short) b;
         }
         switch (b) {
-            case Code.UINT8: // unsigned int 8
+            case MessagePackCode.UINT8: // unsigned int 8
                 byte u8 = readByte();
                 return (short) (u8 & 0xff);
-            case Code.UINT16: // unsigned int 16
+            case MessagePackCode.UINT16: // unsigned int 16
                 short u16 = readShort();
                 if (u16 < (short) 0) {
                     throw overflowU16(u16);
                 }
                 return u16;
-            case Code.UINT32: // unsigned int 32
+            case MessagePackCode.UINT32: // unsigned int 32
                 int u32 = readInt();
                 if (u32 < 0 || u32 > Short.MAX_VALUE) {
                     throw overflowU32(u32);
                 }
                 return (short) u32;
-            case Code.UINT64: // unsigned int 64
+            case MessagePackCode.UINT64: // unsigned int 64
                 long u64 = readLong();
                 if (u64 < 0L || u64 > Short.MAX_VALUE) {
                     throw overflowU64(u64);
                 }
                 return (short) u64;
-            case Code.INT8: // signed int 8
+            case MessagePackCode.INT8: // signed int 8
                 byte i8 = readByte();
                 return (short) i8;
-            case Code.INT16: // signed int 16
+            case MessagePackCode.INT16: // signed int 16
                 short i16 = readShort();
                 return i16;
-            case Code.INT32: // signed int 32
+            case MessagePackCode.INT32: // signed int 32
                 int i32 = readInt();
                 if (i32 < Short.MIN_VALUE || i32 > Short.MAX_VALUE) {
                     throw overflowI32(i32);
                 }
                 return (short) i32;
-            case Code.INT64: // signed int 64
+            case MessagePackCode.INT64: // signed int 64
                 long i64 = readLong();
                 if (i64 < Short.MIN_VALUE || i64 > Short.MAX_VALUE) {
                     throw overflowI64(i64);
@@ -937,38 +937,38 @@ public int unpackInt()
             throws IOException
     {
         byte b = readByte();
-        if (Code.isFixInt(b)) {
+        if (MessagePackCode.isFixInt(b)) {
             return (int) b;
         }
         switch (b) {
-            case Code.UINT8: // unsigned int 8
+            case MessagePackCode.UINT8: // unsigned int 8
                 byte u8 = readByte();
                 return u8 & 0xff;
-            case Code.UINT16: // unsigned int 16
+            case MessagePackCode.UINT16: // unsigned int 16
                 short u16 = readShort();
                 return u16 & 0xffff;
-            case Code.UINT32: // unsigned int 32
+            case MessagePackCode.UINT32: // unsigned int 32
                 int u32 = readInt();
                 if (u32 < 0) {
                     throw overflowU32(u32);
                 }
                 return u32;
-            case Code.UINT64: // unsigned int 64
+            case MessagePackCode.UINT64: // unsigned int 64
                 long u64 = readLong();
                 if (u64 < 0L || u64 > (long) Integer.MAX_VALUE) {
                     throw overflowU64(u64);
                 }
                 return (int) u64;
-            case Code.INT8: // signed int 8
+            case MessagePackCode.INT8: // signed int 8
                 byte i8 = readByte();
                 return i8;
-            case Code.INT16: // signed int 16
+            case MessagePackCode.INT16: // signed int 16
                 short i16 = readShort();
                 return i16;
-            case Code.INT32: // signed int 32
+            case MessagePackCode.INT32: // signed int 32
                 int i32 = readInt();
                 return i32;
-            case Code.INT64: // signed int 64
+            case MessagePackCode.INT64: // signed int 64
                 long i64 = readLong();
                 if (i64 < (long) Integer.MIN_VALUE || i64 > (long) Integer.MAX_VALUE) {
                     throw overflowI64(i64);
@@ -992,17 +992,17 @@ public long unpackLong()
             throws IOException
     {
         byte b = readByte();
-        if (Code.isFixInt(b)) {
+        if (MessagePackCode.isFixInt(b)) {
             return (long) b;
         }
         switch (b) {
-            case Code.UINT8: // unsigned int 8
+            case MessagePackCode.UINT8: // unsigned int 8
                 byte u8 = readByte();
                 return (long) (u8 & 0xff);
-            case Code.UINT16: // unsigned int 16
+            case MessagePackCode.UINT16: // unsigned int 16
                 short u16 = readShort();
                 return (long) (u16 & 0xffff);
-            case Code.UINT32: // unsigned int 32
+            case MessagePackCode.UINT32: // unsigned int 32
                 int u32 = readInt();
                 if (u32 < 0) {
                     return (long) (u32 & 0x7fffffff) + 0x80000000L;
@@ -1010,22 +1010,22 @@ public long unpackLong()
                 else {
                     return (long) u32;
                 }
-            case Code.UINT64: // unsigned int 64
+            case MessagePackCode.UINT64: // unsigned int 64
                 long u64 = readLong();
                 if (u64 < 0L) {
                     throw overflowU64(u64);
                 }
                 return u64;
-            case Code.INT8: // signed int 8
+            case MessagePackCode.INT8: // signed int 8
                 byte i8 = readByte();
                 return (long) i8;
-            case Code.INT16: // signed int 16
+            case MessagePackCode.INT16: // signed int 16
                 short i16 = readShort();
                 return (long) i16;
-            case Code.INT32: // signed int 32
+            case MessagePackCode.INT32: // signed int 32
                 int i32 = readInt();
                 return (long) i32;
-            case Code.INT64: // signed int 64
+            case MessagePackCode.INT64: // signed int 64
                 long i64 = readLong();
                 return i64;
         }
@@ -1043,17 +1043,17 @@ public BigInteger unpackBigInteger()
             throws IOException
     {
         byte b = readByte();
-        if (Code.isFixInt(b)) {
+        if (MessagePackCode.isFixInt(b)) {
             return BigInteger.valueOf((long) b);
         }
         switch (b) {
-            case Code.UINT8: // unsigned int 8
+            case MessagePackCode.UINT8: // unsigned int 8
                 byte u8 = readByte();
                 return BigInteger.valueOf((long) (u8 & 0xff));
-            case Code.UINT16: // unsigned int 16
+            case MessagePackCode.UINT16: // unsigned int 16
                 short u16 = readShort();
                 return BigInteger.valueOf((long) (u16 & 0xffff));
-            case Code.UINT32: // unsigned int 32
+            case MessagePackCode.UINT32: // unsigned int 32
                 int u32 = readInt();
                 if (u32 < 0) {
                     return BigInteger.valueOf((long) (u32 & 0x7fffffff) + 0x80000000L);
@@ -1061,7 +1061,7 @@ public BigInteger unpackBigInteger()
                 else {
                     return BigInteger.valueOf((long) u32);
                 }
-            case Code.UINT64: // unsigned int 64
+            case MessagePackCode.UINT64: // unsigned int 64
                 long u64 = readLong();
                 if (u64 < 0L) {
                     BigInteger bi = BigInteger.valueOf(u64 + Long.MAX_VALUE + 1L).setBit(63);
@@ -1070,16 +1070,16 @@ public BigInteger unpackBigInteger()
                 else {
                     return BigInteger.valueOf(u64);
                 }
-            case Code.INT8: // signed int 8
+            case MessagePackCode.INT8: // signed int 8
                 byte i8 = readByte();
                 return BigInteger.valueOf((long) i8);
-            case Code.INT16: // signed int 16
+            case MessagePackCode.INT16: // signed int 16
                 short i16 = readShort();
                 return BigInteger.valueOf((long) i16);
-            case Code.INT32: // signed int 32
+            case MessagePackCode.INT32: // signed int 32
                 int i32 = readInt();
                 return BigInteger.valueOf((long) i32);
-            case Code.INT64: // signed int 64
+            case MessagePackCode.INT64: // signed int 64
                 long i64 = readLong();
                 return BigInteger.valueOf(i64);
         }
@@ -1100,10 +1100,10 @@ public float unpackFloat()
     {
         byte b = readByte();
         switch (b) {
-            case Code.FLOAT32: // float
+            case MessagePackCode.FLOAT32: // float
                 float fv = readFloat();
                 return fv;
-            case Code.FLOAT64: // double
+            case MessagePackCode.FLOAT64: // double
                 double dv = readDouble();
                 return (float) dv;
         }
@@ -1122,10 +1122,10 @@ public double unpackDouble()
     {
         byte b = readByte();
         switch (b) {
-            case Code.FLOAT32: // float
+            case MessagePackCode.FLOAT32: // float
                 float fv = readFloat();
                 return (double) fv;
-            case Code.FLOAT64: // double
+            case MessagePackCode.FLOAT64: // double
                 double dv = readDouble();
                 return dv;
         }
@@ -1331,15 +1331,15 @@ public int unpackArrayHeader()
             throws IOException
     {
         byte b = readByte();
-        if (Code.isFixedArray(b)) { // fixarray
+        if (MessagePackCode.isFixedArray(b)) { // fixarray
             return b & 0x0f;
         }
         switch (b) {
-            case Code.ARRAY16: { // array 16
+            case MessagePackCode.ARRAY16: { // array 16
                 int len = readNextLength16();
                 return len;
             }
-            case Code.ARRAY32: { // array 32
+            case MessagePackCode.ARRAY32: { // array 32
                 int len = readNextLength32();
                 return len;
             }
@@ -1364,15 +1364,15 @@ public int unpackMapHeader()
             throws IOException
     {
         byte b = readByte();
-        if (Code.isFixedMap(b)) { // fixmap
+        if (MessagePackCode.isFixedMap(b)) { // fixmap
             return b & 0x0f;
         }
         switch (b) {
-            case Code.MAP16: { // map 16
+            case MessagePackCode.MAP16: { // map 16
                 int len = readNextLength16();
                 return len;
             }
-            case Code.MAP32: { // map 32
+            case MessagePackCode.MAP32: { // map 32
                 int len = readNextLength32();
                 return len;
             }
@@ -1385,41 +1385,41 @@ public ExtensionTypeHeader unpackExtensionTypeHeader()
     {
         byte b = readByte();
         switch (b) {
-            case Code.FIXEXT1: {
+            case MessagePackCode.FIXEXT1: {
                 byte type = readByte();
                 return new ExtensionTypeHeader(type, 1);
             }
-            case Code.FIXEXT2: {
+            case MessagePackCode.FIXEXT2: {
                 byte type = readByte();
                 return new ExtensionTypeHeader(type, 2);
             }
-            case Code.FIXEXT4: {
+            case MessagePackCode.FIXEXT4: {
                 byte type = readByte();
                 return new ExtensionTypeHeader(type, 4);
             }
-            case Code.FIXEXT8: {
+            case MessagePackCode.FIXEXT8: {
                 byte type = readByte();
                 return new ExtensionTypeHeader(type, 8);
             }
-            case Code.FIXEXT16: {
+            case MessagePackCode.FIXEXT16: {
                 byte type = readByte();
                 return new ExtensionTypeHeader(type, 16);
             }
-            case Code.EXT8: {
+            case MessagePackCode.EXT8: {
                 MessageBuffer numberBuffer = prepareNumberBuffer(2);
                 int u8 = numberBuffer.getByte(nextReadPosition);
                 int length = u8 & 0xff;
                 byte type = numberBuffer.getByte(nextReadPosition + 1);
                 return new ExtensionTypeHeader(type, length);
             }
-            case Code.EXT16: {
+            case MessagePackCode.EXT16: {
                 MessageBuffer numberBuffer = prepareNumberBuffer(3);
                 int u16 = numberBuffer.getShort(nextReadPosition);
                 int length = u16 & 0xffff;
                 byte type = numberBuffer.getByte(nextReadPosition + 2);
                 return new ExtensionTypeHeader(type, length);
             }
-            case Code.EXT32: {
+            case MessagePackCode.EXT32: {
                 MessageBuffer numberBuffer = prepareNumberBuffer(5);
                 int u32 = numberBuffer.getInt(nextReadPosition);
                 if (u32 < 0) {
@@ -1438,11 +1438,11 @@ private int tryReadStringHeader(byte b)
             throws IOException
     {
         switch (b) {
-            case Code.STR8: // str 8
+            case MessagePackCode.STR8: // str 8
                 return readNextLength8();
-            case Code.STR16: // str 16
+            case MessagePackCode.STR16: // str 16
                 return readNextLength16();
-            case Code.STR32: // str 32
+            case MessagePackCode.STR32: // str 32
                 return readNextLength32();
             default:
                 return -1;
@@ -1453,11 +1453,11 @@ private int tryReadBinaryHeader(byte b)
             throws IOException
     {
         switch (b) {
-            case Code.BIN8: // bin 8
+            case MessagePackCode.BIN8: // bin 8
                 return readNextLength8();
-            case Code.BIN16: // bin 16
+            case MessagePackCode.BIN16: // bin 16
                 return readNextLength16();
-            case Code.BIN32: // bin 32
+            case MessagePackCode.BIN32: // bin 32
                 return readNextLength32();
             default:
                 return -1;
@@ -1468,7 +1468,7 @@ public int unpackRawStringHeader()
             throws IOException
     {
         byte b = readByte();
-        if (Code.isFixedRaw(b)) { // FixRaw
+        if (MessagePackCode.isFixedRaw(b)) { // FixRaw
             return b & 0x1f;
         }
         int len = tryReadStringHeader(b);
@@ -1505,7 +1505,7 @@ public int unpackBinaryHeader()
             throws IOException
     {
         byte b = readByte();
-        if (Code.isFixedRaw(b)) { // FixRaw
+        if (MessagePackCode.isFixedRaw(b)) { // FixRaw
             return b & 0x1f;
         }
         int len = tryReadBinaryHeader(b);
diff --git a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableTimestampValueImpl.java b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableTimestampValueImpl.java
index 227c85d0b..129426b37 100644
--- a/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableTimestampValueImpl.java
+++ b/msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableTimestampValueImpl.java
@@ -28,7 +28,7 @@
 import java.time.Instant;
 import java.util.Arrays;
 
-import static org.msgpack.core.MessagePack.Code.EXT_TIMESTAMP;
+import static org.msgpack.value.MessagePackCode.EXT_TIMESTAMP;
 
 /**
  * {@code ImmutableTimestampValueImpl} Implements {@code ImmutableTimestampValue} using a {@code byte} and a {@code byte[]} fields.
diff --git a/msgpack-core/src/test/scala/org/msgpack/core/InvalidDataReadTest.scala b/msgpack-core/src/test/scala/org/msgpack/core/InvalidDataReadTest.scala
index 4e39ff85c..2c3b04713 100644
--- a/msgpack-core/src/test/scala/org/msgpack/core/InvalidDataReadTest.scala
+++ b/msgpack-core/src/test/scala/org/msgpack/core/InvalidDataReadTest.scala
@@ -1,6 +1,7 @@
 package org.msgpack.core
 
 import org.msgpack.core.MessagePackSpec.createMessagePackData
+import org.msgpack.value.MessagePackCode
 import wvlet.airspec.AirSpec
 
 /**
@@ -11,7 +12,7 @@ class InvalidDataReadTest extends AirSpec {
   test("Reading long EXT32") {
     // Prepare an EXT32 data with 2GB (Int.MaxValue size) payload for testing the behavior of MessageUnpacker.skipValue()
     // Actually preparing 2GB of data, however, is too much for CI, so we create only the header part.
-    val msgpack = createMessagePackData(p => p.packExtensionTypeHeader(MessagePack.Code.EXT32, Int.MaxValue))
+    val msgpack = createMessagePackData(p => p.packExtensionTypeHeader(MessagePackCode.EXT32, Int.MaxValue))
     val u       = MessagePack.newDefaultUnpacker(msgpack)
     try {
       // This error will be thrown after reading the header as the input has no EXT32 body
diff --git a/msgpack-core/src/test/scala/org/msgpack/core/MessageFormatTest.scala b/msgpack-core/src/test/scala/org/msgpack/core/MessageFormatTest.scala
index 5f3447617..a733879f6 100644
--- a/msgpack-core/src/test/scala/org/msgpack/core/MessageFormatTest.scala
+++ b/msgpack-core/src/test/scala/org/msgpack/core/MessageFormatTest.scala
@@ -15,7 +15,7 @@
 //
 package org.msgpack.core
 
-import org.msgpack.core.MessagePack.Code
+import org.msgpack.value.MessagePackCode
 import org.msgpack.value.ValueType
 import wvlet.airspec.AirSpec
 import wvlet.airspec.spi.AirSpecException
@@ -58,45 +58,45 @@ class MessageFormatTest extends AirSpec with Benchmark {
         check(i.toByte, ValueType.ARRAY, MessageFormat.FIXARRAY)
       }
 
-      check(Code.NIL, ValueType.NIL, MessageFormat.NIL)
+      check(MessagePackCode.NIL, ValueType.NIL, MessageFormat.NIL)
 
-      MessageFormat.valueOf(Code.NEVER_USED) shouldBe MessageFormat.NEVER_USED
+      MessageFormat.valueOf(MessagePackCode.NEVER_USED) shouldBe MessageFormat.NEVER_USED
 
-      for (i <- Seq(Code.TRUE, Code.FALSE)) {
+      for (i <- Seq(MessagePackCode.TRUE, MessagePackCode.FALSE)) {
         check(i, ValueType.BOOLEAN, MessageFormat.BOOLEAN)
       }
 
-      check(Code.BIN8, ValueType.BINARY, MessageFormat.BIN8)
-      check(Code.BIN16, ValueType.BINARY, MessageFormat.BIN16)
-      check(Code.BIN32, ValueType.BINARY, MessageFormat.BIN32)
-
-      check(Code.FIXEXT1, ValueType.EXTENSION, MessageFormat.FIXEXT1)
-      check(Code.FIXEXT2, ValueType.EXTENSION, MessageFormat.FIXEXT2)
-      check(Code.FIXEXT4, ValueType.EXTENSION, MessageFormat.FIXEXT4)
-      check(Code.FIXEXT8, ValueType.EXTENSION, MessageFormat.FIXEXT8)
-      check(Code.FIXEXT16, ValueType.EXTENSION, MessageFormat.FIXEXT16)
-      check(Code.EXT8, ValueType.EXTENSION, MessageFormat.EXT8)
-      check(Code.EXT16, ValueType.EXTENSION, MessageFormat.EXT16)
-      check(Code.EXT32, ValueType.EXTENSION, MessageFormat.EXT32)
-
-      check(Code.INT8, ValueType.INTEGER, MessageFormat.INT8)
-      check(Code.INT16, ValueType.INTEGER, MessageFormat.INT16)
-      check(Code.INT32, ValueType.INTEGER, MessageFormat.INT32)
-      check(Code.INT64, ValueType.INTEGER, MessageFormat.INT64)
-      check(Code.UINT8, ValueType.INTEGER, MessageFormat.UINT8)
-      check(Code.UINT16, ValueType.INTEGER, MessageFormat.UINT16)
-      check(Code.UINT32, ValueType.INTEGER, MessageFormat.UINT32)
-      check(Code.UINT64, ValueType.INTEGER, MessageFormat.UINT64)
-
-      check(Code.STR8, ValueType.STRING, MessageFormat.STR8)
-      check(Code.STR16, ValueType.STRING, MessageFormat.STR16)
-      check(Code.STR32, ValueType.STRING, MessageFormat.STR32)
-
-      check(Code.FLOAT32, ValueType.FLOAT, MessageFormat.FLOAT32)
-      check(Code.FLOAT64, ValueType.FLOAT, MessageFormat.FLOAT64)
-
-      check(Code.ARRAY16, ValueType.ARRAY, MessageFormat.ARRAY16)
-      check(Code.ARRAY32, ValueType.ARRAY, MessageFormat.ARRAY32)
+      check(MessagePackCode.BIN8, ValueType.BINARY, MessageFormat.BIN8)
+      check(MessagePackCode.BIN16, ValueType.BINARY, MessageFormat.BIN16)
+      check(MessagePackCode.BIN32, ValueType.BINARY, MessageFormat.BIN32)
+
+      check(MessagePackCode.FIXEXT1, ValueType.EXTENSION, MessageFormat.FIXEXT1)
+      check(MessagePackCode.FIXEXT2, ValueType.EXTENSION, MessageFormat.FIXEXT2)
+      check(MessagePackCode.FIXEXT4, ValueType.EXTENSION, MessageFormat.FIXEXT4)
+      check(MessagePackCode.FIXEXT8, ValueType.EXTENSION, MessageFormat.FIXEXT8)
+      check(MessagePackCode.FIXEXT16, ValueType.EXTENSION, MessageFormat.FIXEXT16)
+      check(MessagePackCode.EXT8, ValueType.EXTENSION, MessageFormat.EXT8)
+      check(MessagePackCode.EXT16, ValueType.EXTENSION, MessageFormat.EXT16)
+      check(MessagePackCode.EXT32, ValueType.EXTENSION, MessageFormat.EXT32)
+
+      check(MessagePackCode.INT8, ValueType.INTEGER, MessageFormat.INT8)
+      check(MessagePackCode.INT16, ValueType.INTEGER, MessageFormat.INT16)
+      check(MessagePackCode.INT32, ValueType.INTEGER, MessageFormat.INT32)
+      check(MessagePackCode.INT64, ValueType.INTEGER, MessageFormat.INT64)
+      check(MessagePackCode.UINT8, ValueType.INTEGER, MessageFormat.UINT8)
+      check(MessagePackCode.UINT16, ValueType.INTEGER, MessageFormat.UINT16)
+      check(MessagePackCode.UINT32, ValueType.INTEGER, MessageFormat.UINT32)
+      check(MessagePackCode.UINT64, ValueType.INTEGER, MessageFormat.UINT64)
+
+      check(MessagePackCode.STR8, ValueType.STRING, MessageFormat.STR8)
+      check(MessagePackCode.STR16, ValueType.STRING, MessageFormat.STR16)
+      check(MessagePackCode.STR32, ValueType.STRING, MessageFormat.STR32)
+
+      check(MessagePackCode.FLOAT32, ValueType.FLOAT, MessageFormat.FLOAT32)
+      check(MessagePackCode.FLOAT64, ValueType.FLOAT, MessageFormat.FLOAT64)
+
+      check(MessagePackCode.ARRAY16, ValueType.ARRAY, MessageFormat.ARRAY16)
+      check(MessagePackCode.ARRAY32, ValueType.ARRAY, MessageFormat.ARRAY32)
 
       for (i <- 0xe0 to 0xff) {
         check(i.toByte, ValueType.INTEGER, MessageFormat.NEGFIXINT)
diff --git a/msgpack-core/src/test/scala/org/msgpack/core/MessageUnpackerTest.scala b/msgpack-core/src/test/scala/org/msgpack/core/MessageUnpackerTest.scala
index 5ae597f27..31bbdb7a1 100644
--- a/msgpack-core/src/test/scala/org/msgpack/core/MessageUnpackerTest.scala
+++ b/msgpack-core/src/test/scala/org/msgpack/core/MessageUnpackerTest.scala
@@ -17,6 +17,7 @@ package org.msgpack.core
 
 import org.msgpack.core.MessagePackSpec.{createMessagePackData, toHex}
 import org.msgpack.core.buffer._
+import org.msgpack.value.MessagePackCode
 import org.msgpack.value.ValueType
 import wvlet.airspec.AirSpec
 import wvlet.log.LogSupport
@@ -911,7 +912,7 @@ class MessageUnpackerTest extends AirSpec with Benchmark {
 
     test("read value length at buffer boundary") {
       val input = new SplitMessageBufferInput(
-        Array(Array[Byte](MessagePack.Code.STR16),
+        Array(Array[Byte](MessagePackCode.STR16),
               Array[Byte](0x00),
               Array[Byte](0x05), // STR16 length at the boundary
               "hello".getBytes(MessagePack.UTF8)))
@@ -919,7 +920,7 @@ class MessageUnpackerTest extends AirSpec with Benchmark {
 
       val input2 = new SplitMessageBufferInput(
         Array(
-          Array[Byte](MessagePack.Code.STR32),
+          Array[Byte](MessagePackCode.STR32),
           Array[Byte](0x00),
           Array[Byte](0x00, 0x00),
           Array[Byte](0x05), // STR32 length at the boundary
diff --git a/msgpack-core/src/test/scala/org/msgpack/value/ValueTypeTest.scala b/msgpack-core/src/test/scala/org/msgpack/value/ValueTypeTest.scala
index 4627faba4..e491832cf 100644
--- a/msgpack-core/src/test/scala/org/msgpack/value/ValueTypeTest.scala
+++ b/msgpack-core/src/test/scala/org/msgpack/value/ValueTypeTest.scala
@@ -15,7 +15,7 @@
 //
 package org.msgpack.value
 
-import org.msgpack.core.MessagePack.Code._
+import org.msgpack.value.MessagePackCode._
 import org.msgpack.core.{MessageFormat, MessageFormatException}
 import wvlet.airspec.AirSpec
 
diff --git a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackGeneratorTest.java b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackGeneratorTest.java
index e2c202bc3..afaf13db6 100644
--- a/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackGeneratorTest.java
+++ b/msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackGeneratorTest.java
@@ -29,6 +29,7 @@
 import org.msgpack.core.MessagePack;
 import org.msgpack.core.MessageUnpacker;
 import org.msgpack.core.buffer.ArrayBufferInput;
+import org.msgpack.value.MessagePackCode;
 
 import java.io.ByteArrayOutputStream;
 import java.io.File;
@@ -460,13 +461,13 @@ public void testDisableStr8Support()
         // Test that produced value having str8 format
         ObjectMapper defaultMapper = new ObjectMapper(new MessagePackFactory());
         byte[] resultWithStr8Format = defaultMapper.writeValueAsBytes(str8LengthString);
-        assertEquals(resultWithStr8Format[0], MessagePack.Code.STR8);
+        assertEquals(resultWithStr8Format[0], MessagePackCode.STR8);
 
         // Test that produced value does not having str8 format
         MessagePack.PackerConfig config = new MessagePack.PackerConfig().withStr8FormatSupport(false);
         ObjectMapper mapperWithConfig = new ObjectMapper(new MessagePackFactory(config));
         byte[] resultWithoutStr8Format = mapperWithConfig.writeValueAsBytes(str8LengthString);
-        assertNotEquals(resultWithoutStr8Format[0], MessagePack.Code.STR8);
+        assertNotEquals(resultWithoutStr8Format[0], MessagePackCode.STR8);
     }
 
     interface NonStringKeyMapHolder
diff --git a/msgpack-value/src/main/java/org/msgpack/value/MessagePackCode.java b/msgpack-value/src/main/java/org/msgpack/value/MessagePackCode.java
new file mode 100644
index 000000000..1c41bad31
--- /dev/null
+++ b/msgpack-value/src/main/java/org/msgpack/value/MessagePackCode.java
@@ -0,0 +1,111 @@
+//
+// MessagePack for Java
+//
+//    Licensed under the Apache License, Version 2.0 (the "License");
+//    you may not use this file except in compliance with the License.
+//    You may obtain a copy of the License at
+//
+//        http://www.apache.org/licenses/LICENSE-2.0
+//
+//    Unless required by applicable law or agreed to in writing, software
+//    distributed under the License is distributed on an "AS IS" BASIS,
+//    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//    See the License for the specific language governing permissions and
+//    limitations under the License.
+//
+package org.msgpack.value;
+
+/**
+ * The prefix code set of MessagePack format. See also https://github.com/msgpack/msgpack/blob/master/spec.md for details.
+ */
+public final class MessagePackCode
+{
+    private MessagePackCode()
+    {
+        // No construction.
+    }
+
+    public static final boolean isFixInt(byte b)
+    {
+        int v = b & 0xFF;
+        return v <= 0x7f || v >= 0xe0;
+    }
+
+    public static final boolean isPosFixInt(byte b)
+    {
+        return (b & POSFIXINT_MASK) == 0;
+    }
+
+    public static final boolean isNegFixInt(byte b)
+    {
+        return (b & NEGFIXINT_PREFIX) == NEGFIXINT_PREFIX;
+    }
+
+    public static final boolean isFixStr(byte b)
+    {
+        return (b & (byte) 0xe0) == MessagePackCode.FIXSTR_PREFIX;
+    }
+
+    public static final boolean isFixedArray(byte b)
+    {
+        return (b & (byte) 0xf0) == MessagePackCode.FIXARRAY_PREFIX;
+    }
+
+    public static final boolean isFixedMap(byte b)
+    {
+        return (b & (byte) 0xf0) == MessagePackCode.FIXMAP_PREFIX;
+    }
+
+    public static final boolean isFixedRaw(byte b)
+    {
+        return (b & (byte) 0xe0) == MessagePackCode.FIXSTR_PREFIX;
+    }
+
+    public static final byte POSFIXINT_MASK = (byte) 0x80;
+
+    public static final byte FIXMAP_PREFIX = (byte) 0x80;
+    public static final byte FIXARRAY_PREFIX = (byte) 0x90;
+    public static final byte FIXSTR_PREFIX = (byte) 0xa0;
+
+    public static final byte NIL = (byte) 0xc0;
+    public static final byte NEVER_USED = (byte) 0xc1;
+    public static final byte FALSE = (byte) 0xc2;
+    public static final byte TRUE = (byte) 0xc3;
+    public static final byte BIN8 = (byte) 0xc4;
+    public static final byte BIN16 = (byte) 0xc5;
+    public static final byte BIN32 = (byte) 0xc6;
+    public static final byte EXT8 = (byte) 0xc7;
+    public static final byte EXT16 = (byte) 0xc8;
+    public static final byte EXT32 = (byte) 0xc9;
+    public static final byte FLOAT32 = (byte) 0xca;
+    public static final byte FLOAT64 = (byte) 0xcb;
+    public static final byte UINT8 = (byte) 0xcc;
+    public static final byte UINT16 = (byte) 0xcd;
+    public static final byte UINT32 = (byte) 0xce;
+    public static final byte UINT64 = (byte) 0xcf;
+
+    public static final byte INT8 = (byte) 0xd0;
+    public static final byte INT16 = (byte) 0xd1;
+    public static final byte INT32 = (byte) 0xd2;
+    public static final byte INT64 = (byte) 0xd3;
+
+    public static final byte FIXEXT1 = (byte) 0xd4;
+    public static final byte FIXEXT2 = (byte) 0xd5;
+    public static final byte FIXEXT4 = (byte) 0xd6;
+    public static final byte FIXEXT8 = (byte) 0xd7;
+    public static final byte FIXEXT16 = (byte) 0xd8;
+
+    public static final byte STR8 = (byte) 0xd9;
+    public static final byte STR16 = (byte) 0xda;
+    public static final byte STR32 = (byte) 0xdb;
+
+    public static final byte ARRAY16 = (byte) 0xdc;
+    public static final byte ARRAY32 = (byte) 0xdd;
+
+    public static final byte MAP16 = (byte) 0xde;
+    public static final byte MAP32 = (byte) 0xdf;
+
+    public static final byte NEGFIXINT_PREFIX = (byte) 0xe0;
+
+    public static final byte EXT_TIMESTAMP = (byte) -1;
+}

From bdff80d9a9ce134e3a52aff622cb57742f8aa954 Mon Sep 17 00:00:00 2001
From: Dai MIKURUBE <dmikurube@treasure-data.com>
Date: Tue, 18 May 2021 18:57:04 +0900
Subject: [PATCH 4/5] Move MessageFormat, MessageFormatException,
 MessagePackException, MessageTypeException and MessageTypeCastException to
 msgpack-value

---
 .../src/main/java/org/msgpack/core/MessageFormat.java           | 2 --
 .../src/main/java/org/msgpack/core/MessageFormatException.java  | 0
 .../src/main/java/org/msgpack/core/MessagePackException.java    | 0
 .../main/java/org/msgpack/core/MessageTypeCastException.java    | 0
 .../src/main/java/org/msgpack/core/MessageTypeException.java    | 0
 5 files changed, 2 deletions(-)
 rename {msgpack-core => msgpack-value}/src/main/java/org/msgpack/core/MessageFormat.java (98%)
 rename {msgpack-core => msgpack-value}/src/main/java/org/msgpack/core/MessageFormatException.java (100%)
 rename {msgpack-core => msgpack-value}/src/main/java/org/msgpack/core/MessagePackException.java (100%)
 rename {msgpack-core => msgpack-value}/src/main/java/org/msgpack/core/MessageTypeCastException.java (100%)
 rename {msgpack-core => msgpack-value}/src/main/java/org/msgpack/core/MessageTypeException.java (100%)

diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessageFormat.java b/msgpack-value/src/main/java/org/msgpack/core/MessageFormat.java
similarity index 98%
rename from msgpack-core/src/main/java/org/msgpack/core/MessageFormat.java
rename to msgpack-value/src/main/java/org/msgpack/core/MessageFormat.java
index 3c3463323..a28628ec3 100644
--- a/msgpack-core/src/main/java/org/msgpack/core/MessageFormat.java
+++ b/msgpack-value/src/main/java/org/msgpack/core/MessageFormat.java
@@ -15,7 +15,6 @@
 //
 package org.msgpack.core;
 
-import org.msgpack.core.annotations.VisibleForTesting;
 import org.msgpack.value.ValueType;
 import org.msgpack.value.MessagePackCode;
 
@@ -114,7 +113,6 @@ public static MessageFormat valueOf(final byte b)
      * @param b MessageFormat of the given byte
      * @return
      */
-    @VisibleForTesting
     static MessageFormat toMessageFormat(final byte b)
     {
         if (MessagePackCode.isPosFixInt(b)) {
diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessageFormatException.java b/msgpack-value/src/main/java/org/msgpack/core/MessageFormatException.java
similarity index 100%
rename from msgpack-core/src/main/java/org/msgpack/core/MessageFormatException.java
rename to msgpack-value/src/main/java/org/msgpack/core/MessageFormatException.java
diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessagePackException.java b/msgpack-value/src/main/java/org/msgpack/core/MessagePackException.java
similarity index 100%
rename from msgpack-core/src/main/java/org/msgpack/core/MessagePackException.java
rename to msgpack-value/src/main/java/org/msgpack/core/MessagePackException.java
diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessageTypeCastException.java b/msgpack-value/src/main/java/org/msgpack/core/MessageTypeCastException.java
similarity index 100%
rename from msgpack-core/src/main/java/org/msgpack/core/MessageTypeCastException.java
rename to msgpack-value/src/main/java/org/msgpack/core/MessageTypeCastException.java
diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessageTypeException.java b/msgpack-value/src/main/java/org/msgpack/core/MessageTypeException.java
similarity index 100%
rename from msgpack-core/src/main/java/org/msgpack/core/MessageTypeException.java
rename to msgpack-value/src/main/java/org/msgpack/core/MessageTypeException.java

From b6b26c6f407a9edb824cf3e6524d1194ab717179 Mon Sep 17 00:00:00 2001
From: Dai MIKURUBE <dmikurube@treasure-data.com>
Date: Tue, 18 May 2021 18:57:15 +0900
Subject: [PATCH 5/5] Split MessagePacker to abstract in msgpack-value and
 implementation in msgpack-core

---
 .../org/msgpack/core/MessageBufferPacker.java |   2 +-
 .../java/org/msgpack/core/MessagePack.java    |  46 +-
 ...sagePacker.java => MessagePackerImpl.java} |  79 ++--
 .../java/org/msgpack/core/MessagePacker.java  | 428 ++++++++++++++++++
 4 files changed, 504 insertions(+), 51 deletions(-)
 rename msgpack-core/src/main/java/org/msgpack/core/{MessagePacker.java => MessagePackerImpl.java} (95%)
 create mode 100644 msgpack-value/src/main/java/org/msgpack/core/MessagePacker.java

diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessageBufferPacker.java b/msgpack-core/src/main/java/org/msgpack/core/MessageBufferPacker.java
index 71edc21d2..0f050e1f6 100644
--- a/msgpack-core/src/main/java/org/msgpack/core/MessageBufferPacker.java
+++ b/msgpack-core/src/main/java/org/msgpack/core/MessageBufferPacker.java
@@ -30,7 +30,7 @@
  * usually needs to copy contents of the buffer.
  */
 public class MessageBufferPacker
-        extends MessagePacker
+        extends MessagePackerImpl
 {
     protected MessageBufferPacker(MessagePack.PackerConfig config)
     {
diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessagePack.java b/msgpack-core/src/main/java/org/msgpack/core/MessagePack.java
index daaa01036..73f3758cc 100644
--- a/msgpack-core/src/main/java/org/msgpack/core/MessagePack.java
+++ b/msgpack-core/src/main/java/org/msgpack/core/MessagePack.java
@@ -56,9 +56,9 @@
  * <table>
  *   <tr><th>Output type</th><th>Factory method</th><th>Return type</th></tr>
  *   <tr><td>byte[]</td><td>{@link #newDefaultBufferPacker()}</td><td>{@link MessageBufferPacker}</td><tr>
- *   <tr><td>OutputStream</td><td>{@link #newDefaultPacker(OutputStream)}</td><td>{@link MessagePacker}</td></tr>
- *   <tr><td>WritableByteChannel</td><td>{@link #newDefaultPacker(WritableByteChannel)}</td><td>{@link MessagePacker}</td></tr>
- *   <tr><td>{@link org.msgpack.core.buffer.MessageBufferOutput}</td><td>{@link #newDefaultPacker(MessageBufferOutput)}</td><td>{@link MessagePacker}</td></tr>
+ *   <tr><td>OutputStream</td><td>{@link #newDefaultPacker(OutputStream)}</td><td>{@link MessagePackerImpl}</td></tr>
+ *   <tr><td>WritableByteChannel</td><td>{@link #newDefaultPacker(WritableByteChannel)}</td><td>{@link MessagePackerImpl}</td></tr>
+ *   <tr><td>{@link org.msgpack.core.buffer.MessageBufferOutput}</td><td>{@link #newDefaultPacker(MessageBufferOutput)}</td><td>{@link MessagePackerImpl}</td></tr>
  * </table>
  *
  */
@@ -71,7 +71,7 @@ public class MessagePack
     public static final Charset UTF8 = Charset.forName("UTF-8");
 
     /**
-     * Configuration of a {@link MessagePacker} used by {@link #newDefaultPacker(MessageBufferOutput)} and {@link #newDefaultBufferPacker()} methods.
+     * Configuration of a {@link MessagePackerImpl} used by {@link #newDefaultPacker(MessageBufferOutput)} and {@link #newDefaultBufferPacker()} methods.
      */
     public static final PackerConfig DEFAULT_PACKER_CONFIG = new PackerConfig();
 
@@ -181,15 +181,15 @@ private MessagePack()
      * Creates a packer that serializes objects into the specified output.
      * <p>
      * {@link org.msgpack.core.buffer.MessageBufferOutput} is an interface that lets applications customize memory
-     * allocation of internal buffer of {@link MessagePacker}. You may prefer {@link #newDefaultBufferPacker()},
+     * allocation of internal buffer of {@link MessagePackerImpl}. You may prefer {@link #newDefaultBufferPacker()},
      * {@link #newDefaultPacker(OutputStream)}, or {@link #newDefaultPacker(WritableByteChannel)} methods instead.
      * <p>
      * This method is equivalent to <code>DEFAULT_PACKER_CONFIG.newPacker(out)</code>.
      *
      * @param out A MessageBufferOutput that allocates buffer chunks and receives the buffer chunks with packed data filled in them
-     * @return A new MessagePacker instance
+     * @return A new MessagePackerImpl instance
      */
-    public static MessagePacker newDefaultPacker(MessageBufferOutput out)
+    public static MessagePackerImpl newDefaultPacker(MessageBufferOutput out)
     {
         return DEFAULT_PACKER_CONFIG.newPacker(out);
     }
@@ -197,15 +197,15 @@ public static MessagePacker newDefaultPacker(MessageBufferOutput out)
     /**
      * Creates a packer that serializes objects into the specified output stream.
      * <p>
-     * Note that you don't have to wrap OutputStream in BufferedOutputStream because MessagePacker has buffering
+     * Note that you don't have to wrap OutputStream in BufferedOutputStream because MessagePackerImpl has buffering
      * internally.
      * <p>
      * This method is equivalent to <code>DEFAULT_PACKER_CONFIG.newPacker(out)</code>.
      *
      * @param out The output stream that receives sequence of bytes
-     * @return A new MessagePacker instance
+     * @return A new MessagePackerImpl instance
      */
-    public static MessagePacker newDefaultPacker(OutputStream out)
+    public static MessagePackerImpl newDefaultPacker(OutputStream out)
     {
         return DEFAULT_PACKER_CONFIG.newPacker(out);
     }
@@ -216,9 +216,9 @@ public static MessagePacker newDefaultPacker(OutputStream out)
      * This method is equivalent to <code>DEFAULT_PACKER_CONFIG.newPacker(channel)</code>.
      *
      * @param channel The output channel that receives sequence of bytes
-     * @return A new MessagePacker instance
+     * @return A new MessagePackerImpl instance
      */
-    public static MessagePacker newDefaultPacker(WritableByteChannel channel)
+    public static MessagePackerImpl newDefaultPacker(WritableByteChannel channel)
     {
         return DEFAULT_PACKER_CONFIG.newPacker(channel);
     }
@@ -334,7 +334,7 @@ public static MessageUnpacker newDefaultUnpacker(ByteBuffer contents)
     }
 
     /**
-     * MessagePacker configuration.
+     * MessagePackerImpl configuration.
      */
     public static class PackerConfig
             implements Cloneable
@@ -392,26 +392,26 @@ public boolean equals(Object obj)
          * Creates a packer that serializes objects into the specified output.
          * <p>
          * {@link org.msgpack.core.buffer.MessageBufferOutput} is an interface that lets applications customize memory
-         * allocation of internal buffer of {@link MessagePacker}.
+         * allocation of internal buffer of {@link MessagePackerImpl}.
          *
          * @param out A MessageBufferOutput that allocates buffer chunks and receives the buffer chunks with packed data filled in them
-         * @return A new MessagePacker instance
+         * @return A new MessagePackerImpl instance
          */
-        public MessagePacker newPacker(MessageBufferOutput out)
+        public MessagePackerImpl newPacker(MessageBufferOutput out)
         {
-            return new MessagePacker(out, this);
+            return new MessagePackerImpl(out, this);
         }
 
         /**
          * Creates a packer that serializes objects into the specified output stream.
          * <p>
-         * Note that you don't have to wrap OutputStream in BufferedOutputStream because MessagePacker has buffering
+         * Note that you don't have to wrap OutputStream in BufferedOutputStream because MessagePackerImpl has buffering
          * internally.
          *
          * @param out The output stream that receives sequence of bytes
-         * @return A new MessagePacker instance
+         * @return A new MessagePackerImpl instance
          */
-        public MessagePacker newPacker(OutputStream out)
+        public MessagePackerImpl newPacker(OutputStream out)
         {
             return newPacker(new OutputStreamBufferOutput(out, bufferSize));
         }
@@ -420,9 +420,9 @@ public MessagePacker newPacker(OutputStream out)
          * Creates a packer that serializes objects into the specified writable channel.
          *
          * @param channel The output channel that receives sequence of bytes
-         * @return A new MessagePacker instance
+         * @return A new MessagePackerImpl instance
          */
-        public MessagePacker newPacker(WritableByteChannel channel)
+        public MessagePackerImpl newPacker(WritableByteChannel channel)
         {
             return newPacker(new ChannelBufferOutput(channel, bufferSize));
         }
@@ -456,7 +456,7 @@ public int getSmallStringOptimizationThreshold()
         }
 
         /**
-         * When the next payload size exceeds this threshold, MessagePacker will call
+         * When the next payload size exceeds this threshold, MessagePackerImpl will call
          * {@link org.msgpack.core.buffer.MessageBufferOutput#flush()} before writing more data (default: 8192).
          */
         public PackerConfig withBufferFlushThreshold(int bytes)
diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessagePacker.java b/msgpack-core/src/main/java/org/msgpack/core/MessagePackerImpl.java
similarity index 95%
rename from msgpack-core/src/main/java/org/msgpack/core/MessagePacker.java
rename to msgpack-core/src/main/java/org/msgpack/core/MessagePackerImpl.java
index c5f0d186a..213f99b19 100644
--- a/msgpack-core/src/main/java/org/msgpack/core/MessagePacker.java
+++ b/msgpack-core/src/main/java/org/msgpack/core/MessagePackerImpl.java
@@ -132,8 +132,8 @@
  * is written. This is convenient behavior when you use a non-blocking output channel that may not be writable
  * immediately.
  */
-public class MessagePacker
-        implements Closeable, Flushable
+public class MessagePackerImpl
+        extends MessagePacker implements Closeable, Flushable
 {
     private static final boolean CORRUPTED_CHARSET_ENCODER;
 
@@ -201,13 +201,13 @@ public class MessagePacker
     private CharsetEncoder encoder;
 
     /**
-     * Create an MessagePacker that outputs the packed data to the given {@link org.msgpack.core.buffer.MessageBufferOutput}.
+     * Create an MessagePackerImpl that outputs the packed data to the given {@link org.msgpack.core.buffer.MessageBufferOutput}.
      * This method is available for subclasses to override. Use MessagePack.PackerConfig.newPacker method to instantiate this implementation.
      *
      * @param out MessageBufferOutput. Use {@link org.msgpack.core.buffer.OutputStreamBufferOutput}, {@link org.msgpack.core.buffer.ChannelBufferOutput} or
      * your own implementation of {@link org.msgpack.core.buffer.MessageBufferOutput} interface.
      */
-    protected MessagePacker(MessageBufferOutput out, MessagePack.PackerConfig config)
+    protected MessagePackerImpl(MessageBufferOutput out, MessagePack.PackerConfig config)
     {
         this.out = checkNotNull(out, "MessageBufferOutput is null");
         this.smallStringOptimizationThreshold = config.getSmallStringOptimizationThreshold();
@@ -257,6 +257,7 @@ public MessageBufferOutput reset(MessageBufferOutput out)
      * <p>
      * Calling {@link #reset(MessageBufferOutput)} resets this number to 0.
      */
+    @Override
     public long getTotalWrittenBytes()
     {
         return totalFlushBytes + position;
@@ -265,6 +266,7 @@ public long getTotalWrittenBytes()
     /**
      * Clears the written data.
      */
+    @Override
     public void clear()
     {
         position = 0;
@@ -415,7 +417,8 @@ private void writeLong(long v)
      * @return this
      * @throws IOException when underlying output throws IOException
      */
-    public MessagePacker packNil()
+    @Override
+    public MessagePackerImpl packNil()
             throws IOException
     {
         writeByte(NIL);
@@ -430,7 +433,8 @@ public MessagePacker packNil()
      * @return this
      * @throws IOException when underlying output throws IOException
      */
-    public MessagePacker packBoolean(boolean b)
+    @Override
+    public MessagePackerImpl packBoolean(boolean b)
             throws IOException
     {
         writeByte(b ? TRUE : FALSE);
@@ -447,7 +451,8 @@ public MessagePacker packBoolean(boolean b)
      * @return this
      * @throws IOException when underlying output throws IOException
      */
-    public MessagePacker packByte(byte b)
+    @Override
+    public MessagePackerImpl packByte(byte b)
             throws IOException
     {
         if (b < -(1 << 5)) {
@@ -469,7 +474,8 @@ public MessagePacker packByte(byte b)
      * @return this
      * @throws IOException when underlying output throws IOException
      */
-    public MessagePacker packShort(short v)
+    @Override
+    public MessagePackerImpl packShort(short v)
             throws IOException
     {
         if (v < -(1 << 5)) {
@@ -504,7 +510,8 @@ else if (v < (1 << 7)) {
      * @return this
      * @throws IOException when underlying output throws IOException
      */
-    public MessagePacker packInt(int r)
+    @Override
+    public MessagePackerImpl packInt(int r)
             throws IOException
     {
         if (r < -(1 << 5)) {
@@ -546,7 +553,8 @@ else if (r < (1 << 16)) {
      * @return this
      * @throws IOException when underlying output throws IOException
      */
-    public MessagePacker packLong(long v)
+    @Override
+    public MessagePackerImpl packLong(long v)
             throws IOException
     {
         if (v < -(1L << 5)) {
@@ -602,7 +610,8 @@ else if (v < (1 << 7)) {
      * @return this
      * @throws IOException when underlying output throws IOException
      */
-    public MessagePacker packBigInteger(BigInteger bi)
+    @Override
+    public MessagePackerImpl packBigInteger(BigInteger bi)
             throws IOException
     {
         if (bi.bitLength() <= 63) {
@@ -627,7 +636,8 @@ else if (bi.bitLength() == 64 && bi.signum() == 1) {
      * @return this
      * @throws IOException when underlying output throws IOException
      */
-    public MessagePacker packFloat(float v)
+    @Override
+    public MessagePackerImpl packFloat(float v)
             throws IOException
     {
         writeByteAndFloat(FLOAT32, v);
@@ -644,7 +654,8 @@ public MessagePacker packFloat(float v)
      * @return this
      * @throws IOException when underlying output throws IOException
      */
-    public MessagePacker packDouble(double v)
+    @Override
+    public MessagePackerImpl packDouble(double v)
             throws IOException
     {
         writeByteAndDouble(FLOAT64, v);
@@ -721,7 +732,8 @@ private int encodeStringToBufferAt(int pos, String s)
      * @return this
      * @throws IOException when underlying output throws IOException
      */
-    public MessagePacker packString(String s)
+    @Override
+    public MessagePackerImpl packString(String s)
             throws IOException
     {
         if (s.length() <= 0) {
@@ -810,7 +822,8 @@ else if (s.length() < (1 << 16)) {
      * @return this packer
      * @throws IOException when underlying output throws IOException
      */
-    public MessagePacker packTimestamp(Instant instant)
+    @Override
+    public MessagePackerImpl packTimestamp(Instant instant)
             throws IOException
     {
         return packTimestamp(instant.getEpochSecond(), instant.getNano());
@@ -822,7 +835,8 @@ public MessagePacker packTimestamp(Instant instant)
      * @return this packer
      * @throws IOException when underlying output throws IOException
      */
-    public MessagePacker packTimestamp(long millis)
+    @Override
+    public MessagePackerImpl packTimestamp(long millis)
             throws IOException
     {
         return packTimestamp(Instant.ofEpochMilli(millis));
@@ -842,7 +856,8 @@ public MessagePacker packTimestamp(long millis)
      * @throws IOException when underlying output throws IOException
      * @throws ArithmeticException when epochSecond plus nanoAdjustment in seconds exceeds the range of long
      */
-    public MessagePacker packTimestamp(long epochSecond, int nanoAdjustment)
+    @Override
+    public MessagePackerImpl packTimestamp(long epochSecond, int nanoAdjustment)
             throws IOException, ArithmeticException
     {
         long sec = Math.addExact(epochSecond, Math.floorDiv(nanoAdjustment, NANOS_PER_SECOND));
@@ -916,7 +931,8 @@ private void writeTimestamp96(long sec, int nsec)
      * @return this
      * @throws IOException when underlying output throws IOException
      */
-    public MessagePacker packArrayHeader(int arraySize)
+    @Override
+    public MessagePackerImpl packArrayHeader(int arraySize)
             throws IOException
     {
         if (arraySize < 0) {
@@ -947,7 +963,8 @@ else if (arraySize < (1 << 16)) {
      * @return this
      * @throws IOException when underlying output throws IOException
      */
-    public MessagePacker packMapHeader(int mapSize)
+    @Override
+    public MessagePackerImpl packMapHeader(int mapSize)
             throws IOException
     {
         if (mapSize < 0) {
@@ -973,7 +990,8 @@ else if (mapSize < (1 << 16)) {
      * @return this
      * @throws IOException when underlying output throws IOException
      */
-    public MessagePacker packValue(Value v)
+    @Override
+    public MessagePackerImpl packValue(Value v)
             throws IOException
     {
         v.writeTo(this);
@@ -990,7 +1008,8 @@ public MessagePacker packValue(Value v)
      * @return this
      * @throws IOException when underlying output throws IOException
      */
-    public MessagePacker packExtensionTypeHeader(byte extType, int payloadLen)
+    @Override
+    public MessagePackerImpl packExtensionTypeHeader(byte extType, int payloadLen)
             throws IOException
     {
         if (payloadLen < (1 << 8)) {
@@ -1042,7 +1061,8 @@ else if (payloadLen < (1 << 16)) {
      * @return this
      * @throws IOException when underlying output throws IOException
      */
-    public MessagePacker packBinaryHeader(int len)
+    @Override
+    public MessagePackerImpl packBinaryHeader(int len)
             throws IOException
     {
         if (len < (1 << 8)) {
@@ -1069,7 +1089,8 @@ else if (len < (1 << 16)) {
      * @return this
      * @throws IOException when underlying output throws IOException
      */
-    public MessagePacker packRawStringHeader(int len)
+    @Override
+    public MessagePackerImpl packRawStringHeader(int len)
             throws IOException
     {
         if (len < (1 << 5)) {
@@ -1096,7 +1117,8 @@ else if (len < (1 << 16)) {
      * @return this
      * @throws IOException when underlying output throws IOException
      */
-    public MessagePacker writePayload(byte[] src)
+    @Override
+    public MessagePackerImpl writePayload(byte[] src)
             throws IOException
     {
         return writePayload(src, 0, src.length);
@@ -1113,7 +1135,8 @@ public MessagePacker writePayload(byte[] src)
      * @return this
      * @throws IOException when underlying output throws IOException
      */
-    public MessagePacker writePayload(byte[] src, int off, int len)
+    @Override
+    public MessagePackerImpl writePayload(byte[] src, int off, int len)
             throws IOException
     {
         if (buffer == null || buffer.size() - position < len || len > bufferFlushThreshold) {
@@ -1144,7 +1167,8 @@ public MessagePacker writePayload(byte[] src, int off, int len)
      * @throws IOException when underlying output throws IOException
      * @see #writePayload(byte[])
      */
-    public MessagePacker addPayload(byte[] src)
+    @Override
+    public MessagePackerImpl addPayload(byte[] src)
             throws IOException
     {
         return addPayload(src, 0, src.length);
@@ -1167,7 +1191,8 @@ public MessagePacker addPayload(byte[] src)
      * @throws IOException when underlying output throws IOException
      * @see #writePayload(byte[], int, int)
      */
-    public MessagePacker addPayload(byte[] src, int off, int len)
+    @Override
+    public MessagePackerImpl addPayload(byte[] src, int off, int len)
             throws IOException
     {
         if (buffer == null || buffer.size() - position < len || len > bufferFlushThreshold) {
diff --git a/msgpack-value/src/main/java/org/msgpack/core/MessagePacker.java b/msgpack-value/src/main/java/org/msgpack/core/MessagePacker.java
new file mode 100644
index 000000000..780f50687
--- /dev/null
+++ b/msgpack-value/src/main/java/org/msgpack/core/MessagePacker.java
@@ -0,0 +1,428 @@
+//
+// MessagePack for Java
+//
+//    Licensed under the Apache License, Version 2.0 (the "License");
+//    you may not use this file except in compliance with the License.
+//    You may obtain a copy of the License at
+//
+//        http://www.apache.org/licenses/LICENSE-2.0
+//
+//    Unless required by applicable law or agreed to in writing, software
+//    distributed under the License is distributed on an "AS IS" BASIS,
+//    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//    See the License for the specific language governing permissions and
+//    limitations under the License.
+//
+package org.msgpack.core;
+
+import org.msgpack.value.Value;
+
+import java.io.Closeable;
+import java.io.Flushable;
+import java.io.IOException;
+import java.math.BigInteger;
+import java.time.Instant;
+
+/**
+ * MessagePack serializer that converts objects into binary.
+ * You can use factory methods of {@link MessagePack} class or {@link MessagePack.PackerConfig} class to create
+ * an instance.
+ * <p>
+ * This class provides following primitive methods to write MessagePack values. These primitive methods write
+ * short bytes (1 to 7 bytes) to the internal buffer at once. There are also some utility methods for convenience.
+ * <p>
+ * Primitive methods:
+ *
+ * <table>
+ *   <tr><th>Java type</th><th>Packer method</th><th>MessagePack type</th></tr>
+ *   <tr><td>null</td><td>{@link #packNil()}</td><td>Nil</td></tr>
+ *   <tr><td>boolean</td><td>{@link #packBoolean(boolean)}</td><td>Boolean</td></tr>
+ *   <tr><td>byte</td><td>{@link #packByte(byte)}</td><td>Integer</td></tr>
+ *   <tr><td>short</td><td>{@link #packShort(short)}</td><td>Integer</td></tr>
+ *   <tr><td>int</td><td>{@link #packInt(int)}</td><td>Integer</td></tr>
+ *   <tr><td>long</td><td>{@link #packLong(long)}</td><td>Integer</td></tr>
+ *   <tr><td>BigInteger</td><td>{@link #packBigInteger(BigInteger)}</td><td>Integer</td></tr>
+ *   <tr><td>float</td><td>{@link #packFloat(float)}</td><td>Float</td></tr>
+ *   <tr><td>double</td><td>{@link #packDouble(double)}</td><td>Float</td></tr>
+ *   <tr><td>byte[]</td><td>{@link #packBinaryHeader(int)}</td><td>Binary</td></tr>
+ *   <tr><td>String</td><td>{@link #packRawStringHeader(int)}</td><td>String</td></tr>
+ *   <tr><td>List</td><td>{@link #packArrayHeader(int)}</td><td>Array</td></tr>
+ *   <tr><td>Map</td><td>{@link #packMapHeader(int)}</td><td>Map</td></tr>
+ *   <tr><td>custom user type</td><td>{@link #packExtensionTypeHeader(byte, int)}</td><td>Extension</td></tr>
+ * </table>
+ *
+ * <p>
+ * Utility methods:
+ *
+ * <table>
+ *   <tr><th>Java type</th><th>Packer method</th><th>MessagePack type</th></tr>
+ *   <tr><td>String</td><td>{@link #packString(String)}</td><td>String</td></tr>
+ *   <tr><td>{@link Value}</td><td>{@link #packValue(Value)}</td><td></td></tr>
+ * </table>
+ *
+ * <p>
+ * To write a byte array, first you call {@link #packBinaryHeader} method with length of the byte array. Then,
+ * you call {@link #writePayload(byte[], int, int)} or {@link #addPayload(byte[], int, int)} method to write the
+ * contents.
+ *
+ * <p>
+ * To write a List, Collection or array, first you call {@link #packArrayHeader(int)} method with the number of
+ * elements. Then, you call packer methods for each element.
+ * iteration.
+ *
+ * <p>
+ * To write a Map, first you call {@link #packMapHeader(int)} method with size of the map. Then, for each pair,
+ * you call packer methods for key first, and then value. You will call packer methods twice as many time as the
+ * size of the map.
+ *
+ * <p>
+ * Note that packXxxHeader methods don't validate number of elements. You must call packer methods for correct
+ * number of times to produce valid MessagePack data.
+ *
+ * <p>
+ * When IOException is thrown, primitive methods guarantee that all data is written to the internal buffer or no data
+ * is written. This is convenient behavior when you use a non-blocking output channel that may not be writable
+ * immediately.
+ *
+ * <p>{@code MessageBufferOutput reset(MessageBufferOutput out)} has incompatibly gone.
+ */
+public abstract class MessagePacker
+        implements Closeable, Flushable
+{
+    /**
+     * Returns total number of written bytes.
+     * <p>
+     * This method returns total of amount of data flushed to the underlying output plus size of current
+     * internal buffer.
+     */
+    public abstract long getTotalWrittenBytes();
+
+    /**
+     * Clears the written data.
+     */
+    public abstract void clear();
+
+    /**
+     * Flushes internal buffer to the underlying output.
+     * <p>
+     * This method also calls flush method of the underlying output after writing internal buffer.
+     */
+    @Override
+    public abstract void flush()
+            throws IOException;
+
+    /**
+     * Closes underlying output.
+     * <p>
+     * This method flushes internal buffer before closing.
+     */
+    @Override
+    public abstract void close()
+            throws IOException;
+
+    /**
+     * Writes a Nil value.
+     *
+     * This method writes a nil byte.
+     *
+     * @return this
+     * @throws IOException when underlying output throws IOException
+     */
+    public abstract MessagePacker packNil()
+            throws IOException;
+
+    /**
+     * Writes a Boolean value.
+     *
+     * This method writes a true byte or a false byte.
+     *
+     * @return this
+     * @throws IOException when underlying output throws IOException
+     */
+    public abstract MessagePacker packBoolean(boolean b)
+            throws IOException;
+
+    /**
+     * Writes an Integer value.
+     *
+     * <p>
+     * This method writes an integer using the smallest format from the int format family.
+     *
+     * @param b the integer to be written
+     * @return this
+     * @throws IOException when underlying output throws IOException
+     */
+    public abstract MessagePacker packByte(byte b)
+            throws IOException;
+
+    /**
+     * Writes an Integer value.
+     *
+     * <p>
+     * This method writes an integer using the smallest format from the int format family.
+     *
+     * @param v the integer to be written
+     * @return this
+     * @throws IOException when underlying output throws IOException
+     */
+    public abstract MessagePacker packShort(short v)
+            throws IOException;
+
+    /**
+     * Writes an Integer value.
+     *
+     * <p>
+     * This method writes an integer using the smallest format from the int format family.
+     *
+     * @param r the integer to be written
+     * @return this
+     * @throws IOException when underlying output throws IOException
+     */
+    public abstract MessagePacker packInt(int r)
+            throws IOException;
+
+    /**
+     * Writes an Integer value.
+     *
+     * <p>
+     * This method writes an integer using the smallest format from the int format family.
+     *
+     * @param v the integer to be written
+     * @return this
+     * @throws IOException when underlying output throws IOException
+     */
+    public abstract MessagePacker packLong(long v)
+            throws IOException;
+
+    /**
+     * Writes an Integer value.
+     *
+     * <p>
+     * This method writes an integer using the smallest format from the int format family.
+     *
+     * @param bi the integer to be written
+     * @return this
+     * @throws IOException when underlying output throws IOException
+     */
+    public abstract MessagePacker packBigInteger(BigInteger bi)
+            throws IOException;
+
+    /**
+     * Writes a Float value.
+     *
+     * <p>
+     * This method writes a float value using float format family.
+     *
+     * @param v the value to be written
+     * @return this
+     * @throws IOException when underlying output throws IOException
+     */
+    public abstract MessagePacker packFloat(float v)
+            throws IOException;
+
+    /**
+     * Writes a Float value.
+     *
+     * <p>
+     * This method writes a float value using float format family.
+     *
+     * @param v the value to be written
+     * @return this
+     * @throws IOException when underlying output throws IOException
+     */
+    public abstract MessagePacker packDouble(double v)
+            throws IOException;
+
+    /**
+     * Writes a String vlaue in UTF-8 encoding.
+     *
+     * <p>
+     * This method writes a UTF-8 string using the smallest format from the str format family by default. If {@link MessagePack.PackerConfig#withStr8FormatSupport(boolean)} is set to false, smallest format from the str format family excepting str8 format.
+     *
+     * @param s the string to be written
+     * @return this
+     * @throws IOException when underlying output throws IOException
+     */
+    public abstract MessagePacker packString(String s)
+            throws IOException;
+
+    /**
+     * Writes a Timestamp value.
+     *
+     * <p>
+     * This method writes a timestamp value using timestamp format family.
+     *
+     * @param instant the timestamp to be written
+     * @return this packer
+     * @throws IOException when underlying output throws IOException
+     */
+    public abstract MessagePacker packTimestamp(Instant instant)
+            throws IOException;
+
+    /**
+     * Writes a Timesamp value using a millisecond value (e.g., System.currentTimeMillis())
+     * @param millis the millisecond value
+     * @return this packer
+     * @throws IOException when underlying output throws IOException
+     */
+    public abstract MessagePacker packTimestamp(long millis)
+            throws IOException;
+
+    /**
+     * Writes a Timestamp value.
+     *
+     * <p>
+     * This method writes a timestamp value using timestamp format family.
+     *
+     * @param epochSecond the number of seconds from 1970-01-01T00:00:00Z
+     * @param nanoAdjustment the nanosecond adjustment to the number of seconds, positive or negative
+     * @return this
+     * @throws IOException when underlying output throws IOException
+     * @throws ArithmeticException when epochSecond plus nanoAdjustment in seconds exceeds the range of long
+     */
+    public abstract MessagePacker packTimestamp(long epochSecond, int nanoAdjustment)
+            throws IOException, ArithmeticException;
+
+    /**
+     * Writes header of an Array value.
+     * <p>
+     * You will call other packer methods for each element after this method call.
+     * <p>
+     * You don't have to call anything at the end of iteration.
+     *
+     * @param arraySize number of elements to be written
+     * @return this
+     * @throws IOException when underlying output throws IOException
+     */
+    public abstract MessagePacker packArrayHeader(int arraySize)
+            throws IOException;
+
+    /**
+     * Writes header of a Map value.
+     * <p>
+     * After this method call, for each key-value pair, you will call packer methods for key first, and then value.
+     * You will call packer methods twice as many time as the size of the map.
+     * <p>
+     * You don't have to call anything at the end of iteration.
+     *
+     * @param mapSize number of pairs to be written
+     * @return this
+     * @throws IOException when underlying output throws IOException
+     */
+    public abstract MessagePacker packMapHeader(int mapSize)
+            throws IOException;
+
+    /**
+     * Writes a dynamically typed value.
+     *
+     * @param v the value to be written
+     * @return this
+     * @throws IOException when underlying output throws IOException
+     */
+    public abstract MessagePacker packValue(Value v)
+            throws IOException;
+
+    /**
+     * Writes header of an Extension value.
+     * <p>
+     * You MUST call {@link #writePayload(byte[])} or {@link #addPayload(byte[])} method to write body binary.
+     *
+     * @param extType the extension type tag to be written
+     * @param payloadLen number of bytes of a payload binary to be written
+     * @return this
+     * @throws IOException when underlying output throws IOException
+     */
+    public abstract MessagePacker packExtensionTypeHeader(byte extType, int payloadLen)
+            throws IOException;
+
+    /**
+     * Writes header of a Binary value.
+     * <p>
+     * You MUST call {@link #writePayload(byte[])} or {@link #addPayload(byte[])} method to write body binary.
+     *
+     * @param len number of bytes of a binary to be written
+     * @return this
+     * @throws IOException when underlying output throws IOException
+     */
+    public abstract MessagePacker packBinaryHeader(int len)
+            throws IOException;
+
+    /**
+     * Writes header of a String value.
+     * <p>
+     * Length must be number of bytes of a string in UTF-8 encoding.
+     * <p>
+     * You MUST call {@link #writePayload(byte[])} or {@link #addPayload(byte[])} method to write body of the
+     * UTF-8 encoded string.
+     *
+     * @param len number of bytes of a UTF-8 string to be written
+     * @return this
+     * @throws IOException when underlying output throws IOException
+     */
+    public abstract MessagePacker packRawStringHeader(int len)
+            throws IOException;
+
+    /**
+     * Writes a byte array to the output.
+     * <p>
+     * This method is used with {@link #packRawStringHeader(int)} or {@link #packBinaryHeader(int)} methods.
+     *
+     * @param src the data to add
+     * @return this
+     * @throws IOException when underlying output throws IOException
+     */
+    public abstract MessagePacker writePayload(byte[] src)
+            throws IOException;
+
+    /**
+     * Writes a byte array to the output.
+     * <p>
+     * This method is used with {@link #packRawStringHeader(int)} or {@link #packBinaryHeader(int)} methods.
+     *
+     * @param src the data to add
+     * @param off the start offset in the data
+     * @param len the number of bytes to add
+     * @return this
+     * @throws IOException when underlying output throws IOException
+     */
+    public abstract MessagePacker writePayload(byte[] src, int off, int len)
+            throws IOException;
+
+    /**
+     * Writes a byte array to the output.
+     * <p>
+     * This method is used with {@link #packRawStringHeader(int)} or {@link #packBinaryHeader(int)} methods.
+     * <p>
+     * Unlike {@link #writePayload(byte[])} method, this method does not make a defensive copy of the given byte
+     * array, even if it is shorter than {@link MessagePack.PackerConfig#withBufferFlushThreshold(int)}. This is
+     * faster than {@link #writePayload(byte[])} method but caller must not modify the byte array after calling
+     * this method.
+     *
+     * @param src the data to add
+     * @return this
+     * @throws IOException when underlying output throws IOException
+     * @see #writePayload(byte[])
+     */
+    public abstract MessagePacker addPayload(byte[] src)
+            throws IOException;
+
+    /**
+     * Writes a byte array to the output.
+     * <p>
+     * This method is used with {@link #packRawStringHeader(int)} or {@link #packBinaryHeader(int)} methods.
+     * <p>
+     * Unlike {@link #writePayload(byte[], int, int)} method, this method does not make a defensive copy of the
+     * given byte array, even if it is shorter than {@link MessagePack.PackerConfig#withBufferFlushThreshold(int)}.
+     * This is faster than {@link #writePayload(byte[])} method but caller must not modify the byte array after
+     * calling this method.
+     *
+     * @param src the data to add
+     * @param off the start offset in the data
+     * @param len the number of bytes to add
+     * @return this
+     * @throws IOException when underlying output throws IOException
+     * @see #writePayload(byte[], int, int)
+     */
+    public abstract MessagePacker addPayload(byte[] src, int off, int len)
+            throws IOException;
+}