public void testMergeIncompatibleTypes() throws IOException {
    Directory dir = newDirectory();
    IndexWriterConfig writerConfig =
        newIndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(random()));
    writerConfig.setMergePolicy(
        NoMergePolicy.NO_COMPOUND_FILES); // no merges until we are done with adding values
    IndexWriter writer = new IndexWriter(dir, writerConfig);
    int num_1 = atLeast(200);
    int num_2 = atLeast(200);
    long[] values = new long[num_1 + num_2];
    index(writer, randomValueType(INTEGERS, random()), values, 0, num_1);
    writer.commit();

    if (random().nextInt(4) == 0) {
      // once in a while use addIndexes
      Directory dir_2 = newDirectory();
      IndexWriter writer_2 =
          new IndexWriter(
              dir_2, newIndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(random())));
      index(
          writer_2,
          randomValueType(random().nextBoolean() ? UNSORTED_BYTES : SORTED_BYTES, random()),
          values,
          num_1,
          num_2);
      writer_2.commit();
      writer_2.close();
      if (random().nextBoolean()) {
        writer.addIndexes(dir_2);
      } else {
        // do a real merge here
        IndexReader open = IndexReader.open(dir_2);
        writer.addIndexes(open);
        open.close();
      }
      dir_2.close();
    } else {
      index(
          writer,
          randomValueType(random().nextBoolean() ? UNSORTED_BYTES : SORTED_BYTES, random()),
          values,
          num_1,
          num_2);
      writer.commit();
    }
    writer.close();
    writerConfig = newIndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(random()));
    if (writerConfig.getMergePolicy() instanceof NoMergePolicy) {
      writerConfig.setMergePolicy(
          newLogMergePolicy()); // make sure we merge to one segment (merge everything together)
    }
    writer = new IndexWriter(dir, writerConfig);
    // now merge
    writer.forceMerge(1);
    writer.close();
    DirectoryReader reader = DirectoryReader.open(dir);
    assertEquals(1, reader.getSequentialSubReaders().length);
    IndexReaderContext topReaderContext = reader.getTopReaderContext();
    AtomicReaderContext[] children = topReaderContext.leaves();
    DocValues docValues = children[0].reader().docValues("promote");
    assertNotNull(docValues);
    assertValues(TestType.Byte, dir, values);
    assertEquals(Type.BYTES_VAR_STRAIGHT, docValues.getType());
    reader.close();
    dir.close();
  }
  private void assertValues(TestType type, Directory dir, long[] values)
      throws CorruptIndexException, IOException {
    DirectoryReader reader = DirectoryReader.open(dir);
    assertEquals(1, reader.getSequentialSubReaders().length);
    IndexReaderContext topReaderContext = reader.getTopReaderContext();
    AtomicReaderContext[] children = topReaderContext.leaves();
    assertEquals(1, children.length);
    DocValues docValues = children[0].reader().docValues("promote");
    Source directSource = docValues.getDirectSource();
    for (int i = 0; i < values.length; i++) {
      int id = Integer.parseInt(reader.document(i).get("id"));
      String msg = "id: " + id + " doc: " + i;
      switch (type) {
        case Byte:
          BytesRef bytes = directSource.getBytes(i, new BytesRef());
          long value = 0;
          switch (bytes.length) {
            case 1:
              value = bytes.bytes[bytes.offset];
              break;
            case 2:
              value =
                  ((bytes.bytes[bytes.offset] & 0xFF) << 8)
                      | (bytes.bytes[bytes.offset + 1] & 0xFF);
              break;
            case 4:
              value =
                  ((bytes.bytes[bytes.offset] & 0xFF) << 24)
                      | ((bytes.bytes[bytes.offset + 1] & 0xFF) << 16)
                      | ((bytes.bytes[bytes.offset + 2] & 0xFF) << 8)
                      | (bytes.bytes[bytes.offset + 3] & 0xFF);
              break;
            case 8:
              value =
                  (((long) (bytes.bytes[bytes.offset] & 0xff) << 56)
                      | ((long) (bytes.bytes[bytes.offset + 1] & 0xff) << 48)
                      | ((long) (bytes.bytes[bytes.offset + 2] & 0xff) << 40)
                      | ((long) (bytes.bytes[bytes.offset + 3] & 0xff) << 32)
                      | ((long) (bytes.bytes[bytes.offset + 4] & 0xff) << 24)
                      | ((long) (bytes.bytes[bytes.offset + 5] & 0xff) << 16)
                      | ((long) (bytes.bytes[bytes.offset + 6] & 0xff) << 8)
                      | ((long) (bytes.bytes[bytes.offset + 7] & 0xff)));
              break;

            default:
              fail(msg + " bytessize: " + bytes.length);
          }

          assertEquals(msg + " byteSize: " + bytes.length, values[id], value);
          break;
        case Float:
          assertEquals(msg, values[id], Double.doubleToRawLongBits(directSource.getFloat(i)));
          break;
        case Int:
          assertEquals(msg, values[id], directSource.getInt(i));
          break;
        default:
          break;
      }
    }
    docValues.close();
    reader.close();
  }