diff --git a/.clang-format b/.clang-format
deleted file mode 100644
index 06453df..0000000
--- a/.clang-format
+++ /dev/null
@@ -1,20 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you 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.
----
-BasedOnStyle:  Google
-DerivePointerAlignment: false
-ColumnLimit: 90
diff --git a/.clang-tidy b/.clang-tidy
deleted file mode 100644
index bae34bc..0000000
--- a/.clang-tidy
+++ /dev/null
@@ -1,30 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you 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.
-
----
-Checks:          'clang-diagnostic-*,clang-analyzer-*,-clang-analyzer-alpha*,google-.*,modernize-.*,readablity-.*'
-HeaderFilterRegex: 'parquet/.*'
-AnalyzeTemporaryDtors: true
-CheckOptions:
-  - key:             google-readability-braces-around-statements.ShortStatementLines
-    value:           '1'
-  - key:             google-readability-function-size.StatementThreshold
-    value:           '800'
-  - key:             google-readability-namespace-comments.ShortNamespaceLines
-    value:           '10'
-  - key:             google-readability-namespace-comments.SpacesBeforeComments
-    value:           '2'
diff --git a/.clang-tidy-ignore b/.clang-tidy-ignore
deleted file mode 100644
index 8b13789..0000000
--- a/.clang-tidy-ignore
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/.parquetcppversion b/.parquetcppversion
deleted file mode 100644
index f825f7c..0000000
--- a/.parquetcppversion
+++ /dev/null
@@ -1 +0,0 @@
-1.5.1-SNAPSHOT
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index e1faf68..0000000
--- a/.travis.yml
+++ /dev/null
@@ -1,108 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you 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.
-
-sudo: required
-dist: trusty
-
-language: cpp
-
-cache:
-  ccache: true
-
-addons:
-  apt:
-    sources:
-    - ubuntu-toolchain-r-test
-    packages:
-    - gcc-4.9
-    - g++-4.9
-    - valgrind
-    - libboost-dev
-    - libboost-filesystem-dev
-    - libboost-regex-dev
-    - libboost-system-dev
-    - libboost-program-options-dev
-    - libboost-test-dev
-    - libssl-dev
-    - libtool
-    - bison
-    - flex
-    - pkg-config
-
-matrix:
-  fast_finish: true
-  include:
-  - compiler: gcc
-    os: linux
-    before_script:
-    - export PARQUET_CXXFLAGS="-DARROW_NO_DEPRECATED_API"
-    - export PARQUET_TRAVIS_VALGRIND=1
-    - source $TRAVIS_BUILD_DIR/ci/before_script_travis.sh
-  - compiler: clang
-    os: linux
-    before_script:
-    - export PARQUET_CXXFLAGS="-DARROW_NO_DEPRECATED_API"
-    - source $TRAVIS_BUILD_DIR/ci/before_script_travis.sh
-  - compiler: clang
-    os: osx
-    osx_image: xcode6.4
-    addons:
-    before_script:
-    - export PARQUET_CXXFLAGS="-DARROW_NO_DEPRECATED_API"
-    - source $TRAVIS_BUILD_DIR/ci/before_script_travis.sh
-    before_install:
-    - mkdir $TRAVIS_BUILD_DIR/parquet-build
-    - pushd $TRAVIS_BUILD_DIR/parquet-build
-  - compiler: gcc
-    os: linux
-    env: PARQUET_BUILD_GROUP=toolchain
-    before_script:
-    script:
-    - export PARQUET_CXXFLAGS="-DARROW_NO_DEPRECATED_API"
-    - $TRAVIS_BUILD_DIR/ci/travis_script_static.sh
-  - compiler: gcc
-    os: linux
-    env: PARQUET_BUILD_GROUP=toolchain
-    before_script:
-    script:
-    - $TRAVIS_BUILD_DIR/ci/travis_script_toolchain.sh
-
-# PARQUET-626: revisit llvm toolchain when/if llvm.org apt repo resurfaces
-
-# before_install:
-# - wget -O - http://llvm.org/apt/llvm-snapshot.gpg.key|sudo apt-key add -
-# - sudo apt-get install -y software-properties-common
-# - sudo add-apt-repository -y ppa:george-edison55/cmake-3.x
-# - sudo apt-add-repository -y "deb http://llvm.org/apt/trusty/ llvm-toolchain-trusty-3.7
-#   main"
-# - sudo apt-add-repository -y "deb http://llvm.org/apt/trusty/ llvm-toolchain-trusty-3.8
-#   main"
-# - sudo apt-get update
-# - sudo apt-get install -y clang-tidy-3.7 clang-format-3.7 cmake
-# - mkdir $TRAVIS_BUILD_DIR/parquet-build
-# - pushd $TRAVIS_BUILD_DIR/parquet-build
-
-before_install:
-- mkdir $TRAVIS_BUILD_DIR/parquet-build
-- pushd $TRAVIS_BUILD_DIR/parquet-build
-
-script:
-- $TRAVIS_BUILD_DIR/ci/travis_script_cpp.sh
-
-env:
-  global:
-  - secure: "sGGfe2N9i2dItR0FryQYZDdzdi9gl6QFXxGWxxXWfPz+mideJWaMLSA17dsWkbrag5GlAcs+8BRGWWagAXicPlOqD1tKKJqZxA4PEPDECny26Sh/pebZvmvnAV5136sXkKXMQkcTfoo3v22zYdVthVa+8EQTXKxGzhbL61AosSk="
diff --git a/CHANGELOG b/CHANGELOG
deleted file mode 100644
index 4673741..0000000
--- a/CHANGELOG
+++ /dev/null
@@ -1,503 +0,0 @@
-Parquet C++ 1.5.0
---------------------------------------------------------------------------------
-## Bug
-    * [PARQUET-979] - [C++] Limit size of min, max or disable stats for long binary types
-    * [PARQUET-1071] - [C++] parquet::arrow::FileWriter::Close is not idempotent
-    * [PARQUET-1349] - [C++] PARQUET_RPATH_ORIGIN is not picked by the build
-    * [PARQUET-1334] - [C++] memory_map parameter seems missleading in parquet file opener
-    * [PARQUET-1333] - [C++] Reading of files with dictionary size 0 fails on Windows with bad_alloc
-    * [PARQUET-1283] - [C++] FormatStatValue appends trailing space to string and int96
-    * [PARQUET-1270] - [C++] Executable tools do not get installed
-    * [PARQUET-1272] - [C++] ScanFileContents reports wrong row count for nested columns
-    * [PARQUET-1268] - [C++] Conversion of Arrow null list columns fails
-    * [PARQUET-1255] - [C++] Exceptions thrown in some tests
-    * [PARQUET-1358] - [C++] index_page_offset should be unset as it is not supported.
-    * [PARQUET-1357] - [C++] FormatStatValue truncates binary statistics on zero character
-    * [PARQUET-1319] - [C++] Pass BISON_EXECUTABLE to Thrift EP for MacOS
-    * [PARQUET-1313] - [C++] Compilation failure with VS2017
-    * [PARQUET-1315] - [C++] ColumnChunkMetaData.has_dictionary_page() should return bool, not int64_t
-    * [PARQUET-1307] - [C++] memory-test fails with latest Arrow
-    * [PARQUET-1274] - [Python] SegFault in pyarrow.parquet.write_table with specific options
-    * [PARQUET-1209] - locally defined symbol ... imported in function ..
-    * [PARQUET-1245] - [C++] Segfault when writing Arrow table with duplicate columns
-    * [PARQUET-1273] - [Python] Error writing to partitioned Parquet dataset
-    * [PARQUET-1384] - [C++] Clang compiler warnings in bloom_filter-test.cc
-
-## Improvement
-    * [PARQUET-1348] - [C++] Allow Arrow FileWriter To Write FileMetaData
-    * [PARQUET-1346] - [C++] Protect against null values data in empty Arrow array
-    * [PARQUET-1340] - [C++] Fix Travis Ci valgrind errors related to std::random_device
-    * [PARQUET-1323] - [C++] Fix compiler warnings with clang-6.0
-    * [PARQUET-1279] - Use ASSERT_NO_FATAIL_FAILURE in C++ unit tests
-    * [PARQUET-1262] - [C++] Use the same BOOST_ROOT and Boost_NAMESPACE for Thrift 
-    * [PARQUET-1267] - replace "unsafe" std::equal by std::memcmp
-    * [PARQUET-1360] - [C++] Minor API + style changes follow up to PARQUET-1348
-    * [PARQUET-1166] - [API Proposal] Add GetRecordBatchReader in parquet/arrow/reader.h
-    * [PARQUET-1378] - [c++] Allow RowGroups with zero rows to be written
-    * [PARQUET-1256] - [C++] Add --print-key-value-metadata option to parquet_reader tool
-    * [PARQUET-1276] - [C++] Reduce the amount of memory used for writing null decimal values
-
-## New Feature
-    * [PARQUET-1392] - [C++] Supply row group indices to parquet::arrow::FileReader::ReadTable
-
-## Sub-task
-    * [PARQUET-1227] - Thrift crypto metadata structures
-    * [PARQUET-1332] - [C++] Add bloom filter utility class
-
-## Task
-    * [PARQUET-1350] - [C++] Use abstract ResizableBuffer instead of concrete PoolBuffer
-    * [PARQUET-1366] - [C++] Streamline use of Arrow bit-util.h
-    * [PARQUET-1308] - [C++] parquet::arrow should use thread pool, not ParallelFor
-    * [PARQUET-1382] - [C++] Prepare for arrow::test namespace removal
-    * [PARQUET-1372] - [C++] Add an API to allow writing RowGroups based on their size rather than num_rows
-
-
-Parquet C++ 1.4.0
---------------------------------------------------------------------------------
-## Bug
-    * [PARQUET-1193] - [CPP] Implement ColumnOrder to support min_value and max_value
-    * [PARQUET-1180] - C++: Fix behaviour of num_children element of primitive nodes
-    * [PARQUET-1146] - C++: Add macOS-compatible sha512sum call to release verify script
-    * [PARQUET-1167] - [C++] FieldToNode function should return a status when throwing an exception
-    * [PARQUET-1175] - [C++] Fix usage of deprecated Arrow API
-    * [PARQUET-1113] - [C++] Incorporate fix from ARROW-1601 on bitmap read path
-    * [PARQUET-1111] - dev/release/verify-release-candidate has stale help
-    * [PARQUET-1109] - C++: Update release verification script to SHA512
-    * [PARQUET-1179] - [C++] Support Apache Thrift 0.11
-    * [PARQUET-1226] - [C++] Fix new build warnings with clang 5.0
-    * [PARQUET-1233] - [CPP ]Enable option to switch between stl classes and boost classes for thrift header
-    * [PARQUET-1205] - Fix msvc static build
-    * [PARQUET-1210] - [C++] Boost 1.66 compilation fails on Windows on linkage stage
-
-## Improvement
-    * [PARQUET-1092] - [C++] Write Arrow tables with chunked columns
-    * [PARQUET-1086] - [C++] Remove usage of arrow/util/compiler-util.h after 1.3.0 release
-    * [PARQUET-1097] - [C++] Account for Arrow API deprecation in ARROW-1511
-    * [PARQUET-1150] - C++: Hide statically linked boost symbols
-    * [PARQUET-1151] - [C++] Add build options / configuration to use static runtime libraries with MSVC
-    * [PARQUET-1147] - [C++] Account for API deprecation / change in ARROW-1671
-    * [PARQUET-1162] - C++: Update dev/README after migration to Gitbox
-    * [PARQUET-1165] - [C++] Pin clang-format version to 4.0
-    * [PARQUET-1164] - [C++] Follow API changes in ARROW-1808
-    * [PARQUET-1177] - [C++] Add more extensive compiler warnings when using Clang
-    * [PARQUET-1110] - [C++] Release verification script for Windows
-    * [PARQUET-859] - [C++] Flatten parquet/file directory
-    * [PARQUET-1220] - [C++] Don't build Thrift examples and tutorials in the ExternalProject
-    * [PARQUET-1219] - [C++] Update release-candidate script links to gitbox
-    * [PARQUET-1196] - [C++] Provide a parquet_arrow example project incl. CMake setup
-    * [PARQUET-1200] - [C++] Support reading a single Arrow column from a Parquet file
-
-## New Feature
-    * [PARQUET-1095] - [C++] Read and write Arrow decimal values
-    * [PARQUET-970] - Add Add Lz4 and Zstd compression codecs
-
-## Task
-    * [PARQUET-1221] - [C++] Extend release README
-    * [PARQUET-1225] - NaN values may lead to incorrect filtering under certain circumstances
-
-
-Parquet C++ 1.3.1
---------------------------------------------------------------------------------
-## Bug
-    * [PARQUET-1105] - [CPP] Remove libboost_system dependency 
-    * [PARQUET-1138] - [C++] Fix compilation with Arrow 0.7.1
-    * [PARQUET-1123] - [C++] Update parquet-cpp to use Arrow's AssertArraysEqual
-    * [PARQUET-1121] - C++: DictionaryArrays of NullType cannot be written
-    * [PARQUET-1139] - Add license to cmake_modules/parquet-cppConfig.cmake.in
-
-## Improvement
-    * [PARQUET-1140] - [C++] Fail on RAT errors in CI
-    * [PARQUET-1070] - Add CPack support to the build
-
-
-Parquet C++ 1.3.0
---------------------------------------------------------------------------------
-## Bug
-    * [PARQUET-1098] - [C++] Install new header in parquet/util
-    * [PARQUET-1085] - [C++] Backwards compatibility from macro cleanup in transitive dependencies in ARROW-1452
-    * [PARQUET-1074] - [C++] Switch to long key ids in KEYs file
-    * [PARQUET-1075] - C++: Coverage upload is broken
-    * [PARQUET-1088] - [CPP] remove parquet_version.h from version control since it gets auto generated 
-    * [PARQUET-1002] - [C++] Compute statistics based on Logical Types
-    * [PARQUET-1100] - [C++] Reading repeated types should decode number of records rather than number of values
-    * [PARQUET-1090] - [C++] Fix int32 overflow in Arrow table writer, add max row group size property
-    * [PARQUET-1108] - [C++] Fix Int96 comparators
-
-## Improvement
-    * [PARQUET-1104] - [C++] Upgrade to Apache Arrow 0.7.0 RC0
-    * [PARQUET-1072] - [C++] Add ARROW_NO_DEPRECATED_API to CI to check for deprecated API use
-    * [PARQUET-1096] - C++: Update sha{1, 256, 512} checksums per latest ASF release policy
-    * [PARQUET-1079] - [C++] Account for Arrow API change in ARROW-1335
-    * [PARQUET-1087] - [C++] Add wrapper for ScanFileContents in parquet::arrow that catches exceptions
-    * [PARQUET-1093] - C++: Improve Arrow level generation error message
-    * [PARQUET-1094] - C++: Add benchmark for boolean Arrow column I/O
-    * [PARQUET-1083] - [C++] Refactor core logic in parquet-scan.cc so that it can be used as a library function for benchmarking
-    * [PARQUET-1037] - Allow final RowGroup to be unfilled
-
-## New Feature
-    * [PARQUET-1078] - [C++] Add Arrow writer option to coerce timestamps to milliseconds or microseconds
-    * [PARQUET-929] - [C++] Handle arrow::DictionaryArray when writing Arrow data
-
-
-Parquet C++ 1.2.0
---------------------------------------------------------------------------------
-## Bug
-    * [PARQUET-1029] - [C++] TypedColumnReader/TypeColumnWriter symbols are no longer being exported
-    * [PARQUET-997] - Fix override compiler warnings
-    * [PARQUET-1033] - Mismatched Read and Write
-    * [PARQUET-1007] - [C++ ] Update parquet.thrift from https://github.com/apache/parquet-format
-    * [PARQUET-1039] - PARQUET-911 Breaks Arrow
-    * [PARQUET-1038] - Key value metadata should be nullptr if not set
-    * [PARQUET-1018] - [C++] parquet.dll has runtime dependencies on one or more libraries in the build toolchain
-    * [PARQUET-1003] - [C++] Modify DEFAULT_CREATED_BY value for every new release version
-    * [PARQUET-1004] - CPP Building fails on windows
-    * [PARQUET-1040] - Missing writer method implementations
-    * [PARQUET-1054] - [C++] Account for Arrow API changes in ARROW-1199
-    * [PARQUET-1042] - C++: Compilation breaks on GCC 4.8
-    * [PARQUET-1048] - [C++] Static linking of libarrow is no longer supported
-    * [PARQUET-1013] - Fix ZLIB_INCLUDE_DIR
-    * [PARQUET-998] - C++: Release script is not usable
-    * [PARQUET-1023] - [C++] Brotli libraries are not being statically linked on Windows
-    * [PARQUET-1000] - [C++] Do not build thirdparty Arrow with /WX on MSVC
-    * [PARQUET-1052] - [C++] add_compiler_export_flags() throws warning with CMake >= 3.3
-    * [PARQUET-1069] - C++: ./dev/release/verify-release-candidate is broken due to missing Arrow dependencies
-
-## Improvement
-    * [PARQUET-996] - Improve MSVC build - ThirdpartyToolchain - Arrow
-    * [PARQUET-911] - C++: Support nested structs in parquet_arrow
-    * [PARQUET-986] - Improve MSVC build - ThirdpartyToolchain - Thrift
-    * [PARQUET-864] - [C++] Consolidate non-Parquet-specific bit utility code into Apache Arrow
-    * [PARQUET-1043] - [C++] Raise minimum supported CMake version to 3.2
-    * [PARQUET-1016] - Upgrade thirdparty Arrow to 0.4.0
-    * [PARQUET-858] - [C++] Flatten parquet/column directory, consolidate related code
-    * [PARQUET-978] - [C++] Minimizing footer reads for small(ish) metadata
-    * [PARQUET-991] - [C++] Fix compiler warnings on MSVC and build with /WX in Appveyor
-    * [PARQUET-863] - [C++] Move SIMD, CPU info, hashing, and other generic utilities into Apache Arrow
-    * [PARQUET-1053] - Fix unused result warnings due to unchecked Statuses
-    * [PARQUET-1067] - C++: Update arrow hash to 0.5.0
-    * [PARQUET-1041] - C++: Support Arrow's NullArray
-    * [PARQUET-1008] - Update TypedColumnReader::ReadBatch method to accept batch_size as int64_t
-    * [PARQUET-1044] - [C++] Use compression libraries from Apache Arrow
-    * [PARQUET-999] - Improve MSVC build - Enable PARQUET_BUILD_BENCHMARKS
-    * [PARQUET-967] - [C++] Combine libparquet/libparquet_arrow libraries
-    * [PARQUET-1045] - [C++] Refactor to account for computational utility code migration in ARROW-1154
-
-## New Feature
-    * [PARQUET-1035] - Write Int96 from Arrow Timestamp(ns)
-
-## Task
-    * [PARQUET-994] - C++: release-candidate script should not push to master
-    * [PARQUET-902] - [C++] Move compressor interfaces into Apache Arrow
-
-## Test
-    * [PARQUET-706] - [C++] Create test case that uses libparquet as a 3rd party library
-
-
-Parquet C++ 1.1.0
---------------------------------------------------------------------------------
-## Bug
-    * [PARQUET-898] - [C++] Change Travis CI OS X image to Xcode 6.4 and fix our thirdparty build
-    * [PARQUET-976] - [C++] Pass unit test suite with MSVC, build in Appveyor
-    * [PARQUET-963] - [C++] Disallow reading struct types in Arrow reader for now
-    * [PARQUET-959] - [C++] Arrow thirdparty build fails on multiarch systems
-    * [PARQUET-962] - [C++] GTEST_MAIN_STATIC_LIB is not defined in FindGTest.cmake
-    * [PARQUET-958] - [C++] Print Parquet metadata in JSON format
-    * [PARQUET-956] - C++: BUILD_BYPRODUCTS not specified anymore for gtest
-    * [PARQUET-948] - [C++] Account for API changes in ARROW-782
-    * [PARQUET-947] - [C++] Refactor to account for ARROW-795 Arrow core library consolidation
-    * [PARQUET-965] - [C++] FIXED_LEN_BYTE_ARRAY types are unhandled in the Arrow reader
-    * [PARQUET-949] - [C++] Arrow version pinning seems to not be working properly
-    * [PARQUET-955] - [C++] pkg_check_modules will override $ARROW_HOME if it is set in the environment
-    * [PARQUET-945] - [C++] Thrift static libraries are not used with recent patch
-    * [PARQUET-943] - [C++] Overflow build error on x86
-    * [PARQUET-938] - [C++] There is a typo in cmake_modules/FindSnappy.cmake comment
-    * [PARQUET-936] - [C++] parquet::arrow::WriteTable can enter infinite loop if chunk_size is 0
-    * [PARQUET-981] - Repair usage of *_HOME 3rd party dependencies environment variables during Windows build 
-    * [PARQUET-992] - [C++] parquet/compression.h leaks zlib.h
-    * [PARQUET-987] - [C++] Fix regressions caused by PARQUET-981
-    * [PARQUET-933] - [C++] Account for Arrow Table API changes coming in ARROW-728
-    * [PARQUET-915] - Support Arrow Time Types in Schema
-    * [PARQUET-914] - [C++] Throw more informative exception when user writes too many values to a column in a row group
-    * [PARQUET-923] - [C++] Account for Time metadata changes in ARROW-686
-    * [PARQUET-918] - FromParquetSchema API crashes on nested schemas
-    * [PARQUET-925] - [C++] FindArrow.cmake sets the wrong library path after ARROW-648
-    * [PARQUET-932] - [c++] Add option to build parquet library with minimal dependency
-    * [PARQUET-919] - [C++] Account for API changes in ARROW-683
-    * [PARQUET-995] - [C++] Int96 reader in parquet_arrow uses size of Int96Type instead of Int96
-
-## Improvement
-    * [PARQUET-508] - Add ParquetFilePrinter
-    * [PARQUET-595] - Add API for key-value metadata
-    * [PARQUET-897] - [C++] Only use designated public headers from libarrow
-    * [PARQUET-679] - [C++] Build and unit tests support for MSVC on Windows
-    * [PARQUET-977] - Improve MSVC build
-    * [PARQUET-957] - [C++] Add optional $PARQUET_BUILD_TOOLCHAIN environment variable option for configuring build environment
-    * [PARQUET-961] - [C++] Strip debug symbols from libparquet libraries in release builds by default
-    * [PARQUET-954] - C++: Use Brolti 0.6 release
-    * [PARQUET-953] - [C++] Change arrow::FileWriter API to be initialized from a Schema, and provide for writing multiple tables
-    * [PARQUET-941] - [C++] Stop needless Boost static library detection for CentOS 7 support
-    * [PARQUET-942] - [C++] Fix wrong variabe use in FindSnappy
-    * [PARQUET-939] - [C++] Support Thrift_HOME CMake variable like FindSnappy does as Snappy_HOME
-    * [PARQUET-940] - [C++] Fix Arrow library path detection
-    * [PARQUET-937] - [C++] Support CMake < 3.4 again for Arrow detection
-    * [PARQUET-935] - [C++] Set shared library version for .deb packages
-    * [PARQUET-934] - [C++] Support multiarch on Debian
-    * [PARQUET-984] - C++: Add abi and so version to pkg-config
-    * [PARQUET-983] - C++: Update Thirdparty hash to Arrow 0.3.0
-    * [PARQUET-989] - [C++] Link dynamically to libarrow in toolchain build, set LD_LIBRARY_PATH
-    * [PARQUET-988] - [C++] Add Linux toolchain-based build to Travis CI
-    * [PARQUET-928] - [C++] Support pkg-config
-    * [PARQUET-927] - [C++] Specify shared library version of Apache Arrow
-    * [PARQUET-931] - [C++] Add option to pin thirdparty Arrow version used in ExternalProject
-    * [PARQUET-926] - [C++] Use pkg-config to find Apache Arrow
-    * [PARQUET-917] - C++: Build parquet_arrow by default
-    * [PARQUET-910] - C++: Support TIME logical type in parquet_arrow
-    * [PARQUET-909] - [CPP]: Reduce buffer allocations (mallocs) on critical path
-
-## New Feature
-    * [PARQUET-853] - [C++] Add option to link with shared boost libraries when building Arrow in the thirdparty toolchain
-    * [PARQUET-946] - [C++] Refactoring in parquet::arrow::FileReader to be able to read a single row group
-    * [PARQUET-930] - [C++] Account for all Arrow date/time types 
-
-
-Parquet C++ 1.0.0
---------------------------------------------------------------------------------
-## Bug
-    * [PARQUET-455] - Fix compiler warnings on OS X / Clang
-    * [PARQUET-558] - Support ZSH in build scripts
-    * [PARQUET-720] - Parquet-cpp fails to link when included in multiple TUs
-    * [PARQUET-718] - Reading boolean pages written by parquet-cpp fails
-    * [PARQUET-640] - [C++] Force the use of gcc 4.9 in conda builds
-    * [PARQUET-643] - Add const modifier to schema pointer reference in ParquetFileWriter
-    * [PARQUET-672] - [C++] Build testing conda artifacts in debug mode
-    * [PARQUET-661] - [C++] Do not assume that perl is found in /usr/bin
-    * [PARQUET-659] - [C++] Instantiated template visibility is broken on clang / OS X
-    * [PARQUET-657] - [C++] Don't define DISALLOW_COPY_AND_ASSIGN if already defined
-    * [PARQUET-656] - [C++] Revert PARQUET-653
-    * [PARQUET-676] - MAX_VALUES_PER_LITERAL_RUN causes RLE encoding failure
-    * [PARQUET-614] - C++: Remove unneeded LZ4-related code
-    * [PARQUET-604] - Install writer.h headers
-    * [PARQUET-621] - C++: Uninitialised DecimalMetadata is read
-    * [PARQUET-620] - C++: Duplicate calls to ParquetFileWriter::Close cause duplicate metdata writes
-    * [PARQUET-599] - ColumnWriter::RleEncodeLevels' size estimation might be wrong
-    * [PARQUET-617] - C++: Enable conda build to work on systems with non-default C++ toolchains
-    * [PARQUET-627] - Ensure that thrift headers are generated before source compilation
-    * [PARQUET-745] - TypedRowGroupStatistics fails to PlainDecode min and max in ByteArrayType
-    * [PARQUET-738] - Update arrow version that also supports newer Xcode
-    * [PARQUET-747] - [C++] TypedRowGroupStatistics are not being exported in libparquet.so
-    * [PARQUET-711] - Use metadata builders in parquet writer
-    * [PARQUET-732] - Building a subset of dependencies does not work
-    * [PARQUET-760] - On switching from dictionary to the fallback encoding, an incorrect encoding is set
-    * [PARQUET-691] - [C++] Write ColumnChunk metadata after each column chunk in the file
-    * [PARQUET-797] - [C++] Update for API changes in ARROW-418
-    * [PARQUET-837] - [C++] SerializedFile::ParseMetaData uses Seek, followed by Read, and could have race conditions
-    * [PARQUET-827] - [C++] Incorporate addition of arrow::MemoryPool::Reallocate
-    * [PARQUET-502] - Scanner segfaults when its batch size is smaller than the number of rows
-    * [PARQUET-469] - Roll back Thrift bindings to 0.9.0
-    * [PARQUET-889] - Fix compilation when PARQUET_USE_SSE is on
-    * [PARQUET-888] - C++ Memory leak in RowGroupSerializer
-    * [PARQUET-819] - C++: Trying to install non-existing parquet/arrow/utils.h
-    * [PARQUET-736] - XCode 8.0 breaks builds
-    * [PARQUET-505] - Column reader: automatically handle large data pages
-    * [PARQUET-615] - C++: Building static or shared libparquet should not be mutually exclusive
-    * [PARQUET-658] - ColumnReader has no virtual destructor
-    * [PARQUET-799] - concurrent usage of the file reader API
-    * [PARQUET-513] - Valgrind errors are not failing the Travis CI build
-    * [PARQUET-841] - [C++] Writing wrong format version when using ParquetVersion::PARQUET_1_0
-    * [PARQUET-742] - Add missing license headers
-    * [PARQUET-741] - compression_buffer_ is reused although it shouldn't
-    * [PARQUET-700] - C++: Disable dictionary encoding for boolean columns
-    * [PARQUET-662] - [C++] ParquetException must be explicitly exported in dynamic libraries
-    * [PARQUET-704] - [C++] scan-all.h is not being installed
-    * [PARQUET-865] - C++: Pass all CXXFLAGS to Thrift ExternalProject
-    * [PARQUET-875] - [C++] Fix coveralls build given changes to thirdparty build procedure
-    * [PARQUET-709] - [C++] Fix conda dev binary builds
-    * [PARQUET-638] - [C++] Revert static linking of libstdc++ in conda builds until symbol visibility addressed
-    * [PARQUET-606] - Travis coverage is broken
-    * [PARQUET-880] - [CPP] Prevent destructors from throwing
-    * [PARQUET-886] - [C++] Revise build documentation and requirements in README.md
-    * [PARQUET-900] - C++: Fix NOTICE / LICENSE issues
-    * [PARQUET-885] - [C++] Do not search for Thrift in default system paths
-    * [PARQUET-879] - C++: ExternalProject compilation for Thrift fails on older CMake versions
-    * [PARQUET-635] - [C++] Statically link libstdc++ on Linux in conda recipe
-    * [PARQUET-710] - Remove unneeded private member variables from RowGroupReader ABI
-    * [PARQUET-766] - C++: Expose ParquetFileReader through Arrow reader as const
-    * [PARQUET-876] - C++: Correct snapshot version
-    * [PARQUET-821] - [C++] zlib download link is broken
-    * [PARQUET-818] - [C++] Refactor library to share IO, Buffer, and memory management abstractions with Apache Arrow
-    * [PARQUET-537] - LocalFileSource leaks resources
-    * [PARQUET-764] - [CPP] Parquet Writer does not write Boolean values correctly
-    * [PARQUET-812] - [C++] Failure reading BYTE_ARRAY data from file in parquet-compatibility project
-    * [PARQUET-759] - Cannot store columns consisting of empty strings
-    * [PARQUET-846] - [CPP] CpuInfo::Init() is not thread safe
-    * [PARQUET-694] - C++: Revert default data page size back to 1M
-    * [PARQUET-842] - [C++] Impala rejects DOUBLE columns if decimal metadata is set
-    * [PARQUET-708] - [C++] RleEncoder does not account for "worst case scenario" in MaxBufferSize for bit_width > 1
-    * [PARQUET-639] - Do not export DCHECK in public headers
-    * [PARQUET-828] - [C++] "version" field set improperly in file metadata
-    * [PARQUET-891] - [C++] Do not search for Snappy in default system paths
-    * [PARQUET-626] - Fix builds due to unavailable llvm.org apt mirror
-    * [PARQUET-629] - RowGroupSerializer should only close itself once
-    * [PARQUET-472] - Clean up InputStream ownership semantics in ColumnReader
-    * [PARQUET-739] - Rle-decoding uses static buffer that is shared accross threads
-    * [PARQUET-561] - ParquetFileReader::Contents PIMPL missing a virtual destructor
-    * [PARQUET-892] - [C++] Clean up link library targets in CMake files
-    * [PARQUET-454] - Address inconsistencies in boolean decoding
-    * [PARQUET-816] - [C++] Failure decoding sample dict-encoded file from parquet-compatibility project
-    * [PARQUET-565] - Use PATH instead of DIRECTORY in get_filename_component to support CMake<2.8.12
-    * [PARQUET-446] - Hide thrift dependency in parquet-cpp
-    * [PARQUET-843] - [C++] Impala unable to read files created by parquet-cpp
-    * [PARQUET-555] - Dictionary page metadata handling inconsistencies
-    * [PARQUET-908] - Fix for PARQUET-890 introduces undefined symbol in libparquet_arrow.so
-    * [PARQUET-793] - [CPP] Do not return incorrect statistics
-    * [PARQUET-887] - C++: Fix issues in release scripts arise in RC1
-
-## Improvement
-    * [PARQUET-277] - Remove boost dependency
-    * [PARQUET-500] - Enable coveralls.io for apache/parquet-cpp
-    * [PARQUET-497] - Decouple Parquet physical file structure from FileReader class
-    * [PARQUET-597] - Add data rates to benchmark output
-    * [PARQUET-522] - #include cleanup with include-what-you-use 
-    * [PARQUET-515] - Add "Reset" to LevelEncoder and LevelDecoder
-    * [PARQUET-514] - Automate coveralls.io updates in Travis CI
-    * [PARQUET-551] - Handle compiler warnings due to disabled DCHECKs in release builds
-    * [PARQUET-559] - Enable InputStream as a source to the ParquetFileReader
-    * [PARQUET-562] - Simplified ZSH support in build scripts
-    * [PARQUET-538] - Improve ColumnReader Tests
-    * [PARQUET-541] - Portable build scripts
-    * [PARQUET-724] - Test more advanced properties setting
-    * [PARQUET-641] - Instantiate stringstream only if needed in SerializedPageReader::NextPage
-    * [PARQUET-636] - Expose selection for different encodings
-    * [PARQUET-603] - Implement missing information in schema descriptor
-    * [PARQUET-610] - Print ColumnMetaData for each RowGroup
-    * [PARQUET-600] - Add benchmarks for RLE-Level encoding
-    * [PARQUET-592] - Support compressed writes
-    * [PARQUET-593] - Add API for writing Page statistics
-    * [PARQUET-589] - Implement Chunked InMemoryInputStream for better memory usage
-    * [PARQUET-587] - Implement BufferReader::Read(int64_t,uint8_t*)
-    * [PARQUET-616] - C++: WriteBatch should accept const arrays
-    * [PARQUET-630] - C++: Support link flags for older CMake versions
-    * [PARQUET-634] - Consistent private linking of dependencies
-    * [PARQUET-633] - Add version to WriterProperties
-    * [PARQUET-625] - Improve RLE read performance
-    * [PARQUET-737] - Use absolute namespace in macros
-    * [PARQUET-762] - C++: Use optimistic allocation instead of Arrow Builders
-    * [PARQUET-773] - C++: Check licenses with RAT in CI
-    * [PARQUET-687] - C++: Switch to PLAIN encoding if dictionary grows too large
-    * [PARQUET-784] - C++: Reference Spark, Kudu and FrameOfReference in LICENSE
-    * [PARQUET-809] - [C++] Add API to determine if two files' schemas are compatible 
-    * [PARQUET-778] - Standardize the schema output to match the parquet-mr format
-    * [PARQUET-463] - Add DCHECK* macros for assertions in debug builds
-    * [PARQUET-471] - Use the same environment setup script for Travis CI as local sandbox development
-    * [PARQUET-449] - Update to latest parquet.thrift
-    * [PARQUET-496] - Fix cpplint configuration to be more restrictive
-    * [PARQUET-468] - Add a cmake option to generate the Parquet thrift headers with the thriftc in the environment
-    * [PARQUET-482] - Organize src code file structure to have a very clear folder with public headers.
-    * [PARQUET-591] - Page size estimation during writes
-    * [PARQUET-518] - Review usages of size_t and unsigned integers generally per Google style guide
-    * [PARQUET-533] - Simplify RandomAccessSource API to combine Seek/Read 
-    * [PARQUET-767] - Add release scripts for parquet-cpp
-    * [PARQUET-699] - Update parquet.thrift from https://github.com/apache/parquet-format
-    * [PARQUET-653] - [C++] Re-enable -static-libstdc++ in dev artifact builds
-    * [PARQUET-763] - C++: Expose ParquetFileReader through Arrow reader
-    * [PARQUET-857] - [C++] Flatten parquet/encodings directory
-    * [PARQUET-862] - Provide defaut cache size values if CPU info probing is not available
-    * [PARQUET-689] - C++: Compress DataPages eagerly
-    * [PARQUET-874] - [C++] Use default memory allocator from Arrow
-    * [PARQUET-267] - Detach thirdparty code from build configuration.
-    * [PARQUET-418] - Add a utility to print contents of a Parquet file to stdout
-    * [PARQUET-519] - Disable compiler warning supressions and fix all DEBUG build warnings
-    * [PARQUET-447] - Add Debug and Release build types and associated compiler flags
-    * [PARQUET-868] - C++: Build snappy with optimizations
-    * [PARQUET-894] - Fix compilation warning
-    * [PARQUET-883] - C++: Support non-standard gcc version strings
-    * [PARQUET-607] - Public Writer header
-    * [PARQUET-731] - [CPP] Add API to return metadata size and Skip reading values
-    * [PARQUET-628] - Link thrift privately
-    * [PARQUET-877] - C++: Update Arrow Hash, update Version in metadata.
-    * [PARQUET-547] - Refactor most templates to use DataType structs rather than the Type::type enum
-    * [PARQUET-882] - [CPP] Improve Application Version parsing
-    * [PARQUET-448] - Add cmake option to skip building the unit tests
-    * [PARQUET-721] - Performance benchmarks for reading into Arrow structures
-    * [PARQUET-820] - C++: Decoders should directly emit arrays with spacing for null entries
-    * [PARQUET-813] - C++: Build dependencies using CMake External project
-    * [PARQUET-488] - Add SSE-related cmake options to manage compiler flags
-    * [PARQUET-564] - Add option to run unit tests with valgrind --tool=memcheck
-    * [PARQUET-572] - Rename parquet_cpp namespace to parquet
-    * [PARQUET-829] - C++: Make use of ARROW-469
-    * [PARQUET-501] - Add an OutputStream abstraction (capable of memory allocation) for Encoder public API
-    * [PARQUET-744] - Clarifications on build instructions
-    * [PARQUET-520] - Add version of LocalFileSource that uses memory-mapping for zero-copy reads
-    * [PARQUET-556] - Extend RowGroupStatistics to include "min" "max" statistics
-    * [PARQUET-671] - Improve performance of RLE/bit-packed decoding in parquet-cpp
-    * [PARQUET-681] - Add tool to scan a parquet file
-
-## New Feature
-    * [PARQUET-499] - Complete PlainEncoder implementation for all primitive types and test end to end
-    * [PARQUET-439] - Conform all copyright headers to ASF requirements
-    * [PARQUET-436] - Implement ParquetFileWriter class entry point for generating new Parquet files
-    * [PARQUET-435] - Provide vectorized ColumnReader interface
-    * [PARQUET-438] - Update RLE encoder/decoder modules from Impala upstream changes and adapt unit tests
-    * [PARQUET-512] - Add optional google/benchmark 3rd-party dependency for performance testing
-    * [PARQUET-566] - Add method to retrieve the full column path
-    * [PARQUET-613] - C++: Add conda packaging recipe
-    * [PARQUET-605] - Expose schema node in ColumnDescriptor
-    * [PARQUET-619] - C++: Add OutputStream for local files
-    * [PARQUET-583] - Implement Parquet to Thrift schema conversion
-    * [PARQUET-582] - Conversion functions for Parquet enums to Thrift enums
-    * [PARQUET-728] - [C++] Bring parquet::arrow up to date with API changes in arrow::io 
-    * [PARQUET-752] - [C++] Conform parquet_arrow to upstream API changes
-    * [PARQUET-788] - [C++] Reference Impala / Apache Impala (incubating) in LICENSE
-    * [PARQUET-808] - [C++] Add API to read file given externally-provided FileMetadata
-    * [PARQUET-807] - [C++] Add API to read file metadata only from a file handle
-    * [PARQUET-805] - C++: Read Int96 into Arrow Timestamp(ns)
-    * [PARQUET-836] - [C++] Add column selection to parquet::arrow::FileReader
-    * [PARQUET-835] - [C++] Add option to parquet::arrow to read columns in parallel using a thread pool
-    * [PARQUET-830] - [C++] Add additional configuration options to parquet::arrow::OpenFIle
-    * [PARQUET-769] - C++: Add support for Brotli Compression
-    * [PARQUET-489] - Add visibility macros to be used for public and internal APIs of libparquet
-    * [PARQUET-542] - Support memory allocation from external memory
-    * [PARQUET-844] - [C++] Consolidate encodings, schema, and compression subdirectories into fewer files
-    * [PARQUET-848] - [C++] Consolidate libparquet_thrift subcomponent
-    * [PARQUET-646] - [C++] Enable easier 3rd-party toolchain clang builds on Linux
-    * [PARQUET-598] - [C++] Test writing all primitive data types
-    * [PARQUET-442] - Convert flat SchemaElement vector to implied nested schema data structure
-    * [PARQUET-867] - [C++] Support writing sliced Arrow arrays
-    * [PARQUET-456] - Add zlib codec support
-    * [PARQUET-834] - C++: Support r/w of arrow::ListArray
-    * [PARQUET-485] - Decouple data page delimiting from column reader / scanner classes, create test fixtures
-    * [PARQUET-434] - Add a ParquetFileReader class to encapsulate some low-level details of interacting with Parquet files
-    * [PARQUET-666] - PLAIN_DICTIONARY write support
-    * [PARQUET-437] - Incorporate googletest thirdparty dependency and add cmake tools (ADD_PARQUET_TEST) to simplify adding new unit tests
-    * [PARQUET-866] - [C++] Account for API changes in ARROW-33
-    * [PARQUET-545] - Improve API to support Decimal type
-    * [PARQUET-579] - Add API for writing Column statistics
-    * [PARQUET-494] - Implement PLAIN_DICTIONARY encoding and decoding
-    * [PARQUET-618] - C++: Automatically upload conda build artifacts on commits to master
-    * [PARQUET-833] - C++: Provide API to write spaced arrays (e.g. Arrow)
-    * [PARQUET-903] - C++: Add option to set RPATH to ORIGIN
-    * [PARQUET-451] - Add a RowGroup reader interface class
-    * [PARQUET-785] - C++: List conversion for Arrow Schemas
-    * [PARQUET-712] - C++: Read into Arrow memory
-    * [PARQUET-890] - C++: Support I/O of DATE columns in parquet_arrow
-    * [PARQUET-782] - C++: Support writing to Arrow sinks
-    * [PARQUET-849] - [C++] Upgrade default Thrift in thirdparty toolchain to 0.9.3 or 0.10
-    * [PARQUET-573] - C++: Create a public API for reading and writing file metadata
-
-## Task
-    * [PARQUET-814] - C++: Remove Conda recipes
-    * [PARQUET-503] - Re-enable parquet 2.0 encodings
-    * [PARQUET-169] - Parquet-cpp: Implement support for bulk reading and writing repetition/definition levels.
-    * [PARQUET-878] - C++: Remove setup_build_env from rc-verification script
-    * [PARQUET-881] - C++: Update Arrow hash to 0.2.0-rc2
-    * [PARQUET-771] - C++: Sync KEYS file
-    * [PARQUET-901] - C++: Publish RCs in apache-parquet-VERSION in SVN
-
-## Test
-    * [PARQUET-525] - Test coverage for malformed file failure modes on the read path
-    * [PARQUET-703] - [C++] Validate num_values metadata for columns with nulls
-    * [PARQUET-507] - Improve runtime of rle-test.cc
-    * [PARQUET-549] - Add scanner and column reader tests for dictionary data pages
-    * [PARQUET-457] - Add compressed data page unit tests
-
-
diff --git a/CMakeLists.txt b/CMakeLists.txt
deleted file mode 100644
index fa4fb21..0000000
--- a/CMakeLists.txt
+++ /dev/null
@@ -1,783 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you 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.
-
-# Require cmake that supports BYPRODUCTS in add_custom_command, ExternalProject_Add [1].
-cmake_minimum_required(VERSION 3.2.0)
-
-message(FATAL_ERROR "Building parquet-cpp master is no longer supported. "
-  "Build from C++ codebase in https://github.com/apache/arrow with -DARROW_PARQUET=ON")
-
-file(READ "${CMAKE_CURRENT_SOURCE_DIR}/.parquetcppversion" PARQUET_VERSION)
-string(REPLACE "\n" "" PARQUET_VERSION "${PARQUET_VERSION}")
-string(REGEX MATCH "^([0-9]+\.[0-9]+\.[0-9]+(\.[0-9]+)?)" VERSION ${PARQUET_VERSION})
-if(NOT VERSION)
-  message(FATAL_ERROR "invalid .parquetcppversion")
-endif()
-
-project(parquet-cpp VERSION ${VERSION})
-set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "C++ library to read and write the Apache Parquet columnar data format")
-set(CPACK_PACKAGE_VERSION_MAJOR ${PROJECT_VERSION_MAJOR})
-set(CPACK_PACKAGE_VERSION_MINOR ${PROJECT_VERSION_MINOR})
-set(CPACK_PACKAGE_VERSION_PATCH ${PROJECT_VERSION_PATCH})
-set(CPACK_PACKAGE_VENDOR        "Apache Software Foundation")
-set(CPACK_PACKAGE_CONTACT       "Apache Parquet Development <dev@parquet.apache.org>")
-set(CPACK_STRIP_FILES           TRUE)
-set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_SOURCE_DIR}/LICENSE.txt")
-set(CPACK_DEBIAN_FILE_NAME      "DEB-DEFAULT")
-set(CPACK_RPM_FILE_NAME         "RPM-DEFAULT")
-set(CPACK_RPM_PACKAGE_LICENSE   "Apache v2.0")
-
-include(ExternalProject)
-include(FindPkgConfig)
-
-# This ensures that things like gnu++11 get passed correctly
-set(CMAKE_CXX_STANDARD 11)
-
-# We require a C++11 compliant compiler
-set(CMAKE_CXX_STANDARD_REQUIRED ON)
-
-include(GNUInstallDirs)
-
-set(PARQUET_SO_VERSION ${PROJECT_VERSION_MAJOR})
-set(PARQUET_ABI_VERSION ${PROJECT_VERSION})
-if(WIN32)
-  set(INSTALL_CMAKE_DIR cmake)
-else()
-  set(INSTALL_CMAKE_DIR "${CMAKE_INSTALL_DATAROOTDIR}/${PROJECT_NAME}/cmake")
-endif()
-set(CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST_ADDITION "/usr/${CMAKE_INSTALL_LIBDIR}/pkgconfig")
-include(CPack)
-
-include(CMakePackageConfigHelpers)
-configure_package_config_file(cmake_modules/${PROJECT_NAME}Config.cmake.in
-                              ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake
-                              INSTALL_DESTINATION ${INSTALL_CMAKE_DIR}
-                              PATH_VARS CMAKE_INSTALL_INCLUDEDIR CMAKE_INSTALL_LIBDIR)
-write_basic_package_version_file(${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake
-                                 COMPATIBILITY SameMajorVersion)
-install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake
-              ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake
-DESTINATION ${INSTALL_CMAKE_DIR})
-
-if (NOT "$ENV{PARQUET_GCC_ROOT}" STREQUAL "")
-  set(GCC_ROOT $ENV{PARQUET_GCC_ROOT})
-  set(CMAKE_C_COMPILER ${GCC_ROOT}/bin/gcc)
-  set(GCOV_PATH ${GCC_ROOT}/bin/gcov)
-  set(CMAKE_CXX_COMPILER ${GCC_ROOT}/bin/g++)
-endif()
-
-# generate CTest input files
-enable_testing()
-
-# where to find cmake modules
-set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake_modules")
-set(BUILD_SUPPORT_DIR "${CMAKE_SOURCE_DIR}/build-support")
-
-set(CLANG_FORMAT_VERSION "6.0")
-find_package(ClangTools)
-if ("$ENV{CMAKE_EXPORT_COMPILE_COMMANDS}" STREQUAL "1" OR CLANG_TIDY_FOUND)
-  # Generate a Clang compile_commands.json "compilation database" file for use
-  # with various development tools, such as Vim's YouCompleteMe plugin.
-  # See http://clang.llvm.org/docs/JSONCompilationDatabase.html
-  set(CMAKE_EXPORT_COMPILE_COMMANDS 1)
-endif()
-
-find_program(CCACHE_FOUND ccache)
-if(CCACHE_FOUND)
-  set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ccache)
-  set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK ccache)
-endif(CCACHE_FOUND)
-
-if(APPLE)
-  set(CMAKE_MACOSX_RPATH 1)
-endif()
-
-# if no build build type is specified, default to debug builds
-if (NOT CMAKE_BUILD_TYPE)
-  set(CMAKE_BUILD_TYPE Debug)
-endif(NOT CMAKE_BUILD_TYPE)
-
-# set compile output directory
-string (TOLOWER ${CMAKE_BUILD_TYPE} BUILD_SUBDIR_NAME)
-
-# Top level cmake file, set options
-if ("${CMAKE_SOURCE_DIR}" STREQUAL "${CMAKE_CURRENT_SOURCE_DIR}")
-  option(PARQUET_BUILD_SHARED
-    "Build the shared version of libparquet"
-    ON)
-  option(PARQUET_BUILD_STATIC
-    "Build the static version of libparquet. Always ON if building unit tests"
-    ON)
-  set(PARQUET_ARROW_LINKAGE "shared" CACHE STRING
-    "Libraries to link for Apache Arrow. static|shared (default shared)")
-  set(PARQUET_CXXFLAGS "" CACHE STRING
-    "Compiler flags to use when compiling Parquet")
-  option(PARQUET_USE_SSE
-    "Build with SSE4 optimizations"
-    OFF)
-  option(PARQUET_BUILD_BENCHMARKS
-    "Build the libparquet benchmark suite"
-    OFF)
-
-  set(PARQUET_BUILD_WARNING_LEVEL "PRODUCTION" CACHE STRING
-    "Levels of compiler warnings for development: PRODUCTION/CHECKIN/EVERYTHING")
-
-  option(PARQUET_BOOST_USE_SHARED
-    "Rely on boost shared libraries where relevant"
-    ON)
-  option(PARQUET_BUILD_TESTS
-    "Build the libparquet test suite"
-    ON)
-  option(PARQUET_TEST_MEMCHECK
-    "Run the test suite using valgrind --tool=memcheck"
-    OFF)
-  option(PARQUET_BUILD_EXECUTABLES
-    "Build the libparquet executable CLI tools"
-    ON)
-  option(PARQUET_RPATH_ORIGIN
-    "Build Parquet libraries with RPATH set to \$ORIGIN"
-    OFF)
-  option(PARQUET_MINIMAL_DEPENDENCY
-    "Depend only on Thirdparty headers to build libparquet. Always OFF if building binaries"
-    OFF)
-
-  option(PARQUET_THRIFT_USE_BOOST
-    "Enable if Thirdparty Thrift uses boost::shared_ptr (Apache Thrift < 0.11)"
-    OFF)
-
-  if (MSVC)
-    set(ARROW_MSVC_STATIC_LIB_SUFFIX "_static" CACHE STRING
-      "Arrow static lib suffix used on Windows with MSVC (default _static)")
-    set(THRIFT_MSVC_STATIC_LIB_SUFFIX "md" CACHE STRING
-      "Thrift static lib suffix used on Windows with MSVC (default md)")
-    option(PARQUET_USE_STATIC_CRT
-      "Build Parquet with statically linked CRT"
-      OFF)
-    option(PARQUET_USE_CLCACHE
-      "Use clcache if available"
-      ON)
-  endif()
-
-  option(PARQUET_VERBOSE_THIRDPARTY_BUILD
-    "If off, output from ExternalProjects will be logged to files rather than shown"
-    OFF)
-
-endif()
-
-if (MSVC AND PARQUET_USE_CLCACHE AND
-     (("${CMAKE_GENERATOR}" STREQUAL "NMake Makefiles") OR
-      ("${CMAKE_GENERATOR}" STREQUAL "Ninja")))
-  find_program(CLCACHE_FOUND clcache)
-  if(CLCACHE_FOUND)
-    set(CMAKE_CXX_COMPILER ${CLCACHE_FOUND})
-  endif(CLCACHE_FOUND)
-endif()
-
-include(BuildUtils)
-
-if (PARQUET_BUILD_TESTS OR PARQUET_BUILD_EXECUTABLES OR PARQUET_BUILD_BENCHMARKS)
-  set(PARQUET_BUILD_STATIC ON)
-  set(PARQUET_MINIMAL_DEPENDENCY OFF)
-endif()
-
-# If build in-source, create the latest symlink. If build out-of-source, which is
-# preferred, simply output the binaries in the build folder
-if (${CMAKE_SOURCE_DIR} STREQUAL "${CMAKE_CURRENT_BINARY_DIR}")
-  set(BUILD_OUTPUT_ROOT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/build/${BUILD_SUBDIR_NAME}")
-  # Link build/latest to the current build directory, to avoid developers
-  # accidentally running the latest debug build when in fact they're building
-  # release builds.
-  FILE(MAKE_DIRECTORY ${BUILD_OUTPUT_ROOT_DIRECTORY})
-  if (NOT APPLE)
-    set(MORE_ARGS "-T")
-  endif()
-EXECUTE_PROCESS(COMMAND ln ${MORE_ARGS} -sf ${BUILD_OUTPUT_ROOT_DIRECTORY}
-  ${CMAKE_CURRENT_BINARY_DIR}/build/latest)
-else()
-  set(BUILD_OUTPUT_ROOT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${BUILD_SUBDIR_NAME}")
-endif()
-
-# where to put generated archives (.a files)
-set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${BUILD_OUTPUT_ROOT_DIRECTORY}")
-set(ARCHIVE_OUTPUT_DIRECTORY "${BUILD_OUTPUT_ROOT_DIRECTORY}")
-
-# where to put generated libraries (.so files)
-set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${BUILD_OUTPUT_ROOT_DIRECTORY}")
-set(LIBRARY_OUTPUT_DIRECTORY "${BUILD_OUTPUT_ROOT_DIRECTORY}")
-
-# where to put generated binaries
-set(EXECUTABLE_OUTPUT_PATH "${BUILD_OUTPUT_ROOT_DIRECTORY}")
-
-if (MSVC)
-  # define output directories to overwrite default Visual Studio generator output directories
-  FOREACH(BUILD_CONFIG ${CMAKE_CONFIGURATION_TYPES})
-    string(TOUPPER ${BUILD_CONFIG} UPPERCASE_BUILD_CONFIG)
-    set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_${UPPERCASE_BUILD_CONFIG} ${BUILD_OUTPUT_ROOT_DIRECTORY})
-    set(CMAKE_PDB_OUTPUT_DIRECTORY_${UPPERCASE_BUILD_CONFIG} ${BUILD_OUTPUT_ROOT_DIRECTORY})
-    set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_${UPPERCASE_BUILD_CONFIG} ${BUILD_OUTPUT_ROOT_DIRECTORY})
-    set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_${UPPERCASE_BUILD_CONFIG} ${BUILD_OUTPUT_ROOT_DIRECTORY})
-  ENDFOREACH()
-endif()
-
-############################################################
-# Benchmarking
-############################################################
-# Add a new micro benchmark, with or without an executable that should be built.
-# If benchmarks are enabled then they will be run along side unit tests with ctest.
-# 'make runbenchmark' and 'make unittest' to build/run only benchmark or unittests,
-# respectively.
-#
-# REL_BENCHMARK_NAME is the name of the benchmark app. It may be a single component
-# (e.g. monotime-benchmark) or contain additional components (e.g.
-# net/net_util-benchmark). Either way, the last component must be a globally
-# unique name.
-
-# The benchmark will registered as unit test with ctest with a label
-# of 'benchmark'.
-#
-# Arguments after the test name will be passed to set_tests_properties().
-function(ADD_PARQUET_BENCHMARK REL_BENCHMARK_NAME)
-  if(NOT PARQUET_BUILD_BENCHMARKS)
-    return()
-  endif()
-  get_filename_component(BENCHMARK_NAME ${REL_BENCHMARK_NAME} NAME_WE)
-
-  if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${REL_BENCHMARK_NAME}.cc)
-    # This benchmark has a corresponding .cc file, set it up as an executable.
-    set(BENCHMARK_PATH "${EXECUTABLE_OUTPUT_PATH}/${BENCHMARK_NAME}")
-    add_executable(${BENCHMARK_NAME} "${REL_BENCHMARK_NAME}.cc")
-
-    if(APPLE)
-      # On OS X / Thrift >= 0.9.2, tr1/tuple.h is not in libc++
-      SET_TARGET_PROPERTIES(${TEST_NAME} PROPERTIES COMPILE_FLAGS
-        -DGTEST_USE_OWN_TR1_TUPLE=1)
-    else()
-      # Linux, for Thrift >= 0.9.2
-      SET_TARGET_PROPERTIES(${TEST_NAME} PROPERTIES COMPILE_FLAGS
-        -DGTEST_USE_OWN_TR1_TUPLE=0)
-    endif()
-
-    target_link_libraries(${BENCHMARK_NAME} ${PARQUET_BENCHMARK_LINK_LIBS})
-    add_dependencies(runbenchmark ${BENCHMARK_NAME})
-    set(NO_COLOR "--color_print=false")
-  else()
-    # No executable, just invoke the benchmark (probably a script) directly.
-    set(BENCHMARK_PATH ${CMAKE_CURRENT_SOURCE_DIR}/${REL_BENCHMARK_NAME})
-    set(NO_COLOR "")
-  endif()
-
-  if(WIN32)
-    add_test(${BENCHMARK_NAME} ${BENCHMARK_PATH} ${NO_COLOR})
-  else()
-    add_test(${BENCHMARK_NAME}
-      ${BUILD_SUPPORT_DIR}/run-test.sh ${CMAKE_BINARY_DIR} benchmark ${BENCHMARK_PATH} ${NO_COLOR})
-  endif()
-  set_tests_properties(${BENCHMARK_NAME} PROPERTIES LABELS "benchmark")
-  if(ARGN)
-    set_tests_properties(${BENCHMARK_NAME} PROPERTIES ${ARGN})
-  endif()
-endfunction()
-
-# A wrapper for add_dependencies() that is compatible with NO_BENCHMARKS.
-function(ADD_PARQUET_BENCHMARK_DEPENDENCIES REL_BENCHMARK_NAME)
-  if(NOT PARQUET_BUILD_BENCHMARKS)
-    return()
-  endif()
-  get_filename_component(BENCMARK_NAME ${REL_BENCHMARK_NAME} NAME_WE)
-
-  add_dependencies(${BENCHMARK_NAME} ${ARGN})
-endfunction()
-
-############################################################
-# Testing
-############################################################
-
-# Add a new test case, with or without an executable that should be built.
-#
-# REL_TEST_NAME is the name of the test. It may be a single component
-# (e.g. monotime-test) or contain additional components (e.g.
-# net/net_util-test). Either way, the last component must be a globally
-# unique name.
-#
-# The unit test is added with a label of "unittest" to support filtering with
-# ctest.
-#
-# Arguments after the test name will be passed to set_tests_properties().
-function(ADD_PARQUET_TEST REL_TEST_NAME)
-  set(options)
-  set(one_value_args LINKAGE)
-  set(multi_value_args)
-  cmake_parse_arguments(ARG "${options}" "${one_value_args}" "${multi_value_args}" ${ARGN})
-
-  if(NOT PARQUET_BUILD_TESTS)
-    return()
-  endif()
-
-  # TODO(wesm): not very rigorous error checking
-  if (ARG_LINKAGE AND "${ARG_LINKAGE}" STREQUAL "shared")
-    if(NOT PARQUET_BUILD_SHARED)
-      # Skip this test if we are not building the shared library
-      return()
-    else()
-      set(TEST_LINK_LIBS ${PARQUET_TEST_SHARED_LINK_LIBS})
-    endif()
-  else()
-    set(TEST_LINK_LIBS ${PARQUET_TEST_LINK_LIBS})
-  endif()
-
-  get_filename_component(TEST_NAME ${REL_TEST_NAME} NAME_WE)
-
-  if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${REL_TEST_NAME}.cc)
-    # This test has a corresponding .cc file, set it up as an executable.
-    set(TEST_PATH "${EXECUTABLE_OUTPUT_PATH}/${TEST_NAME}")
-    add_executable(${TEST_NAME} "${REL_TEST_NAME}.cc")
-    add_dependencies(unittest ${TEST_NAME})
-
-    if(APPLE)
-      # On OS X / Thrift >= 0.9.2, tr1/tuple.h is not in libc++
-      SET_TARGET_PROPERTIES(${TEST_NAME} PROPERTIES COMPILE_FLAGS
-        -DGTEST_USE_OWN_TR1_TUPLE=1)
-    else()
-      # Linux, for Thrift >= 0.9.2
-      SET_TARGET_PROPERTIES(${TEST_NAME} PROPERTIES COMPILE_FLAGS
-        -DGTEST_USE_OWN_TR1_TUPLE=0)
-    endif()
-
-    target_link_libraries(${TEST_NAME} ${TEST_LINK_LIBS})
-  else()
-    # No executable, just invoke the test (probably a script) directly.
-    set(TEST_PATH ${CMAKE_CURRENT_SOURCE_DIR}/${REL_TEST_NAME})
-  endif()
-
-  if (PARQUET_TEST_MEMCHECK)
-    SET_PROPERTY(TARGET ${TEST_NAME}
-      APPEND_STRING PROPERTY
-      COMPILE_FLAGS " -DPARQUET_VALGRIND")
-    add_test(${TEST_NAME}
-      valgrind --tool=memcheck --leak-check=full --error-exitcode=1 ${TEST_PATH})
-  elseif(MSVC)
-    add_test(${TEST_NAME} ${TEST_PATH})
-  else()
-    add_test(${TEST_NAME}
-        ${BUILD_SUPPORT_DIR}/run-test.sh ${CMAKE_BINARY_DIR} test ${TEST_PATH})
-  endif()
-  set_tests_properties(${TEST_NAME} PROPERTIES LABELS "unittest")
-  if(ARGN)
-    set_tests_properties(${TEST_NAME} PROPERTIES ${ARGN})
-  endif()
-endfunction()
-
-# A wrapper for add_dependencies() that is compatible with PARQUET_BUILD_TESTS.
-function(ADD_PARQUET_TEST_DEPENDENCIES REL_TEST_NAME)
-  if(NOT PARQUET_BUILD_TESTS)
-    return()
-  endif()
-  get_filename_component(TEST_NAME ${REL_TEST_NAME} NAME_WE)
-
-  add_dependencies(${TEST_NAME} ${ARGN})
-endfunction()
-
-# A wrapper for add_dependencies() that is compatible with PARQUET_BUILD_TESTS.
-function(ADD_PARQUET_LINK_LIBRARIES REL_TEST_NAME)
-  if(NOT PARQUET_BUILD_TESTS)
-    return()
-  endif()
-  get_filename_component(TEST_NAME ${REL_TEST_NAME} NAME_WE)
-
-  target_link_libraries(${TEST_NAME} ${ARGN})
-endfunction()
-
-enable_testing()
-
-############################################################
-# Dependencies
-############################################################
-
-# Determine compiler version
-include(CompilerInfo)
-include(SetupCxxFlags)
-
-include_directories(${CMAKE_CURRENT_BINARY_DIR}/src)
-include_directories(
-  ${CMAKE_CURRENT_SOURCE_DIR}/src
-)
-
-if (PARQUET_MINIMAL_DEPENDENCY)
-    set(IGNORE_OPTIONAL_PACKAGES ON)
-    message(STATUS "Build using minimal dependencies")
-else()
-    set(IGNORE_OPTIONAL_PACKAGES OFF)
-endif()
-include(ThirdpartyToolchain)
-
-set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CXX_COMMON_FLAGS}")
-set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${PARQUET_CXXFLAGS}")
-
-message(STATUS "CMAKE_CXX_FLAGS: ${CMAKE_CXX_FLAGS}")
-
-# Thrift requires these definitions for some types that we use
-add_definitions(-DHAVE_INTTYPES_H -DHAVE_NETDB_H)
-if (MSVC)
-  add_definitions(-DNOMINMAX -D_CRT_SECURE_NO_WARNINGS)
-else()
-  add_definitions(-DHAVE_NETINET_IN_H -fPIC)
-endif()
-
-############################################################
-# "make lint" target
-############################################################
-if (UNIX)
-  find_program(CPPLINT_BIN NAMES cpplint cpplint.py HINTS ${BUILD_SUPPORT_DIR})
-  message(STATUS "Found cpplint executable at ${CPPLINT_BIN}")
-  # Full lint
-  add_custom_target(lint ${CPPLINT_BIN}
-  --verbose=2
-  --linelength=90
-  --filter=-whitespace/comments,-readability/todo,-build/header_guard,-runtime/references,-readability/check,-build/c++11,-build/include_order
-    `find ${CMAKE_CURRENT_SOURCE_DIR}/src ${CMAKE_CURRENT_SOURCE_DIR}/tools ${CMAKE_CURRENT_SOURCE_DIR}/examples  ${CMAKE_CURRENT_SOURCE_DIR}/benchmarks -name \\*.cc -or -name \\*.h | sed -e '/parquet\\/parquet_/g'`)
-endif (UNIX)
-
-############################################################
-# "make format" and "make check-format" targets
-############################################################
-
-# runs clang format and updates files in place.
-add_custom_target(format-example
-  COMMAND
-  ${BUILD_SUPPORT_DIR}/run_clang_format.py
-  ${CLANG_FORMAT_BIN}
-  ${BUILD_SUPPORT_DIR}/clang_format_exclusions.txt
-  ${CMAKE_CURRENT_SOURCE_DIR}/examples)
-
-add_custom_target(format
-  DEPENDS format-example
-  COMMAND
-  ${BUILD_SUPPORT_DIR}/run_clang_format.py
-  ${CLANG_FORMAT_BIN}
-  ${BUILD_SUPPORT_DIR}/clang_format_exclusions.txt
-  ${CMAKE_CURRENT_SOURCE_DIR}/src)
-
-# runs clang format and exits with a non-zero exit code if any files need to be reformatted
-
-# TODO(wesm): Make this work in run_clang_format.py
-add_custom_target(check-format-examples ${BUILD_SUPPORT_DIR}/run_clang_format.py
-   ${CLANG_FORMAT_BIN}
-   ${BUILD_SUPPORT_DIR}/clang_format_exclusions.txt
-   ${CMAKE_CURRENT_SOURCE_DIR}/examples 1)
-add_custom_target(check-format
-   DEPENDS check-format-examples
-   COMMAND
-   ${BUILD_SUPPORT_DIR}/run_clang_format.py
-   ${CLANG_FORMAT_BIN}
-   ${BUILD_SUPPORT_DIR}/clang_format_exclusions.txt
-   ${CMAKE_CURRENT_SOURCE_DIR}/src 1)
-
-############################################################
-# "make clang-tidy" and "make check-clang-tidy" targets
-############################################################
-
-if (${CLANG_TIDY_FOUND})
-  # runs clang-tidy and attempts to fix any warning automatically
-  add_custom_target(clang-tidy ${BUILD_SUPPORT_DIR}/run-clang-tidy.sh ${CLANG_TIDY_BIN} ${CMAKE_BINARY_DIR}/compile_commands.json 1
-  `find ${CMAKE_CURRENT_SOURCE_DIR}/src ${CMAKE_CURRENT_SOURCE_DIR}/tools  ${CMAKE_CURRENT_SOURCE_DIR}/examples ${CMAKE_CURRENT_SOURCE_DIR}/benchmarks -name \\*.cc | sed -e '/_types/g' | sed -e '/_constants/g'`)
-  # runs clang-tidy and exits with a non-zero exit code if any errors are found.
-  add_custom_target(check-clang-tidy ${BUILD_SUPPORT_DIR}/run-clang-tidy.sh ${CLANG_TIDY_BIN} ${CMAKE_BINARY_DIR}/compile_commands.json
-  0 `find ${CMAKE_CURRENT_SOURCE_DIR}/src ${CMAKE_CURRENT_SOURCE_DIR}/tools  ${CMAKE_CURRENT_SOURCE_DIR}/examples ${CMAKE_CURRENT_SOURCE_DIR}/benchmarks -name \\*.cc |grep -v -F -f ${CMAKE_CURRENT_SOURCE_DIR}/.clang-tidy-ignore`)
-
-endif()
-
-#############################################################
-# Code coverage
-
-# Adapted from Apache Kudu (incubating)
-if ("${PARQUET_GENERATE_COVERAGE}")
-  if("${CMAKE_CXX_COMPILER}" MATCHES ".*clang.*")
-    # There appears to be some bugs in clang 3.3 which cause code coverage
-    # to have link errors, not locating the llvm_gcda_* symbols.
-    # This should be fixed in llvm 3.4 with http://llvm.org/viewvc/llvm-project?view=revision&revision=184666
-    message(SEND_ERROR "Cannot currently generate coverage with clang")
-  endif()
-  message(STATUS "Configuring build for gcov")
-  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --coverage")
-  # For coverage to work properly, we need to use static linkage. Otherwise,
-  # __gcov_flush() doesn't properly flush coverage from every module.
-  # See http://stackoverflow.com/questions/28164543/using-gcov-flush-within-a-library-doesnt-force-the-other-modules-to-yield-gc
-  if(NOT PARQUET_BUILD_STATIC)
-    message(SEND_ERROR "Coverage requires the static lib to be built")
-  endif()
-endif()
-
-#############################################################
-# Boost linkage
-
-if (PARQUET_BOOST_USE_SHARED)
-  set(BOOST_LINK_LIBS
-    boost_shared_regex)
-  if(MSVC)
-    set(BOOST_LINK_LIBS ${BOOST_LINK_LIBS}
-      boost_shared_system)
-  endif()
-else()
-  set(BOOST_LINK_LIBS
-    boost_static_regex)
-  if(MSVC)
-    set(BOOST_LINK_LIBS ${BOOST_LINK_LIBS}
-      boost_static_system boost_static_filesystem)
-  endif()
-endif()
-
-#############################################################
-# Apache Arrow linkage
-
-if ("${PARQUET_ARROW_LINKAGE}" STREQUAL "shared")
-  set(ARROW_LINK_LIBS
-    arrow)
-else()
-  #############################################################
-  # Transitive Library Linkage
-
-  if (NOT DEFINED ENV{BROTLI_STATIC_LIB_ENC} OR
-      NOT DEFINED ENV{BROTLI_STATIC_LIB_DEC} OR
-      NOT DEFINED ENV{BROTLI_STATIC_LIB_COMMON} OR
-      NOT DEFINED ENV{SNAPPY_STATIC_LIB} OR
-      NOT DEFINED ENV{ZLIB_STATIC_LIB} OR
-      NOT DEFINED ENV{LZ4_STATIC_LIB} OR
-      NOT DEFINED ENV{ZSTD_STATIC_LIB})
-    message(FATAL_ERROR "Missing transitive dependencies for Arrow static linking")
-  endif()
-
-  set(BROTLI_STATIC_LIB_ENC "$ENV{BROTLI_STATIC_LIB_ENC}")
-  set(BROTLI_STATIC_LIB_DEC "$ENV{BROTLI_STATIC_LIB_DEC}")
-  set(BROTLI_STATIC_LIB_COMMON "$ENV{BROTLI_STATIC_LIB_COMMON}")
-  set(SNAPPY_STATIC_LIB "$ENV{SNAPPY_STATIC_LIB}")
-  set(ZLIB_STATIC_LIB "$ENV{ZLIB_STATIC_LIB}")
-  set(LZ4_STATIC_LIB "$ENV{LZ4_STATIC_LIB}")
-  set(ZSTD_STATIC_LIB "$ENV{ZSTD_STATIC_LIB}")
-
-  add_library(brotli_enc STATIC IMPORTED)
-  set_target_properties(brotli_enc PROPERTIES IMPORTED_LOCATION ${BROTLI_STATIC_LIB_ENC})
-  add_library(brotli_dec STATIC IMPORTED)
-  set_target_properties(brotli_dec PROPERTIES IMPORTED_LOCATION ${BROTLI_STATIC_LIB_DEC})
-  add_library(brotli_common STATIC IMPORTED)
-  set_target_properties(brotli_common PROPERTIES IMPORTED_LOCATION ${BROTLI_STATIC_LIB_COMMON})
-  add_library(snappy STATIC IMPORTED)
-  set_target_properties(snappy PROPERTIES IMPORTED_LOCATION ${SNAPPY_STATIC_LIB})
-  add_library(zlib STATIC IMPORTED)
-  set_target_properties(zlib PROPERTIES IMPORTED_LOCATION ${ZLIB_STATIC_LIB})
-  add_library(lz4 STATIC IMPORTED)
-  set_target_properties(lz4 PROPERTIES IMPORTED_LOCATION ${LZ4_STATIC_LIB})
-  add_library(zstd STATIC IMPORTED)
-  set_target_properties(zstd PROPERTIES IMPORTED_LOCATION ${ZSTD_STATIC_LIB})
-
-  set(TRANSITIVE_LINK_LIBS
-    snappy
-    zlib
-    brotli_enc
-    brotli_dec
-    brotli_common
-    lz4
-    zstd
-  )
-
-  add_definitions(-DARROW_STATIC)
-
-  set(ARROW_LINK_LIBS
-    arrow_static
-    ${TRANSITIVE_LINK_LIBS})
-endif()
-
-#############################################################
-# Test linking
-
-set(PARQUET_MIN_TEST_LIBS
-  gtest
-  gtest_main)
-
-if (APPLE)
-  set(PARQUET_MIN_TEST_LIBS
-    ${PARQUET_MIN_TEST_LIBS}
-    ${CMAKE_DL_LIBS})
-elseif(NOT MSVC)
-  set(PARQUET_MIN_TEST_LIBS
-    ${PARQUET_MIN_TEST_LIBS}
-    pthread
-    ${CMAKE_DL_LIBS})
-endif()
-
-set(PARQUET_TEST_LINK_LIBS ${PARQUET_MIN_TEST_LIBS}
-  ${ARROW_LINK_LIBS}
-  parquet_static)
-
-set(PARQUET_TEST_SHARED_LINK_LIBS ${PARQUET_MIN_TEST_LIBS}
-  parquet_shared)
-
-#############################################################
-# Benchmark linking
-
-if (PARQUET_BUILD_STATIC)
-    set(PARQUET_BENCHMARK_LINK_LIBS
-      parquet_benchmark_main
-      parquet_static)
-else()
-    set(PARQUET_BENCHMARK_LINK_LIBS
-      parquet_benchmark_main
-      parquet_shared)
-endif()
-
-############################################################
-# Generated Thrift sources
-
-set(THRIFT_SRCS
-  src/parquet/parquet_constants.cpp
-  src/parquet/parquet_types.cpp)
-
-if (NOT MSVC)
-  set_source_files_properties(src/parquet/parquet_types.cpp PROPERTIES
-    COMPILE_FLAGS -Wno-unused-variable)
-endif()
-
-# List of thrift output targets
-set(THRIFT_OUTPUT_DIR ${CMAKE_CURRENT_BINARY_DIR}/src/parquet)
-set(THRIFT_OUTPUT_FILES "${THRIFT_OUTPUT_DIR}/parquet_types.cpp")
-set(THRIFT_OUTPUT_FILES ${THRIFT_OUTPUT_FILES} "${THRIFT_OUTPUT_DIR}/parquet_types.h")
-set(THRIFT_OUTPUT_FILES ${THRIFT_OUTPUT_FILES} "${THRIFT_OUTPUT_DIR}/parquet_constants.cpp")
-set(THRIFT_OUTPUT_FILES ${THRIFT_OUTPUT_FILES} "${THRIFT_OUTPUT_DIR}/parquet_constants.h")
-
-set_source_files_properties(${THRIFT_OUTPUT_FILES} PROPERTIES GENERATED TRUE)
-
-get_filename_component(ABS_PARQUET_THRIFT src/parquet/parquet.thrift ABSOLUTE)
-
-add_custom_command(
-  OUTPUT ${THRIFT_OUTPUT_FILES}
-  COMMAND ${THRIFT_COMPILER} --gen cpp -out ${THRIFT_OUTPUT_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/src/parquet/parquet.thrift
-  DEPENDS ${ABS_PARQUET_THRIFT} thriftstatic
-  COMMENT "Running thrift compiler on parquet.thrift"
-  VERBATIM
-)
-
-############################################################
-# Library config
-
-set(LIBPARQUET_SRCS
-  src/parquet/arrow/reader.cc
-  src/parquet/arrow/record_reader.cc
-  src/parquet/arrow/schema.cc
-  src/parquet/arrow/writer.cc
-  src/parquet/bloom_filter.cc
-  src/parquet/column_reader.cc
-  src/parquet/column_scanner.cc
-  src/parquet/column_writer.cc
-  src/parquet/exception.cc
-  src/parquet/file_reader.cc
-  src/parquet/file_writer.cc
-  src/parquet/metadata.cc
-  src/parquet/murmur3.cc
-  src/parquet/parquet_constants.cpp
-  src/parquet/parquet_types.cpp
-  src/parquet/printer.cc
-  src/parquet/schema.cc
-  src/parquet/statistics.cc
-  src/parquet/types.cc
-  src/parquet/util/comparison.cc
-  src/parquet/util/memory.cc
-)
-
-# # Ensure that thrift compilation is done before using its generated headers
-# # in parquet code.
-add_custom_target(thrift-deps ALL
-  DEPENDS ${THRIFT_OUTPUT_FILES})
-set(PARQUET_DEPENDENCIES ${PARQUET_DEPENDENCIES} thrift-deps)
-
-if (NOT PARQUET_MINIMAL_DEPENDENCY)
-# These are libraries that we will link privately with parquet_shared (as they
-# do not need to be linked transitively by other linkers), but publicly with
-# parquet_static (because internal users need to transitively link all
-# dependencies)
-  set(LIBPARQUET_INTERFACE_LINK_LIBS
-    ${ARROW_LINK_LIBS}
-    ${BOOST_LINK_LIBS}
-    thriftstatic
-  )
-# Although we don't link parquet_objlib against anything, we need it to depend
-# on these libs as we may generate their headers via ExternalProject_Add
-  set(PARQUET_DEPENDENCIES ${PARQUET_DEPENDENCIES} ${LIBPARQUET_INTERFACE_LINK_LIBS})
-endif()
-
-if(NOT APPLE AND NOT MSVC)
-  # Localize thirdparty symbols using a linker version script. This hides them
-  # from the client application. The OS X linker does not support the
-  # version-script option.
-  set(SHARED_LINK_FLAGS "-Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/src/parquet/symbols.map")
-endif()
-
-ADD_LIB(parquet
-        SOURCES ${LIBPARQUET_SRCS}
-        LIB_BUILD_SHARED ${PARQUET_BUILD_SHARED}
-        LIB_BUILD_STATIC ${PARQUET_BUILD_STATIC}
-        DEPENDENCIES ${PARQUET_DEPENDENCIES}
-        SHARED_LINK_FLAGS ${SHARED_LINK_FLAGS}
-        SHARED_PRIVATE_LINK_LIBS ${LIBPARQUET_INTERFACE_LINK_LIBS}
-        STATIC_LINK_LIBS ${LIBPARQUET_INTERFACE_LINK_LIBS}
-        ABI_VERSION ${PARQUET_ABI_VERSION}
-        SO_VERSION ${PARQUET_SO_VERSION}
-)
-
-############################################################
-# Visibility
-############################################################
-# For generate_export_header() and add_compiler_export_flags().
-include(GenerateExportHeader)
-
-# Adapted from Apache Kudu: https://github.com/apache/kudu/commit/bd549e13743a51013585
-# Honor visibility properties for all target types. See
-# "cmake --help-policy CMP0063" for details.
-#
-# This policy was only added to cmake in version 3.3, so until the cmake in
-# thirdparty is updated, we must check if the policy exists before setting it.
-if(POLICY CMP0063)
-  cmake_policy(SET CMP0063 NEW)
-endif()
-
-if (PARQUET_BUILD_SHARED)
-  if (POLICY CMP0063)
-    set_target_properties(parquet_shared
-      PROPERTIES C_VISIBILITY_PRESET hidden)
-    set_target_properties(parquet_shared
-      PROPERTIES CXX_VISIBILITY_PRESET hidden)
-    set_target_properties(parquet_shared
-      PROPERTIES VISIBILITY_INLINES_HIDDEN 1)
-  else()
-    # Sets -fvisibility=hidden for gcc
-    add_compiler_export_flags()
-  endif()
-endif()
-
-add_subdirectory(src/parquet)
-add_subdirectory(src/parquet/api)
-add_subdirectory(src/parquet/arrow)
-add_subdirectory(src/parquet/util)
-
-if (NOT MSVC)
-  add_subdirectory(benchmarks)
-endif()
-add_subdirectory(examples/low-level-api)
-add_subdirectory(tools)
-
-add_custom_target(clean-all
-   COMMAND ${CMAKE_BUILD_TOOL} clean
-   COMMAND ${CMAKE_COMMAND} -P cmake_modules/clean-all.cmake
-)
diff --git a/NOTICE.txt b/NOTICE.txt
deleted file mode 100644
index a1ab98e..0000000
--- a/NOTICE.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-Apache Parquet
-Copyright 2016 The Apache Software Foundation
-
-This product includes software developed at
-The Apache Software Foundation (http://www.apache.org/).
diff --git a/README.md b/README.md
index a42e7b4..cf0c62f 100644
--- a/README.md
+++ b/README.md
@@ -12,271 +12,11 @@
   limitations under the License. See accompanying LICENSE file.
 -->
 
-## Note: Development for Apache Parquet in C++ has moved
+# Note: Development for Apache Parquet in C++ has moved
 
-The Apache Arrow and Parquet have merged development process and build systems
-in the Arrow repository. Please submit pull requests in
+The Apache Arrow and Parquet C++ projects have merged development process and
+build systems in the Arrow repository. Please submit pull requests in
 https://github.com/apache/arrow.
 
 JIRA issues should continue to be opened in the PARQUET JIRA project.
-
-## Apache Parquet for C++: a C++ library to read and write the Apache Parquet
-   columnar data format.
-
-<table>
-  <tr>
-    <td>Build Status</td>
-    <td>
-    <a href="https://travis-ci.org/apache/parquet-cpp">
-    <img src="https://travis-ci.org/apache/parquet-cpp.svg?branch=master" alt="travis build status" />
-    </a>
-    </td>
-  </tr>
-  <tr>
-    <td>Test coverage</td>
-    <td>
-      <a href='https://coveralls.io/github/apache/parquet-cpp?branch=master'><img src='https://coveralls.io/repos/github/apache/parquet-cpp/badge.svg?branch=master' alt='Coverage Status' /></a>
-    </td>
-  </tr>
-</table>
-
-## System Dependencies
-
-We use the CMake build system and require a minimum version of 3.2. If you are
-using an older Linux distribution, you may need to use a PPA (for apt users) or
-build CMake from source.
-
-### Linux
-
-parquet-cpp requires gcc 4.8 or higher on Linux.
-
-To build parquet-cpp out of the box, you must install some build prerequisites
-for the thirdparty dependencies. On Debian/Ubuntu, these can be installed with:
-
-```
-sudo apt-get install libboost-dev libboost-filesystem-dev \
-                     libboost-program-options-dev libboost-regex-dev \
-                     libboost-system-dev libboost-test-dev \
-                     libssl-dev libtool bison flex pkg-config
-```
-
-### OS X
-
-You must use XCode 6 or higher. We recommend using Homebrew to install Boost,
-which is required for Thrift:
-
-```
-brew install boost
-```
-
-### Windows
-
-Check [Windows developer guide][1] for instructions to build parquet-cpp on Windows.
-
-## Third Party Dependencies
-
-- Apache Arrow >= 0.7.0 (memory management, compression, IO, optional columnar
-  data adapters)
-- Thrift 0.7+ [install instructions](https://thrift.apache.org/docs/install/)
-- googletest 1.7.0 (cannot be installed with package managers)
-- Google Benchmark (only required if building benchmarks)
-
-You can either install these dependencies separately, otherwise they will be
-built automatically as part of the build.
-
-Symbols from Thrift, Snappy, and ZLib are statically-linked into the
-`libparquet` shared library, so these dependencies must be built with `-fPIC`
-on Linux and OS X. Since Linux package managers do not consistently compile the
-static libraries for these components with `-fPIC`, you may have issues with
-Linux packages such as `libsnappy-dev`. It may be easier to depend on the
-thirdparty toolchain that parquet-cpp builds automatically.
-
-## Build
-
-- `cmake .`
-
-  - You can customize build dependency locations through various environment variables:
-    - ARROW_HOME customizes the Apache Arrow installed location.
-    - THRIFT_HOME customizes the Apache Thrift (C++ libraries and compiler
-      installed location.
-    - GTEST_HOME customizes the googletest installed location (if you are
-      building the unit tests).
-    - GBENCHMARK_HOME customizes the Google Benchmark installed location (if
-      you are building the benchmarks).
-
-- `make`
-
-The binaries will be built to ./debug which contains the libraries to link against as
-well as a few example executables.
-
-To disable the testing (which requires `googletest`), pass
-`-DPARQUET_BUILD_TESTS=Off` to `cmake`.
-
-For release-level builds (enable optimizations and disable debugging), pass
-`-DCMAKE_BUILD_TYPE=Release` to `cmake`.
-
-To build only the library with minimal dependencies, pass
-`-DPARQUET_MINIMAL_DEPENDENCY=ON` to `cmake`.
-Note that the executables, tests, and benchmarks should be disabled as well.
-
-Incremental builds can be done afterwords with just `make`.
-
-## Using with Apache Arrow
-
-Arrow provides some of the memory management and IO interfaces that we use in
-parquet-cpp. By default, Parquet links to Arrow's shared libraries. If you wish
-to statically-link the Arrow symbols instead, pass
-`-DPARQUET_ARROW_LINKAGE=static`.
-
-## Testing
-
-This library uses Google's `googletest` unit test framework. After building
-with `make`, you can run the test suite by running
-
-```
-make unittest
-```
-
-The test suite relies on an environment variable `PARQUET_TEST_DATA` pointing
-to the `data` directory in the source checkout, for example:
-
-```
-export PARQUET_TEST_DATA=`pwd`/data
-```
-
-See `ctest --help` for configuration details about ctest. On GNU/Linux systems,
-you can use valgrind with ctest to look for memory leaks:
-
-```
-valgrind --tool=memcheck --leak-check=yes ctest
-```
-
-## Building/Running benchmarks
-
-Follow the directions for simple build except run cmake
-with the `--PARQUET_BUILD_BENCHMARKS` parameter set correctly:
-
-    cmake -DPARQUET_BUILD_BENCHMARKS=ON ..
-
-and instead of make unittest run either `make; ctest` to run both unit tests
-and benchmarks or `make runbenchmark` to run only the benchmark tests.
-
-Benchmark logs will be placed in the build directory under `build/benchmark-logs`.
-
-
-## Out-of-source builds
-
-parquet-cpp supports out of source builds. For example:
-
-```
-mkdir test-build
-cd test-build
-cmake ..
-make
-ctest -L unittest
-```
-
-By using out-of-source builds you can preserve your current build state in case
-you need to switch to another git branch.
-
-Design
-========
-The library consists of 3 layers that map to the 3 units in the parquet format.
-
-The first is the encodings which correspond to data pages. The APIs at this level
-return single values.
-
-The second layer is the column reader which corresponds to column chunks. The APIs at
-this level return a triple: definition level, repetition level and value. It also handles
-reading pages, compression and managing encodings.
-
-The 3rd layer would handle reading/writing records.
-
-Developer Notes
-========
-The project adheres to the google coding convention:
-http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml
-with two notable exceptions. We do not encourage anonymous namespaces and the line
-length is 90 characters.
-
-You can run `cpplint` through the build system with
-
-```
-make lint
-```
-
-The project prefers the use of C++ style memory management. new/delete should be used
-over malloc/free. new/delete should be avoided whenever possible by using stl/boost
-where possible. For example, scoped_ptr instead of explicit new/delete and using
-std::vector instead of allocated buffers. Currently, c++11 features are not used.
-
-For error handling, this project uses exceptions.
-
-In general, many of the APIs at the layers are interface based for extensibility. To
-minimize the cost of virtual calls, the APIs should be batch-centric. For example,
-encoding should operate on batches of values rather than a single value.
-
-## Using clang with a custom gcc toolchain
-
-Suppose you are building libraries with a thirdparty gcc toolchain (not a
-built-in system one) on Linux. To use clang for development while linking to
-the proper toolchain, you can do (for out of source builds):
-
-```shell
-export CMAKE_CLANG_OPTIONS=--gcc-toolchain=$TOOLCHAIN/gcc-4.9.2
-
-export CC=$TOOLCHAIN/llvm-3.7.0/bin/clang
-export CXX=$TOOLCHAIN/llvm-3.7.0/bin/clang++
-
-cmake -DCMAKE_CLANG_OPTIONS=$CMAKE_CLANG_OPTIONS \
-	  -DCMAKE_CXX_FLAGS="-Werror" ..
-```
-
-## Code Coverage
-
-To build with `gcov` code coverage and upload results to http://coveralls.io or
-http://codecov.io, here are some instructions.
-
-First, build the project with coverage and run the test suite
-
-```
-cd $PARQUET_HOME
-mkdir coverage-build
-cd coverage-build
-cmake -DPARQUET_GENERATE_COVERAGE=1
-make -j$PARALLEL
-ctest -L unittest
-```
-
-The `gcov` artifacts are not located in a place that works well with either
-coveralls or codecov, so there is a helper script you need to run
-
-```
-mkdir coverage_artifacts
-python ../build-support/collect_coverage.py CMakeFiles/parquet.dir/src/ coverage_artifacts
-```
-
-For codecov.io (using the provided project token -- be sure to keep this
-private):
-
-```
-cd coverage_artifacts
-codecov --token $PARQUET_CPP_CODECOV_TOKEN --gcov-args '\-l' --root $PARQUET_ROOT
-```
-
-For coveralls, install `cpp_coveralls`:
-
-```
-pip install cpp_coveralls
-```
-
-And the coveralls upload script:
-
-```
-coveralls -t $PARQUET_CPP_COVERAGE_TOKEN --gcov-options '\-l' -r $PARQUET_ROOT --exclude $PARQUET_ROOT/thirdparty --exclude $PARQUET_ROOT/build --exclude $NATIVE_TOOLCHAIN --exclude $PARQUET_ROOT/src/parquet/thrift
-```
-
-Note that `gcov` throws off artifacts from the STL, so I excluded my toolchain
-root stored in `$NATIVE_TOOLCHAIN` to avoid a cluttered coverage report.
-
-[1]: https://github.com/apache/parquet-cpp/blob/master/docs/Windows.md
+Discussions continue to be help on the Parquet dev mailing list.
diff --git a/appveyor.yml b/appveyor.yml
deleted file mode 100644
index 5cc8354..0000000
--- a/appveyor.yml
+++ /dev/null
@@ -1,68 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you 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.
-
-# Operating system (build VM template)
-os: Visual Studio 2015
-
-matrix:
-  fast_finish: true
-
-environment:
-  matrix:
-    - GENERATOR: NMake Makefiles
-      PYTHON: "3.5"
-      ARCH: "64"
-      CONFIGURATION: "Release"
-    - GENERATOR: Visual Studio 14 2015 Win64
-      PYTHON: "3.5"
-      ARCH: "64"
-      CONFIGURATION: "Debug"
-    - GENERATOR: Visual Studio 15 2017 Win64
-      PYTHON: "3.5"
-      ARCH: "64"
-      CONFIGURATION: "Release"
-      APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
-      BOOST_ROOT: C:\Libraries\boost_1_64_0
-    - GENERATOR: Visual Studio 14 2015 Win64
-      PYTHON: "3.5"
-      ARCH: "64"
-      CONFIGURATION: "Debug"
-      USE_STATIC_CRT: "ON"
-    - GENERATOR: Visual Studio 14 2015 Win64
-      PYTHON: "3.5"
-      ARCH: "64"
-      CONFIGURATION: "Release"
-      USE_STATIC_CRT: "ON"
-    - GENERATOR: Visual Studio 14 2015 Win64
-      PYTHON: "3.5"
-      ARCH: "64"
-      CONFIGURATION: "Toolchain"
-
-  MSVC_DEFAULT_OPTIONS: ON
-  BOOST_ROOT: C:\Libraries\boost_1_63_0
-  BOOST_LIBRARYDIR: C:\Libraries\boost_1_63_0\lib64-msvc-14.0
-  USE_CLCACHE: false
-
-init:
-  - set MINICONDA=C:\Miniconda35-x64
-  - set PATH=%MINICONDA%;%MINICONDA%/Scripts;%MINICONDA%/Library/bin;%PATH%
-
-build_script:
-  - call ci\msvc-build.bat
-
-# Disable test discovery
-test: off
diff --git a/benchmarks/CMakeLists.txt b/benchmarks/CMakeLists.txt
deleted file mode 100644
index 9566aec..0000000
--- a/benchmarks/CMakeLists.txt
+++ /dev/null
@@ -1,32 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you 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.
-
-SET(LINK_LIBS
-  ${ARROW_LINK_LIBS}
-  ${PARQUET_MIN_TEST_LIBS}
-  thriftstatic)
-
-if (PARQUET_BUILD_BENCHMARKS)
-  add_executable(decode_benchmark decode_benchmark.cc)
-
-  add_dependencies(decode_benchmark gtest)
-
-  # This uses private APIs
-  target_link_libraries(decode_benchmark
-    ${LINK_LIBS}
-    parquet_static)
-endif()
diff --git a/benchmarks/decode_benchmark.cc b/benchmarks/decode_benchmark.cc
deleted file mode 100644
index 3ae32b4..0000000
--- a/benchmarks/decode_benchmark.cc
+++ /dev/null
@@ -1,471 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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.
-
-#include <stdio.h>
-#include <iostream>
-#include <random>
-
-#include "arrow/test-util.h"
-#include "arrow/util/compression.h"
-#include "arrow/util/compression_snappy.h"
-
-#include "parquet/encoding-internal.h"
-#include "parquet/util/logging.h"
-#include "parquet/util/stopwatch.h"
-
-/**
- * Test bed for encodings and some utilities to measure their throughput.
- * TODO: this file needs some major cleanup.
- */
-
-class DeltaBitPackEncoder {
- public:
-  explicit DeltaBitPackEncoder(int mini_block_size = 8) {
-    mini_block_size_ = mini_block_size;
-  }
-
-  void Add(int64_t v) { values_.push_back(v); }
-
-  uint8_t* Encode(int* encoded_len) {
-    uint8_t* result = new uint8_t[10 * 1024 * 1024];
-    int num_mini_blocks = static_cast<int>(arrow::BitUtil::CeilDiv(num_values() - 1,
-                                                                   mini_block_size_));
-    uint8_t* mini_block_widths = NULL;
-
-    arrow::BitWriter writer(result, 10 * 1024 * 1024);
-
-    // Writer the size of each block. We only use 1 block currently.
-    writer.PutVlqInt(static_cast<uint32_t>(num_mini_blocks * mini_block_size_));
-
-    // Write the number of mini blocks.
-    writer.PutVlqInt(static_cast<uint32_t>(num_mini_blocks));
-
-    // Write the number of values.
-    writer.PutVlqInt(num_values() - 1);
-
-    // Write the first value.
-    writer.PutZigZagVlqInt(static_cast<uint32_t>(values_[0]));
-
-    // Compute the values as deltas and the min delta.
-    int64_t min_delta = std::numeric_limits<int64_t>::max();
-    for (size_t i = values_.size() - 1; i > 0; --i) {
-      values_[i] -= values_[i - 1];
-      min_delta = std::min(min_delta, values_[i]);
-    }
-
-    // Write out the min delta.
-    writer.PutZigZagVlqInt(static_cast<int32_t>(min_delta));
-
-    // We need to save num_mini_blocks bytes to store the bit widths of the mini
-    // blocks.
-    mini_block_widths = writer.GetNextBytePtr(num_mini_blocks);
-
-    int idx = 1;
-    for (int i = 0; i < num_mini_blocks; ++i) {
-      int n = std::min(mini_block_size_, num_values() - idx);
-
-      // Compute the max delta in this mini block.
-      int64_t max_delta = std::numeric_limits<int64_t>::min();
-      for (int j = 0; j < n; ++j) {
-        max_delta = std::max(values_[idx + j], max_delta);
-      }
-
-      // The bit width for this block is the number of bits needed to store
-      // (max_delta - min_delta).
-      int bit_width = arrow::BitUtil::NumRequiredBits(max_delta - min_delta);
-      mini_block_widths[i] = static_cast<uint8_t>(bit_width);
-
-      // Encode this mini blocking using min_delta and bit_width
-      for (int j = 0; j < n; ++j) {
-        writer.PutValue(values_[idx + j] - min_delta, bit_width);
-      }
-
-      // Pad out the last block.
-      for (int j = n; j < mini_block_size_; ++j) {
-        writer.PutValue(0, bit_width);
-      }
-      idx += n;
-    }
-
-    writer.Flush();
-    *encoded_len = writer.bytes_written();
-    return result;
-  }
-
-  int num_values() const { return static_cast<int>(values_.size()); }
-
- private:
-  int mini_block_size_;
-  std::vector<int64_t> values_;
-};
-
-class DeltaLengthByteArrayEncoder {
- public:
-  explicit DeltaLengthByteArrayEncoder(int mini_block_size = 8)
-      : len_encoder_(mini_block_size),
-        buffer_(new uint8_t[10 * 1024 * 1024]),
-        offset_(0),
-        plain_encoded_len_(0) {}
-
-  void Add(const std::string& s) {
-    Add(reinterpret_cast<const uint8_t*>(s.data()), static_cast<int>(s.size()));
-  }
-
-  void Add(const uint8_t* ptr, int len) {
-    plain_encoded_len_ += static_cast<int>(len + sizeof(int));
-    len_encoder_.Add(len);
-    memcpy(buffer_ + offset_, ptr, len);
-    offset_ += len;
-  }
-
-  uint8_t* Encode(int* encoded_len) {
-    uint8_t* encoded_lengths = len_encoder_.Encode(encoded_len);
-    memmove(buffer_ + *encoded_len + sizeof(int), buffer_, offset_);
-    memcpy(buffer_, encoded_len, sizeof(int));
-    memcpy(buffer_ + sizeof(int), encoded_lengths, *encoded_len);
-    *encoded_len += static_cast<int>(offset_ + sizeof(int));
-    return buffer_;
-  }
-
-  int num_values() const { return len_encoder_.num_values(); }
-  int plain_encoded_len() const { return plain_encoded_len_; }
-
- private:
-  DeltaBitPackEncoder len_encoder_;
-  uint8_t* buffer_;
-  int offset_;
-  int plain_encoded_len_;
-};
-
-class DeltaByteArrayEncoder {
- public:
-  DeltaByteArrayEncoder() : plain_encoded_len_(0) {}
-
-  void Add(const std::string& s) {
-    plain_encoded_len_ += static_cast<int>(s.size() + sizeof(int));
-    int min_len = static_cast<int>(std::min(s.size(), last_value_.size()));
-    int prefix_len = 0;
-    for (int i = 0; i < min_len; ++i) {
-      if (s[i] == last_value_[i]) {
-        ++prefix_len;
-      } else {
-        break;
-      }
-    }
-    prefix_len_encoder_.Add(prefix_len);
-    suffix_encoder_.Add(reinterpret_cast<const uint8_t*>(s.data()) + prefix_len,
-                        static_cast<int>(s.size() - prefix_len));
-    last_value_ = s;
-  }
-
-  uint8_t* Encode(int* encoded_len) {
-    int prefix_buffer_len;
-    uint8_t* prefix_buffer = prefix_len_encoder_.Encode(&prefix_buffer_len);
-    int suffix_buffer_len;
-    uint8_t* suffix_buffer = suffix_encoder_.Encode(&suffix_buffer_len);
-
-    uint8_t* buffer = new uint8_t[10 * 1024 * 1024];
-    memcpy(buffer, &prefix_buffer_len, sizeof(int));
-    memcpy(buffer + sizeof(int), prefix_buffer, prefix_buffer_len);
-    memcpy(buffer + sizeof(int) + prefix_buffer_len, suffix_buffer, suffix_buffer_len);
-    *encoded_len = static_cast<int>(sizeof(int) + prefix_buffer_len + suffix_buffer_len);
-    return buffer;
-  }
-
-  int num_values() const { return prefix_len_encoder_.num_values(); }
-  int plain_encoded_len() const { return plain_encoded_len_; }
-
- private:
-  DeltaBitPackEncoder prefix_len_encoder_;
-  DeltaLengthByteArrayEncoder suffix_encoder_;
-  std::string last_value_;
-  int plain_encoded_len_;
-};
-
-uint64_t TestPlainIntEncoding(const uint8_t* data, int num_values, int batch_size) {
-  uint64_t result = 0;
-  parquet::PlainDecoder<parquet::Int64Type> decoder(nullptr);
-  decoder.SetData(num_values, data, static_cast<int>(num_values * sizeof(int64_t)));
-  std::vector<int64_t> values(batch_size);
-  for (int i = 0; i < num_values;) {
-    int n = decoder.Decode(values.data(), batch_size);
-    for (int j = 0; j < n; ++j) {
-      result += values[j];
-    }
-    i += n;
-  }
-  return result;
-}
-
-uint64_t TestBinaryPackedEncoding(const char* name, const std::vector<int64_t>& values,
-                                  int benchmark_iters = -1,
-                                  int benchmark_batch_size = 1) {
-  int mini_block_size;
-  if (values.size() < 8) {
-    mini_block_size = 8;
-  } else if (values.size() < 16) {
-    mini_block_size = 16;
-  } else {
-    mini_block_size = 32;
-  }
-  parquet::DeltaBitPackDecoder<parquet::Int64Type> decoder(nullptr);
-  DeltaBitPackEncoder encoder(mini_block_size);
-  for (size_t i = 0; i < values.size(); ++i) {
-    encoder.Add(values[i]);
-  }
-
-  int raw_len = static_cast<int>(encoder.num_values() * sizeof(int));
-  int len;
-  uint8_t* buffer = encoder.Encode(&len);
-
-  if (benchmark_iters == -1) {
-    printf("%s\n", name);
-    printf("  Raw len: %d\n", raw_len);
-    printf("  Encoded len: %d (%0.2f%%)\n", len,
-           static_cast<float>(len) * 100.0f / static_cast<float>(raw_len));
-    decoder.SetData(encoder.num_values(), buffer, len);
-    for (int i = 0; i < encoder.num_values(); ++i) {
-      int64_t x = 0;
-      decoder.Decode(&x, 1);
-      if (values[i] != x) {
-        std::cerr << "Bad: " << i << std::endl;
-        std::cerr << "  " << x << " != " << values[i] << std::endl;
-        break;
-      }
-    }
-    return 0;
-  } else {
-    printf("%s\n", name);
-    printf("  Raw len: %d\n", raw_len);
-    printf("  Encoded len: %d (%0.2f%%)\n", len,
-           static_cast<float>(len) * 100.0f / static_cast<float>(raw_len));
-
-    uint64_t result = 0;
-    std::vector<int64_t> buf(benchmark_batch_size);
-    parquet::StopWatch sw;
-    sw.Start();
-    for (int k = 0; k < benchmark_iters; ++k) {
-      decoder.SetData(encoder.num_values(), buffer, len);
-      for (size_t i = 0; i < values.size();) {
-        int n = decoder.Decode(buf.data(), benchmark_batch_size);
-        for (int j = 0; j < n; ++j) {
-          result += buf[j];
-        }
-        i += n;
-      }
-    }
-    uint64_t elapsed = sw.Stop();
-    double num_ints = static_cast<double>(values.size() * benchmark_iters) * 1000.;
-    printf("%s rate (batch size = %2d): %0.3fM per second.\n", name, benchmark_batch_size,
-           num_ints / static_cast<double>(elapsed));
-    return result;
-  }
-}
-
-#define DECODE_TEST(NAME, FN, DATA, BATCH_SIZE)                                \
-  sw.Start();                                                                  \
-  for (int i = 0; i < NUM_ITERS; ++i) {                                        \
-    FN(reinterpret_cast<uint8_t*>(&DATA[0]), NUM_VALUES, BATCH_SIZE);          \
-  }                                                                            \
-  elapsed = sw.Stop();                                                         \
-  printf("%s rate (batch size = %2d): %0.3fM per second.\n", NAME, BATCH_SIZE, \
-         mult / static_cast<double>(elapsed));
-
-void TestPlainIntCompressed(::arrow::Codec* codec, const std::vector<int64_t>& data,
-                            int num_iters, int batch_size) {
-  const uint8_t* raw_data = reinterpret_cast<const uint8_t*>(&data[0]);
-  int uncompressed_len = static_cast<int>(data.size() * sizeof(int64_t));
-  uint8_t* decompressed_data = new uint8_t[uncompressed_len];
-
-  int64_t max_compressed_size = codec->MaxCompressedLen(uncompressed_len, raw_data);
-  uint8_t* compressed_data = new uint8_t[max_compressed_size];
-  int64_t compressed_len;
-  DCHECK(codec
-             ->Compress(uncompressed_len, raw_data, max_compressed_size, compressed_data,
-                        &compressed_len)
-             .ok());
-
-  printf("\n%s:\n  Uncompressed len: %d\n  Compressed len:   %d\n", codec->name(),
-         uncompressed_len, static_cast<int>(compressed_len));
-
-  double mult = static_cast<double>(num_iters * data.size()) * 1000.;
-  parquet::StopWatch sw;
-  sw.Start();
-  uint64_t r = 0;
-  for (int i = 0; i < num_iters; ++i) {
-    ABORT_NOT_OK(codec->Decompress(compressed_len, compressed_data, uncompressed_len,
-                                   decompressed_data));
-    r += TestPlainIntEncoding(decompressed_data, static_cast<int>(data.size()),
-                              batch_size);
-  }
-  int64_t elapsed = sw.Stop();
-  printf("Compressed(%s) plain int rate (batch size = %2d): %0.3fM per second.\n",
-         codec->name(), batch_size, mult / static_cast<double>(elapsed));
-
-  delete[] compressed_data;
-  delete[] decompressed_data;
-}
-
-void TestBinaryPacking() {
-  std::vector<int64_t> values;
-  values.clear();
-  for (int i = 0; i < 100; ++i) values.push_back(0);
-  TestBinaryPackedEncoding("Zeros", values);
-
-  values.clear();
-  for (int i = 1; i <= 5; ++i) values.push_back(i);
-  TestBinaryPackedEncoding("Example 1", values);
-
-  values.clear();
-  values.push_back(7);
-  values.push_back(5);
-  values.push_back(3);
-  values.push_back(1);
-  values.push_back(2);
-  values.push_back(3);
-  values.push_back(4);
-  values.push_back(5);
-  TestBinaryPackedEncoding("Example 2", values);
-
-  // Test rand ints between 0 and 10K
-  values.clear();
-  int seed = 0;
-  std::mt19937 gen(seed);
-  std::uniform_int_distribution<int> d(0, 10000);
-  for (int i = 0; i < 500000; ++i) {
-    values.push_back(d(gen));
-  }
-  TestBinaryPackedEncoding("Rand [0, 10000)", values);
-
-  // Test rand ints between 0 and 100
-  values.clear();
-  std::uniform_int_distribution<int> d1(0, 100);
-  for (int i = 0; i < 500000; ++i) {
-    values.push_back(d1(gen));
-  }
-  TestBinaryPackedEncoding("Rand [0, 100)", values);
-}
-
-void TestDeltaLengthByteArray() {
-  parquet::DeltaLengthByteArrayDecoder decoder(nullptr);
-  DeltaLengthByteArrayEncoder encoder;
-
-  std::vector<std::string> values;
-  values.push_back("Hello");
-  values.push_back("World");
-  values.push_back("Foobar");
-  values.push_back("ABCDEF");
-
-  for (size_t i = 0; i < values.size(); ++i) {
-    encoder.Add(values[i]);
-  }
-
-  int len = 0;
-  uint8_t* buffer = encoder.Encode(&len);
-  printf("DeltaLengthByteArray\n  Raw len: %d\n  Encoded len: %d\n",
-         encoder.plain_encoded_len(), len);
-  decoder.SetData(encoder.num_values(), buffer, len);
-  for (int i = 0; i < encoder.num_values(); ++i) {
-    parquet::ByteArray v = {0, NULL};
-    decoder.Decode(&v, 1);
-    std::string r = std::string(reinterpret_cast<const char*>(v.ptr), v.len);
-    if (r != values[i]) {
-      std::cout << "Bad " << r << " != " << values[i] << std::endl;
-    }
-  }
-}
-
-void TestDeltaByteArray() {
-  parquet::DeltaByteArrayDecoder decoder(nullptr);
-  DeltaByteArrayEncoder encoder;
-
-  std::vector<std::string> values;
-
-  // Wikipedia example
-  values.push_back("myxa");
-  values.push_back("myxophyta");
-  values.push_back("myxopod");
-  values.push_back("nab");
-  values.push_back("nabbed");
-  values.push_back("nabbing");
-  values.push_back("nabit");
-  values.push_back("nabk");
-  values.push_back("nabob");
-  values.push_back("nacarat");
-  values.push_back("nacelle");
-
-  for (size_t i = 0; i < values.size(); ++i) {
-    encoder.Add(values[i]);
-  }
-
-  int len = 0;
-  uint8_t* buffer = encoder.Encode(&len);
-  printf("DeltaLengthByteArray\n  Raw len: %d\n  Encoded len: %d\n",
-         encoder.plain_encoded_len(), len);
-  decoder.SetData(encoder.num_values(), buffer, len);
-  for (int i = 0; i < encoder.num_values(); ++i) {
-    parquet::ByteArray v;
-    decoder.Decode(&v, 1);
-    std::string r = std::string(reinterpret_cast<const char*>(v.ptr), v.len);
-    if (r != values[i]) {
-      std::cout << "Bad " << r << " != " << values[i] << std::endl;
-    }
-  }
-}
-
-int main(int argc, char** argv) {
-  TestBinaryPacking();
-  TestDeltaLengthByteArray();
-  TestDeltaByteArray();
-
-  parquet::StopWatch sw;
-  uint64_t elapsed = 0;
-
-  const int NUM_VALUES = 1024 * 1024;
-  const int NUM_ITERS = 10;
-  const double mult = NUM_VALUES * NUM_ITERS * 1000.;
-
-  std::vector<int64_t> plain_int_data;
-  plain_int_data.resize(NUM_VALUES);
-
-  DECODE_TEST("Plain decoder", TestPlainIntEncoding, plain_int_data, 1);
-  DECODE_TEST("Plain decoder", TestPlainIntEncoding, plain_int_data, 16);
-  DECODE_TEST("Plain decoder", TestPlainIntEncoding, plain_int_data, 32);
-  DECODE_TEST("Plain decoder", TestPlainIntEncoding, plain_int_data, 64);
-
-  // Test rand ints between 0 and 10K
-  std::vector<int64_t> values;
-  int seed = 0;
-  std::mt19937 gen(seed);
-  std::uniform_int_distribution<int> d(0, 10000);
-  for (int i = 0; i < 1000000; ++i) {
-    values.push_back(d(gen));
-  }
-  TestBinaryPackedEncoding("Rand 0-10K", values, 100, 1);
-  TestBinaryPackedEncoding("Rand 0-10K", values, 100, 16);
-  TestBinaryPackedEncoding("Rand 0-10K", values, 100, 32);
-  TestBinaryPackedEncoding("Rand 0-10K", values, 100, 64);
-
-  ::arrow::SnappyCodec snappy_codec;
-
-  TestPlainIntCompressed(&snappy_codec, values, 100, 1);
-  TestPlainIntCompressed(&snappy_codec, values, 100, 16);
-  TestPlainIntCompressed(&snappy_codec, values, 100, 32);
-  TestPlainIntCompressed(&snappy_codec, values, 100, 64);
-
-  return 0;
-}
diff --git a/build-support/clang_format_exclusions.txt b/build-support/clang_format_exclusions.txt
deleted file mode 100644
index ce72d2f..0000000
--- a/build-support/clang_format_exclusions.txt
+++ /dev/null
@@ -1 +0,0 @@
-*_generated*
diff --git a/build-support/collect_coverage.py b/build-support/collect_coverage.py
deleted file mode 100755
index 6712760..0000000
--- a/build-support/collect_coverage.py
+++ /dev/null
@@ -1,43 +0,0 @@
-#!/usr/bin/env python
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you 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.
-
-import os
-import os.path as osp
-import shutil
-import sys
-
-
-def is_coverage_file(path):
-    return path.endswith('gcno') or path.endswith('gcda')
-
-
-def copy_files(path, outpath='.'):
-    for root, dirs, files in os.walk(path):
-        for fname in files:
-            if not is_coverage_file(fname):
-                continue
-            relpath = osp.join(root, fname)
-            dstpath = '_'.join((root.replace(path, '').replace('/', '_'),
-                                fname))
-
-            shutil.copy(relpath, osp.join(outpath, dstpath))
-
-if __name__ == '__main__':
-    path = sys.argv[1]
-    outpath = sys.argv[2]
-    copy_files(path, outpath)
diff --git a/build-support/cpplint.py b/build-support/cpplint.py
deleted file mode 100755
index ece520b..0000000
--- a/build-support/cpplint.py
+++ /dev/null
@@ -1,6323 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright (c) 2009 Google Inc. All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-#
-#    * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-#    * Redistributions in binary form must reproduce the above
-# copyright notice, this list of conditions and the following disclaimer
-# in the documentation and/or other materials provided with the
-# distribution.
-#    * Neither the name of Google Inc. nor the names of its
-# contributors may be used to endorse or promote products derived from
-# this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-"""Does google-lint on c++ files.
-
-The goal of this script is to identify places in the code that *may*
-be in non-compliance with google style.  It does not attempt to fix
-up these problems -- the point is to educate.  It does also not
-attempt to find all problems, or to ensure that everything it does
-find is legitimately a problem.
-
-In particular, we can get very confused by /* and // inside strings!
-We do a small hack, which is to ignore //'s with "'s after them on the
-same line, but it is far from perfect (in either direction).
-"""
-
-import codecs
-import copy
-import getopt
-import math  # for log
-import os
-import re
-import sre_compile
-import string
-import sys
-import unicodedata
-
-
-_USAGE = """
-Syntax: cpplint.py [--verbose=#] [--output=vs7] [--filter=-x,+y,...]
-                   [--counting=total|toplevel|detailed] [--root=subdir]
-                   [--linelength=digits]
-        <file> [file] ...
-
-  The style guidelines this tries to follow are those in
-    http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml
-
-  Every problem is given a confidence score from 1-5, with 5 meaning we are
-  certain of the problem, and 1 meaning it could be a legitimate construct.
-  This will miss some errors, and is not a substitute for a code review.
-
-  To suppress false-positive errors of a certain category, add a
-  'NOLINT(category)' comment to the line.  NOLINT or NOLINT(*)
-  suppresses errors of all categories on that line.
-
-  The files passed in will be linted; at least one file must be provided.
-  Default linted extensions are .cc, .cpp, .cu, .cuh and .h.  Change the
-  extensions with the --extensions flag.
-
-  Flags:
-
-    output=vs7
-      By default, the output is formatted to ease emacs parsing.  Visual Studio
-      compatible output (vs7) may also be used.  Other formats are unsupported.
-
-    verbose=#
-      Specify a number 0-5 to restrict errors to certain verbosity levels.
-
-    filter=-x,+y,...
-      Specify a comma-separated list of category-filters to apply: only
-      error messages whose category names pass the filters will be printed.
-      (Category names are printed with the message and look like
-      "[whitespace/indent]".)  Filters are evaluated left to right.
-      "-FOO" and "FOO" means "do not print categories that start with FOO".
-      "+FOO" means "do print categories that start with FOO".
-
-      Examples: --filter=-whitespace,+whitespace/braces
-                --filter=whitespace,runtime/printf,+runtime/printf_format
-                --filter=-,+build/include_what_you_use
-
-      To see a list of all the categories used in cpplint, pass no arg:
-         --filter=
-
-    counting=total|toplevel|detailed
-      The total number of errors found is always printed. If
-      'toplevel' is provided, then the count of errors in each of
-      the top-level categories like 'build' and 'whitespace' will
-      also be printed. If 'detailed' is provided, then a count
-      is provided for each category like 'build/class'.
-
-    root=subdir
-      The root directory used for deriving header guard CPP variable.
-      By default, the header guard CPP variable is calculated as the relative
-      path to the directory that contains .git, .hg, or .svn.  When this flag
-      is specified, the relative path is calculated from the specified
-      directory. If the specified directory does not exist, this flag is
-      ignored.
-
-      Examples:
-        Assuming that src/.git exists, the header guard CPP variables for
-        src/chrome/browser/ui/browser.h are:
-
-        No flag => CHROME_BROWSER_UI_BROWSER_H_
-        --root=chrome => BROWSER_UI_BROWSER_H_
-        --root=chrome/browser => UI_BROWSER_H_
-
-    linelength=digits
-      This is the allowed line length for the project. The default value is
-      80 characters.
-
-      Examples:
-        --linelength=120
-
-    extensions=extension,extension,...
-      The allowed file extensions that cpplint will check
-
-      Examples:
-        --extensions=hpp,cpp
-
-    cpplint.py supports per-directory configurations specified in CPPLINT.cfg
-    files. CPPLINT.cfg file can contain a number of key=value pairs.
-    Currently the following options are supported:
-
-      set noparent
-      filter=+filter1,-filter2,...
-      exclude_files=regex
-      linelength=80
-
-    "set noparent" option prevents cpplint from traversing directory tree
-    upwards looking for more .cfg files in parent directories. This option
-    is usually placed in the top-level project directory.
-
-    The "filter" option is similar in function to --filter flag. It specifies
-    message filters in addition to the |_DEFAULT_FILTERS| and those specified
-    through --filter command-line flag.
-
-    "exclude_files" allows to specify a regular expression to be matched against
-    a file name. If the expression matches, the file is skipped and not run
-    through liner.
-
-    "linelength" allows to specify the allowed line length for the project.
-
-    CPPLINT.cfg has an effect on files in the same directory and all
-    sub-directories, unless overridden by a nested configuration file.
-
-      Example file:
-        filter=-build/include_order,+build/include_alpha
-        exclude_files=.*\.cc
-
-    The above example disables build/include_order warning and enables
-    build/include_alpha as well as excludes all .cc from being
-    processed by linter, in the current directory (where the .cfg
-    file is located) and all sub-directories.
-"""
-
-# We categorize each error message we print.  Here are the categories.
-# We want an explicit list so we can list them all in cpplint --filter=.
-# If you add a new error message with a new category, add it to the list
-# here!  cpplint_unittest.py should tell you if you forget to do this.
-_ERROR_CATEGORIES = [
-    'build/class',
-    'build/c++11',
-    'build/deprecated',
-    'build/endif_comment',
-    'build/explicit_make_pair',
-    'build/forward_decl',
-    'build/header_guard',
-    'build/include',
-    'build/include_alpha',
-    'build/include_order',
-    'build/include_what_you_use',
-    'build/namespaces',
-    'build/printf_format',
-    'build/storage_class',
-    'legal/copyright',
-    'readability/alt_tokens',
-    'readability/braces',
-    'readability/casting',
-    'readability/check',
-    'readability/constructors',
-    'readability/fn_size',
-    'readability/function',
-    'readability/inheritance',
-    'readability/multiline_comment',
-    'readability/multiline_string',
-    'readability/namespace',
-    'readability/nolint',
-    'readability/nul',
-    'readability/strings',
-    'readability/todo',
-    'readability/utf8',
-    'runtime/arrays',
-    'runtime/casting',
-    'runtime/explicit',
-    'runtime/int',
-    'runtime/init',
-    'runtime/invalid_increment',
-    'runtime/member_string_references',
-    'runtime/memset',
-    'runtime/indentation_namespace',
-    'runtime/operator',
-    'runtime/printf',
-    'runtime/printf_format',
-    'runtime/references',
-    'runtime/string',
-    'runtime/threadsafe_fn',
-    'runtime/vlog',
-    'whitespace/blank_line',
-    'whitespace/braces',
-    'whitespace/comma',
-    'whitespace/comments',
-    'whitespace/empty_conditional_body',
-    'whitespace/empty_loop_body',
-    'whitespace/end_of_line',
-    'whitespace/ending_newline',
-    'whitespace/forcolon',
-    'whitespace/indent',
-    'whitespace/line_length',
-    'whitespace/newline',
-    'whitespace/operators',
-    'whitespace/parens',
-    'whitespace/semicolon',
-    'whitespace/tab',
-    'whitespace/todo',
-    ]
-
-# These error categories are no longer enforced by cpplint, but for backwards-
-# compatibility they may still appear in NOLINT comments.
-_LEGACY_ERROR_CATEGORIES = [
-    'readability/streams',
-    ]
-
-# The default state of the category filter. This is overridden by the --filter=
-# flag. By default all errors are on, so only add here categories that should be
-# off by default (i.e., categories that must be enabled by the --filter= flags).
-# All entries here should start with a '-' or '+', as in the --filter= flag.
-_DEFAULT_FILTERS = ['-build/include_alpha']
-
-# We used to check for high-bit characters, but after much discussion we
-# decided those were OK, as long as they were in UTF-8 and didn't represent
-# hard-coded international strings, which belong in a separate i18n file.
-
-# C++ headers
-_CPP_HEADERS = frozenset([
-    # Legacy
-    'algobase.h',
-    'algo.h',
-    'alloc.h',
-    'builtinbuf.h',
-    'bvector.h',
-    'complex.h',
-    'defalloc.h',
-    'deque.h',
-    'editbuf.h',
-    'fstream.h',
-    'function.h',
-    'hash_map',
-    'hash_map.h',
-    'hash_set',
-    'hash_set.h',
-    'hashtable.h',
-    'heap.h',
-    'indstream.h',
-    'iomanip.h',
-    'iostream.h',
-    'istream.h',
-    'iterator.h',
-    'list.h',
-    'map.h',
-    'multimap.h',
-    'multiset.h',
-    'ostream.h',
-    'pair.h',
-    'parsestream.h',
-    'pfstream.h',
-    'procbuf.h',
-    'pthread_alloc',
-    'pthread_alloc.h',
-    'rope',
-    'rope.h',
-    'ropeimpl.h',
-    'set.h',
-    'slist',
-    'slist.h',
-    'stack.h',
-    'stdiostream.h',
-    'stl_alloc.h',
-    'stl_relops.h',
-    'streambuf.h',
-    'stream.h',
-    'strfile.h',
-    'strstream.h',
-    'tempbuf.h',
-    'tree.h',
-    'type_traits.h',
-    'vector.h',
-    # 17.6.1.2 C++ library headers
-    'algorithm',
-    'array',
-    'atomic',
-    'bitset',
-    'chrono',
-    'codecvt',
-    'complex',
-    'condition_variable',
-    'deque',
-    'exception',
-    'forward_list',
-    'fstream',
-    'functional',
-    'future',
-    'initializer_list',
-    'iomanip',
-    'ios',
-    'iosfwd',
-    'iostream',
-    'istream',
-    'iterator',
-    'limits',
-    'list',
-    'locale',
-    'map',
-    'memory',
-    'mutex',
-    'new',
-    'numeric',
-    'ostream',
-    'queue',
-    'random',
-    'ratio',
-    'regex',
-    'set',
-    'sstream',
-    'stack',
-    'stdexcept',
-    'streambuf',
-    'string',
-    'strstream',
-    'system_error',
-    'thread',
-    'tuple',
-    'typeindex',
-    'typeinfo',
-    'type_traits',
-    'unordered_map',
-    'unordered_set',
-    'utility',
-    'valarray',
-    'vector',
-    # 17.6.1.2 C++ headers for C library facilities
-    'cassert',
-    'ccomplex',
-    'cctype',
-    'cerrno',
-    'cfenv',
-    'cfloat',
-    'cinttypes',
-    'ciso646',
-    'climits',
-    'clocale',
-    'cmath',
-    'csetjmp',
-    'csignal',
-    'cstdalign',
-    'cstdarg',
-    'cstdbool',
-    'cstddef',
-    'cstdint',
-    'cstdio',
-    'cstdlib',
-    'cstring',
-    'ctgmath',
-    'ctime',
-    'cuchar',
-    'cwchar',
-    'cwctype',
-    ])
-
-
-# These headers are excluded from [build/include] and [build/include_order]
-# checks:
-# - Anything not following google file name conventions (containing an
-#   uppercase character, such as Python.h or nsStringAPI.h, for example).
-# - Lua headers.
-_THIRD_PARTY_HEADERS_PATTERN = re.compile(
-    r'^(?:[^/]*[A-Z][^/]*\.h|lua\.h|lauxlib\.h|lualib\.h)$')
-
-
-# Assertion macros.  These are defined in base/logging.h and
-# testing/base/gunit.h.  Note that the _M versions need to come first
-# for substring matching to work.
-_CHECK_MACROS = [
-    'DCHECK', 'CHECK',
-    'EXPECT_TRUE_M', 'EXPECT_TRUE',
-    'ASSERT_TRUE_M', 'ASSERT_TRUE',
-    'EXPECT_FALSE_M', 'EXPECT_FALSE',
-    'ASSERT_FALSE_M', 'ASSERT_FALSE',
-    ]
-
-# Replacement macros for CHECK/DCHECK/EXPECT_TRUE/EXPECT_FALSE
-_CHECK_REPLACEMENT = dict([(m, {}) for m in _CHECK_MACROS])
-
-for op, replacement in [('==', 'EQ'), ('!=', 'NE'),
-                        ('>=', 'GE'), ('>', 'GT'),
-                        ('<=', 'LE'), ('<', 'LT')]:
-  _CHECK_REPLACEMENT['DCHECK'][op] = 'DCHECK_%s' % replacement
-  _CHECK_REPLACEMENT['CHECK'][op] = 'CHECK_%s' % replacement
-  _CHECK_REPLACEMENT['EXPECT_TRUE'][op] = 'EXPECT_%s' % replacement
-  _CHECK_REPLACEMENT['ASSERT_TRUE'][op] = 'ASSERT_%s' % replacement
-  _CHECK_REPLACEMENT['EXPECT_TRUE_M'][op] = 'EXPECT_%s_M' % replacement
-  _CHECK_REPLACEMENT['ASSERT_TRUE_M'][op] = 'ASSERT_%s_M' % replacement
-
-for op, inv_replacement in [('==', 'NE'), ('!=', 'EQ'),
-                            ('>=', 'LT'), ('>', 'LE'),
-                            ('<=', 'GT'), ('<', 'GE')]:
-  _CHECK_REPLACEMENT['EXPECT_FALSE'][op] = 'EXPECT_%s' % inv_replacement
-  _CHECK_REPLACEMENT['ASSERT_FALSE'][op] = 'ASSERT_%s' % inv_replacement
-  _CHECK_REPLACEMENT['EXPECT_FALSE_M'][op] = 'EXPECT_%s_M' % inv_replacement
-  _CHECK_REPLACEMENT['ASSERT_FALSE_M'][op] = 'ASSERT_%s_M' % inv_replacement
-
-# Alternative tokens and their replacements.  For full list, see section 2.5
-# Alternative tokens [lex.digraph] in the C++ standard.
-#
-# Digraphs (such as '%:') are not included here since it's a mess to
-# match those on a word boundary.
-_ALT_TOKEN_REPLACEMENT = {
-    'and': '&&',
-    'bitor': '|',
-    'or': '||',
-    'xor': '^',
-    'compl': '~',
-    'bitand': '&',
-    'and_eq': '&=',
-    'or_eq': '|=',
-    'xor_eq': '^=',
-    'not': '!',
-    'not_eq': '!='
-    }
-
-# Compile regular expression that matches all the above keywords.  The "[ =()]"
-# bit is meant to avoid matching these keywords outside of boolean expressions.
-#
-# False positives include C-style multi-line comments and multi-line strings
-# but those have always been troublesome for cpplint.
-_ALT_TOKEN_REPLACEMENT_PATTERN = re.compile(
-    r'[ =()](' + ('|'.join(_ALT_TOKEN_REPLACEMENT.keys())) + r')(?=[ (]|$)')
-
-
-# These constants define types of headers for use with
-# _IncludeState.CheckNextIncludeOrder().
-_C_SYS_HEADER = 1
-_CPP_SYS_HEADER = 2
-_LIKELY_MY_HEADER = 3
-_POSSIBLE_MY_HEADER = 4
-_OTHER_HEADER = 5
-
-# These constants define the current inline assembly state
-_NO_ASM = 0       # Outside of inline assembly block
-_INSIDE_ASM = 1   # Inside inline assembly block
-_END_ASM = 2      # Last line of inline assembly block
-_BLOCK_ASM = 3    # The whole block is an inline assembly block
-
-# Match start of assembly blocks
-_MATCH_ASM = re.compile(r'^\s*(?:asm|_asm|__asm|__asm__)'
-                        r'(?:\s+(volatile|__volatile__))?'
-                        r'\s*[{(]')
-
-
-_regexp_compile_cache = {}
-
-# {str, set(int)}: a map from error categories to sets of linenumbers
-# on which those errors are expected and should be suppressed.
-_error_suppressions = {}
-
-# The root directory used for deriving header guard CPP variable.
-# This is set by --root flag.
-_root = None
-
-# The allowed line length of files.
-# This is set by --linelength flag.
-_line_length = 80
-
-# The allowed extensions for file names
-# This is set by --extensions flag.
-_valid_extensions = set(['cc', 'h', 'cpp', 'cu', 'cuh'])
-
-def ParseNolintSuppressions(filename, raw_line, linenum, error):
-  """Updates the global list of error-suppressions.
-
-  Parses any NOLINT comments on the current line, updating the global
-  error_suppressions store.  Reports an error if the NOLINT comment
-  was malformed.
-
-  Args:
-    filename: str, the name of the input file.
-    raw_line: str, the line of input text, with comments.
-    linenum: int, the number of the current line.
-    error: function, an error handler.
-  """
-  matched = Search(r'\bNOLINT(NEXTLINE)?\b(\([^)]+\))?', raw_line)
-  if matched:
-    if matched.group(1):
-      suppressed_line = linenum + 1
-    else:
-      suppressed_line = linenum
-    category = matched.group(2)
-    if category in (None, '(*)'):  # => "suppress all"
-      _error_suppressions.setdefault(None, set()).add(suppressed_line)
-    else:
-      if category.startswith('(') and category.endswith(')'):
-        category = category[1:-1]
-        if category in _ERROR_CATEGORIES:
-          _error_suppressions.setdefault(category, set()).add(suppressed_line)
-        elif category not in _LEGACY_ERROR_CATEGORIES:
-          error(filename, linenum, 'readability/nolint', 5,
-                'Unknown NOLINT error category: %s' % category)
-
-
-def ResetNolintSuppressions():
-  """Resets the set of NOLINT suppressions to empty."""
-  _error_suppressions.clear()
-
-
-def IsErrorSuppressedByNolint(category, linenum):
-  """Returns true if the specified error category is suppressed on this line.
-
-  Consults the global error_suppressions map populated by
-  ParseNolintSuppressions/ResetNolintSuppressions.
-
-  Args:
-    category: str, the category of the error.
-    linenum: int, the current line number.
-  Returns:
-    bool, True iff the error should be suppressed due to a NOLINT comment.
-  """
-  return (linenum in _error_suppressions.get(category, set()) or
-          linenum in _error_suppressions.get(None, set()))
-
-
-def Match(pattern, s):
-  """Matches the string with the pattern, caching the compiled regexp."""
-  # The regexp compilation caching is inlined in both Match and Search for
-  # performance reasons; factoring it out into a separate function turns out
-  # to be noticeably expensive.
-  if pattern not in _regexp_compile_cache:
-    _regexp_compile_cache[pattern] = sre_compile.compile(pattern)
-  return _regexp_compile_cache[pattern].match(s)
-
-
-def ReplaceAll(pattern, rep, s):
-  """Replaces instances of pattern in a string with a replacement.
-
-  The compiled regex is kept in a cache shared by Match and Search.
-
-  Args:
-    pattern: regex pattern
-    rep: replacement text
-    s: search string
-
-  Returns:
-    string with replacements made (or original string if no replacements)
-  """
-  if pattern not in _regexp_compile_cache:
-    _regexp_compile_cache[pattern] = sre_compile.compile(pattern)
-  return _regexp_compile_cache[pattern].sub(rep, s)
-
-
-def Search(pattern, s):
-  """Searches the string for the pattern, caching the compiled regexp."""
-  if pattern not in _regexp_compile_cache:
-    _regexp_compile_cache[pattern] = sre_compile.compile(pattern)
-  return _regexp_compile_cache[pattern].search(s)
-
-
-class _IncludeState(object):
-  """Tracks line numbers for includes, and the order in which includes appear.
-
-  include_list contains list of lists of (header, line number) pairs.
-  It's a lists of lists rather than just one flat list to make it
-  easier to update across preprocessor boundaries.
-
-  Call CheckNextIncludeOrder() once for each header in the file, passing
-  in the type constants defined above. Calls in an illegal order will
-  raise an _IncludeError with an appropriate error message.
-
-  """
-  # self._section will move monotonically through this set. If it ever
-  # needs to move backwards, CheckNextIncludeOrder will raise an error.
-  _INITIAL_SECTION = 0
-  _MY_H_SECTION = 1
-  _C_SECTION = 2
-  _CPP_SECTION = 3
-  _OTHER_H_SECTION = 4
-
-  _TYPE_NAMES = {
-      _C_SYS_HEADER: 'C system header',
-      _CPP_SYS_HEADER: 'C++ system header',
-      _LIKELY_MY_HEADER: 'header this file implements',
-      _POSSIBLE_MY_HEADER: 'header this file may implement',
-      _OTHER_HEADER: 'other header',
-      }
-  _SECTION_NAMES = {
-      _INITIAL_SECTION: "... nothing. (This can't be an error.)",
-      _MY_H_SECTION: 'a header this file implements',
-      _C_SECTION: 'C system header',
-      _CPP_SECTION: 'C++ system header',
-      _OTHER_H_SECTION: 'other header',
-      }
-
-  def __init__(self):
-    self.include_list = [[]]
-    self.ResetSection('')
-
-  def FindHeader(self, header):
-    """Check if a header has already been included.
-
-    Args:
-      header: header to check.
-    Returns:
-      Line number of previous occurrence, or -1 if the header has not
-      been seen before.
-    """
-    for section_list in self.include_list:
-      for f in section_list:
-        if f[0] == header:
-          return f[1]
-    return -1
-
-  def ResetSection(self, directive):
-    """Reset section checking for preprocessor directive.
-
-    Args:
-      directive: preprocessor directive (e.g. "if", "else").
-    """
-    # The name of the current section.
-    self._section = self._INITIAL_SECTION
-    # The path of last found header.
-    self._last_header = ''
-
-    # Update list of includes.  Note that we never pop from the
-    # include list.
-    if directive in ('if', 'ifdef', 'ifndef'):
-      self.include_list.append([])
-    elif directive in ('else', 'elif'):
-      self.include_list[-1] = []
-
-  def SetLastHeader(self, header_path):
-    self._last_header = header_path
-
-  def CanonicalizeAlphabeticalOrder(self, header_path):
-    """Returns a path canonicalized for alphabetical comparison.
-
-    - replaces "-" with "_" so they both cmp the same.
-    - removes '-inl' since we don't require them to be after the main header.
-    - lowercase everything, just in case.
-
-    Args:
-      header_path: Path to be canonicalized.
-
-    Returns:
-      Canonicalized path.
-    """
-    return header_path.replace('-inl.h', '.h').replace('-', '_').lower()
-
-  def IsInAlphabeticalOrder(self, clean_lines, linenum, header_path):
-    """Check if a header is in alphabetical order with the previous header.
-
-    Args:
-      clean_lines: A CleansedLines instance containing the file.
-      linenum: The number of the line to check.
-      header_path: Canonicalized header to be checked.
-
-    Returns:
-      Returns true if the header is in alphabetical order.
-    """
-    # If previous section is different from current section, _last_header will
-    # be reset to empty string, so it's always less than current header.
-    #
-    # If previous line was a blank line, assume that the headers are
-    # intentionally sorted the way they are.
-    if (self._last_header > header_path and
-        Match(r'^\s*#\s*include\b', clean_lines.elided[linenum - 1])):
-      return False
-    return True
-
-  def CheckNextIncludeOrder(self, header_type):
-    """Returns a non-empty error message if the next header is out of order.
-
-    This function also updates the internal state to be ready to check
-    the next include.
-
-    Args:
-      header_type: One of the _XXX_HEADER constants defined above.
-
-    Returns:
-      The empty string if the header is in the right order, or an
-      error message describing what's wrong.
-
-    """
-    error_message = ('Found %s after %s' %
-                     (self._TYPE_NAMES[header_type],
-                      self._SECTION_NAMES[self._section]))
-
-    last_section = self._section
-
-    if header_type == _C_SYS_HEADER:
-      if self._section <= self._C_SECTION:
-        self._section = self._C_SECTION
-      else:
-        self._last_header = ''
-        return error_message
-    elif header_type == _CPP_SYS_HEADER:
-      if self._section <= self._CPP_SECTION:
-        self._section = self._CPP_SECTION
-      else:
-        self._last_header = ''
-        return error_message
-    elif header_type == _LIKELY_MY_HEADER:
-      if self._section <= self._MY_H_SECTION:
-        self._section = self._MY_H_SECTION
-      else:
-        self._section = self._OTHER_H_SECTION
-    elif header_type == _POSSIBLE_MY_HEADER:
-      if self._section <= self._MY_H_SECTION:
-        self._section = self._MY_H_SECTION
-      else:
-        # This will always be the fallback because we're not sure
-        # enough that the header is associated with this file.
-        self._section = self._OTHER_H_SECTION
-    else:
-      assert header_type == _OTHER_HEADER
-      self._section = self._OTHER_H_SECTION
-
-    if last_section != self._section:
-      self._last_header = ''
-
-    return ''
-
-
-class _CppLintState(object):
-  """Maintains module-wide state.."""
-
-  def __init__(self):
-    self.verbose_level = 1  # global setting.
-    self.error_count = 0    # global count of reported errors
-    # filters to apply when emitting error messages
-    self.filters = _DEFAULT_FILTERS[:]
-    # backup of filter list. Used to restore the state after each file.
-    self._filters_backup = self.filters[:]
-    self.counting = 'total'  # In what way are we counting errors?
-    self.errors_by_category = {}  # string to int dict storing error counts
-
-    # output format:
-    # "emacs" - format that emacs can parse (default)
-    # "vs7" - format that Microsoft Visual Studio 7 can parse
-    self.output_format = 'emacs'
-
-  def SetOutputFormat(self, output_format):
-    """Sets the output format for errors."""
-    self.output_format = output_format
-
-  def SetVerboseLevel(self, level):
-    """Sets the module's verbosity, and returns the previous setting."""
-    last_verbose_level = self.verbose_level
-    self.verbose_level = level
-    return last_verbose_level
-
-  def SetCountingStyle(self, counting_style):
-    """Sets the module's counting options."""
-    self.counting = counting_style
-
-  def SetFilters(self, filters):
-    """Sets the error-message filters.
-
-    These filters are applied when deciding whether to emit a given
-    error message.
-
-    Args:
-      filters: A string of comma-separated filters (eg "+whitespace/indent").
-               Each filter should start with + or -; else we die.
-
-    Raises:
-      ValueError: The comma-separated filters did not all start with '+' or '-'.
-                  E.g. "-,+whitespace,-whitespace/indent,whitespace/badfilter"
-    """
-    # Default filters always have less priority than the flag ones.
-    self.filters = _DEFAULT_FILTERS[:]
-    self.AddFilters(filters)
-
-  def AddFilters(self, filters):
-    """ Adds more filters to the existing list of error-message filters. """
-    for filt in filters.split(','):
-      clean_filt = filt.strip()
-      if clean_filt:
-        self.filters.append(clean_filt)
-    for filt in self.filters:
-      if not (filt.startswith('+') or filt.startswith('-')):
-        raise ValueError('Every filter in --filters must start with + or -'
-                         ' (%s does not)' % filt)
-
-  def BackupFilters(self):
-    """ Saves the current filter list to backup storage."""
-    self._filters_backup = self.filters[:]
-
-  def RestoreFilters(self):
-    """ Restores filters previously backed up."""
-    self.filters = self._filters_backup[:]
-
-  def ResetErrorCounts(self):
-    """Sets the module's error statistic back to zero."""
-    self.error_count = 0
-    self.errors_by_category = {}
-
-  def IncrementErrorCount(self, category):
-    """Bumps the module's error statistic."""
-    self.error_count += 1
-    if self.counting in ('toplevel', 'detailed'):
-      if self.counting != 'detailed':
-        category = category.split('/')[0]
-      if category not in self.errors_by_category:
-        self.errors_by_category[category] = 0
-      self.errors_by_category[category] += 1
-
-  def PrintErrorCounts(self):
-    """Print a summary of errors by category, and the total."""
-    for category, count in self.errors_by_category.iteritems():
-      sys.stderr.write('Category \'%s\' errors found: %d\n' %
-                       (category, count))
-    sys.stderr.write('Total errors found: %d\n' % self.error_count)
-
-_cpplint_state = _CppLintState()
-
-
-def _OutputFormat():
-  """Gets the module's output format."""
-  return _cpplint_state.output_format
-
-
-def _SetOutputFormat(output_format):
-  """Sets the module's output format."""
-  _cpplint_state.SetOutputFormat(output_format)
-
-
-def _VerboseLevel():
-  """Returns the module's verbosity setting."""
-  return _cpplint_state.verbose_level
-
-
-def _SetVerboseLevel(level):
-  """Sets the module's verbosity, and returns the previous setting."""
-  return _cpplint_state.SetVerboseLevel(level)
-
-
-def _SetCountingStyle(level):
-  """Sets the module's counting options."""
-  _cpplint_state.SetCountingStyle(level)
-
-
-def _Filters():
-  """Returns the module's list of output filters, as a list."""
-  return _cpplint_state.filters
-
-
-def _SetFilters(filters):
-  """Sets the module's error-message filters.
-
-  These filters are applied when deciding whether to emit a given
-  error message.
-
-  Args:
-    filters: A string of comma-separated filters (eg "whitespace/indent").
-             Each filter should start with + or -; else we die.
-  """
-  _cpplint_state.SetFilters(filters)
-
-def _AddFilters(filters):
-  """Adds more filter overrides.
-
-  Unlike _SetFilters, this function does not reset the current list of filters
-  available.
-
-  Args:
-    filters: A string of comma-separated filters (eg "whitespace/indent").
-             Each filter should start with + or -; else we die.
-  """
-  _cpplint_state.AddFilters(filters)
-
-def _BackupFilters():
-  """ Saves the current filter list to backup storage."""
-  _cpplint_state.BackupFilters()
-
-def _RestoreFilters():
-  """ Restores filters previously backed up."""
-  _cpplint_state.RestoreFilters()
-
-class _FunctionState(object):
-  """Tracks current function name and the number of lines in its body."""
-
-  _NORMAL_TRIGGER = 250  # for --v=0, 500 for --v=1, etc.
-  _TEST_TRIGGER = 400    # about 50% more than _NORMAL_TRIGGER.
-
-  def __init__(self):
-    self.in_a_function = False
-    self.lines_in_function = 0
-    self.current_function = ''
-
-  def Begin(self, function_name):
-    """Start analyzing function body.
-
-    Args:
-      function_name: The name of the function being tracked.
-    """
-    self.in_a_function = True
-    self.lines_in_function = 0
-    self.current_function = function_name
-
-  def Count(self):
-    """Count line in current function body."""
-    if self.in_a_function:
-      self.lines_in_function += 1
-
-  def Check(self, error, filename, linenum):
-    """Report if too many lines in function body.
-
-    Args:
-      error: The function to call with any errors found.
-      filename: The name of the current file.
-      linenum: The number of the line to check.
-    """
-    if Match(r'T(EST|est)', self.current_function):
-      base_trigger = self._TEST_TRIGGER
-    else:
-      base_trigger = self._NORMAL_TRIGGER
-    trigger = base_trigger * 2**_VerboseLevel()
-
-    if self.lines_in_function > trigger:
-      error_level = int(math.log(self.lines_in_function / base_trigger, 2))
-      # 50 => 0, 100 => 1, 200 => 2, 400 => 3, 800 => 4, 1600 => 5, ...
-      if error_level > 5:
-        error_level = 5
-      error(filename, linenum, 'readability/fn_size', error_level,
-            'Small and focused functions are preferred:'
-            ' %s has %d non-comment lines'
-            ' (error triggered by exceeding %d lines).'  % (
-                self.current_function, self.lines_in_function, trigger))
-
-  def End(self):
-    """Stop analyzing function body."""
-    self.in_a_function = False
-
-
-class _IncludeError(Exception):
-  """Indicates a problem with the include order in a file."""
-  pass
-
-
-class FileInfo(object):
-  """Provides utility functions for filenames.
-
-  FileInfo provides easy access to the components of a file's path
-  relative to the project root.
-  """
-
-  def __init__(self, filename):
-    self._filename = filename
-
-  def FullName(self):
-    """Make Windows paths like Unix."""
-    return os.path.abspath(self._filename).replace('\\', '/')
-
-  def RepositoryName(self):
-    """FullName after removing the local path to the repository.
-
-    If we have a real absolute path name here we can try to do something smart:
-    detecting the root of the checkout and truncating /path/to/checkout from
-    the name so that we get header guards that don't include things like
-    "C:\Documents and Settings\..." or "/home/username/..." in them and thus
-    people on different computers who have checked the source out to different
-    locations won't see bogus errors.
-    """
-    fullname = self.FullName()
-
-    if os.path.exists(fullname):
-      project_dir = os.path.dirname(fullname)
-
-      if os.path.exists(os.path.join(project_dir, ".svn")):
-        # If there's a .svn file in the current directory, we recursively look
-        # up the directory tree for the top of the SVN checkout
-        root_dir = project_dir
-        one_up_dir = os.path.dirname(root_dir)
-        while os.path.exists(os.path.join(one_up_dir, ".svn")):
-          root_dir = os.path.dirname(root_dir)
-          one_up_dir = os.path.dirname(one_up_dir)
-
-        prefix = os.path.commonprefix([root_dir, project_dir])
-        return fullname[len(prefix) + 1:]
-
-      # Not SVN <= 1.6? Try to find a git, hg, or svn top level directory by
-      # searching up from the current path.
-      root_dir = os.path.dirname(fullname)
-      while (root_dir != os.path.dirname(root_dir) and
-             not os.path.exists(os.path.join(root_dir, ".git")) and
-             not os.path.exists(os.path.join(root_dir, ".hg")) and
-             not os.path.exists(os.path.join(root_dir, ".svn"))):
-        root_dir = os.path.dirname(root_dir)
-
-      if (os.path.exists(os.path.join(root_dir, ".git")) or
-          os.path.exists(os.path.join(root_dir, ".hg")) or
-          os.path.exists(os.path.join(root_dir, ".svn"))):
-        prefix = os.path.commonprefix([root_dir, project_dir])
-        return fullname[len(prefix) + 1:]
-
-    # Don't know what to do; header guard warnings may be wrong...
-    return fullname
-
-  def Split(self):
-    """Splits the file into the directory, basename, and extension.
-
-    For 'chrome/browser/browser.cc', Split() would
-    return ('chrome/browser', 'browser', '.cc')
-
-    Returns:
-      A tuple of (directory, basename, extension).
-    """
-
-    googlename = self.RepositoryName()
-    project, rest = os.path.split(googlename)
-    return (project,) + os.path.splitext(rest)
-
-  def BaseName(self):
-    """File base name - text after the final slash, before the final period."""
-    return self.Split()[1]
-
-  def Extension(self):
-    """File extension - text following the final period."""
-    return self.Split()[2]
-
-  def NoExtension(self):
-    """File has no source file extension."""
-    return '/'.join(self.Split()[0:2])
-
-  def IsSource(self):
-    """File has a source file extension."""
-    return self.Extension()[1:] in ('c', 'cc', 'cpp', 'cxx')
-
-
-def _ShouldPrintError(category, confidence, linenum):
-  """If confidence >= verbose, category passes filter and is not suppressed."""
-
-  # There are three ways we might decide not to print an error message:
-  # a "NOLINT(category)" comment appears in the source,
-  # the verbosity level isn't high enough, or the filters filter it out.
-  if IsErrorSuppressedByNolint(category, linenum):
-    return False
-
-  if confidence < _cpplint_state.verbose_level:
-    return False
-
-  is_filtered = False
-  for one_filter in _Filters():
-    if one_filter.startswith('-'):
-      if category.startswith(one_filter[1:]):
-        is_filtered = True
-    elif one_filter.startswith('+'):
-      if category.startswith(one_filter[1:]):
-        is_filtered = False
-    else:
-      assert False  # should have been checked for in SetFilter.
-  if is_filtered:
-    return False
-
-  return True
-
-
-def Error(filename, linenum, category, confidence, message):
-  """Logs the fact we've found a lint error.
-
-  We log where the error was found, and also our confidence in the error,
-  that is, how certain we are this is a legitimate style regression, and
-  not a misidentification or a use that's sometimes justified.
-
-  False positives can be suppressed by the use of
-  "cpplint(category)"  comments on the offending line.  These are
-  parsed into _error_suppressions.
-
-  Args:
-    filename: The name of the file containing the error.
-    linenum: The number of the line containing the error.
-    category: A string used to describe the "category" this bug
-      falls under: "whitespace", say, or "runtime".  Categories
-      may have a hierarchy separated by slashes: "whitespace/indent".
-    confidence: A number from 1-5 representing a confidence score for
-      the error, with 5 meaning that we are certain of the problem,
-      and 1 meaning that it could be a legitimate construct.
-    message: The error message.
-  """
-  if _ShouldPrintError(category, confidence, linenum):
-    _cpplint_state.IncrementErrorCount(category)
-    if _cpplint_state.output_format == 'vs7':
-      sys.stderr.write('%s(%s):  %s  [%s] [%d]\n' % (
-          filename, linenum, message, category, confidence))
-    elif _cpplint_state.output_format == 'eclipse':
-      sys.stderr.write('%s:%s: warning: %s  [%s] [%d]\n' % (
-          filename, linenum, message, category, confidence))
-    else:
-      sys.stderr.write('%s:%s:  %s  [%s] [%d]\n' % (
-          filename, linenum, message, category, confidence))
-
-
-# Matches standard C++ escape sequences per 2.13.2.3 of the C++ standard.
-_RE_PATTERN_CLEANSE_LINE_ESCAPES = re.compile(
-    r'\\([abfnrtv?"\\\']|\d+|x[0-9a-fA-F]+)')
-# Match a single C style comment on the same line.
-_RE_PATTERN_C_COMMENTS = r'/\*(?:[^*]|\*(?!/))*\*/'
-# Matches multi-line C style comments.
-# This RE is a little bit more complicated than one might expect, because we
-# have to take care of space removals tools so we can handle comments inside
-# statements better.
-# The current rule is: We only clear spaces from both sides when we're at the
-# end of the line. Otherwise, we try to remove spaces from the right side,
-# if this doesn't work we try on left side but only if there's a non-character
-# on the right.
-_RE_PATTERN_CLEANSE_LINE_C_COMMENTS = re.compile(
-    r'(\s*' + _RE_PATTERN_C_COMMENTS + r'\s*$|' +
-    _RE_PATTERN_C_COMMENTS + r'\s+|' +
-    r'\s+' + _RE_PATTERN_C_COMMENTS + r'(?=\W)|' +
-    _RE_PATTERN_C_COMMENTS + r')')
-
-
-def IsCppString(line):
-  """Does line terminate so, that the next symbol is in string constant.
-
-  This function does not consider single-line nor multi-line comments.
-
-  Args:
-    line: is a partial line of code starting from the 0..n.
-
-  Returns:
-    True, if next character appended to 'line' is inside a
-    string constant.
-  """
-
-  line = line.replace(r'\\', 'XX')  # after this, \\" does not match to \"
-  return ((line.count('"') - line.count(r'\"') - line.count("'\"'")) & 1) == 1
-
-
-def CleanseRawStrings(raw_lines):
-  """Removes C++11 raw strings from lines.
-
-    Before:
-      static const char kData[] = R"(
-          multi-line string
-          )";
-
-    After:
-      static const char kData[] = ""
-          (replaced by blank line)
-          "";
-
-  Args:
-    raw_lines: list of raw lines.
-
-  Returns:
-    list of lines with C++11 raw strings replaced by empty strings.
-  """
-
-  delimiter = None
-  lines_without_raw_strings = []
-  for line in raw_lines:
-    if delimiter:
-      # Inside a raw string, look for the end
-      end = line.find(delimiter)
-      if end >= 0:
-        # Found the end of the string, match leading space for this
-        # line and resume copying the original lines, and also insert
-        # a "" on the last line.
-        leading_space = Match(r'^(\s*)\S', line)
-        line = leading_space.group(1) + '""' + line[end + len(delimiter):]
-        delimiter = None
-      else:
-        # Haven't found the end yet, append a blank line.
-        line = '""'
-
-    # Look for beginning of a raw string, and replace them with
-    # empty strings.  This is done in a loop to handle multiple raw
-    # strings on the same line.
-    while delimiter is None:
-      # Look for beginning of a raw string.
-      # See 2.14.15 [lex.string] for syntax.
-      matched = Match(r'^(.*)\b(?:R|u8R|uR|UR|LR)"([^\s\\()]*)\((.*)$', line)
-      if matched:
-        delimiter = ')' + matched.group(2) + '"'
-
-        end = matched.group(3).find(delimiter)
-        if end >= 0:
-          # Raw string ended on same line
-          line = (matched.group(1) + '""' +
-                  matched.group(3)[end + len(delimiter):])
-          delimiter = None
-        else:
-          # Start of a multi-line raw string
-          line = matched.group(1) + '""'
-      else:
-        break
-
-    lines_without_raw_strings.append(line)
-
-  # TODO(unknown): if delimiter is not None here, we might want to
-  # emit a warning for unterminated string.
-  return lines_without_raw_strings
-
-
-def FindNextMultiLineCommentStart(lines, lineix):
-  """Find the beginning marker for a multiline comment."""
-  while lineix < len(lines):
-    if lines[lineix].strip().startswith('/*'):
-      # Only return this marker if the comment goes beyond this line
-      if lines[lineix].strip().find('*/', 2) < 0:
-        return lineix
-    lineix += 1
-  return len(lines)
-
-
-def FindNextMultiLineCommentEnd(lines, lineix):
-  """We are inside a comment, find the end marker."""
-  while lineix < len(lines):
-    if lines[lineix].strip().endswith('*/'):
-      return lineix
-    lineix += 1
-  return len(lines)
-
-
-def RemoveMultiLineCommentsFromRange(lines, begin, end):
-  """Clears a range of lines for multi-line comments."""
-  # Having // dummy comments makes the lines non-empty, so we will not get
-  # unnecessary blank line warnings later in the code.
-  for i in range(begin, end):
-    lines[i] = '/**/'
-
-
-def RemoveMultiLineComments(filename, lines, error):
-  """Removes multiline (c-style) comments from lines."""
-  lineix = 0
-  while lineix < len(lines):
-    lineix_begin = FindNextMultiLineCommentStart(lines, lineix)
-    if lineix_begin >= len(lines):
-      return
-    lineix_end = FindNextMultiLineCommentEnd(lines, lineix_begin)
-    if lineix_end >= len(lines):
-      error(filename, lineix_begin + 1, 'readability/multiline_comment', 5,
-            'Could not find end of multi-line comment')
-      return
-    RemoveMultiLineCommentsFromRange(lines, lineix_begin, lineix_end + 1)
-    lineix = lineix_end + 1
-
-
-def CleanseComments(line):
-  """Removes //-comments and single-line C-style /* */ comments.
-
-  Args:
-    line: A line of C++ source.
-
-  Returns:
-    The line with single-line comments removed.
-  """
-  commentpos = line.find('//')
-  if commentpos != -1 and not IsCppString(line[:commentpos]):
-    line = line[:commentpos].rstrip()
-  # get rid of /* ... */
-  return _RE_PATTERN_CLEANSE_LINE_C_COMMENTS.sub('', line)
-
-
-class CleansedLines(object):
-  """Holds 4 copies of all lines with different preprocessing applied to them.
-
-  1) elided member contains lines without strings and comments.
-  2) lines member contains lines without comments.
-  3) raw_lines member contains all the lines without processing.
-  4) lines_without_raw_strings member is same as raw_lines, but with C++11 raw
-     strings removed.
-  All these members are of <type 'list'>, and of the same length.
-  """
-
-  def __init__(self, lines):
-    self.elided = []
-    self.lines = []
-    self.raw_lines = lines
-    self.num_lines = len(lines)
-    self.lines_without_raw_strings = CleanseRawStrings(lines)
-    for linenum in range(len(self.lines_without_raw_strings)):
-      self.lines.append(CleanseComments(
-          self.lines_without_raw_strings[linenum]))
-      elided = self._CollapseStrings(self.lines_without_raw_strings[linenum])
-      self.elided.append(CleanseComments(elided))
-
-  def NumLines(self):
-    """Returns the number of lines represented."""
-    return self.num_lines
-
-  @staticmethod
-  def _CollapseStrings(elided):
-    """Collapses strings and chars on a line to simple "" or '' blocks.
-
-    We nix strings first so we're not fooled by text like '"http://"'
-
-    Args:
-      elided: The line being processed.
-
-    Returns:
-      The line with collapsed strings.
-    """
-    if _RE_PATTERN_INCLUDE.match(elided):
-      return elided
-
-    # Remove escaped characters first to make quote/single quote collapsing
-    # basic.  Things that look like escaped characters shouldn't occur
-    # outside of strings and chars.
-    elided = _RE_PATTERN_CLEANSE_LINE_ESCAPES.sub('', elided)
-
-    # Replace quoted strings and digit separators.  Both single quotes
-    # and double quotes are processed in the same loop, otherwise
-    # nested quotes wouldn't work.
-    collapsed = ''
-    while True:
-      # Find the first quote character
-      match = Match(r'^([^\'"]*)([\'"])(.*)$', elided)
-      if not match:
-        collapsed += elided
-        break
-      head, quote, tail = match.groups()
-
-      if quote == '"':
-        # Collapse double quoted strings
-        second_quote = tail.find('"')
-        if second_quote >= 0:
-          collapsed += head + '""'
-          elided = tail[second_quote + 1:]
-        else:
-          # Unmatched double quote, don't bother processing the rest
-          # of the line since this is probably a multiline string.
-          collapsed += elided
-          break
-      else:
-        # Found single quote, check nearby text to eliminate digit separators.
-        #
-        # There is no special handling for floating point here, because
-        # the integer/fractional/exponent parts would all be parsed
-        # correctly as long as there are digits on both sides of the
-        # separator.  So we are fine as long as we don't see something
-        # like "0.'3" (gcc 4.9.0 will not allow this literal).
-        if Search(r'\b(?:0[bBxX]?|[1-9])[0-9a-fA-F]*$', head):
-          match_literal = Match(r'^((?:\'?[0-9a-zA-Z_])*)(.*)$', "'" + tail)
-          collapsed += head + match_literal.group(1).replace("'", '')
-          elided = match_literal.group(2)
-        else:
-          second_quote = tail.find('\'')
-          if second_quote >= 0:
-            collapsed += head + "''"
-            elided = tail[second_quote + 1:]
-          else:
-            # Unmatched single quote
-            collapsed += elided
-            break
-
-    return collapsed
-
-
-def FindEndOfExpressionInLine(line, startpos, stack):
-  """Find the position just after the end of current parenthesized expression.
-
-  Args:
-    line: a CleansedLines line.
-    startpos: start searching at this position.
-    stack: nesting stack at startpos.
-
-  Returns:
-    On finding matching end: (index just after matching end, None)
-    On finding an unclosed expression: (-1, None)
-    Otherwise: (-1, new stack at end of this line)
-  """
-  for i in xrange(startpos, len(line)):
-    char = line[i]
-    if char in '([{':
-      # Found start of parenthesized expression, push to expression stack
-      stack.append(char)
-    elif char == '<':
-      # Found potential start of template argument list
-      if i > 0 and line[i - 1] == '<':
-        # Left shift operator
-        if stack and stack[-1] == '<':
-          stack.pop()
-          if not stack:
-            return (-1, None)
-      elif i > 0 and Search(r'\boperator\s*$', line[0:i]):
-        # operator<, don't add to stack
-        continue
-      else:
-        # Tentative start of template argument list
-        stack.append('<')
-    elif char in ')]}':
-      # Found end of parenthesized expression.
-      #
-      # If we are currently expecting a matching '>', the pending '<'
-      # must have been an operator.  Remove them from expression stack.
-      while stack and stack[-1] == '<':
-        stack.pop()
-      if not stack:
-        return (-1, None)
-      if ((stack[-1] == '(' and char == ')') or
-          (stack[-1] == '[' and char == ']') or
-          (stack[-1] == '{' and char == '}')):
-        stack.pop()
-        if not stack:
-          return (i + 1, None)
-      else:
-        # Mismatched parentheses
-        return (-1, None)
-    elif char == '>':
-      # Found potential end of template argument list.
-
-      # Ignore "->" and operator functions
-      if (i > 0 and
-          (line[i - 1] == '-' or Search(r'\boperator\s*$', line[0:i - 1]))):
-        continue
-
-      # Pop the stack if there is a matching '<'.  Otherwise, ignore
-      # this '>' since it must be an operator.
-      if stack:
-        if stack[-1] == '<':
-          stack.pop()
-          if not stack:
-            return (i + 1, None)
-    elif char == ';':
-      # Found something that look like end of statements.  If we are currently
-      # expecting a '>', the matching '<' must have been an operator, since
-      # template argument list should not contain statements.
-      while stack and stack[-1] == '<':
-        stack.pop()
-      if not stack:
-        return (-1, None)
-
-  # Did not find end of expression or unbalanced parentheses on this line
-  return (-1, stack)
-
-
-def CloseExpression(clean_lines, linenum, pos):
-  """If input points to ( or { or [ or <, finds the position that closes it.
-
-  If lines[linenum][pos] points to a '(' or '{' or '[' or '<', finds the
-  linenum/pos that correspond to the closing of the expression.
-
-  TODO(unknown): cpplint spends a fair bit of time matching parentheses.
-  Ideally we would want to index all opening and closing parentheses once
-  and have CloseExpression be just a simple lookup, but due to preprocessor
-  tricks, this is not so easy.
-
-  Args:
-    clean_lines: A CleansedLines instance containing the file.
-    linenum: The number of the line to check.
-    pos: A position on the line.
-
-  Returns:
-    A tuple (line, linenum, pos) pointer *past* the closing brace, or
-    (line, len(lines), -1) if we never find a close.  Note we ignore
-    strings and comments when matching; and the line we return is the
-    'cleansed' line at linenum.
-  """
-
-  line = clean_lines.elided[linenum]
-  if (line[pos] not in '({[<') or Match(r'<[<=]', line[pos:]):
-    return (line, clean_lines.NumLines(), -1)
-
-  # Check first line
-  (end_pos, stack) = FindEndOfExpressionInLine(line, pos, [])
-  if end_pos > -1:
-    return (line, linenum, end_pos)
-
-  # Continue scanning forward
-  while stack and linenum < clean_lines.NumLines() - 1:
-    linenum += 1
-    line = clean_lines.elided[linenum]
-    (end_pos, stack) = FindEndOfExpressionInLine(line, 0, stack)
-    if end_pos > -1:
-      return (line, linenum, end_pos)
-
-  # Did not find end of expression before end of file, give up
-  return (line, clean_lines.NumLines(), -1)
-
-
-def FindStartOfExpressionInLine(line, endpos, stack):
-  """Find position at the matching start of current expression.
-
-  This is almost the reverse of FindEndOfExpressionInLine, but note
-  that the input position and returned position differs by 1.
-
-  Args:
-    line: a CleansedLines line.
-    endpos: start searching at this position.
-    stack: nesting stack at endpos.
-
-  Returns:
-    On finding matching start: (index at matching start, None)
-    On finding an unclosed expression: (-1, None)
-    Otherwise: (-1, new stack at beginning of this line)
-  """
-  i = endpos
-  while i >= 0:
-    char = line[i]
-    if char in ')]}':
-      # Found end of expression, push to expression stack
-      stack.append(char)
-    elif char == '>':
-      # Found potential end of template argument list.
-      #
-      # Ignore it if it's a "->" or ">=" or "operator>"
-      if (i > 0 and
-          (line[i - 1] == '-' or
-           Match(r'\s>=\s', line[i - 1:]) or
-           Search(r'\boperator\s*$', line[0:i]))):
-        i -= 1
-      else:
-        stack.append('>')
-    elif char == '<':
-      # Found potential start of template argument list
-      if i > 0 and line[i - 1] == '<':
-        # Left shift operator
-        i -= 1
-      else:
-        # If there is a matching '>', we can pop the expression stack.
-        # Otherwise, ignore this '<' since it must be an operator.
-        if stack and stack[-1] == '>':
-          stack.pop()
-          if not stack:
-            return (i, None)
-    elif char in '([{':
-      # Found start of expression.
-      #
-      # If there are any unmatched '>' on the stack, they must be
-      # operators.  Remove those.
-      while stack and stack[-1] == '>':
-        stack.pop()
-      if not stack:
-        return (-1, None)
-      if ((char == '(' and stack[-1] == ')') or
-          (char == '[' and stack[-1] == ']') or
-          (char == '{' and stack[-1] == '}')):
-        stack.pop()
-        if not stack:
-          return (i, None)
-      else:
-        # Mismatched parentheses
-        return (-1, None)
-    elif char == ';':
-      # Found something that look like end of statements.  If we are currently
-      # expecting a '<', the matching '>' must have been an operator, since
-      # template argument list should not contain statements.
-      while stack and stack[-1] == '>':
-        stack.pop()
-      if not stack:
-        return (-1, None)
-
-    i -= 1
-
-  return (-1, stack)
-
-
-def ReverseCloseExpression(clean_lines, linenum, pos):
-  """If input points to ) or } or ] or >, finds the position that opens it.
-
-  If lines[linenum][pos] points to a ')' or '}' or ']' or '>', finds the
-  linenum/pos that correspond to the opening of the expression.
-
-  Args:
-    clean_lines: A CleansedLines instance containing the file.
-    linenum: The number of the line to check.
-    pos: A position on the line.
-
-  Returns:
-    A tuple (line, linenum, pos) pointer *at* the opening brace, or
-    (line, 0, -1) if we never find the matching opening brace.  Note
-    we ignore strings and comments when matching; and the line we
-    return is the 'cleansed' line at linenum.
-  """
-  line = clean_lines.elided[linenum]
-  if line[pos] not in ')}]>':
-    return (line, 0, -1)
-
-  # Check last line
-  (start_pos, stack) = FindStartOfExpressionInLine(line, pos, [])
-  if start_pos > -1:
-    return (line, linenum, start_pos)
-
-  # Continue scanning backward
-  while stack and linenum > 0:
-    linenum -= 1
-    line = clean_lines.elided[linenum]
-    (start_pos, stack) = FindStartOfExpressionInLine(line, len(line) - 1, stack)
-    if start_pos > -1:
-      return (line, linenum, start_pos)
-
-  # Did not find start of expression before beginning of file, give up
-  return (line, 0, -1)
-
-
-def CheckForCopyright(filename, lines, error):
-  """Logs an error if no Copyright message appears at the top of the file."""
-
-  # We'll say it should occur by line 10. Don't forget there's a
-  # dummy line at the front.
-  for line in xrange(1, min(len(lines), 11)):
-    if re.search(r'Copyright', lines[line], re.I): break
-  else:                       # means no copyright line was found
-    error(filename, 0, 'legal/copyright', 5,
-          'No copyright message found.  '
-          'You should have a line: "Copyright [year] <Copyright Owner>"')
-
-
-def GetIndentLevel(line):
-  """Return the number of leading spaces in line.
-
-  Args:
-    line: A string to check.
-
-  Returns:
-    An integer count of leading spaces, possibly zero.
-  """
-  indent = Match(r'^( *)\S', line)
-  if indent:
-    return len(indent.group(1))
-  else:
-    return 0
-
-
-def GetHeaderGuardCPPVariable(filename):
-  """Returns the CPP variable that should be used as a header guard.
-
-  Args:
-    filename: The name of a C++ header file.
-
-  Returns:
-    The CPP variable that should be used as a header guard in the
-    named file.
-
-  """
-
-  # Restores original filename in case that cpplint is invoked from Emacs's
-  # flymake.
-  filename = re.sub(r'_flymake\.h$', '.h', filename)
-  filename = re.sub(r'/\.flymake/([^/]*)$', r'/\1', filename)
-  # Replace 'c++' with 'cpp'.
-  filename = filename.replace('C++', 'cpp').replace('c++', 'cpp')
-
-  fileinfo = FileInfo(filename)
-  file_path_from_root = fileinfo.RepositoryName()
-  if _root:
-    file_path_from_root = re.sub('^' + _root + os.sep, '', file_path_from_root)
-  return re.sub(r'[^a-zA-Z0-9]', '_', file_path_from_root).upper() + '_'
-
-
-def CheckForHeaderGuard(filename, clean_lines, error):
-  """Checks that the file contains a header guard.
-
-  Logs an error if no #ifndef header guard is present.  For other
-  headers, checks that the full pathname is used.
-
-  Args:
-    filename: The name of the C++ header file.
-    clean_lines: A CleansedLines instance containing the file.
-    error: The function to call with any errors found.
-  """
-
-  # Don't check for header guards if there are error suppression
-  # comments somewhere in this file.
-  #
-  # Because this is silencing a warning for a nonexistent line, we
-  # only support the very specific NOLINT(build/header_guard) syntax,
-  # and not the general NOLINT or NOLINT(*) syntax.
-  raw_lines = clean_lines.lines_without_raw_strings
-  for i in raw_lines:
-    if Search(r'//\s*NOLINT\(build/header_guard\)', i):
-      return
-
-  cppvar = GetHeaderGuardCPPVariable(filename)
-
-  ifndef = ''
-  ifndef_linenum = 0
-  define = ''
-  endif = ''
-  endif_linenum = 0
-  for linenum, line in enumerate(raw_lines):
-    linesplit = line.split()
-    if len(linesplit) >= 2:
-      # find the first occurrence of #ifndef and #define, save arg
-      if not ifndef and linesplit[0] == '#ifndef':
-        # set ifndef to the header guard presented on the #ifndef line.
-        ifndef = linesplit[1]
-        ifndef_linenum = linenum
-      if not define and linesplit[0] == '#define':
-        define = linesplit[1]
-    # find the last occurrence of #endif, save entire line
-    if line.startswith('#endif'):
-      endif = line
-      endif_linenum = linenum
-
-  if not ifndef or not define or ifndef != define:
-    error(filename, 0, 'build/header_guard', 5,
-          'No #ifndef header guard found, suggested CPP variable is: %s' %
-          cppvar)
-    return
-
-  # The guard should be PATH_FILE_H_, but we also allow PATH_FILE_H__
-  # for backward compatibility.
-  if ifndef != cppvar:
-    error_level = 0
-    if ifndef != cppvar + '_':
-      error_level = 5
-
-    ParseNolintSuppressions(filename, raw_lines[ifndef_linenum], ifndef_linenum,
-                            error)
-    error(filename, ifndef_linenum, 'build/header_guard', error_level,
-          '#ifndef header guard has wrong style, please use: %s' % cppvar)
-
-  # Check for "//" comments on endif line.
-  ParseNolintSuppressions(filename, raw_lines[endif_linenum], endif_linenum,
-                          error)
-  match = Match(r'#endif\s*//\s*' + cppvar + r'(_)?\b', endif)
-  if match:
-    if match.group(1) == '_':
-      # Issue low severity warning for deprecated double trailing underscore
-      error(filename, endif_linenum, 'build/header_guard', 0,
-            '#endif line should be "#endif  // %s"' % cppvar)
-    return
-
-  # Didn't find the corresponding "//" comment.  If this file does not
-  # contain any "//" comments at all, it could be that the compiler
-  # only wants "/**/" comments, look for those instead.
-  no_single_line_comments = True
-  for i in xrange(1, len(raw_lines) - 1):
-    line = raw_lines[i]
-    if Match(r'^(?:(?:\'(?:\.|[^\'])*\')|(?:"(?:\.|[^"])*")|[^\'"])*//', line):
-      no_single_line_comments = False
-      break
-
-  if no_single_line_comments:
-    match = Match(r'#endif\s*/\*\s*' + cppvar + r'(_)?\s*\*/', endif)
-    if match:
-      if match.group(1) == '_':
-        # Low severity warning for double trailing underscore
-        error(filename, endif_linenum, 'build/header_guard', 0,
-              '#endif line should be "#endif  /* %s */"' % cppvar)
-      return
-
-  # Didn't find anything
-  error(filename, endif_linenum, 'build/header_guard', 5,
-        '#endif line should be "#endif  // %s"' % cppvar)
-
-
-def CheckHeaderFileIncluded(filename, include_state, error):
-  """Logs an error if a .cc file does not include its header."""
-
-  # Do not check test files
-  if filename.endswith('_test.cc') or filename.endswith('_unittest.cc'):
-    return
-
-  fileinfo = FileInfo(filename)
-  headerfile = filename[0:len(filename) - 2] + 'h'
-  if not os.path.exists(headerfile):
-    return
-  headername = FileInfo(headerfile).RepositoryName()
-  first_include = 0
-  for section_list in include_state.include_list:
-    for f in section_list:
-      if headername in f[0] or f[0] in headername:
-        return
-      if not first_include:
-        first_include = f[1]
-
-  error(filename, first_include, 'build/include', 5,
-        '%s should include its header file %s' % (fileinfo.RepositoryName(),
-                                                  headername))
-
-
-def CheckForBadCharacters(filename, lines, error):
-  """Logs an error for each line containing bad characters.
-
-  Two kinds of bad characters:
-
-  1. Unicode replacement characters: These indicate that either the file
-  contained invalid UTF-8 (likely) or Unicode replacement characters (which
-  it shouldn't).  Note that it's possible for this to throw off line
-  numbering if the invalid UTF-8 occurred adjacent to a newline.
-
-  2. NUL bytes.  These are problematic for some tools.
-
-  Args:
-    filename: The name of the current file.
-    lines: An array of strings, each representing a line of the file.
-    error: The function to call with any errors found.
-  """
-  for linenum, line in enumerate(lines):
-    if u'\ufffd' in line:
-      error(filename, linenum, 'readability/utf8', 5,
-            'Line contains invalid UTF-8 (or Unicode replacement character).')
-    if '\0' in line:
-      error(filename, linenum, 'readability/nul', 5, 'Line contains NUL byte.')
-
-
-def CheckForNewlineAtEOF(filename, lines, error):
-  """Logs an error if there is no newline char at the end of the file.
-
-  Args:
-    filename: The name of the current file.
-    lines: An array of strings, each representing a line of the file.
-    error: The function to call with any errors found.
-  """
-
-  # The array lines() was created by adding two newlines to the
-  # original file (go figure), then splitting on \n.
-  # To verify that the file ends in \n, we just have to make sure the
-  # last-but-two element of lines() exists and is empty.
-  if len(lines) < 3 or lines[-2]:
-    error(filename, len(lines) - 2, 'whitespace/ending_newline', 5,
-          'Could not find a newline character at the end of the file.')
-
-
-def CheckForMultilineCommentsAndStrings(filename, clean_lines, linenum, error):
-  """Logs an error if we see /* ... */ or "..." that extend past one line.
-
-  /* ... */ comments are legit inside macros, for one line.
-  Otherwise, we prefer // comments, so it's ok to warn about the
-  other.  Likewise, it's ok for strings to extend across multiple
-  lines, as long as a line continuation character (backslash)
-  terminates each line. Although not currently prohibited by the C++
-  style guide, it's ugly and unnecessary. We don't do well with either
-  in this lint program, so we warn about both.
-
-  Args:
-    filename: The name of the current file.
-    clean_lines: A CleansedLines instance containing the file.
-    linenum: The number of the line to check.
-    error: The function to call with any errors found.
-  """
-  line = clean_lines.elided[linenum]
-
-  # Remove all \\ (escaped backslashes) from the line. They are OK, and the
-  # second (escaped) slash may trigger later \" detection erroneously.
-  line = line.replace('\\\\', '')
-
-  if line.count('/*') > line.count('*/'):
-    error(filename, linenum, 'readability/multiline_comment', 5,
-          'Complex multi-line /*...*/-style comment found. '
-          'Lint may give bogus warnings.  '
-          'Consider replacing these with //-style comments, '
-          'with #if 0...#endif, '
-          'or with more clearly structured multi-line comments.')
-
-  if (line.count('"') - line.count('\\"')) % 2:
-    error(filename, linenum, 'readability/multiline_string', 5,
-          'Multi-line string ("...") found.  This lint script doesn\'t '
-          'do well with such strings, and may give bogus warnings.  '
-          'Use C++11 raw strings or concatenation instead.')
-
-
-# (non-threadsafe name, thread-safe alternative, validation pattern)
-#
-# The validation pattern is used to eliminate false positives such as:
-#  _rand();               // false positive due to substring match.
-#  ->rand();              // some member function rand().
-#  ACMRandom rand(seed);  // some variable named rand.
-#  ISAACRandom rand();    // another variable named rand.
-#
-# Basically we require the return value of these functions to be used
-# in some expression context on the same line by matching on some
-# operator before the function name.  This eliminates constructors and
-# member function calls.
-_UNSAFE_FUNC_PREFIX = r'(?:[-+*/=%^&|(<]\s*|>\s+)'
-_THREADING_LIST = (
-    ('asctime(', 'asctime_r(', _UNSAFE_FUNC_PREFIX + r'asctime\([^)]+\)'),
-    ('ctime(', 'ctime_r(', _UNSAFE_FUNC_PREFIX + r'ctime\([^)]+\)'),
-    ('getgrgid(', 'getgrgid_r(', _UNSAFE_FUNC_PREFIX + r'getgrgid\([^)]+\)'),
-    ('getgrnam(', 'getgrnam_r(', _UNSAFE_FUNC_PREFIX + r'getgrnam\([^)]+\)'),
-    ('getlogin(', 'getlogin_r(', _UNSAFE_FUNC_PREFIX + r'getlogin\(\)'),
-    ('getpwnam(', 'getpwnam_r(', _UNSAFE_FUNC_PREFIX + r'getpwnam\([^)]+\)'),
-    ('getpwuid(', 'getpwuid_r(', _UNSAFE_FUNC_PREFIX + r'getpwuid\([^)]+\)'),
-    ('gmtime(', 'gmtime_r(', _UNSAFE_FUNC_PREFIX + r'gmtime\([^)]+\)'),
-    ('localtime(', 'localtime_r(', _UNSAFE_FUNC_PREFIX + r'localtime\([^)]+\)'),
-    ('rand(', 'rand_r(', _UNSAFE_FUNC_PREFIX + r'rand\(\)'),
-    ('strtok(', 'strtok_r(',
-     _UNSAFE_FUNC_PREFIX + r'strtok\([^)]+\)'),
-    ('ttyname(', 'ttyname_r(', _UNSAFE_FUNC_PREFIX + r'ttyname\([^)]+\)'),
-    )
-
-
-def CheckPosixThreading(filename, clean_lines, linenum, error):
-  """Checks for calls to thread-unsafe functions.
-
-  Much code has been originally written without consideration of
-  multi-threading. Also, engineers are relying on their old experience;
-  they have learned posix before threading extensions were added. These
-  tests guide the engineers to use thread-safe functions (when using
-  posix directly).
-
-  Args:
-    filename: The name of the current file.
-    clean_lines: A CleansedLines instance containing the file.
-    linenum: The number of the line to check.
-    error: The function to call with any errors found.
-  """
-  line = clean_lines.elided[linenum]
-  for single_thread_func, multithread_safe_func, pattern in _THREADING_LIST:
-    # Additional pattern matching check to confirm that this is the
-    # function we are looking for
-    if Search(pattern, line):
-      error(filename, linenum, 'runtime/threadsafe_fn', 2,
-            'Consider using ' + multithread_safe_func +
-            '...) instead of ' + single_thread_func +
-            '...) for improved thread safety.')
-
-
-def CheckVlogArguments(filename, clean_lines, linenum, error):
-  """Checks that VLOG() is only used for defining a logging level.
-
-  For example, VLOG(2) is correct. VLOG(INFO), VLOG(WARNING), VLOG(ERROR), and
-  VLOG(FATAL) are not.
-
-  Args:
-    filename: The name of the current file.
-    clean_lines: A CleansedLines instance containing the file.
-    linenum: The number of the line to check.
-    error: The function to call with any errors found.
-  """
-  line = clean_lines.elided[linenum]
-  if Search(r'\bVLOG\((INFO|ERROR|WARNING|DFATAL|FATAL)\)', line):
-    error(filename, linenum, 'runtime/vlog', 5,
-          'VLOG() should be used with numeric verbosity level.  '
-          'Use LOG() if you want symbolic severity levels.')
-
-# Matches invalid increment: *count++, which moves pointer instead of
-# incrementing a value.
-_RE_PATTERN_INVALID_INCREMENT = re.compile(
-    r'^\s*\*\w+(\+\+|--);')
-
-
-def CheckInvalidIncrement(filename, clean_lines, linenum, error):
-  """Checks for invalid increment *count++.
-
-  For example following function:
-  void increment_counter(int* count) {
-    *count++;
-  }
-  is invalid, because it effectively does count++, moving pointer, and should
-  be replaced with ++*count, (*count)++ or *count += 1.
-
-  Args:
-    filename: The name of the current file.
-    clean_lines: A CleansedLines instance containing the file.
-    linenum: The number of the line to check.
-    error: The function to call with any errors found.
-  """
-  line = clean_lines.elided[linenum]
-  if _RE_PATTERN_INVALID_INCREMENT.match(line):
-    error(filename, linenum, 'runtime/invalid_increment', 5,
-          'Changing pointer instead of value (or unused value of operator*).')
-
-
-def IsMacroDefinition(clean_lines, linenum):
-  if Search(r'^#define', clean_lines[linenum]):
-    return True
-
-  if linenum > 0 and Search(r'\\$', clean_lines[linenum - 1]):
-    return True
-
-  return False
-
-
-def IsForwardClassDeclaration(clean_lines, linenum):
-  return Match(r'^\s*(\btemplate\b)*.*class\s+\w+;\s*$', clean_lines[linenum])
-
-
-class _BlockInfo(object):
-  """Stores information about a generic block of code."""
-
-  def __init__(self, seen_open_brace):
-    self.seen_open_brace = seen_open_brace
-    self.open_parentheses = 0
-    self.inline_asm = _NO_ASM
-    self.check_namespace_indentation = False
-
-  def CheckBegin(self, filename, clean_lines, linenum, error):
-    """Run checks that applies to text up to the opening brace.
-
-    This is mostly for checking the text after the class identifier
-    and the "{", usually where the base class is specified.  For other
-    blocks, there isn't much to check, so we always pass.
-
-    Args:
-      filename: The name of the current file.
-      clean_lines: A CleansedLines instance containing the file.
-      linenum: The number of the line to check.
-      error: The function to call with any errors found.
-    """
-    pass
-
-  def CheckEnd(self, filename, clean_lines, linenum, error):
-    """Run checks that applies to text after the closing brace.
-
-    This is mostly used for checking end of namespace comments.
-
-    Args:
-      filename: The name of the current file.
-      clean_lines: A CleansedLines instance containing the file.
-      linenum: The number of the line to check.
-      error: The function to call with any errors found.
-    """
-    pass
-
-  def IsBlockInfo(self):
-    """Returns true if this block is a _BlockInfo.
-
-    This is convenient for verifying that an object is an instance of
-    a _BlockInfo, but not an instance of any of the derived classes.
-
-    Returns:
-      True for this class, False for derived classes.
-    """
-    return self.__class__ == _BlockInfo
-
-
-class _ExternCInfo(_BlockInfo):
-  """Stores information about an 'extern "C"' block."""
-
-  def __init__(self):
-    _BlockInfo.__init__(self, True)
-
-
-class _ClassInfo(_BlockInfo):
-  """Stores information about a class."""
-
-  def __init__(self, name, class_or_struct, clean_lines, linenum):
-    _BlockInfo.__init__(self, False)
-    self.name = name
-    self.starting_linenum = linenum
-    self.is_derived = False
-    self.check_namespace_indentation = True
-    if class_or_struct == 'struct':
-      self.access = 'public'
-      self.is_struct = True
-    else:
-      self.access = 'private'
-      self.is_struct = False
-
-    # Remember initial indentation level for this class.  Using raw_lines here
-    # instead of elided to account for leading comments.
-    self.class_indent = GetIndentLevel(clean_lines.raw_lines[linenum])
-
-    # Try to find the end of the class.  This will be confused by things like:
-    #   class A {
-    #   } *x = { ...
-    #
-    # But it's still good enough for CheckSectionSpacing.
-    self.last_line = 0
-    depth = 0
-    for i in range(linenum, clean_lines.NumLines()):
-      line = clean_lines.elided[i]
-      depth += line.count('{') - line.count('}')
-      if not depth:
-        self.last_line = i
-        break
-
-  def CheckBegin(self, filename, clean_lines, linenum, error):
-    # Look for a bare ':'
-    if Search('(^|[^:]):($|[^:])', clean_lines.elided[linenum]):
-      self.is_derived = True
-
-  def CheckEnd(self, filename, clean_lines, linenum, error):
-    # If there is a DISALLOW macro, it should appear near the end of
-    # the class.
-    seen_last_thing_in_class = False
-    for i in xrange(linenum - 1, self.starting_linenum, -1):
-      match = Search(
-          r'\b(DISALLOW_COPY_AND_ASSIGN|DISALLOW_IMPLICIT_CONSTRUCTORS)\(' +
-          self.name + r'\)',
-          clean_lines.elided[i])
-      if match:
-        if seen_last_thing_in_class:
-          error(filename, i, 'readability/constructors', 3,
-                match.group(1) + ' should be the last thing in the class')
-        break
-
-      if not Match(r'^\s*$', clean_lines.elided[i]):
-        seen_last_thing_in_class = True
-
-    # Check that closing brace is aligned with beginning of the class.
-    # Only do this if the closing brace is indented by only whitespaces.
-    # This means we will not check single-line class definitions.
-    indent = Match(r'^( *)\}', clean_lines.elided[linenum])
-    if indent and len(indent.group(1)) != self.class_indent:
-      if self.is_struct:
-        parent = 'struct ' + self.name
-      else:
-        parent = 'class ' + self.name
-      error(filename, linenum, 'whitespace/indent', 3,
-            'Closing brace should be aligned with beginning of %s' % parent)
-
-
-class _NamespaceInfo(_BlockInfo):
-  """Stores information about a namespace."""
-
-  def __init__(self, name, linenum):
-    _BlockInfo.__init__(self, False)
-    self.name = name or ''
-    self.starting_linenum = linenum
-    self.check_namespace_indentation = True
-
-  def CheckEnd(self, filename, clean_lines, linenum, error):
-    """Check end of namespace comments."""
-    line = clean_lines.raw_lines[linenum]
-
-    # Check how many lines is enclosed in this namespace.  Don't issue
-    # warning for missing namespace comments if there aren't enough
-    # lines.  However, do apply checks if there is already an end of
-    # namespace comment and it's incorrect.
-    #
-    # TODO(unknown): We always want to check end of namespace comments
-    # if a namespace is large, but sometimes we also want to apply the
-    # check if a short namespace contained nontrivial things (something
-    # other than forward declarations).  There is currently no logic on
-    # deciding what these nontrivial things are, so this check is
-    # triggered by namespace size only, which works most of the time.
-    if (linenum - self.starting_linenum < 10
-        and not Match(r'};*\s*(//|/\*).*\bnamespace\b', line)):
-      return
-
-    # Look for matching comment at end of namespace.
-    #
-    # Note that we accept C style "/* */" comments for terminating
-    # namespaces, so that code that terminate namespaces inside
-    # preprocessor macros can be cpplint clean.
-    #
-    # We also accept stuff like "// end of namespace <name>." with the
-    # period at the end.
-    #
-    # Besides these, we don't accept anything else, otherwise we might
-    # get false negatives when existing comment is a substring of the
-    # expected namespace.
-    if self.name:
-      # Named namespace
-      if not Match((r'};*\s*(//|/\*).*\bnamespace\s+' + re.escape(self.name) +
-                    r'[\*/\.\\\s]*$'),
-                   line):
-        error(filename, linenum, 'readability/namespace', 5,
-              'Namespace should be terminated with "// namespace %s"' %
-              self.name)
-    else:
-      # Anonymous namespace
-      if not Match(r'};*\s*(//|/\*).*\bnamespace[\*/\.\\\s]*$', line):
-        # If "// namespace anonymous" or "// anonymous namespace (more text)",
-        # mention "// anonymous namespace" as an acceptable form
-        if Match(r'}.*\b(namespace anonymous|anonymous namespace)\b', line):
-          error(filename, linenum, 'readability/namespace', 5,
-                'Anonymous namespace should be terminated with "// namespace"'
-                ' or "// anonymous namespace"')
-        else:
-          error(filename, linenum, 'readability/namespace', 5,
-                'Anonymous namespace should be terminated with "// namespace"')
-
-
-class _PreprocessorInfo(object):
-  """Stores checkpoints of nesting stacks when #if/#else is seen."""
-
-  def __init__(self, stack_before_if):
-    # The entire nesting stack before #if
-    self.stack_before_if = stack_before_if
-
-    # The entire nesting stack up to #else
-    self.stack_before_else = []
-
-    # Whether we have already seen #else or #elif
-    self.seen_else = False
-
-
-class NestingState(object):
-  """Holds states related to parsing braces."""
-
-  def __init__(self):
-    # Stack for tracking all braces.  An object is pushed whenever we
-    # see a "{", and popped when we see a "}".  Only 3 types of
-    # objects are possible:
-    # - _ClassInfo: a class or struct.
-    # - _NamespaceInfo: a namespace.
-    # - _BlockInfo: some other type of block.
-    self.stack = []
-
-    # Top of the previous stack before each Update().
-    #
-    # Because the nesting_stack is updated at the end of each line, we
-    # had to do some convoluted checks to find out what is the current
-    # scope at the beginning of the line.  This check is simplified by
-    # saving the previous top of nesting stack.
-    #
-    # We could save the full stack, but we only need the top.  Copying
-    # the full nesting stack would slow down cpplint by ~10%.
-    self.previous_stack_top = []
-
-    # Stack of _PreprocessorInfo objects.
-    self.pp_stack = []
-
-  def SeenOpenBrace(self):
-    """Check if we have seen the opening brace for the innermost block.
-
-    Returns:
-      True if we have seen the opening brace, False if the innermost
-      block is still expecting an opening brace.
-    """
-    return (not self.stack) or self.stack[-1].seen_open_brace
-
-  def InNamespaceBody(self):
-    """Check if we are currently one level inside a namespace body.
-
-    Returns:
-      True if top of the stack is a namespace block, False otherwise.
-    """
-    return self.stack and isinstance(self.stack[-1], _NamespaceInfo)
-
-  def InExternC(self):
-    """Check if we are currently one level inside an 'extern "C"' block.
-
-    Returns:
-      True if top of the stack is an extern block, False otherwise.
-    """
-    return self.stack and isinstance(self.stack[-1], _ExternCInfo)
-
-  def InClassDeclaration(self):
-    """Check if we are currently one level inside a class or struct declaration.
-
-    Returns:
-      True if top of the stack is a class/struct, False otherwise.
-    """
-    return self.stack and isinstance(self.stack[-1], _ClassInfo)
-
-  def InAsmBlock(self):
-    """Check if we are currently one level inside an inline ASM block.
-
-    Returns:
-      True if the top of the stack is a block containing inline ASM.
-    """
-    return self.stack and self.stack[-1].inline_asm != _NO_ASM
-
-  def InTemplateArgumentList(self, clean_lines, linenum, pos):
-    """Check if current position is inside template argument list.
-
-    Args:
-      clean_lines: A CleansedLines instance containing the file.
-      linenum: The number of the line to check.
-      pos: position just after the suspected template argument.
-    Returns:
-      True if (linenum, pos) is inside template arguments.
-    """
-    while linenum < clean_lines.NumLines():
-      # Find the earliest character that might indicate a template argument
-      line = clean_lines.elided[linenum]
-      match = Match(r'^[^{};=\[\]\.<>]*(.)', line[pos:])
-      if not match:
-        linenum += 1
-        pos = 0
-        continue
-      token = match.group(1)
-      pos += len(match.group(0))
-
-      # These things do not look like template argument list:
-      #   class Suspect {
-      #   class Suspect x; }
-      if token in ('{', '}', ';'): return False
-
-      # These things look like template argument list:
-      #   template <class Suspect>
-      #   template <class Suspect = default_value>
-      #   template <class Suspect[]>
-      #   template <class Suspect...>
-      if token in ('>', '=', '[', ']', '.'): return True
-
-      # Check if token is an unmatched '<'.
-      # If not, move on to the next character.
-      if token != '<':
-        pos += 1
-        if pos >= len(line):
-          linenum += 1
-          pos = 0
-        continue
-
-      # We can't be sure if we just find a single '<', and need to
-      # find the matching '>'.
-      (_, end_line, end_pos) = CloseExpression(clean_lines, linenum, pos - 1)
-      if end_pos < 0:
-        # Not sure if template argument list or syntax error in file
-        return False
-      linenum = end_line
-      pos = end_pos
-    return False
-
-  def UpdatePreprocessor(self, line):
-    """Update preprocessor stack.
-
-    We need to handle preprocessors due to classes like this:
-      #ifdef SWIG
-      struct ResultDetailsPageElementExtensionPoint {
-      #else
-      struct ResultDetailsPageElementExtensionPoint : public Extension {
-      #endif
-
-    We make the following assumptions (good enough for most files):
-    - Preprocessor condition evaluates to true from #if up to first
-      #else/#elif/#endif.
-
-    - Preprocessor condition evaluates to false from #else/#elif up
-      to #endif.  We still perform lint checks on these lines, but
-      these do not affect nesting stack.
-
-    Args:
-      line: current line to check.
-    """
-    if Match(r'^\s*#\s*(if|ifdef|ifndef)\b', line):
-      # Beginning of #if block, save the nesting stack here.  The saved
-      # stack will allow us to restore the parsing state in the #else case.
-      self.pp_stack.append(_PreprocessorInfo(copy.deepcopy(self.stack)))
-    elif Match(r'^\s*#\s*(else|elif)\b', line):
-      # Beginning of #else block
-      if self.pp_stack:
-        if not self.pp_stack[-1].seen_else:
-          # This is the first #else or #elif block.  Remember the
-          # whole nesting stack up to this point.  This is what we
-          # keep after the #endif.
-          self.pp_stack[-1].seen_else = True
-          self.pp_stack[-1].stack_before_else = copy.deepcopy(self.stack)
-
-        # Restore the stack to how it was before the #if
-        self.stack = copy.deepcopy(self.pp_stack[-1].stack_before_if)
-      else:
-        # TODO(unknown): unexpected #else, issue warning?
-        pass
-    elif Match(r'^\s*#\s*endif\b', line):
-      # End of #if or #else blocks.
-      if self.pp_stack:
-        # If we saw an #else, we will need to restore the nesting
-        # stack to its former state before the #else, otherwise we
-        # will just continue from where we left off.
-        if self.pp_stack[-1].seen_else:
-          # Here we can just use a shallow copy since we are the last
-          # reference to it.
-          self.stack = self.pp_stack[-1].stack_before_else
-        # Drop the corresponding #if
-        self.pp_stack.pop()
-      else:
-        # TODO(unknown): unexpected #endif, issue warning?
-        pass
-
-  # TODO(unknown): Update() is too long, but we will refactor later.
-  def Update(self, filename, clean_lines, linenum, error):
-    """Update nesting state with current line.
-
-    Args:
-      filename: The name of the current file.
-      clean_lines: A CleansedLines instance containing the file.
-      linenum: The number of the line to check.
-      error: The function to call with any errors found.
-    """
-    line = clean_lines.elided[linenum]
-
-    # Remember top of the previous nesting stack.
-    #
-    # The stack is always pushed/popped and not modified in place, so
-    # we can just do a shallow copy instead of copy.deepcopy.  Using
-    # deepcopy would slow down cpplint by ~28%.
-    if self.stack:
-      self.previous_stack_top = self.stack[-1]
-    else:
-      self.previous_stack_top = None
-
-    # Update pp_stack
-    self.UpdatePreprocessor(line)
-
-    # Count parentheses.  This is to avoid adding struct arguments to
-    # the nesting stack.
-    if self.stack:
-      inner_block = self.stack[-1]
-      depth_change = line.count('(') - line.count(')')
-      inner_block.open_parentheses += depth_change
-
-      # Also check if we are starting or ending an inline assembly block.
-      if inner_block.inline_asm in (_NO_ASM, _END_ASM):
-        if (depth_change != 0 and
-            inner_block.open_parentheses == 1 and
-            _MATCH_ASM.match(line)):
-          # Enter assembly block
-          inner_block.inline_asm = _INSIDE_ASM
-        else:
-          # Not entering assembly block.  If previous line was _END_ASM,
-          # we will now shift to _NO_ASM state.
-          inner_block.inline_asm = _NO_ASM
-      elif (inner_block.inline_asm == _INSIDE_ASM and
-            inner_block.open_parentheses == 0):
-        # Exit assembly block
-        inner_block.inline_asm = _END_ASM
-
-    # Consume namespace declaration at the beginning of the line.  Do
-    # this in a loop so that we catch same line declarations like this:
-    #   namespace proto2 { namespace bridge { class MessageSet; } }
-    while True:
-      # Match start of namespace.  The "\b\s*" below catches namespace
-      # declarations even if it weren't followed by a whitespace, this
-      # is so that we don't confuse our namespace checker.  The
-      # missing spaces will be flagged by CheckSpacing.
-      namespace_decl_match = Match(r'^\s*namespace\b\s*([:\w]+)?(.*)$', line)
-      if not namespace_decl_match:
-        break
-
-      new_namespace = _NamespaceInfo(namespace_decl_match.group(1), linenum)
-      self.stack.append(new_namespace)
-
-      line = namespace_decl_match.group(2)
-      if line.find('{') != -1:
-        new_namespace.seen_open_brace = True
-        line = line[line.find('{') + 1:]
-
-    # Look for a class declaration in whatever is left of the line
-    # after parsing namespaces.  The regexp accounts for decorated classes
-    # such as in:
-    #   class LOCKABLE API Object {
-    #   };
-    class_decl_match = Match(
-        r'^(\s*(?:template\s*<[\w\s<>,:]*>\s*)?'
-        r'(class|struct)\s+(?:[A-Z_]+\s+)*(\w+(?:::\w+)*))'
-        r'(.*)$', line)
-    if (class_decl_match and
-        (not self.stack or self.stack[-1].open_parentheses == 0)):
-      # We do not want to accept classes that are actually template arguments:
-      #   template <class Ignore1,
-      #             class Ignore2 = Default<Args>,
-      #             template <Args> class Ignore3>
-      #   void Function() {};
-      #
-      # To avoid template argument cases, we scan forward and look for
-      # an unmatched '>'.  If we see one, assume we are inside a
-      # template argument list.
-      end_declaration = len(class_decl_match.group(1))
-      if not self.InTemplateArgumentList(clean_lines, linenum, end_declaration):
-        self.stack.append(_ClassInfo(
-            class_decl_match.group(3), class_decl_match.group(2),
-            clean_lines, linenum))
-        line = class_decl_match.group(4)
-
-    # If we have not yet seen the opening brace for the innermost block,
-    # run checks here.
-    if not self.SeenOpenBrace():
-      self.stack[-1].CheckBegin(filename, clean_lines, linenum, error)
-
-    # Update access control if we are inside a class/struct
-    if self.stack and isinstance(self.stack[-1], _ClassInfo):
-      classinfo = self.stack[-1]
-      access_match = Match(
-          r'^(.*)\b(public|private|protected|signals)(\s+(?:slots\s*)?)?'
-          r':(?:[^:]|$)',
-          line)
-      if access_match:
-        classinfo.access = access_match.group(2)
-
-        # Check that access keywords are indented +1 space.  Skip this
-        # check if the keywords are not preceded by whitespaces.
-        indent = access_match.group(1)
-        if (len(indent) != classinfo.class_indent + 1 and
-            Match(r'^\s*$', indent)):
-          if classinfo.is_struct:
-            parent = 'struct ' + classinfo.name
-          else:
-            parent = 'class ' + classinfo.name
-          slots = ''
-          if access_match.group(3):
-            slots = access_match.group(3)
-          error(filename, linenum, 'whitespace/indent', 3,
-                '%s%s: should be indented +1 space inside %s' % (
-                    access_match.group(2), slots, parent))
-
-    # Consume braces or semicolons from what's left of the line
-    while True:
-      # Match first brace, semicolon, or closed parenthesis.
-      matched = Match(r'^[^{;)}]*([{;)}])(.*)$', line)
-      if not matched:
-        break
-
-      token = matched.group(1)
-      if token == '{':
-        # If namespace or class hasn't seen a opening brace yet, mark
-        # namespace/class head as complete.  Push a new block onto the
-        # stack otherwise.
-        if not self.SeenOpenBrace():
-          self.stack[-1].seen_open_brace = True
-        elif Match(r'^extern\s*"[^"]*"\s*\{', line):
-          self.stack.append(_ExternCInfo())
-        else:
-          self.stack.append(_BlockInfo(True))
-          if _MATCH_ASM.match(line):
-            self.stack[-1].inline_asm = _BLOCK_ASM
-
-      elif token == ';' or token == ')':
-        # If we haven't seen an opening brace yet, but we already saw
-        # a semicolon, this is probably a forward declaration.  Pop
-        # the stack for these.
-        #
-        # Similarly, if we haven't seen an opening brace yet, but we
-        # already saw a closing parenthesis, then these are probably
-        # function arguments with extra "class" or "struct" keywords.
-        # Also pop these stack for these.
-        if not self.SeenOpenBrace():
-          self.stack.pop()
-      else:  # token == '}'
-        # Perform end of block checks and pop the stack.
-        if self.stack:
-          self.stack[-1].CheckEnd(filename, clean_lines, linenum, error)
-          self.stack.pop()
-      line = matched.group(2)
-
-  def InnermostClass(self):
-    """Get class info on the top of the stack.
-
-    Returns:
-      A _ClassInfo object if we are inside a class, or None otherwise.
-    """
-    for i in range(len(self.stack), 0, -1):
-      classinfo = self.stack[i - 1]
-      if isinstance(classinfo, _ClassInfo):
-        return classinfo
-    return None
-
-  def CheckCompletedBlocks(self, filename, error):
-    """Checks that all classes and namespaces have been completely parsed.
-
-    Call this when all lines in a file have been processed.
-    Args:
-      filename: The name of the current file.
-      error: The function to call with any errors found.
-    """
-    # Note: This test can result in false positives if #ifdef constructs
-    # get in the way of brace matching. See the testBuildClass test in
-    # cpplint_unittest.py for an example of this.
-    for obj in self.stack:
-      if isinstance(obj, _ClassInfo):
-        error(filename, obj.starting_linenum, 'build/class', 5,
-              'Failed to find complete declaration of class %s' %
-              obj.name)
-      elif isinstance(obj, _NamespaceInfo):
-        error(filename, obj.starting_linenum, 'build/namespaces', 5,
-              'Failed to find complete declaration of namespace %s' %
-              obj.name)
-
-
-def CheckForNonStandardConstructs(filename, clean_lines, linenum,
-                                  nesting_state, error):
-  r"""Logs an error if we see certain non-ANSI constructs ignored by gcc-2.
-
-  Complain about several constructs which gcc-2 accepts, but which are
-  not standard C++.  Warning about these in lint is one way to ease the
-  transition to new compilers.
-  - put storage class first (e.g. "static const" instead of "const static").
-  - "%lld" instead of %qd" in printf-type functions.
-  - "%1$d" is non-standard in printf-type functions.
-  - "\%" is an undefined character escape sequence.
-  - text after #endif is not allowed.
-  - invalid inner-style forward declaration.
-  - >? and <? operators, and their >?= and <?= cousins.
-
-  Additionally, check for constructor/destructor style violations and reference
-  members, as it is very convenient to do so while checking for
-  gcc-2 compliance.
-
-  Args:
-    filename: The name of the current file.
-    clean_lines: A CleansedLines instance containing the file.
-    linenum: The number of the line to check.
-    nesting_state: A NestingState instance which maintains information about
-                   the current stack of nested blocks being parsed.
-    error: A callable to which errors are reported, which takes 4 arguments:
-           filename, line number, error level, and message
-  """
-
-  # Remove comments from the line, but leave in strings for now.
-  line = clean_lines.lines[linenum]
-
-  if Search(r'printf\s*\(.*".*%[-+ ]?\d*q', line):
-    error(filename, linenum, 'runtime/printf_format', 3,
-          '%q in format strings is deprecated.  Use %ll instead.')
-
-  if Search(r'printf\s*\(.*".*%\d+\$', line):
-    error(filename, linenum, 'runtime/printf_format', 2,
-          '%N$ formats are unconventional.  Try rewriting to avoid them.')
-
-  # Remove escaped backslashes before looking for undefined escapes.
-  line = line.replace('\\\\', '')
-
-  if Search(r'("|\').*\\(%|\[|\(|{)', line):
-    error(filename, linenum, 'build/printf_format', 3,
-          '%, [, (, and { are undefined character escapes.  Unescape them.')
-
-  # For the rest, work with both comments and strings removed.
-  line = clean_lines.elided[linenum]
-
-  if Search(r'\b(const|volatile|void|char|short|int|long'
-            r'|float|double|signed|unsigned'
-            r'|schar|u?int8|u?int16|u?int32|u?int64)'
-            r'\s+(register|static|extern|typedef)\b',
-            line):
-    error(filename, linenum, 'build/storage_class', 5,
-          'Storage class (static, extern, typedef, etc) should be first.')
-
-  if Match(r'\s*#\s*endif\s*[^/\s]+', line):
-    error(filename, linenum, 'build/endif_comment', 5,
-          'Uncommented text after #endif is non-standard.  Use a comment.')
-
-  if Match(r'\s*class\s+(\w+\s*::\s*)+\w+\s*;', line):
-    error(filename, linenum, 'build/forward_decl', 5,
-          'Inner-style forward declarations are invalid.  Remove this line.')
-
-  if Search(r'(\w+|[+-]?\d+(\.\d*)?)\s*(<|>)\?=?\s*(\w+|[+-]?\d+)(\.\d*)?',
-            line):
-    error(filename, linenum, 'build/deprecated', 3,
-          '>? and <? (max and min) operators are non-standard and deprecated.')
-
-  if Search(r'^\s*const\s*string\s*&\s*\w+\s*;', line):
-    # TODO(unknown): Could it be expanded safely to arbitrary references,
-    # without triggering too many false positives? The first
-    # attempt triggered 5 warnings for mostly benign code in the regtest, hence
-    # the restriction.
-    # Here's the original regexp, for the reference:
-    # type_name = r'\w+((\s*::\s*\w+)|(\s*<\s*\w+?\s*>))?'
-    # r'\s*const\s*' + type_name + '\s*&\s*\w+\s*;'
-    error(filename, linenum, 'runtime/member_string_references', 2,
-          'const string& members are dangerous. It is much better to use '
-          'alternatives, such as pointers or simple constants.')
-
-  # Everything else in this function operates on class declarations.
-  # Return early if the top of the nesting stack is not a class, or if
-  # the class head is not completed yet.
-  classinfo = nesting_state.InnermostClass()
-  if not classinfo or not classinfo.seen_open_brace:
-    return
-
-  # The class may have been declared with namespace or classname qualifiers.
-  # The constructor and destructor will not have those qualifiers.
-  base_classname = classinfo.name.split('::')[-1]
-
-  # Look for single-argument constructors that aren't marked explicit.
-  # Technically a valid construct, but against style. Also look for
-  # non-single-argument constructors which are also technically valid, but
-  # strongly suggest something is wrong.
-  explicit_constructor_match = Match(
-      r'\s+(?:inline\s+)?(explicit\s+)?(?:inline\s+)?%s\s*'
-      r'\(((?:[^()]|\([^()]*\))*)\)'
-      % re.escape(base_classname),
-      line)
-
-  if explicit_constructor_match:
-    is_marked_explicit = explicit_constructor_match.group(1)
-
-    if not explicit_constructor_match.group(2):
-      constructor_args = []
-    else:
-      constructor_args = explicit_constructor_match.group(2).split(',')
-
-    # collapse arguments so that commas in template parameter lists and function
-    # argument parameter lists don't split arguments in two
-    i = 0
-    while i < len(constructor_args):
-      constructor_arg = constructor_args[i]
-      while (constructor_arg.count('<') > constructor_arg.count('>') or
-             constructor_arg.count('(') > constructor_arg.count(')')):
-        constructor_arg += ',' + constructor_args[i + 1]
-        del constructor_args[i + 1]
-      constructor_args[i] = constructor_arg
-      i += 1
-
-    defaulted_args = [arg for arg in constructor_args if '=' in arg]
-    noarg_constructor = (not constructor_args or  # empty arg list
-                         # 'void' arg specifier
-                         (len(constructor_args) == 1 and
-                          constructor_args[0].strip() == 'void'))
-    onearg_constructor = ((len(constructor_args) == 1 and  # exactly one arg
-                           not noarg_constructor) or
-                          # all but at most one arg defaulted
-                          (len(constructor_args) >= 1 and
-                           not noarg_constructor and
-                           len(defaulted_args) >= len(constructor_args) - 1))
-    initializer_list_constructor = bool(
-        onearg_constructor and
-        Search(r'\bstd\s*::\s*initializer_list\b', constructor_args[0]))
-    copy_constructor = bool(
-        onearg_constructor and
-        Match(r'(const\s+)?%s(\s*<[^>]*>)?(\s+const)?\s*(?:<\w+>\s*)?&'
-              % re.escape(base_classname), constructor_args[0].strip()))
-
-    if (not is_marked_explicit and
-        onearg_constructor and
-        not initializer_list_constructor and
-        not copy_constructor):
-      if defaulted_args:
-        error(filename, linenum, 'runtime/explicit', 5,
-              'Constructors callable with one argument '
-              'should be marked explicit.')
-      else:
-        error(filename, linenum, 'runtime/explicit', 5,
-              'Single-parameter constructors should be marked explicit.')
-    elif is_marked_explicit and not onearg_constructor:
-      if noarg_constructor:
-        error(filename, linenum, 'runtime/explicit', 5,
-              'Zero-parameter constructors should not be marked explicit.')
-      else:
-        error(filename, linenum, 'runtime/explicit', 0,
-              'Constructors that require multiple arguments '
-              'should not be marked explicit.')
-
-
-def CheckSpacingForFunctionCall(filename, clean_lines, linenum, error):
-  """Checks for the correctness of various spacing around function calls.
-
-  Args:
-    filename: The name of the current file.
-    clean_lines: A CleansedLines instance containing the file.
-    linenum: The number of the line to check.
-    error: The function to call with any errors found.
-  """
-  line = clean_lines.elided[linenum]
-
-  # Since function calls often occur inside if/for/while/switch
-  # expressions - which have their own, more liberal conventions - we
-  # first see if we should be looking inside such an expression for a
-  # function call, to which we can apply more strict standards.
-  fncall = line    # if there's no control flow construct, look at whole line
-  for pattern in (r'\bif\s*\((.*)\)\s*{',
-                  r'\bfor\s*\((.*)\)\s*{',
-                  r'\bwhile\s*\((.*)\)\s*[{;]',
-                  r'\bswitch\s*\((.*)\)\s*{'):
-    match = Search(pattern, line)
-    if match:
-      fncall = match.group(1)    # look inside the parens for function calls
-      break
-
-  # Except in if/for/while/switch, there should never be space
-  # immediately inside parens (eg "f( 3, 4 )").  We make an exception
-  # for nested parens ( (a+b) + c ).  Likewise, there should never be
-  # a space before a ( when it's a function argument.  I assume it's a
-  # function argument when the char before the whitespace is legal in
-  # a function name (alnum + _) and we're not starting a macro. Also ignore
-  # pointers and references to arrays and functions coz they're too tricky:
-  # we use a very simple way to recognize these:
-  # " (something)(maybe-something)" or
-  # " (something)(maybe-something," or
-  # " (something)[something]"
-  # Note that we assume the contents of [] to be short enough that
-  # they'll never need to wrap.
-  if (  # Ignore control structures.
-      not Search(r'\b(if|for|while|switch|return|new|delete|catch|sizeof)\b',
-                 fncall) and
-      # Ignore pointers/references to functions.
-      not Search(r' \([^)]+\)\([^)]*(\)|,$)', fncall) and
-      # Ignore pointers/references to arrays.
-      not Search(r' \([^)]+\)\[[^\]]+\]', fncall)):
-    if Search(r'\w\s*\(\s(?!\s*\\$)', fncall):      # a ( used for a fn call
-      error(filename, linenum, 'whitespace/parens', 4,
-            'Extra space after ( in function call')
-    elif Search(r'\(\s+(?!(\s*\\)|\()', fncall):
-      error(filename, linenum, 'whitespace/parens', 2,
-            'Extra space after (')
-    if (Search(r'\w\s+\(', fncall) and
-        not Search(r'#\s*define|typedef|using\s+\w+\s*=', fncall) and
-        not Search(r'\w\s+\((\w+::)*\*\w+\)\(', fncall) and
-        not Search(r'\bcase\s+\(', fncall)):
-      # TODO(unknown): Space after an operator function seem to be a common
-      # error, silence those for now by restricting them to highest verbosity.
-      if Search(r'\boperator_*\b', line):
-        error(filename, linenum, 'whitespace/parens', 0,
-              'Extra space before ( in function call')
-      else:
-        error(filename, linenum, 'whitespace/parens', 4,
-              'Extra space before ( in function call')
-    # If the ) is followed only by a newline or a { + newline, assume it's
-    # part of a control statement (if/while/etc), and don't complain
-    if Search(r'[^)]\s+\)\s*[^{\s]', fncall):
-      # If the closing parenthesis is preceded by only whitespaces,
-      # try to give a more descriptive error message.
-      if Search(r'^\s+\)', fncall):
-        error(filename, linenum, 'whitespace/parens', 2,
-              'Closing ) should be moved to the previous line')
-      else:
-        error(filename, linenum, 'whitespace/parens', 2,
-              'Extra space before )')
-
-
-def IsBlankLine(line):
-  """Returns true if the given line is blank.
-
-  We consider a line to be blank if the line is empty or consists of
-  only white spaces.
-
-  Args:
-    line: A line of a string.
-
-  Returns:
-    True, if the given line is blank.
-  """
-  return not line or line.isspace()
-
-
-def CheckForNamespaceIndentation(filename, nesting_state, clean_lines, line,
-                                 error):
-  is_namespace_indent_item = (
-      len(nesting_state.stack) > 1 and
-      nesting_state.stack[-1].check_namespace_indentation and
-      isinstance(nesting_state.previous_stack_top, _NamespaceInfo) and
-      nesting_state.previous_stack_top == nesting_state.stack[-2])
-
-  if ShouldCheckNamespaceIndentation(nesting_state, is_namespace_indent_item,
-                                     clean_lines.elided, line):
-    CheckItemIndentationInNamespace(filename, clean_lines.elided,
-                                    line, error)
-
-
-def CheckForFunctionLengths(filename, clean_lines, linenum,
-                            function_state, error):
-  """Reports for long function bodies.
-
-  For an overview why this is done, see:
-  http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Write_Short_Functions
-
-  Uses a simplistic algorithm assuming other style guidelines
-  (especially spacing) are followed.
-  Only checks unindented functions, so class members are unchecked.
-  Trivial bodies are unchecked, so constructors with huge initializer lists
-  may be missed.
-  Blank/comment lines are not counted so as to avoid encouraging the removal
-  of vertical space and comments just to get through a lint check.
-  NOLINT *on the last line of a function* disables this check.
-
-  Args:
-    filename: The name of the current file.
-    clean_lines: A CleansedLines instance containing the file.
-    linenum: The number of the line to check.
-    function_state: Current function name and lines in body so far.
-    error: The function to call with any errors found.
-  """
-  lines = clean_lines.lines
-  line = lines[linenum]
-  joined_line = ''
-
-  starting_func = False
-  regexp = r'(\w(\w|::|\*|\&|\s)*)\('  # decls * & space::name( ...
-  match_result = Match(regexp, line)
-  if match_result:
-    # If the name is all caps and underscores, figure it's a macro and
-    # ignore it, unless it's TEST or TEST_F.
-    function_name = match_result.group(1).split()[-1]
-    if function_name == 'TEST' or function_name == 'TEST_F' or (
-        not Match(r'[A-Z_]+$', function_name)):
-      starting_func = True
-
-  if starting_func:
-    body_found = False
-    for start_linenum in xrange(linenum, clean_lines.NumLines()):
-      start_line = lines[start_linenum]
-      joined_line += ' ' + start_line.lstrip()
-      if Search(r'(;|})', start_line):  # Declarations and trivial functions
-        body_found = True
-        break                              # ... ignore
-      elif Search(r'{', start_line):
-        body_found = True
-        function = Search(r'((\w|:)*)\(', line).group(1)
-        if Match(r'TEST', function):    # Handle TEST... macros
-          parameter_regexp = Search(r'(\(.*\))', joined_line)
-          if parameter_regexp:             # Ignore bad syntax
-            function += parameter_regexp.group(1)
-        else:
-          function += '()'
-        function_state.Begin(function)
-        break
-    if not body_found:
-      # No body for the function (or evidence of a non-function) was found.
-      error(filename, linenum, 'readability/fn_size', 5,
-            'Lint failed to find start of function body.')
-  elif Match(r'^\}\s*$', line):  # function end
-    function_state.Check(error, filename, linenum)
-    function_state.End()
-  elif not Match(r'^\s*$', line):
-    function_state.Count()  # Count non-blank/non-comment lines.
-
-
-_RE_PATTERN_TODO = re.compile(r'^//(\s*)TODO(\(.+?\))?:?(\s|$)?')
-
-
-def CheckComment(line, filename, linenum, next_line_start, error):
-  """Checks for common mistakes in comments.
-
-  Args:
-    line: The line in question.
-    filename: The name of the current file.
-    linenum: The number of the line to check.
-    next_line_start: The first non-whitespace column of the next line.
-    error: The function to call with any errors found.
-  """
-  commentpos = line.find('//')
-  if commentpos != -1:
-    # Check if the // may be in quotes.  If so, ignore it
-    # Comparisons made explicit for clarity -- pylint: disable=g-explicit-bool-comparison
-    if (line.count('"', 0, commentpos) -
-        line.count('\\"', 0, commentpos)) % 2 == 0:   # not in quotes
-      # Allow one space for new scopes, two spaces otherwise:
-      if (not (Match(r'^.*{ *//', line) and next_line_start == commentpos) and
-          ((commentpos >= 1 and
-            line[commentpos-1] not in string.whitespace) or
-           (commentpos >= 2 and
-            line[commentpos-2] not in string.whitespace))):
-        error(filename, linenum, 'whitespace/comments', 2,
-              'At least two spaces is best between code and comments')
-
-      # Checks for common mistakes in TODO comments.
-      comment = line[commentpos:]
-      match = _RE_PATTERN_TODO.match(comment)
-      if match:
-        # One whitespace is correct; zero whitespace is handled elsewhere.
-        leading_whitespace = match.group(1)
-        if len(leading_whitespace) > 1:
-          error(filename, linenum, 'whitespace/todo', 2,
-                'Too many spaces before TODO')
-
-        username = match.group(2)
-        if not username:
-          error(filename, linenum, 'readability/todo', 2,
-                'Missing username in TODO; it should look like '
-                '"// TODO(my_username): Stuff."')
-
-        middle_whitespace = match.group(3)
-        # Comparisons made explicit for correctness -- pylint: disable=g-explicit-bool-comparison
-        if middle_whitespace != ' ' and middle_whitespace != '':
-          error(filename, linenum, 'whitespace/todo', 2,
-                'TODO(my_username) should be followed by a space')
-
-      # If the comment contains an alphanumeric character, there
-      # should be a space somewhere between it and the // unless
-      # it's a /// or //! Doxygen comment.
-      if (Match(r'//[^ ]*\w', comment) and
-          not Match(r'(///|//\!)(\s+|$)', comment)):
-        error(filename, linenum, 'whitespace/comments', 4,
-              'Should have a space between // and comment')
-
-
-def CheckAccess(filename, clean_lines, linenum, nesting_state, error):
-  """Checks for improper use of DISALLOW* macros.
-
-  Args:
-    filename: The name of the current file.
-    clean_lines: A CleansedLines instance containing the file.
-    linenum: The number of the line to check.
-    nesting_state: A NestingState instance which maintains information about
-                   the current stack of nested blocks being parsed.
-    error: The function to call with any errors found.
-  """
-  line = clean_lines.elided[linenum]  # get rid of comments and strings
-
-  matched = Match((r'\s*(DISALLOW_COPY_AND_ASSIGN|'
-                   r'DISALLOW_IMPLICIT_CONSTRUCTORS)'), line)
-  if not matched:
-    return
-  if nesting_state.stack and isinstance(nesting_state.stack[-1], _ClassInfo):
-    if nesting_state.stack[-1].access != 'private':
-      error(filename, linenum, 'readability/constructors', 3,
-            '%s must be in the private: section' % matched.group(1))
-
-  else:
-    # Found DISALLOW* macro outside a class declaration, or perhaps it
-    # was used inside a function when it should have been part of the
-    # class declaration.  We could issue a warning here, but it
-    # probably resulted in a compiler error already.
-    pass
-
-
-def CheckSpacing(filename, clean_lines, linenum, nesting_state, error):
-  """Checks for the correctness of various spacing issues in the code.
-
-  Things we check for: spaces around operators, spaces after
-  if/for/while/switch, no spaces around parens in function calls, two
-  spaces between code and comment, don't start a block with a blank
-  line, don't end a function with a blank line, don't add a blank line
-  after public/protected/private, don't have too many blank lines in a row.
-
-  Args:
-    filename: The name of the current file.
-    clean_lines: A CleansedLines instance containing the file.
-    linenum: The number of the line to check.
-    nesting_state: A NestingState instance which maintains information about
-                   the current stack of nested blocks being parsed.
-    error: The function to call with any errors found.
-  """
-
-  # Don't use "elided" lines here, otherwise we can't check commented lines.
-  # Don't want to use "raw" either, because we don't want to check inside C++11
-  # raw strings,
-  raw = clean_lines.lines_without_raw_strings
-  line = raw[linenum]
-
-  # Before nixing comments, check if the line is blank for no good
-  # reason.  This includes the first line after a block is opened, and
-  # blank lines at the end of a function (ie, right before a line like '}'
-  #
-  # Skip all the blank line checks if we are immediately inside a
-  # namespace body.  In other words, don't issue blank line warnings
-  # for this block:
-  #   namespace {
-  #
-  #   }
-  #
-  # A warning about missing end of namespace comments will be issued instead.
-  #
-  # Also skip blank line checks for 'extern "C"' blocks, which are formatted
-  # like namespaces.
-  if (IsBlankLine(line) and
-      not nesting_state.InNamespaceBody() and
-      not nesting_state.InExternC()):
-    elided = clean_lines.elided
-    prev_line = elided[linenum - 1]
-    prevbrace = prev_line.rfind('{')
-    # TODO(unknown): Don't complain if line before blank line, and line after,
-    #                both start with alnums and are indented the same amount.
-    #                This ignores whitespace at the start of a namespace block
-    #                because those are not usually indented.
-    if prevbrace != -1 and prev_line[prevbrace:].find('}') == -1:
-      # OK, we have a blank line at the start of a code block.  Before we
-      # complain, we check if it is an exception to the rule: The previous
-      # non-empty line has the parameters of a function header that are indented
-      # 4 spaces (because they did not fit in a 80 column line when placed on
-      # the same line as the function name).  We also check for the case where
-      # the previous line is indented 6 spaces, which may happen when the
-      # initializers of a constructor do not fit into a 80 column line.
-      exception = False
-      if Match(r' {6}\w', prev_line):  # Initializer list?
-        # We are looking for the opening column of initializer list, which
-        # should be indented 4 spaces to cause 6 space indentation afterwards.
-        search_position = linenum-2
-        while (search_position >= 0
-               and Match(r' {6}\w', elided[search_position])):
-          search_position -= 1
-        exception = (search_position >= 0
-                     and elided[search_position][:5] == '    :')
-      else:
-        # Search for the function arguments or an initializer list.  We use a
-        # simple heuristic here: If the line is indented 4 spaces; and we have a
-        # closing paren, without the opening paren, followed by an opening brace
-        # or colon (for initializer lists) we assume that it is the last line of
-        # a function header.  If we have a colon indented 4 spaces, it is an
-        # initializer list.
-        exception = (Match(r' {4}\w[^\(]*\)\s*(const\s*)?(\{\s*$|:)',
-                           prev_line)
-                     or Match(r' {4}:', prev_line))
-
-      if not exception:
-        error(filename, linenum, 'whitespace/blank_line', 2,
-              'Redundant blank line at the start of a code block '
-              'should be deleted.')
-    # Ignore blank lines at the end of a block in a long if-else
-    # chain, like this:
-    #   if (condition1) {
-    #     // Something followed by a blank line
-    #
-    #   } else if (condition2) {
-    #     // Something else
-    #   }
-    if linenum + 1 < clean_lines.NumLines():
-      next_line = raw[linenum + 1]
-      if (next_line
-          and Match(r'\s*}', next_line)
-          and next_line.find('} else ') == -1):
-        error(filename, linenum, 'whitespace/blank_line', 3,
-              'Redundant blank line at the end of a code block '
-              'should be deleted.')
-
-    matched = Match(r'\s*(public|protected|private):', prev_line)
-    if matched:
-      error(filename, linenum, 'whitespace/blank_line', 3,
-            'Do not leave a blank line after "%s:"' % matched.group(1))
-
-  # Next, check comments
-  next_line_start = 0
-  if linenum + 1 < clean_lines.NumLines():
-    next_line = raw[linenum + 1]
-    next_line_start = len(next_line) - len(next_line.lstrip())
-  CheckComment(line, filename, linenum, next_line_start, error)
-
-  # get rid of comments and strings
-  line = clean_lines.elided[linenum]
-
-  # You shouldn't have spaces before your brackets, except maybe after
-  # 'delete []' or 'return []() {};'
-  if Search(r'\w\s+\[', line) and not Search(r'(?:delete|return)\s+\[', line):
-    error(filename, linenum, 'whitespace/braces', 5,
-          'Extra space before [')
-
-  # In range-based for, we wanted spaces before and after the colon, but
-  # not around "::" tokens that might appear.
-  if (Search(r'for *\(.*[^:]:[^: ]', line) or
-      Search(r'for *\(.*[^: ]:[^:]', line)):
-    error(filename, linenum, 'whitespace/forcolon', 2,
-          'Missing space around colon in range-based for loop')
-
-
-def CheckOperatorSpacing(filename, clean_lines, linenum, error):
-  """Checks for horizontal spacing around operators.
-
-  Args:
-    filename: The name of the current file.
-    clean_lines: A CleansedLines instance containing the file.
-    linenum: The number of the line to check.
-    error: The function to call with any errors found.
-  """
-  line = clean_lines.elided[linenum]
-
-  # Don't try to do spacing checks for operator methods.  Do this by
-  # replacing the troublesome characters with something else,
-  # preserving column position for all other characters.
-  #
-  # The replacement is done repeatedly to avoid false positives from
-  # operators that call operators.
-  while True:
-    match = Match(r'^(.*\boperator\b)(\S+)(\s*\(.*)$', line)
-    if match:
-      line = match.group(1) + ('_' * len(match.group(2))) + match.group(3)
-    else:
-      break
-
-  # We allow no-spaces around = within an if: "if ( (a=Foo()) == 0 )".
-  # Otherwise not.  Note we only check for non-spaces on *both* sides;
-  # sometimes people put non-spaces on one side when aligning ='s among
-  # many lines (not that this is behavior that I approve of...)
-  if ((Search(r'[\w.]=', line) or
-       Search(r'=[\w.]', line))
-      and not Search(r'\b(if|while|for) ', line)
-      # Operators taken from [lex.operators] in C++11 standard.
-      and not Search(r'(>=|<=|==|!=|&=|\^=|\|=|\+=|\*=|\/=|\%=)', line)
-      and not Search(r'operator=', line)):
-    error(filename, linenum, 'whitespace/operators', 4,
-          'Missing spaces around =')
-
-  # It's ok not to have spaces around binary operators like + - * /, but if
-  # there's too little whitespace, we get concerned.  It's hard to tell,
-  # though, so we punt on this one for now.  TODO.
-
-  # You should always have whitespace around binary operators.
-  #
-  # Check <= and >= first to avoid false positives with < and >, then
-  # check non-include lines for spacing around < and >.
-  #
-  # If the operator is followed by a comma, assume it's be used in a
-  # macro context and don't do any checks.  This avoids false
-  # positives.
-  #
-  # Note that && is not included here.  Those are checked separately
-  # in CheckRValueReference
-  match = Search(r'[^<>=!\s](==|!=|<=|>=|\|\|)[^<>=!\s,;\)]', line)
-  if match:
-    error(filename, linenum, 'whitespace/operators', 3,
-          'Missing spaces around %s' % match.group(1))
-  elif not Match(r'#.*include', line):
-    # Look for < that is not surrounded by spaces.  This is only
-    # triggered if both sides are missing spaces, even though
-    # technically should should flag if at least one side is missing a
-    # space.  This is done to avoid some false positives with shifts.
-    match = Match(r'^(.*[^\s<])<[^\s=<,]', line)
-    if match:
-      (_, _, end_pos) = CloseExpression(
-          clean_lines, linenum, len(match.group(1)))
-      if end_pos <= -1:
-        error(filename, linenum, 'whitespace/operators', 3,
-              'Missing spaces around <')
-
-    # Look for > that is not surrounded by spaces.  Similar to the
-    # above, we only trigger if both sides are missing spaces to avoid
-    # false positives with shifts.
-    match = Match(r'^(.*[^-\s>])>[^\s=>,]', line)
-    if match:
-      (_, _, start_pos) = ReverseCloseExpression(
-          clean_lines, linenum, len(match.group(1)))
-      if start_pos <= -1:
-        error(filename, linenum, 'whitespace/operators', 3,
-              'Missing spaces around >')
-
-  # We allow no-spaces around << when used like this: 10<<20, but
-  # not otherwise (particularly, not when used as streams)
-  #
-  # We also allow operators following an opening parenthesis, since
-  # those tend to be macros that deal with operators.
-  match = Search(r'(operator|[^\s(<])(?:L|UL|ULL|l|ul|ull)?<<([^\s,=<])', line)
-  if (match and not (match.group(1).isdigit() and match.group(2).isdigit()) and
-      not (match.group(1) == 'operator' and match.group(2) == ';')):
-    error(filename, linenum, 'whitespace/operators', 3,
-          'Missing spaces around <<')
-
-  # We allow no-spaces around >> for almost anything.  This is because
-  # C++11 allows ">>" to close nested templates, which accounts for
-  # most cases when ">>" is not followed by a space.
-  #
-  # We still warn on ">>" followed by alpha character, because that is
-  # likely due to ">>" being used for right shifts, e.g.:
-  #   value >> alpha
-  #
-  # When ">>" is used to close templates, the alphanumeric letter that
-  # follows would be part of an identifier, and there should still be
-  # a space separating the template type and the identifier.
-  #   type<type<type>> alpha
-  match = Search(r'>>[a-zA-Z_]', line)
-  if match:
-    error(filename, linenum, 'whitespace/operators', 3,
-          'Missing spaces around >>')
-
-  # There shouldn't be space around unary operators
-  match = Search(r'(!\s|~\s|[\s]--[\s;]|[\s]\+\+[\s;])', line)
-  if match:
-    error(filename, linenum, 'whitespace/operators', 4,
-          'Extra space for operator %s' % match.group(1))
-
-
-def CheckParenthesisSpacing(filename, clean_lines, linenum, error):
-  """Checks for horizontal spacing around parentheses.
-
-  Args:
-    filename: The name of the current file.
-    clean_lines: A CleansedLines instance containing the file.
-    linenum: The number of the line to check.
-    error: The function to call with any errors found.
-  """
-  line = clean_lines.elided[linenum]
-
-  # No spaces after an if, while, switch, or for
-  match = Search(r' (if\(|for\(|while\(|switch\()', line)
-  if match:
-    error(filename, linenum, 'whitespace/parens', 5,
-          'Missing space before ( in %s' % match.group(1))
-
-  # For if/for/while/switch, the left and right parens should be
-  # consistent about how many spaces are inside the parens, and
-  # there should either be zero or one spaces inside the parens.
-  # We don't want: "if ( foo)" or "if ( foo   )".
-  # Exception: "for ( ; foo; bar)" and "for (foo; bar; )" are allowed.
-  match = Search(r'\b(if|for|while|switch)\s*'
-                 r'\(([ ]*)(.).*[^ ]+([ ]*)\)\s*{\s*$',
-                 line)
-  if match:
-    if len(match.group(2)) != len(match.group(4)):
-      if not (match.group(3) == ';' and
-              len(match.group(2)) == 1 + len(match.group(4)) or
-              not match.group(2) and Search(r'\bfor\s*\(.*; \)', line)):
-        error(filename, linenum, 'whitespace/parens', 5,
-              'Mismatching spaces inside () in %s' % match.group(1))
-    if len(match.group(2)) not in [0, 1]:
-      error(filename, linenum, 'whitespace/parens', 5,
-            'Should have zero or one spaces inside ( and ) in %s' %
-            match.group(1))
-
-
-def CheckCommaSpacing(filename, clean_lines, linenum, error):
-  """Checks for horizontal spacing near commas and semicolons.
-
-  Args:
-    filename: The name of the current file.
-    clean_lines: A CleansedLines instance containing the file.
-    linenum: The number of the line to check.
-    error: The function to call with any errors found.
-  """
-  raw = clean_lines.lines_without_raw_strings
-  line = clean_lines.elided[linenum]
-
-  # You should always have a space after a comma (either as fn arg or operator)
-  #
-  # This does not apply when the non-space character following the
-  # comma is another comma, since the only time when that happens is
-  # for empty macro arguments.
-  #
-  # We run this check in two passes: first pass on elided lines to
-  # verify that lines contain missing whitespaces, second pass on raw
-  # lines to confirm that those missing whitespaces are not due to
-  # elided comments.
-  if (Search(r',[^,\s]', ReplaceAll(r'\boperator\s*,\s*\(', 'F(', line)) and
-      Search(r',[^,\s]', raw[linenum])):
-    error(filename, linenum, 'whitespace/comma', 3,
-          'Missing space after ,')
-
-  # You should always have a space after a semicolon
-  # except for few corner cases
-  # TODO(unknown): clarify if 'if (1) { return 1;}' is requires one more
-  # space after ;
-  if Search(r';[^\s};\\)/]', line):
-    error(filename, linenum, 'whitespace/semicolon', 3,
-          'Missing space after ;')
-
-
-def CheckBracesSpacing(filename, clean_lines, linenum, error):
-  """Checks for horizontal spacing near commas.
-
-  Args:
-    filename: The name of the current file.
-    clean_lines: A CleansedLines instance containing the file.
-    linenum: The number of the line to check.
-    error: The function to call with any errors found.
-  """
-  line = clean_lines.elided[linenum]
-
-  # Except after an opening paren, or after another opening brace (in case of
-  # an initializer list, for instance), you should have spaces before your
-  # braces. And since you should never have braces at the beginning of a line,
-  # this is an easy test.
-  match = Match(r'^(.*[^ ({>]){', line)
-  if match:
-    # Try a bit harder to check for brace initialization.  This
-    # happens in one of the following forms:
-    #   Constructor() : initializer_list_{} { ... }
-    #   Constructor{}.MemberFunction()
-    #   Type variable{};
-    #   FunctionCall(type{}, ...);
-    #   LastArgument(..., type{});
-    #   LOG(INFO) << type{} << " ...";
-    #   map_of_type[{...}] = ...;
-    #   ternary = expr ? new type{} : nullptr;
-    #   OuterTemplate<InnerTemplateConstructor<Type>{}>
-    #
-    # We check for the character following the closing brace, and
-    # silence the warning if it's one of those listed above, i.e.
-    # "{.;,)<>]:".
-    #
-    # To account for nested initializer list, we allow any number of
-    # closing braces up to "{;,)<".  We can't simply silence the
-    # warning on first sight of closing brace, because that would
-    # cause false negatives for things that are not initializer lists.
-    #   Silence this:         But not this:
-    #     Outer{                if (...) {
-    #       Inner{...}            if (...){  // Missing space before {
-    #     };                    }
-    #
-    # There is a false negative with this approach if people inserted
-    # spurious semicolons, e.g. "if (cond){};", but we will catch the
-    # spurious semicolon with a separate check.
-    (endline, endlinenum, endpos) = CloseExpression(
-        clean_lines, linenum, len(match.group(1)))
-    trailing_text = ''
-    if endpos > -1:
-      trailing_text = endline[endpos:]
-    for offset in xrange(endlinenum + 1,
-                         min(endlinenum + 3, clean_lines.NumLines() - 1)):
-      trailing_text += clean_lines.elided[offset]
-    if not Match(r'^[\s}]*[{.;,)<>\]:]', trailing_text):
-      error(filename, linenum, 'whitespace/braces', 5,
-            'Missing space before {')
-
-  # Make sure '} else {' has spaces.
-  if Search(r'}else', line):
-    error(filename, linenum, 'whitespace/braces', 5,
-          'Missing space before else')
-
-  # You shouldn't have a space before a semicolon at the end of the line.
-  # There's a special case for "for" since the style guide allows space before
-  # the semicolon there.
-  if Search(r':\s*;\s*$', line):
-    error(filename, linenum, 'whitespace/semicolon', 5,
-          'Semicolon defining empty statement. Use {} instead.')
-  elif Search(r'^\s*;\s*$', line):
-    error(filename, linenum, 'whitespace/semicolon', 5,
-          'Line contains only semicolon. If this should be an empty statement, '
-          'use {} instead.')
-  elif (Search(r'\s+;\s*$', line) and
-        not Search(r'\bfor\b', line)):
-    error(filename, linenum, 'whitespace/semicolon', 5,
-          'Extra space before last semicolon. If this should be an empty '
-          'statement, use {} instead.')
-
-
-def IsDecltype(clean_lines, linenum, column):
-  """Check if the token ending on (linenum, column) is decltype().
-
-  Args:
-    clean_lines: A CleansedLines instance containing the file.
-    linenum: the number of the line to check.
-    column: end column of the token to check.
-  Returns:
-    True if this token is decltype() expression, False otherwise.
-  """
-  (text, _, start_col) = ReverseCloseExpression(clean_lines, linenum, column)
-  if start_col < 0:
-    return False
-  if Search(r'\bdecltype\s*$', text[0:start_col]):
-    return True
-  return False
-
-
-def IsTemplateParameterList(clean_lines, linenum, column):
-  """Check if the token ending on (linenum, column) is the end of template<>.
-
-  Args:
-    clean_lines: A CleansedLines instance containing the file.
-    linenum: the number of the line to check.
-    column: end column of the token to check.
-  Returns:
-    True if this token is end of a template parameter list, False otherwise.
-  """
-  (_, startline, startpos) = ReverseCloseExpression(
-      clean_lines, linenum, column)
-  if (startpos > -1 and
-      Search(r'\btemplate\s*$', clean_lines.elided[startline][0:startpos])):
-    return True
-  return False
-
-
-def IsRValueType(typenames, clean_lines, nesting_state, linenum, column):
-  """Check if the token ending on (linenum, column) is a type.
-
-  Assumes that text to the right of the column is "&&" or a function
-  name.
-
-  Args:
-    typenames: set of type names from template-argument-list.
-    clean_lines: A CleansedLines instance containing the file.
-    nesting_state: A NestingState instance which maintains information about
-                   the current stack of nested blocks being parsed.
-    linenum: the number of the line to check.
-    column: end column of the token to check.
-  Returns:
-    True if this token is a type, False if we are not sure.
-  """
-  prefix = clean_lines.elided[linenum][0:column]
-
-  # Get one word to the left.  If we failed to do so, this is most
-  # likely not a type, since it's unlikely that the type name and "&&"
-  # would be split across multiple lines.
-  match = Match(r'^(.*)(\b\w+|[>*)&])\s*$', prefix)
-  if not match:
-    return False
-
-  # Check text following the token.  If it's "&&>" or "&&," or "&&...", it's
-  # most likely a rvalue reference used inside a template.
-  suffix = clean_lines.elided[linenum][column:]
-  if Match(r'&&\s*(?:[>,]|\.\.\.)', suffix):
-    return True
-
-  # Check for known types and end of templates:
-  #   int&& variable
-  #   vector<int>&& variable
-  #
-  # Because this function is called recursively, we also need to
-  # recognize pointer and reference types:
-  #   int* Function()
-  #   int& Function()
-  if (match.group(2) in typenames or
-      match.group(2) in ['char', 'char16_t', 'char32_t', 'wchar_t', 'bool',
-                         'short', 'int', 'long', 'signed', 'unsigned',
-                         'float', 'double', 'void', 'auto', '>', '*', '&']):
-    return True
-
-  # If we see a close parenthesis, look for decltype on the other side.
-  # decltype would unambiguously identify a type, anything else is
-  # probably a parenthesized expression and not a type.
-  if match.group(2) == ')':
-    return IsDecltype(
-        clean_lines, linenum, len(match.group(1)) + len(match.group(2)) - 1)
-
-  # Check for casts and cv-qualifiers.
-  #   match.group(1)  remainder
-  #   --------------  ---------
-  #   const_cast<     type&&
-  #   const           type&&
-  #   type            const&&
-  if Search(r'\b(?:const_cast\s*<|static_cast\s*<|dynamic_cast\s*<|'
-            r'reinterpret_cast\s*<|\w+\s)\s*$',
-            match.group(1)):
-    return True
-
-  # Look for a preceding symbol that might help differentiate the context.
-  # These are the cases that would be ambiguous:
-  #   match.group(1)  remainder
-  #   --------------  ---------
-  #   Call         (   expression &&
-  #   Declaration  (   type&&
-  #   sizeof       (   type&&
-  #   if           (   expression &&
-  #   while        (   expression &&
-  #   for          (   type&&
-  #   for(         ;   expression &&
-  #   statement    ;   type&&
-  #   block        {   type&&
-  #   constructor  {   expression &&
-  start = linenum
-  line = match.group(1)
-  match_symbol = None
-  while start >= 0:
-    # We want to skip over identifiers and commas to get to a symbol.
-    # Commas are skipped so that we can find the opening parenthesis
-    # for function parameter lists.
-    match_symbol = Match(r'^(.*)([^\w\s,])[\w\s,]*$', line)
-    if match_symbol:
-      break
-    start -= 1
-    line = clean_lines.elided[start]
-
-  if not match_symbol:
-    # Probably the first statement in the file is an rvalue reference
-    return True
-
-  if match_symbol.group(2) == '}':
-    # Found closing brace, probably an indicate of this:
-    #   block{} type&&
-    return True
-
-  if match_symbol.group(2) == ';':
-    # Found semicolon, probably one of these:
-    #   for(; expression &&
-    #   statement; type&&
-
-    # Look for the previous 'for(' in the previous lines.
-    before_text = match_symbol.group(1)
-    for i in xrange(start - 1, max(start - 6, 0), -1):
-      before_text = clean_lines.elided[i] + before_text
-    if Search(r'for\s*\([^{};]*$', before_text):
-      # This is the condition inside a for-loop
-      return False
-
-    # Did not find a for-init-statement before this semicolon, so this
-    # is probably a new statement and not a condition.
-    return True
-
-  if match_symbol.group(2) == '{':
-    # Found opening brace, probably one of these:
-    #   block{ type&& = ... ; }
-    #   constructor{ expression && expression }
-
-    # Look for a closing brace or a semicolon.  If we see a semicolon
-    # first, this is probably a rvalue reference.
-    line = clean_lines.elided[start][0:len(match_symbol.group(1)) + 1]
-    end = start
-    depth = 1
-    while True:
-      for ch in line:
-        if ch == ';':
-          return True
-        elif ch == '{':
-          depth += 1
-        elif ch == '}':
-          depth -= 1
-          if depth == 0:
-            return False
-      end += 1
-      if end >= clean_lines.NumLines():
-        break
-      line = clean_lines.elided[end]
-    # Incomplete program?
-    return False
-
-  if match_symbol.group(2) == '(':
-    # Opening parenthesis.  Need to check what's to the left of the
-    # parenthesis.  Look back one extra line for additional context.
-    before_text = match_symbol.group(1)
-    if linenum > 1:
-      before_text = clean_lines.elided[linenum - 1] + before_text
-    before_text = match_symbol.group(1)
-
-    # Patterns that are likely to be types:
-    #   [](type&&
-    #   for (type&&
-    #   sizeof(type&&
-    #   operator=(type&&
-    #
-    if Search(r'(?:\]|\bfor|\bsizeof|\boperator\s*\S+\s*)\s*$', before_text):
-      return True
-
-    # Patterns that are likely to be expressions:
-    #   if (expression &&
-    #   while (expression &&
-    #   : initializer(expression &&
-    #   , initializer(expression &&
-    #   ( FunctionCall(expression &&
-    #   + FunctionCall(expression &&
-    #   + (expression &&
-    #
-    # The last '+' represents operators such as '+' and '-'.
-    if Search(r'(?:\bif|\bwhile|[-+=%^(<!?:,&*]\s*)$', before_text):
-      return False
-
-    # Something else.  Check that tokens to the left look like
-    #   return_type function_name
-    match_func = Match(r'^(.*\S.*)\s+\w(?:\w|::)*(?:<[^<>]*>)?\s*$',
-                       match_symbol.group(1))
-    if match_func:
-      # Check for constructors, which don't have return types.
-      if Search(r'\b(?:explicit|inline)$', match_func.group(1)):
-        return True
-      implicit_constructor = Match(r'\s*(\w+)\((?:const\s+)?(\w+)', prefix)
-      if (implicit_constructor and
-          implicit_constructor.group(1) == implicit_constructor.group(2)):
-        return True
-      return IsRValueType(typenames, clean_lines, nesting_state, linenum,
-                          len(match_func.group(1)))
-
-    # Nothing before the function name.  If this is inside a block scope,
-    # this is probably a function call.
-    return not (nesting_state.previous_stack_top and
-                nesting_state.previous_stack_top.IsBlockInfo())
-
-  if match_symbol.group(2) == '>':
-    # Possibly a closing bracket, check that what's on the other side
-    # looks like the start of a template.
-    return IsTemplateParameterList(
-        clean_lines, start, len(match_symbol.group(1)))
-
-  # Some other symbol, usually something like "a=b&&c".  This is most
-  # likely not a type.
-  return False
-
-
-def IsDeletedOrDefault(clean_lines, linenum):
-  """Check if current constructor or operator is deleted or default.
-
-  Args:
-    clean_lines: A CleansedLines instance containing the file.
-    linenum: The number of the line to check.
-  Returns:
-    True if this is a deleted or default constructor.
-  """
-  open_paren = clean_lines.elided[linenum].find('(')
-  if open_paren < 0:
-    return False
-  (close_line, _, close_paren) = CloseExpression(
-      clean_lines, linenum, open_paren)
-  if close_paren < 0:
-    return False
-  return Match(r'\s*=\s*(?:delete|default)\b', close_line[close_paren:])
-
-
-def IsRValueAllowed(clean_lines, linenum, typenames):
-  """Check if RValue reference is allowed on a particular line.
-
-  Args:
-    clean_lines: A CleansedLines instance containing the file.
-    linenum: The number of the line to check.
-    typenames: set of type names from template-argument-list.
-  Returns:
-    True if line is within the region where RValue references are allowed.
-  """
-  # Allow region marked by PUSH/POP macros
-  for i in xrange(linenum, 0, -1):
-    line = clean_lines.elided[i]
-    if Match(r'GOOGLE_ALLOW_RVALUE_REFERENCES_(?:PUSH|POP)', line):
-      if not line.endswith('PUSH'):
-        return False
-      for j in xrange(linenum, clean_lines.NumLines(), 1):
-        line = clean_lines.elided[j]
-        if Match(r'GOOGLE_ALLOW_RVALUE_REFERENCES_(?:PUSH|POP)', line):
-          return line.endswith('POP')
-
-  # Allow operator=
-  line = clean_lines.elided[linenum]
-  if Search(r'\boperator\s*=\s*\(', line):
-    return IsDeletedOrDefault(clean_lines, linenum)
-
-  # Allow constructors
-  match = Match(r'\s*(?:[\w<>]+::)*([\w<>]+)\s*::\s*([\w<>]+)\s*\(', line)
-  if match and match.group(1) == match.group(2):
-    return IsDeletedOrDefault(clean_lines, linenum)
-  if Search(r'\b(?:explicit|inline)\s+[\w<>]+\s*\(', line):
-    return IsDeletedOrDefault(clean_lines, linenum)
-
-  if Match(r'\s*[\w<>]+\s*\(', line):
-    previous_line = 'ReturnType'
-    if linenum > 0:
-      previous_line = clean_lines.elided[linenum - 1]
-    if Match(r'^\s*$', previous_line) or Search(r'[{}:;]\s*$', previous_line):
-      return IsDeletedOrDefault(clean_lines, linenum)
-
-  # Reject types not mentioned in template-argument-list
-  while line:
-    match = Match(r'^.*?(\w+)\s*&&(.*)$', line)
-    if not match:
-      break
-    if match.group(1) not in typenames:
-      return False
-    line = match.group(2)
-
-  # All RValue types that were in template-argument-list should have
-  # been removed by now.  Those were allowed, assuming that they will
-  # be forwarded.
-  #
-  # If there are no remaining RValue types left (i.e. types that were
-  # not found in template-argument-list), flag those as not allowed.
-  return line.find('&&') < 0
-
-
-def GetTemplateArgs(clean_lines, linenum):
-  """Find list of template arguments associated with this function declaration.
-
-  Args:
-    clean_lines: A CleansedLines instance containing the file.
-    linenum: Line number containing the start of the function declaration,
-             usually one line after the end of the template-argument-list.
-  Returns:
-    Set of type names, or empty set if this does not appear to have
-    any template parameters.
-  """
-  # Find start of function
-  func_line = linenum
-  while func_line > 0:
-    line = clean_lines.elided[func_line]
-    if Match(r'^\s*$', line):
-      return set()
-    if line.find('(') >= 0:
-      break
-    func_line -= 1
-  if func_line == 0:
-    return set()
-
-  # Collapse template-argument-list into a single string
-  argument_list = ''
-  match = Match(r'^(\s*template\s*)<', clean_lines.elided[func_line])
-  if match:
-    # template-argument-list on the same line as function name
-    start_col = len(match.group(1))
-    _, end_line, end_col = CloseExpression(clean_lines, func_line, start_col)
-    if end_col > -1 and end_line == func_line:
-      start_col += 1  # Skip the opening bracket
-      argument_list = clean_lines.elided[func_line][start_col:end_col]
-
-  elif func_line > 1:
-    # template-argument-list one line before function name
-    match = Match(r'^(.*)>\s*$', clean_lines.elided[func_line - 1])
-    if match:
-      end_col = len(match.group(1))
-      _, start_line, start_col = ReverseCloseExpression(
-          clean_lines, func_line - 1, end_col)
-      if start_col > -1:
-        start_col += 1  # Skip the opening bracket
-        while start_line < func_line - 1:
-          argument_list += clean_lines.elided[start_line][start_col:]
-          start_col = 0
-          start_line += 1
-        argument_list += clean_lines.elided[func_line - 1][start_col:end_col]
-
-  if not argument_list:
-    return set()
-
-  # Extract type names
-  typenames = set()
-  while True:
-    match = Match(r'^[,\s]*(?:typename|class)(?:\.\.\.)?\s+(\w+)(.*)$',
-                  argument_list)
-    if not match:
-      break
-    typenames.add(match.group(1))
-    argument_list = match.group(2)
-  return typenames
-
-
-def CheckRValueReference(filename, clean_lines, linenum, nesting_state, error):
-  """Check for rvalue references.
-
-  Args:
-    filename: The name of the current file.
-    clean_lines: A CleansedLines instance containing the file.
-    linenum: The number of the line to check.
-    nesting_state: A NestingState instance which maintains information about
-                   the current stack of nested blocks being parsed.
-    error: The function to call with any errors found.
-  """
-  # Find lines missing spaces around &&.
-  # TODO(unknown): currently we don't check for rvalue references
-  # with spaces surrounding the && to avoid false positives with
-  # boolean expressions.
-  line = clean_lines.elided[linenum]
-  match = Match(r'^(.*\S)&&', line)
-  if not match:
-    match = Match(r'(.*)&&\S', line)
-  if (not match) or '(&&)' in line or Search(r'\boperator\s*$', match.group(1)):
-    return
-
-  # Either poorly formed && or an rvalue reference, check the context
-  # to get a more accurate error message.  Mostly we want to determine
-  # if what's to the left of "&&" is a type or not.
-  typenames = GetTemplateArgs(clean_lines, linenum)
-  and_pos = len(match.group(1))
-  if IsRValueType(typenames, clean_lines, nesting_state, linenum, and_pos):
-    if not IsRValueAllowed(clean_lines, linenum, typenames):
-      error(filename, linenum, 'build/c++11', 3,
-            'RValue references are an unapproved C++ feature.')
-  else:
-    error(filename, linenum, 'whitespace/operators', 3,
-          'Missing spaces around &&')
-
-
-def CheckSectionSpacing(filename, clean_lines, class_info, linenum, error):
-  """Checks for additional blank line issues related to sections.
-
-  Currently the only thing checked here is blank line before protected/private.
-
-  Args:
-    filename: The name of the current file.
-    clean_lines: A CleansedLines instance containing the file.
-    class_info: A _ClassInfo objects.
-    linenum: The number of the line to check.
-    error: The function to call with any errors found.
-  """
-  # Skip checks if the class is small, where small means 25 lines or less.
-  # 25 lines seems like a good cutoff since that's the usual height of
-  # terminals, and any class that can't fit in one screen can't really
-  # be considered "small".
-  #
-  # Also skip checks if we are on the first line.  This accounts for
-  # classes that look like
-  #   class Foo { public: ... };
-  #
-  # If we didn't find the end of the class, last_line would be zero,
-  # and the check will be skipped by the first condition.
-  if (class_info.last_line - class_info.starting_linenum <= 24 or
-      linenum <= class_info.starting_linenum):
-    return
-
-  matched = Match(r'\s*(public|protected|private):', clean_lines.lines[linenum])
-  if matched:
-    # Issue warning if the line before public/protected/private was
-    # not a blank line, but don't do this if the previous line contains
-    # "class" or "struct".  This can happen two ways:
-    #  - We are at the beginning of the class.
-    #  - We are forward-declaring an inner class that is semantically
-    #    private, but needed to be public for implementation reasons.
-    # Also ignores cases where the previous line ends with a backslash as can be
-    # common when defining classes in C macros.
-    prev_line = clean_lines.lines[linenum - 1]
-    if (not IsBlankLine(prev_line) and
-        not Search(r'\b(class|struct)\b', prev_line) and
-        not Search(r'\\$', prev_line)):
-      # Try a bit harder to find the beginning of the class.  This is to
-      # account for multi-line base-specifier lists, e.g.:
-      #   class Derived
-      #       : public Base {
-      end_class_head = class_info.starting_linenum
-      for i in range(class_info.starting_linenum, linenum):
-        if Search(r'\{\s*$', clean_lines.lines[i]):
-          end_class_head = i
-          break
-      if end_class_head < linenum - 1:
-        error(filename, linenum, 'whitespace/blank_line', 3,
-              '"%s:" should be preceded by a blank line' % matched.group(1))
-
-
-def GetPreviousNonBlankLine(clean_lines, linenum):
-  """Return the most recent non-blank line and its line number.
-
-  Args:
-    clean_lines: A CleansedLines instance containing the file contents.
-    linenum: The number of the line to check.
-
-  Returns:
-    A tuple with two elements.  The first element is the contents of the last
-    non-blank line before the current line, or the empty string if this is the
-    first non-blank line.  The second is the line number of that line, or -1
-    if this is the first non-blank line.
-  """
-
-  prevlinenum = linenum - 1
-  while prevlinenum >= 0:
-    prevline = clean_lines.elided[prevlinenum]
-    if not IsBlankLine(prevline):     # if not a blank line...
-      return (prevline, prevlinenum)
-    prevlinenum -= 1
-  return ('', -1)
-
-
-def CheckBraces(filename, clean_lines, linenum, error):
-  """Looks for misplaced braces (e.g. at the end of line).
-
-  Args:
-    filename: The name of the current file.
-    clean_lines: A CleansedLines instance containing the file.
-    linenum: The number of the line to check.
-    error: The function to call with any errors found.
-  """
-
-  line = clean_lines.elided[linenum]        # get rid of comments and strings
-
-  if Match(r'\s*{\s*$', line):
-    # We allow an open brace to start a line in the case where someone is using
-    # braces in a block to explicitly create a new scope, which is commonly used
-    # to control the lifetime of stack-allocated variables.  Braces are also
-    # used for brace initializers inside function calls.  We don't detect this
-    # perfectly: we just don't complain if the last non-whitespace character on
-    # the previous non-blank line is ',', ';', ':', '(', '{', or '}', or if the
-    # previous line starts a preprocessor block.
-    prevline = GetPreviousNonBlankLine(clean_lines, linenum)[0]
-    if (not Search(r'[,;:}{(]\s*$', prevline) and
-        not Match(r'\s*#', prevline)):
-      error(filename, linenum, 'whitespace/braces', 4,
-            '{ should almost always be at the end of the previous line')
-
-  # An else clause should be on the same line as the preceding closing brace.
-  if Match(r'\s*else\b\s*(?:if\b|\{|$)', line):
-    prevline = GetPreviousNonBlankLine(clean_lines, linenum)[0]
-    if Match(r'\s*}\s*$', prevline):
-      error(filename, linenum, 'whitespace/newline', 4,
-            'An else should appear on the same line as the preceding }')
-
-  # If braces come on one side of an else, they should be on both.
-  # However, we have to worry about "else if" that spans multiple lines!
-  if Search(r'else if\s*\(', line):       # could be multi-line if
-    brace_on_left = bool(Search(r'}\s*else if\s*\(', line))
-    # find the ( after the if
-    pos = line.find('else if')
-    pos = line.find('(', pos)
-    if pos > 0:
-      (endline, _, endpos) = CloseExpression(clean_lines, linenum, pos)
-      brace_on_right = endline[endpos:].find('{') != -1
-      if brace_on_left != brace_on_right:    # must be brace after if
-        error(filename, linenum, 'readability/braces', 5,
-              'If an else has a brace on one side, it should have it on both')
-  elif Search(r'}\s*else[^{]*$', line) or Match(r'[^}]*else\s*{', line):
-    error(filename, linenum, 'readability/braces', 5,
-          'If an else has a brace on one side, it should have it on both')
-
-  # Likewise, an else should never have the else clause on the same line
-  if Search(r'\belse [^\s{]', line) and not Search(r'\belse if\b', line):
-    error(filename, linenum, 'whitespace/newline', 4,
-          'Else clause should never be on same line as else (use 2 lines)')
-
-  # In the same way, a do/while should never be on one line
-  if Match(r'\s*do [^\s{]', line):
-    error(filename, linenum, 'whitespace/newline', 4,
-          'do/while clauses should not be on a single line')
-
-  # Check single-line if/else bodies. The style guide says 'curly braces are not
-  # required for single-line statements'. We additionally allow multi-line,
-  # single statements, but we reject anything with more than one semicolon in
-  # it. This means that the first semicolon after the if should be at the end of
-  # its line, and the line after that should have an indent level equal to or
-  # lower than the if. We also check for ambiguous if/else nesting without
-  # braces.
-  if_else_match = Search(r'\b(if\s*\(|else\b)', line)
-  if if_else_match and not Match(r'\s*#', line):
-    if_indent = GetIndentLevel(line)
-    endline, endlinenum, endpos = line, linenum, if_else_match.end()
-    if_match = Search(r'\bif\s*\(', line)
-    if if_match:
-      # This could be a multiline if condition, so find the end first.
-      pos = if_match.end() - 1
-      (endline, endlinenum, endpos) = CloseExpression(clean_lines, linenum, pos)
-    # Check for an opening brace, either directly after the if or on the next
-    # line. If found, this isn't a single-statement conditional.
-    if (not Match(r'\s*{', endline[endpos:])
-        and not (Match(r'\s*$', endline[endpos:])
-                 and endlinenum < (len(clean_lines.elided) - 1)
-                 and Match(r'\s*{', clean_lines.elided[endlinenum + 1]))):
-      while (endlinenum < len(clean_lines.elided)
-             and ';' not in clean_lines.elided[endlinenum][endpos:]):
-        endlinenum += 1
-        endpos = 0
-      if endlinenum < len(clean_lines.elided):
-        endline = clean_lines.elided[endlinenum]
-        # We allow a mix of whitespace and closing braces (e.g. for one-liner
-        # methods) and a single \ after the semicolon (for macros)
-        endpos = endline.find(';')
-        if not Match(r';[\s}]*(\\?)$', endline[endpos:]):
-          # Semicolon isn't the last character, there's something trailing.
-          # Output a warning if the semicolon is not contained inside
-          # a lambda expression.
-          if not Match(r'^[^{};]*\[[^\[\]]*\][^{}]*\{[^{}]*\}\s*\)*[;,]\s*$',
-                       endline):
-            error(filename, linenum, 'readability/braces', 4,
-                  'If/else bodies with multiple statements require braces')
-        elif endlinenum < len(clean_lines.elided) - 1:
-          # Make sure the next line is dedented
-          next_line = clean_lines.elided[endlinenum + 1]
-          next_indent = GetIndentLevel(next_line)
-          # With ambiguous nested if statements, this will error out on the
-          # if that *doesn't* match the else, regardless of whether it's the
-          # inner one or outer one.
-          if (if_match and Match(r'\s*else\b', next_line)
-              and next_indent != if_indent):
-            error(filename, linenum, 'readability/braces', 4,
-                  'Else clause should be indented at the same level as if. '
-                  'Ambiguous nested if/else chains require braces.')
-          elif next_indent > if_indent:
-            error(filename, linenum, 'readability/braces', 4,
-                  'If/else bodies with multiple statements require braces')
-
-
-def CheckTrailingSemicolon(filename, clean_lines, linenum, error):
-  """Looks for redundant trailing semicolon.
-
-  Args:
-    filename: The name of the current file.
-    clean_lines: A CleansedLines instance containing the file.
-    linenum: The number of the line to check.
-    error: The function to call with any errors found.
-  """
-
-  line = clean_lines.elided[linenum]
-
-  # Block bodies should not be followed by a semicolon.  Due to C++11
-  # brace initialization, there are more places where semicolons are
-  # required than not, so we use a whitelist approach to check these
-  # rather than a blacklist.  These are the places where "};" should
-  # be replaced by just "}":
-  # 1. Some flavor of block following closing parenthesis:
-  #    for (;;) {};
-  #    while (...) {};
-  #    switch (...) {};
-  #    Function(...) {};
-  #    if (...) {};
-  #    if (...) else if (...) {};
-  #
-  # 2. else block:
-  #    if (...) else {};
-  #
-  # 3. const member function:
-  #    Function(...) const {};
-  #
-  # 4. Block following some statement:
-  #    x = 42;
-  #    {};
-  #
-  # 5. Block at the beginning of a function:
-  #    Function(...) {
-  #      {};
-  #    }
-  #
-  #    Note that naively checking for the preceding "{" will also match
-  #    braces inside multi-dimensional arrays, but this is fine since
-  #    that expression will not contain semicolons.
-  #
-  # 6. Block following another block:
-  #    while (true) {}
-  #    {};
-  #
-  # 7. End of namespaces:
-  #    namespace {};
-  #
-  #    These semicolons seems far more common than other kinds of
-  #    redundant semicolons, possibly due to people converting classes
-  #    to namespaces.  For now we do not warn for this case.
-  #
-  # Try matching case 1 first.
-  match = Match(r'^(.*\)\s*)\{', line)
-  if match:
-    # Matched closing parenthesis (case 1).  Check the token before the
-    # matching opening parenthesis, and don't warn if it looks like a
-    # macro.  This avoids these false positives:
-    #  - macro that defines a base class
-    #  - multi-line macro that defines a base class
-    #  - macro that defines the whole class-head
-    #
-    # But we still issue warnings for macros that we know are safe to
-    # warn, specifically:
-    #  - TEST, TEST_F, TEST_P, MATCHER, MATCHER_P
-    #  - TYPED_TEST
-    #  - INTERFACE_DEF
-    #  - EXCLUSIVE_LOCKS_REQUIRED, SHARED_LOCKS_REQUIRED, LOCKS_EXCLUDED:
-    #
-    # We implement a whitelist of safe macros instead of a blacklist of
-    # unsafe macros, even though the latter appears less frequently in
-    # google code and would have been easier to implement.  This is because
-    # the downside for getting the whitelist wrong means some extra
-    # semicolons, while the downside for getting the blacklist wrong
-    # would result in compile errors.
-    #
-    # In addition to macros, we also don't want to warn on
-    #  - Compound literals
-    #  - Lambdas
-    #  - alignas specifier with anonymous structs:
-    closing_brace_pos = match.group(1).rfind(')')
-    opening_parenthesis = ReverseCloseExpression(
-        clean_lines, linenum, closing_brace_pos)
-    if opening_parenthesis[2] > -1:
-      line_prefix = opening_parenthesis[0][0:opening_parenthesis[2]]
-      macro = Search(r'\b([A-Z_]+)\s*$', line_prefix)
-      func = Match(r'^(.*\])\s*$', line_prefix)
-      if ((macro and
-           macro.group(1) not in (
-               'TEST', 'TEST_F', 'MATCHER', 'MATCHER_P', 'TYPED_TEST',
-               'EXCLUSIVE_LOCKS_REQUIRED', 'SHARED_LOCKS_REQUIRED',
-               'LOCKS_EXCLUDED', 'INTERFACE_DEF')) or
-          (func and not Search(r'\boperator\s*\[\s*\]', func.group(1))) or
-          Search(r'\b(?:struct|union)\s+alignas\s*$', line_prefix) or
-          Search(r'\s+=\s*$', line_prefix)):
-        match = None
-    if (match and
-        opening_parenthesis[1] > 1 and
-        Search(r'\]\s*$', clean_lines.elided[opening_parenthesis[1] - 1])):
-      # Multi-line lambda-expression
-      match = None
-
-  else:
-    # Try matching cases 2-3.
-    match = Match(r'^(.*(?:else|\)\s*const)\s*)\{', line)
-    if not match:
-      # Try matching cases 4-6.  These are always matched on separate lines.
-      #
-      # Note that we can't simply concatenate the previous line to the
-      # current line and do a single match, otherwise we may output
-      # duplicate warnings for the blank line case:
-      #   if (cond) {
-      #     // blank line
-      #   }
-      prevline = GetPreviousNonBlankLine(clean_lines, linenum)[0]
-      if prevline and Search(r'[;{}]\s*$', prevline):
-        match = Match(r'^(\s*)\{', line)
-
-  # Check matching closing brace
-  if match:
-    (endline, endlinenum, endpos) = CloseExpression(
-        clean_lines, linenum, len(match.group(1)))
-    if endpos > -1 and Match(r'^\s*;', endline[endpos:]):
-      # Current {} pair is eligible for semicolon check, and we have found
-      # the redundant semicolon, output warning here.
-      #
-      # Note: because we are scanning forward for opening braces, and
-      # outputting warnings for the matching closing brace, if there are
-      # nested blocks with trailing semicolons, we will get the error
-      # messages in reversed order.
-      error(filename, endlinenum, 'readability/braces', 4,
-            "You don't need a ; after a }")
-
-
-def CheckEmptyBlockBody(filename, clean_lines, linenum, error):
-  """Look for empty loop/conditional body with only a single semicolon.
-
-  Args:
-    filename: The name of the current file.
-    clean_lines: A CleansedLines instance containing the file.
-    linenum: The number of the line to check.
-    error: The function to call with any errors found.
-  """
-
-  # Search for loop keywords at the beginning of the line.  Because only
-  # whitespaces are allowed before the keywords, this will also ignore most
-  # do-while-loops, since those lines should start with closing brace.
-  #
-  # We also check "if" blocks here, since an empty conditional block
-  # is likely an error.
-  line = clean_lines.elided[linenum]
-  matched = Match(r'\s*(for|while|if)\s*\(', line)
-  if matched:
-    # Find the end of the conditional expression
-    (end_line, end_linenum, end_pos) = CloseExpression(
-        clean_lines, linenum, line.find('('))
-
-    # Output warning if what follows the condition expression is a semicolon.
-    # No warning for all other cases, including whitespace or newline, since we
-    # have a separate check for semicolons preceded by whitespace.
-    if end_pos >= 0 and Match(r';', end_line[end_pos:]):
-      if matched.group(1) == 'if':
-        error(filename, end_linenum, 'whitespace/empty_conditional_body', 5,
-              'Empty conditional bodies should use {}')
-      else:
-        error(filename, end_linenum, 'whitespace/empty_loop_body', 5,
-              'Empty loop bodies should use {} or continue')
-
-
-def FindCheckMacro(line):
-  """Find a replaceable CHECK-like macro.
-
-  Args:
-    line: line to search on.
-  Returns:
-    (macro name, start position), or (None, -1) if no replaceable
-    macro is found.
-  """
-  for macro in _CHECK_MACROS:
-    i = line.find(macro)
-    if i >= 0:
-      # Find opening parenthesis.  Do a regular expression match here
-      # to make sure that we are matching the expected CHECK macro, as
-      # opposed to some other macro that happens to contain the CHECK
-      # substring.
-      matched = Match(r'^(.*\b' + macro + r'\s*)\(', line)
-      if not matched:
-        continue
-      return (macro, len(matched.group(1)))
-  return (None, -1)
-
-
-def CheckCheck(filename, clean_lines, linenum, error):
-  """Checks the use of CHECK and EXPECT macros.
-
-  Args:
-    filename: The name of the current file.
-    clean_lines: A CleansedLines instance containing the file.
-    linenum: The number of the line to check.
-    error: The function to call with any errors found.
-  """
-
-  # Decide the set of replacement macros that should be suggested
-  lines = clean_lines.elided
-  (check_macro, start_pos) = FindCheckMacro(lines[linenum])
-  if not check_macro:
-    return
-
-  # Find end of the boolean expression by matching parentheses
-  (last_line, end_line, end_pos) = CloseExpression(
-      clean_lines, linenum, start_pos)
-  if end_pos < 0:
-    return
-
-  # If the check macro is followed by something other than a
-  # semicolon, assume users will log their own custom error messages
-  # and don't suggest any replacements.
-  if not Match(r'\s*;', last_line[end_pos:]):
-    return
-
-  if linenum == end_line:
-    expression = lines[linenum][start_pos + 1:end_pos - 1]
-  else:
-    expression = lines[linenum][start_pos + 1:]
-    for i in xrange(linenum + 1, end_line):
-      expression += lines[i]
-    expression += last_line[0:end_pos - 1]
-
-  # Parse expression so that we can take parentheses into account.
-  # This avoids false positives for inputs like "CHECK((a < 4) == b)",
-  # which is not replaceable by CHECK_LE.
-  lhs = ''
-  rhs = ''
-  operator = None
-  while expression:
-    matched = Match(r'^\s*(<<|<<=|>>|>>=|->\*|->|&&|\|\||'
-                    r'==|!=|>=|>|<=|<|\()(.*)$', expression)
-    if matched:
-      token = matched.group(1)
-      if token == '(':
-        # Parenthesized operand
-        expression = matched.group(2)
-        (end, _) = FindEndOfExpressionInLine(expression, 0, ['('])
-        if end < 0:
-          return  # Unmatched parenthesis
-        lhs += '(' + expression[0:end]
-        expression = expression[end:]
-      elif token in ('&&', '||'):
-        # Logical and/or operators.  This means the expression
-        # contains more than one term, for example:
-        #   CHECK(42 < a && a < b);
-        #
-        # These are not replaceable with CHECK_LE, so bail out early.
-        return
-      elif token in ('<<', '<<=', '>>', '>>=', '->*', '->'):
-        # Non-relational operator
-        lhs += token
-        expression = matched.group(2)
-      else:
-        # Relational operator
-        operator = token
-        rhs = matched.group(2)
-        break
-    else:
-      # Unparenthesized operand.  Instead of appending to lhs one character
-      # at a time, we do another regular expression match to consume several
-      # characters at once if possible.  Trivial benchmark shows that this
-      # is more efficient when the operands are longer than a single
-      # character, which is generally the case.
-      matched = Match(r'^([^-=!<>()&|]+)(.*)$', expression)
-      if not matched:
-        matched = Match(r'^(\s*\S)(.*)$', expression)
-        if not matched:
-          break
-      lhs += matched.group(1)
-      expression = matched.group(2)
-
-  # Only apply checks if we got all parts of the boolean expression
-  if not (lhs and operator and rhs):
-    return
-
-  # Check that rhs do not contain logical operators.  We already know
-  # that lhs is fine since the loop above parses out && and ||.
-  if rhs.find('&&') > -1 or rhs.find('||') > -1:
-    return
-
-  # At least one of the operands must be a constant literal.  This is
-  # to avoid suggesting replacements for unprintable things like
-  # CHECK(variable != iterator)
-  #
-  # The following pattern matches decimal, hex integers, strings, and
-  # characters (in that order).
-  lhs = lhs.strip()
-  rhs = rhs.strip()
-  match_constant = r'^([-+]?(\d+|0[xX][0-9a-fA-F]+)[lLuU]{0,3}|".*"|\'.*\')$'
-  if Match(match_constant, lhs) or Match(match_constant, rhs):
-    # Note: since we know both lhs and rhs, we can provide a more
-    # descriptive error message like:
-    #   Consider using CHECK_EQ(x, 42) instead of CHECK(x == 42)
-    # Instead of:
-    #   Consider using CHECK_EQ instead of CHECK(a == b)
-    #
-    # We are still keeping the less descriptive message because if lhs
-    # or rhs gets long, the error message might become unreadable.
-    error(filename, linenum, 'readability/check', 2,
-          'Consider using %s instead of %s(a %s b)' % (
-              _CHECK_REPLACEMENT[check_macro][operator],
-              check_macro, operator))
-
-
-def CheckAltTokens(filename, clean_lines, linenum, error):
-  """Check alternative keywords being used in boolean expressions.
-
-  Args:
-    filename: The name of the current file.
-    clean_lines: A CleansedLines instance containing the file.
-    linenum: The number of the line to check.
-    error: The function to call with any errors found.
-  """
-  line = clean_lines.elided[linenum]
-
-  # Avoid preprocessor lines
-  if Match(r'^\s*#', line):
-    return
-
-  # Last ditch effort to avoid multi-line comments.  This will not help
-  # if the comment started before the current line or ended after the
-  # current line, but it catches most of the false positives.  At least,
-  # it provides a way to workaround this warning for people who use
-  # multi-line comments in preprocessor macros.
-  #
-  # TODO(unknown): remove this once cpplint has better support for
-  # multi-line comments.
-  if line.find('/*') >= 0 or line.find('*/') >= 0:
-    return
-
-  for match in _ALT_TOKEN_REPLACEMENT_PATTERN.finditer(line):
-    error(filename, linenum, 'readability/alt_tokens', 2,
-          'Use operator %s instead of %s' % (
-              _ALT_TOKEN_REPLACEMENT[match.group(1)], match.group(1)))
-
-
-def GetLineWidth(line):
-  """Determines the width of the line in column positions.
-
-  Args:
-    line: A string, which may be a Unicode string.
-
-  Returns:
-    The width of the line in column positions, accounting for Unicode
-    combining characters and wide characters.
-  """
-  if isinstance(line, unicode):
-    width = 0
-    for uc in unicodedata.normalize('NFC', line):
-      if unicodedata.east_asian_width(uc) in ('W', 'F'):
-        width += 2
-      elif not unicodedata.combining(uc):
-        width += 1
-    return width
-  else:
-    return len(line)
-
-
-def CheckStyle(filename, clean_lines, linenum, file_extension, nesting_state,
-               error):
-  """Checks rules from the 'C++ style rules' section of cppguide.html.
-
-  Most of these rules are hard to test (naming, comment style), but we
-  do what we can.  In particular we check for 2-space indents, line lengths,
-  tab usage, spaces inside code, etc.
-
-  Args:
-    filename: The name of the current file.
-    clean_lines: A CleansedLines instance containing the file.
-    linenum: The number of the line to check.
-    file_extension: The extension (without the dot) of the filename.
-    nesting_state: A NestingState instance which maintains information about
-                   the current stack of nested blocks being parsed.
-    error: The function to call with any errors found.
-  """
-
-  # Don't use "elided" lines here, otherwise we can't check commented lines.
-  # Don't want to use "raw" either, because we don't want to check inside C++11
-  # raw strings,
-  raw_lines = clean_lines.lines_without_raw_strings
-  line = raw_lines[linenum]
-
-  if line.find('\t') != -1:
-    error(filename, linenum, 'whitespace/tab', 1,
-          'Tab found; better to use spaces')
-
-  # One or three blank spaces at the beginning of the line is weird; it's
-  # hard to reconcile that with 2-space indents.
-  # NOTE: here are the conditions rob pike used for his tests.  Mine aren't
-  # as sophisticated, but it may be worth becoming so:  RLENGTH==initial_spaces
-  # if(RLENGTH > 20) complain = 0;
-  # if(match($0, " +(error|private|public|protected):")) complain = 0;
-  # if(match(prev, "&& *$")) complain = 0;
-  # if(match(prev, "\\|\\| *$")) complain = 0;
-  # if(match(prev, "[\",=><] *$")) complain = 0;
-  # if(match($0, " <<")) complain = 0;
-  # if(match(prev, " +for \\(")) complain = 0;
-  # if(prevodd && match(prevprev, " +for \\(")) complain = 0;
-  scope_or_label_pattern = r'\s*\w+\s*:\s*\\?$'
-  classinfo = nesting_state.InnermostClass()
-  initial_spaces = 0
-  cleansed_line = clean_lines.elided[linenum]
-  while initial_spaces < len(line) and line[initial_spaces] == ' ':
-    initial_spaces += 1
-  if line and line[-1].isspace():
-    error(filename, linenum, 'whitespace/end_of_line', 4,
-          'Line ends in whitespace.  Consider deleting these extra spaces.')
-  # There are certain situations we allow one space, notably for
-  # section labels, and also lines containing multi-line raw strings.
-  elif ((initial_spaces == 1 or initial_spaces == 3) and
-        not Match(scope_or_label_pattern, cleansed_line) and
-        not (clean_lines.raw_lines[linenum] != line and
-             Match(r'^\s*""', line))):
-    error(filename, linenum, 'whitespace/indent', 3,
-          'Weird number of spaces at line-start.  '
-          'Are you using a 2-space indent?')
-
-  # Check if the line is a header guard.
-  is_header_guard = False
-  if file_extension == 'h':
-    cppvar = GetHeaderGuardCPPVariable(filename)
-    if (line.startswith('#ifndef %s' % cppvar) or
-        line.startswith('#define %s' % cppvar) or
-        line.startswith('#endif  // %s' % cppvar)):
-      is_header_guard = True
-  # #include lines and header guards can be long, since there's no clean way to
-  # split them.
-  #
-  # URLs can be long too.  It's possible to split these, but it makes them
-  # harder to cut&paste.
-  #
-  # The "$Id:...$" comment may also get very long without it being the
-  # developers fault.
-  if (not line.startswith('#include') and not is_header_guard and
-      not Match(r'^\s*//.*http(s?)://\S*$', line) and
-      not Match(r'^// \$Id:.*#[0-9]+ \$$', line)):
-    line_width = GetLineWidth(line)
-    extended_length = int((_line_length * 1.25))
-    if line_width > extended_length:
-      error(filename, linenum, 'whitespace/line_length', 4,
-            'Lines should very rarely be longer than %i characters' %
-            extended_length)
-    elif line_width > _line_length:
-      error(filename, linenum, 'whitespace/line_length', 2,
-            'Lines should be <= %i characters long' % _line_length)
-
-  if (cleansed_line.count(';') > 1 and
-      # for loops are allowed two ;'s (and may run over two lines).
-      cleansed_line.find('for') == -1 and
-      (GetPreviousNonBlankLine(clean_lines, linenum)[0].find('for') == -1 or
-       GetPreviousNonBlankLine(clean_lines, linenum)[0].find(';') != -1) and
-      # It's ok to have many commands in a switch case that fits in 1 line
-      not ((cleansed_line.find('case ') != -1 or
-            cleansed_line.find('default:') != -1) and
-           cleansed_line.find('break;') != -1)):
-    error(filename, linenum, 'whitespace/newline', 0,
-          'More than one command on the same line')
-
-  # Some more style checks
-  CheckBraces(filename, clean_lines, linenum, error)
-  CheckTrailingSemicolon(filename, clean_lines, linenum, error)
-  CheckEmptyBlockBody(filename, clean_lines, linenum, error)
-  CheckAccess(filename, clean_lines, linenum, nesting_state, error)
-  CheckSpacing(filename, clean_lines, linenum, nesting_state, error)
-  CheckOperatorSpacing(filename, clean_lines, linenum, error)
-  CheckParenthesisSpacing(filename, clean_lines, linenum, error)
-  CheckCommaSpacing(filename, clean_lines, linenum, error)
-  CheckBracesSpacing(filename, clean_lines, linenum, error)
-  CheckSpacingForFunctionCall(filename, clean_lines, linenum, error)
-  CheckRValueReference(filename, clean_lines, linenum, nesting_state, error)
-  CheckCheck(filename, clean_lines, linenum, error)
-  CheckAltTokens(filename, clean_lines, linenum, error)
-  classinfo = nesting_state.InnermostClass()
-  if classinfo:
-    CheckSectionSpacing(filename, clean_lines, classinfo, linenum, error)
-
-
-_RE_PATTERN_INCLUDE = re.compile(r'^\s*#\s*include\s*([<"])([^>"]*)[>"].*$')
-# Matches the first component of a filename delimited by -s and _s. That is:
-#  _RE_FIRST_COMPONENT.match('foo').group(0) == 'foo'
-#  _RE_FIRST_COMPONENT.match('foo.cc').group(0) == 'foo'
-#  _RE_FIRST_COMPONENT.match('foo-bar_baz.cc').group(0) == 'foo'
-#  _RE_FIRST_COMPONENT.match('foo_bar-baz.cc').group(0) == 'foo'
-_RE_FIRST_COMPONENT = re.compile(r'^[^-_.]+')
-
-
-def _DropCommonSuffixes(filename):
-  """Drops common suffixes like _test.cc or -inl.h from filename.
-
-  For example:
-    >>> _DropCommonSuffixes('foo/foo-inl.h')
-    'foo/foo'
-    >>> _DropCommonSuffixes('foo/bar/foo.cc')
-    'foo/bar/foo'
-    >>> _DropCommonSuffixes('foo/foo_internal.h')
-    'foo/foo'
-    >>> _DropCommonSuffixes('foo/foo_unusualinternal.h')
-    'foo/foo_unusualinternal'
-
-  Args:
-    filename: The input filename.
-
-  Returns:
-    The filename with the common suffix removed.
-  """
-  for suffix in ('test.cc', 'regtest.cc', 'unittest.cc',
-                 'inl.h', 'impl.h', 'internal.h'):
-    if (filename.endswith(suffix) and len(filename) > len(suffix) and
-        filename[-len(suffix) - 1] in ('-', '_')):
-      return filename[:-len(suffix) - 1]
-  return os.path.splitext(filename)[0]
-
-
-def _IsTestFilename(filename):
-  """Determines if the given filename has a suffix that identifies it as a test.
-
-  Args:
-    filename: The input filename.
-
-  Returns:
-    True if 'filename' looks like a test, False otherwise.
-  """
-  if (filename.endswith('_test.cc') or
-      filename.endswith('_unittest.cc') or
-      filename.endswith('_regtest.cc')):
-    return True
-  else:
-    return False
-
-
-def _ClassifyInclude(fileinfo, include, is_system):
-  """Figures out what kind of header 'include' is.
-
-  Args:
-    fileinfo: The current file cpplint is running over. A FileInfo instance.
-    include: The path to a #included file.
-    is_system: True if the #include used <> rather than "".
-
-  Returns:
-    One of the _XXX_HEADER constants.
-
-  For example:
-    >>> _ClassifyInclude(FileInfo('foo/foo.cc'), 'stdio.h', True)
-    _C_SYS_HEADER
-    >>> _ClassifyInclude(FileInfo('foo/foo.cc'), 'string', True)
-    _CPP_SYS_HEADER
-    >>> _ClassifyInclude(FileInfo('foo/foo.cc'), 'foo/foo.h', False)
-    _LIKELY_MY_HEADER
-    >>> _ClassifyInclude(FileInfo('foo/foo_unknown_extension.cc'),
-    ...                  'bar/foo_other_ext.h', False)
-    _POSSIBLE_MY_HEADER
-    >>> _ClassifyInclude(FileInfo('foo/foo.cc'), 'foo/bar.h', False)
-    _OTHER_HEADER
-  """
-  # This is a list of all standard c++ header files, except
-  # those already checked for above.
-  is_cpp_h = include in _CPP_HEADERS
-
-  if is_system:
-    if is_cpp_h:
-      return _CPP_SYS_HEADER
-    else:
-      return _C_SYS_HEADER
-
-  # If the target file and the include we're checking share a
-  # basename when we drop common extensions, and the include
-  # lives in . , then it's likely to be owned by the target file.
-  target_dir, target_base = (
-      os.path.split(_DropCommonSuffixes(fileinfo.RepositoryName())))
-  include_dir, include_base = os.path.split(_DropCommonSuffixes(include))
-  if target_base == include_base and (
-      include_dir == target_dir or
-      include_dir == os.path.normpath(target_dir + '/../public')):
-    return _LIKELY_MY_HEADER
-
-  # If the target and include share some initial basename
-  # component, it's possible the target is implementing the
-  # include, so it's allowed to be first, but we'll never
-  # complain if it's not there.
-  target_first_component = _RE_FIRST_COMPONENT.match(target_base)
-  include_first_component = _RE_FIRST_COMPONENT.match(include_base)
-  if (target_first_component and include_first_component and
-      target_first_component.group(0) ==
-      include_first_component.group(0)):
-    return _POSSIBLE_MY_HEADER
-
-  return _OTHER_HEADER
-
-
-
-def CheckIncludeLine(filename, clean_lines, linenum, include_state, error):
-  """Check rules that are applicable to #include lines.
-
-  Strings on #include lines are NOT removed from elided line, to make
-  certain tasks easier. However, to prevent false positives, checks
-  applicable to #include lines in CheckLanguage must be put here.
-
-  Args:
-    filename: The name of the current file.
-    clean_lines: A CleansedLines instance containing the file.
-    linenum: The number of the line to check.
-    include_state: An _IncludeState instance in which the headers are inserted.
-    error: The function to call with any errors found.
-  """
-  fileinfo = FileInfo(filename)
-  line = clean_lines.lines[linenum]
-
-  # "include" should use the new style "foo/bar.h" instead of just "bar.h"
-  # Only do this check if the included header follows google naming
-  # conventions.  If not, assume that it's a 3rd party API that
-  # requires special include conventions.
-  #
-  # We also make an exception for Lua headers, which follow google
-  # naming convention but not the include convention.
-  match = Match(r'#include\s*"([^/]+\.h)"', line)
-  if match and not _THIRD_PARTY_HEADERS_PATTERN.match(match.group(1)):
-    error(filename, linenum, 'build/include', 4,
-          'Include the directory when naming .h files')
-
-  # we shouldn't include a file more than once. actually, there are a
-  # handful of instances where doing so is okay, but in general it's
-  # not.
-  match = _RE_PATTERN_INCLUDE.search(line)
-  if match:
-    include = match.group(2)
-    is_system = (match.group(1) == '<')
-    duplicate_line = include_state.FindHeader(include)
-    if duplicate_line >= 0:
-      error(filename, linenum, 'build/include', 4,
-            '"%s" already included at %s:%s' %
-            (include, filename, duplicate_line))
-    elif (include.endswith('.cc') and
-          os.path.dirname(fileinfo.RepositoryName()) != os.path.dirname(include)):
-      error(filename, linenum, 'build/include', 4,
-            'Do not include .cc files from other packages')
-    elif not _THIRD_PARTY_HEADERS_PATTERN.match(include):
-      include_state.include_list[-1].append((include, linenum))
-
-      # We want to ensure that headers appear in the right order:
-      # 1) for foo.cc, foo.h  (preferred location)
-      # 2) c system files
-      # 3) cpp system files
-      # 4) for foo.cc, foo.h  (deprecated location)
-      # 5) other google headers
-      #
-      # We classify each include statement as one of those 5 types
-      # using a number of techniques. The include_state object keeps
-      # track of the highest type seen, and complains if we see a
-      # lower type after that.
-      error_message = include_state.CheckNextIncludeOrder(
-          _ClassifyInclude(fileinfo, include, is_system))
-      if error_message:
-        error(filename, linenum, 'build/include_order', 4,
-              '%s. Should be: %s.h, c system, c++ system, other.' %
-              (error_message, fileinfo.BaseName()))
-      canonical_include = include_state.CanonicalizeAlphabeticalOrder(include)
-      if not include_state.IsInAlphabeticalOrder(
-          clean_lines, linenum, canonical_include):
-        error(filename, linenum, 'build/include_alpha', 4,
-              'Include "%s" not in alphabetical order' % include)
-      include_state.SetLastHeader(canonical_include)
-
-
-
-def _GetTextInside(text, start_pattern):
-  r"""Retrieves all the text between matching open and close parentheses.
-
-  Given a string of lines and a regular expression string, retrieve all the text
-  following the expression and between opening punctuation symbols like
-  (, [, or {, and the matching close-punctuation symbol. This properly nested
-  occurrences of the punctuations, so for the text like
-    printf(a(), b(c()));
-  a call to _GetTextInside(text, r'printf\(') will return 'a(), b(c())'.
-  start_pattern must match string having an open punctuation symbol at the end.
-
-  Args:
-    text: The lines to extract text. Its comments and strings must be elided.
-           It can be single line and can span multiple lines.
-    start_pattern: The regexp string indicating where to start extracting
-                   the text.
-  Returns:
-    The extracted text.
-    None if either the opening string or ending punctuation could not be found.
-  """
-  # TODO(unknown): Audit cpplint.py to see what places could be profitably
-  # rewritten to use _GetTextInside (and use inferior regexp matching today).
-
-  # Give opening punctuations to get the matching close-punctuations.
-  matching_punctuation = {'(': ')', '{': '}', '[': ']'}
-  closing_punctuation = set(matching_punctuation.itervalues())
-
-  # Find the position to start extracting text.
-  match = re.search(start_pattern, text, re.M)
-  if not match:  # start_pattern not found in text.
-    return None
-  start_position = match.end(0)
-
-  assert start_position > 0, (
-      'start_pattern must ends with an opening punctuation.')
-  assert text[start_position - 1] in matching_punctuation, (
-      'start_pattern must ends with an opening punctuation.')
-  # Stack of closing punctuations we expect to have in text after position.
-  punctuation_stack = [matching_punctuation[text[start_position - 1]]]
-  position = start_position
-  while punctuation_stack and position < len(text):
-    if text[position] == punctuation_stack[-1]:
-      punctuation_stack.pop()
-    elif text[position] in closing_punctuation:
-      # A closing punctuation without matching opening punctuations.
-      return None
-    elif text[position] in matching_punctuation:
-      punctuation_stack.append(matching_punctuation[text[position]])
-    position += 1
-  if punctuation_stack:
-    # Opening punctuations left without matching close-punctuations.
-    return None
-  # punctuations match.
-  return text[start_position:position - 1]
-
-
-# Patterns for matching call-by-reference parameters.
-#
-# Supports nested templates up to 2 levels deep using this messy pattern:
-#   < (?: < (?: < [^<>]*
-#               >
-#           |   [^<>] )*
-#         >
-#     |   [^<>] )*
-#   >
-_RE_PATTERN_IDENT = r'[_a-zA-Z]\w*'  # =~ [[:alpha:]][[:alnum:]]*
-_RE_PATTERN_TYPE = (
-    r'(?:const\s+)?(?:typename\s+|class\s+|struct\s+|union\s+|enum\s+)?'
-    r'(?:\w|'
-    r'\s*<(?:<(?:<[^<>]*>|[^<>])*>|[^<>])*>|'
-    r'::)+')
-# A call-by-reference parameter ends with '& identifier'.
-_RE_PATTERN_REF_PARAM = re.compile(
-    r'(' + _RE_PATTERN_TYPE + r'(?:\s*(?:\bconst\b|[*]))*\s*'
-    r'&\s*' + _RE_PATTERN_IDENT + r')\s*(?:=[^,()]+)?[,)]')
-# A call-by-const-reference parameter either ends with 'const& identifier'
-# or looks like 'const type& identifier' when 'type' is atomic.
-_RE_PATTERN_CONST_REF_PARAM = (
-    r'(?:.*\s*\bconst\s*&\s*' + _RE_PATTERN_IDENT +
-    r'|const\s+' + _RE_PATTERN_TYPE + r'\s*&\s*' + _RE_PATTERN_IDENT + r')')
-
-
-def CheckLanguage(filename, clean_lines, linenum, file_extension,
-                  include_state, nesting_state, error):
-  """Checks rules from the 'C++ language rules' section of cppguide.html.
-
-  Some of these rules are hard to test (function overloading, using
-  uint32 inappropriately), but we do the best we can.
-
-  Args:
-    filename: The name of the current file.
-    clean_lines: A CleansedLines instance containing the file.
-    linenum: The number of the line to check.
-    file_extension: The extension (without the dot) of the filename.
-    include_state: An _IncludeState instance in which the headers are inserted.
-    nesting_state: A NestingState instance which maintains information about
-                   the current stack of nested blocks being parsed.
-    error: The function to call with any errors found.
-  """
-  # If the line is empty or consists of entirely a comment, no need to
-  # check it.
-  line = clean_lines.elided[linenum]
-  if not line:
-    return
-
-  match = _RE_PATTERN_INCLUDE.search(line)
-  if match:
-    CheckIncludeLine(filename, clean_lines, linenum, include_state, error)
-    return
-
-  # Reset include state across preprocessor directives.  This is meant
-  # to silence warnings for conditional includes.
-  match = Match(r'^\s*#\s*(if|ifdef|ifndef|elif|else|endif)\b', line)
-  if match:
-    include_state.ResetSection(match.group(1))
-
-  # Make Windows paths like Unix.
-  fullname = os.path.abspath(filename).replace('\\', '/')
-
-  # Perform other checks now that we are sure that this is not an include line
-  CheckCasts(filename, clean_lines, linenum, error)
-  CheckGlobalStatic(filename, clean_lines, linenum, error)
-  CheckPrintf(filename, clean_lines, linenum, error)
-
-  if file_extension == 'h':
-    # TODO(unknown): check that 1-arg constructors are explicit.
-    #                How to tell it's a constructor?
-    #                (handled in CheckForNonStandardConstructs for now)
-    # TODO(unknown): check that classes declare or disable copy/assign
-    #                (level 1 error)
-    pass
-
-  # Check if people are using the verboten C basic types.  The only exception
-  # we regularly allow is "unsigned short port" for port.
-  if Search(r'\bshort port\b', line):
-    if not Search(r'\bunsigned short port\b', line):
-      error(filename, linenum, 'runtime/int', 4,
-            'Use "unsigned short" for ports, not "short"')
-  else:
-    match = Search(r'\b(short|long(?! +double)|long long)\b', line)
-    if match:
-      error(filename, linenum, 'runtime/int', 4,
-            'Use int16/int64/etc, rather than the C type %s' % match.group(1))
-
-  # Check if some verboten operator overloading is going on
-  # TODO(unknown): catch out-of-line unary operator&:
-  #   class X {};
-  #   int operator&(const X& x) { return 42; }  // unary operator&
-  # The trick is it's hard to tell apart from binary operator&:
-  #   class Y { int operator&(const Y& x) { return 23; } }; // binary operator&
-  if Search(r'\boperator\s*&\s*\(\s*\)', line):
-    error(filename, linenum, 'runtime/operator', 4,
-          'Unary operator& is dangerous.  Do not use it.')
-
-  # Check for suspicious usage of "if" like
-  # } if (a == b) {
-  if Search(r'\}\s*if\s*\(', line):
-    error(filename, linenum, 'readability/braces', 4,
-          'Did you mean "else if"? If not, start a new line for "if".')
-
-  # Check for potential format string bugs like printf(foo).
-  # We constrain the pattern not to pick things like DocidForPrintf(foo).
-  # Not perfect but it can catch printf(foo.c_str()) and printf(foo->c_str())
-  # TODO(unknown): Catch the following case. Need to change the calling
-  # convention of the whole function to process multiple line to handle it.
-  #   printf(
-  #       boy_this_is_a_really_long_variable_that_cannot_fit_on_the_prev_line);
-  printf_args = _GetTextInside(line, r'(?i)\b(string)?printf\s*\(')
-  if printf_args:
-    match = Match(r'([\w.\->()]+)$', printf_args)
-    if match and match.group(1) != '__VA_ARGS__':
-      function_name = re.search(r'\b((?:string)?printf)\s*\(',
-                                line, re.I).group(1)
-      error(filename, linenum, 'runtime/printf', 4,
-            'Potential format string bug. Do %s("%%s", %s) instead.'
-            % (function_name, match.group(1)))
-
-  # Check for potential memset bugs like memset(buf, sizeof(buf), 0).
-  match = Search(r'memset\s*\(([^,]*),\s*([^,]*),\s*0\s*\)', line)
-  if match and not Match(r"^''|-?[0-9]+|0x[0-9A-Fa-f]$", match.group(2)):
-    error(filename, linenum, 'runtime/memset', 4,
-          'Did you mean "memset(%s, 0, %s)"?'
-          % (match.group(1), match.group(2)))
-
-  if Search(r'\busing namespace\b', line):
-    error(filename, linenum, 'build/namespaces', 5,
-          'Do not use namespace using-directives.  '
-          'Use using-declarations instead.')
-
-  # Detect variable-length arrays.
-  match = Match(r'\s*(.+::)?(\w+) [a-z]\w*\[(.+)];', line)
-  if (match and match.group(2) != 'return' and match.group(2) != 'delete' and
-      match.group(3).find(']') == -1):
-    # Split the size using space and arithmetic operators as delimiters.
-    # If any of the resulting tokens are not compile time constants then
-    # report the error.
-    tokens = re.split(r'\s|\+|\-|\*|\/|<<|>>]', match.group(3))
-    is_const = True
-    skip_next = False
-    for tok in tokens:
-      if skip_next:
-        skip_next = False
-        continue
-
-      if Search(r'sizeof\(.+\)', tok): continue
-      if Search(r'arraysize\(\w+\)', tok): continue
-
-      tok = tok.lstrip('(')
-      tok = tok.rstrip(')')
-      if not tok: continue
-      if Match(r'\d+', tok): continue
-      if Match(r'0[xX][0-9a-fA-F]+', tok): continue
-      if Match(r'k[A-Z0-9]\w*', tok): continue
-      if Match(r'(.+::)?k[A-Z0-9]\w*', tok): continue
-      if Match(r'(.+::)?[A-Z][A-Z0-9_]*', tok): continue
-      # A catch all for tricky sizeof cases, including 'sizeof expression',
-      # 'sizeof(*type)', 'sizeof(const type)', 'sizeof(struct StructName)'
-      # requires skipping the next token because we split on ' ' and '*'.
-      if tok.startswith('sizeof'):
-        skip_next = True
-        continue
-      is_const = False
-      break
-    if not is_const:
-      error(filename, linenum, 'runtime/arrays', 1,
-            'Do not use variable-length arrays.  Use an appropriately named '
-            "('k' followed by CamelCase) compile-time constant for the size.")
-
-  # Check for use of unnamed namespaces in header files.  Registration
-  # macros are typically OK, so we allow use of "namespace {" on lines
-  # that end with backslashes.
-  if (file_extension == 'h'
-      and Search(r'\bnamespace\s*{', line)
-      and line[-1] != '\\'):
-    error(filename, linenum, 'build/namespaces', 4,
-          'Do not use unnamed namespaces in header files.  See '
-          'http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Namespaces'
-          ' for more information.')
-
-
-def CheckGlobalStatic(filename, clean_lines, linenum, error):
-  """Check for unsafe global or static objects.
-
-  Args:
-    filename: The name of the current file.
-    clean_lines: A CleansedLines instance containing the file.
-    linenum: The number of the line to check.
-    error: The function to call with any errors found.
-  """
-  line = clean_lines.elided[linenum]
-
-  # Match two lines at a time to support multiline declarations
-  if linenum + 1 < clean_lines.NumLines() and not Search(r'[;({]', line):
-    line += clean_lines.elided[linenum + 1].strip()
-
-  # Check for people declaring static/global STL strings at the top level.
-  # This is dangerous because the C++ language does not guarantee that
-  # globals with constructors are initialized before the first access.
-  match = Match(
-      r'((?:|static +)(?:|const +))string +([a-zA-Z0-9_:]+)\b(.*)',
-      line)
-
-  # Remove false positives:
-  # - String pointers (as opposed to values).
-  #    string *pointer
-  #    const string *pointer
-  #    string const *pointer
-  #    string *const pointer
-  #
-  # - Functions and template specializations.
-  #    string Function<Type>(...
-  #    string Class<Type>::Method(...
-  #
-  # - Operators.  These are matched separately because operator names
-  #   cross non-word boundaries, and trying to match both operators
-  #   and functions at the same time would decrease accuracy of
-  #   matching identifiers.
-  #    string Class::operator*()
-  if (match and
-      not Search(r'\bstring\b(\s+const)?\s*\*\s*(const\s+)?\w', line) and
-      not Search(r'\boperator\W', line) and
-      not Match(r'\s*(<.*>)?(::[a-zA-Z0-9_]+)*\s*\(([^"]|$)', match.group(3))):
-    error(filename, linenum, 'runtime/string', 4,
-          'For a static/global string constant, use a C style string instead: '
-          '"%schar %s[]".' %
-          (match.group(1), match.group(2)))
-
-  if Search(r'\b([A-Za-z0-9_]*_)\(\1\)', line):
-    error(filename, linenum, 'runtime/init', 4,
-          'You seem to be initializing a member variable with itself.')
-
-
-def CheckPrintf(filename, clean_lines, linenum, error):
-  """Check for printf related issues.
-
-  Args:
-    filename: The name of the current file.
-    clean_lines: A CleansedLines instance containing the file.
-    linenum: The number of the line to check.
-    error: The function to call with any errors found.
-  """
-  line = clean_lines.elided[linenum]
-
-  # When snprintf is used, the second argument shouldn't be a literal.
-  match = Search(r'snprintf\s*\(([^,]*),\s*([0-9]*)\s*,', line)
-  if match and match.group(2) != '0':
-    # If 2nd arg is zero, snprintf is used to calculate size.
-    error(filename, linenum, 'runtime/printf', 3,
-          'If you can, use sizeof(%s) instead of %s as the 2nd arg '
-          'to snprintf.' % (match.group(1), match.group(2)))
-
-  # Check if some verboten C functions are being used.
-  if Search(r'\bsprintf\s*\(', line):
-    error(filename, linenum, 'runtime/printf', 5,
-          'Never use sprintf. Use snprintf instead.')
-  match = Search(r'\b(strcpy|strcat)\s*\(', line)
-  if match:
-    error(filename, linenum, 'runtime/printf', 4,
-          'Almost always, snprintf is better than %s' % match.group(1))
-
-
-def IsDerivedFunction(clean_lines, linenum):
-  """Check if current line contains an inherited function.
-
-  Args:
-    clean_lines: A CleansedLines instance containing the file.
-    linenum: The number of the line to check.
-  Returns:
-    True if current line contains a function with "override"
-    virt-specifier.
-  """
-  # Scan back a few lines for start of current function
-  for i in xrange(linenum, max(-1, linenum - 10), -1):
-    match = Match(r'^([^()]*\w+)\(', clean_lines.elided[i])
-    if match:
-      # Look for "override" after the matching closing parenthesis
-      line, _, closing_paren = CloseExpression(
-          clean_lines, i, len(match.group(1)))
-      return (closing_paren >= 0 and
-              Search(r'\boverride\b', line[closing_paren:]))
-  return False
-
-
-def IsOutOfLineMethodDefinition(clean_lines, linenum):
-  """Check if current line contains an out-of-line method definition.
-
-  Args:
-    clean_lines: A CleansedLines instance containing the file.
-    linenum: The number of the line to check.
-  Returns:
-    True if current line contains an out-of-line method definition.
-  """
-  # Scan back a few lines for start of current function
-  for i in xrange(linenum, max(-1, linenum - 10), -1):
-    if Match(r'^([^()]*\w+)\(', clean_lines.elided[i]):
-      return Match(r'^[^()]*\w+::\w+\(', clean_lines.elided[i]) is not None
-  return False
-
-
-def IsInitializerList(clean_lines, linenum):
-  """Check if current line is inside constructor initializer list.
-
-  Args:
-    clean_lines: A CleansedLines instance containing the file.
-    linenum: The number of the line to check.
-  Returns:
-    True if current line appears to be inside constructor initializer
-    list, False otherwise.
-  """
-  for i in xrange(linenum, 1, -1):
-    line = clean_lines.elided[i]
-    if i == linenum:
-      remove_function_body = Match(r'^(.*)\{\s*$', line)
-      if remove_function_body:
-        line = remove_function_body.group(1)
-
-    if Search(r'\s:\s*\w+[({]', line):
-      # A lone colon tend to indicate the start of a constructor
-      # initializer list.  It could also be a ternary operator, which
-      # also tend to appear in constructor initializer lists as
-      # opposed to parameter lists.
-      return True
-    if Search(r'\}\s*,\s*$', line):
-      # A closing brace followed by a comma is probably the end of a
-      # brace-initialized member in constructor initializer list.
-      return True
-    if Search(r'[{};]\s*$', line):
-      # Found one of the following:
-      # - A closing brace or semicolon, probably the end of the previous
-      #   function.
-      # - An opening brace, probably the start of current class or namespace.
-      #
-      # Current line is probably not inside an initializer list since
-      # we saw one of those things without seeing the starting colon.
-      return False
-
-  # Got to the beginning of the file without seeing the start of
-  # constructor initializer list.
-  return False
-
-
-def CheckForNonConstReference(filename, clean_lines, linenum,
-                              nesting_state, error):
-  """Check for non-const references.
-
-  Separate from CheckLanguage since it scans backwards from current
-  line, instead of scanning forward.
-
-  Args:
-    filename: The name of the current file.
-    clean_lines: A CleansedLines instance containing the file.
-    linenum: The number of the line to check.
-    nesting_state: A NestingState instance which maintains information about
-                   the current stack of nested blocks being parsed.
-    error: The function to call with any errors found.
-  """
-  # Do nothing if there is no '&' on current line.
-  line = clean_lines.elided[linenum]
-  if '&' not in line:
-    return
-
-  # If a function is inherited, current function doesn't have much of
-  # a choice, so any non-const references should not be blamed on
-  # derived function.
-  if IsDerivedFunction(clean_lines, linenum):
-    return
-
-  # Don't warn on out-of-line method definitions, as we would warn on the
-  # in-line declaration, if it isn't marked with 'override'.
-  if IsOutOfLineMethodDefinition(clean_lines, linenum):
-    return
-
-  # Long type names may be broken across multiple lines, usually in one
-  # of these forms:
-  #   LongType
-  #       ::LongTypeContinued &identifier
-  #   LongType::
-  #       LongTypeContinued &identifier
-  #   LongType<
-  #       ...>::LongTypeContinued &identifier
-  #
-  # If we detected a type split across two lines, join the previous
-  # line to current line so that we can match const references
-  # accordingly.
-  #
-  # Note that this only scans back one line, since scanning back
-  # arbitrary number of lines would be expensive.  If you have a type
-  # that spans more than 2 lines, please use a typedef.
-  if linenum > 1:
-    previous = None
-    if Match(r'\s*::(?:[\w<>]|::)+\s*&\s*\S', line):
-      # previous_line\n + ::current_line
-      previous = Search(r'\b((?:const\s*)?(?:[\w<>]|::)+[\w<>])\s*$',
-                        clean_lines.elided[linenum - 1])
-    elif Match(r'\s*[a-zA-Z_]([\w<>]|::)+\s*&\s*\S', line):
-      # previous_line::\n + current_line
-      previous = Search(r'\b((?:const\s*)?(?:[\w<>]|::)+::)\s*$',
-                        clean_lines.elided[linenum - 1])
-    if previous:
-      line = previous.group(1) + line.lstrip()
-    else:
-      # Check for templated parameter that is split across multiple lines
-      endpos = line.rfind('>')
-      if endpos > -1:
-        (_, startline, startpos) = ReverseCloseExpression(
-            clean_lines, linenum, endpos)
-        if startpos > -1 and startline < linenum:
-          # Found the matching < on an earlier line, collect all
-          # pieces up to current line.
-          line = ''
-          for i in xrange(startline, linenum + 1):
-            line += clean_lines.elided[i].strip()
-
-  # Check for non-const references in function parameters.  A single '&' may
-  # found in the following places:
-  #   inside expression: binary & for bitwise AND
-  #   inside expression: unary & for taking the address of something
-  #   inside declarators: reference parameter
-  # We will exclude the first two cases by checking that we are not inside a
-  # function body, including one that was just introduced by a trailing '{'.
-  # TODO(unknown): Doesn't account for 'catch(Exception& e)' [rare].
-  if (nesting_state.previous_stack_top and
-      not (isinstance(nesting_state.previous_stack_top, _ClassInfo) or
-           isinstance(nesting_state.previous_stack_top, _NamespaceInfo))):
-    # Not at toplevel, not within a class, and not within a namespace
-    return
-
-  # Avoid initializer lists.  We only need to scan back from the
-  # current line for something that starts with ':'.
-  #
-  # We don't need to check the current line, since the '&' would
-  # appear inside the second set of parentheses on the current line as
-  # opposed to the first set.
-  if linenum > 0:
-    for i in xrange(linenum - 1, max(0, linenum - 10), -1):
-      previous_line = clean_lines.elided[i]
-      if not Search(r'[),]\s*$', previous_line):
-        break
-      if Match(r'^\s*:\s+\S', previous_line):
-        return
-
-  # Avoid preprocessors
-  if Search(r'\\\s*$', line):
-    return
-
-  # Avoid constructor initializer lists
-  if IsInitializerList(clean_lines, linenum):
-    return
-
-  # We allow non-const references in a few standard places, like functions
-  # called "swap()" or iostream operators like "<<" or ">>".  Do not check
-  # those function parameters.
-  #
-  # We also accept & in static_assert, which looks like a function but
-  # it's actually a declaration expression.
-  whitelisted_functions = (r'(?:[sS]wap(?:<\w:+>)?|'
-                           r'operator\s*[<>][<>]|'
-                           r'static_assert|COMPILE_ASSERT'
-                           r')\s*\(')
-  if Search(whitelisted_functions, line):
-    return
-  elif not Search(r'\S+\([^)]*$', line):
-    # Don't see a whitelisted function on this line.  Actually we
-    # didn't see any function name on this line, so this is likely a
-    # multi-line parameter list.  Try a bit harder to catch this case.
-    for i in xrange(2):
-      if (linenum > i and
-          Search(whitelisted_functions, clean_lines.elided[linenum - i - 1])):
-        return
-
-  decls = ReplaceAll(r'{[^}]*}', ' ', line)  # exclude function body
-  for parameter in re.findall(_RE_PATTERN_REF_PARAM, decls):
-    if not Match(_RE_PATTERN_CONST_REF_PARAM, parameter):
-      error(filename, linenum, 'runtime/references', 2,
-            'Is this a non-const reference? '
-            'If so, make const or use a pointer: ' +
-            ReplaceAll(' *<', '<', parameter))
-
-
-def CheckCasts(filename, clean_lines, linenum, error):
-  """Various cast related checks.
-
-  Args:
-    filename: The name of the current file.
-    clean_lines: A CleansedLines instance containing the file.
-    linenum: The number of the line to check.
-    error: The function to call with any errors found.
-  """
-  line = clean_lines.elided[linenum]
-
-  # Check to see if they're using an conversion function cast.
-  # I just try to capture the most common basic types, though there are more.
-  # Parameterless conversion functions, such as bool(), are allowed as they are
-  # probably a member operator declaration or default constructor.
-  match = Search(
-      r'(\bnew\s+|\S<\s*(?:const\s+)?)?\b'
-      r'(int|float|double|bool|char|int32|uint32|int64|uint64)'
-      r'(\([^)].*)', line)
-  expecting_function = ExpectingFunctionArgs(clean_lines, linenum)
-  if match and not expecting_function:
-    matched_type = match.group(2)
-
-    # matched_new_or_template is used to silence two false positives:
-    # - New operators
-    # - Template arguments with function types
-    #
-    # For template arguments, we match on types immediately following
-    # an opening bracket without any spaces.  This is a fast way to
-    # silence the common case where the function type is the first
-    # template argument.  False negative with less-than comparison is
-    # avoided because those operators are usually followed by a space.
-    #
-    #   function<double(double)>   // bracket + no space = false positive
-    #   value < double(42)         // bracket + space = true positive
-    matched_new_or_template = match.group(1)
-
-    # Avoid arrays by looking for brackets that come after the closing
-    # parenthesis.
-    if Match(r'\([^()]+\)\s*\[', match.group(3)):
-      return
-
-    # Other things to ignore:
-    # - Function pointers
-    # - Casts to pointer types
-    # - Placement new
-    # - Alias declarations
-    matched_funcptr = match.group(3)
-    if (matched_new_or_template is None and
-        not (matched_funcptr and
-             (Match(r'\((?:[^() ]+::\s*\*\s*)?[^() ]+\)\s*\(',
-                    matched_funcptr) or
-              matched_funcptr.startswith('(*)'))) and
-        not Match(r'\s*using\s+\S+\s*=\s*' + matched_type, line) and
-        not Search(r'new\(\S+\)\s*' + matched_type, line)):
-      error(filename, linenum, 'readability/casting', 4,
-            'Using deprecated casting style.  '
-            'Use static_cast<%s>(...) instead' %
-            matched_type)
-
-  if not expecting_function:
-    CheckCStyleCast(filename, clean_lines, linenum, 'static_cast',
-                    r'\((int|float|double|bool|char|u?int(16|32|64))\)', error)
-
-  # This doesn't catch all cases. Consider (const char * const)"hello".
-  #
-  # (char *) "foo" should always be a const_cast (reinterpret_cast won't
-  # compile).
-  if CheckCStyleCast(filename, clean_lines, linenum, 'const_cast',
-                     r'\((char\s?\*+\s?)\)\s*"', error):
-    pass
-  else:
-    # Check pointer casts for other than string constants
-    CheckCStyleCast(filename, clean_lines, linenum, 'reinterpret_cast',
-                    r'\((\w+\s?\*+\s?)\)', error)
-
-  # In addition, we look for people taking the address of a cast.  This
-  # is dangerous -- casts can assign to temporaries, so the pointer doesn't
-  # point where you think.
-  #
-  # Some non-identifier character is required before the '&' for the
-  # expression to be recognized as a cast.  These are casts:
-  #   expression = &static_cast<int*>(temporary());
-  #   function(&(int*)(temporary()));
-  #
-  # This is not a cast:
-  #   reference_type&(int* function_param);
-  match = Search(
-      r'(?:[^\w]&\(([^)*][^)]*)\)[\w(])|'
-      r'(?:[^\w]&(static|dynamic|down|reinterpret)_cast\b)', line)
-  if match:
-    # Try a better error message when the & is bound to something
-    # dereferenced by the casted pointer, as opposed to the casted
-    # pointer itself.
-    parenthesis_error = False
-    match = Match(r'^(.*&(?:static|dynamic|down|reinterpret)_cast\b)<', line)
-    if match:
-      _, y1, x1 = CloseExpression(clean_lines, linenum, len(match.group(1)))
-      if x1 >= 0 and clean_lines.elided[y1][x1] == '(':
-        _, y2, x2 = CloseExpression(clean_lines, y1, x1)
-        if x2 >= 0:
-          extended_line = clean_lines.elided[y2][x2:]
-          if y2 < clean_lines.NumLines() - 1:
-            extended_line += clean_lines.elided[y2 + 1]
-          if Match(r'\s*(?:->|\[)', extended_line):
-            parenthesis_error = True
-
-    if parenthesis_error:
-      error(filename, linenum, 'readability/casting', 4,
-            ('Are you taking an address of something dereferenced '
-             'from a cast?  Wrapping the dereferenced expression in '
-             'parentheses will make the binding more obvious'))
-    else:
-      error(filename, linenum, 'runtime/casting', 4,
-            ('Are you taking an address of a cast?  '
-             'This is dangerous: could be a temp var.  '
-             'Take the address before doing the cast, rather than after'))
-
-
-def CheckCStyleCast(filename, clean_lines, linenum, cast_type, pattern, error):
-  """Checks for a C-style cast by looking for the pattern.
-
-  Args:
-    filename: The name of the current file.
-    clean_lines: A CleansedLines instance containing the file.
-    linenum: The number of the line to check.
-    cast_type: The string for the C++ cast to recommend.  This is either
-      reinterpret_cast, static_cast, or const_cast, depending.
-    pattern: The regular expression used to find C-style casts.
-    error: The function to call with any errors found.
-
-  Returns:
-    True if an error was emitted.
-    False otherwise.
-  """
-  line = clean_lines.elided[linenum]
-  match = Search(pattern, line)
-  if not match:
-    return False
-
-  # Exclude lines with keywords that tend to look like casts
-  context = line[0:match.start(1) - 1]
-  if Match(r'.*\b(?:sizeof|alignof|alignas|[_A-Z][_A-Z0-9]*)\s*$', context):
-    return False
-
-  # Try expanding current context to see if we one level of
-  # parentheses inside a macro.
-  if linenum > 0:
-    for i in xrange(linenum - 1, max(0, linenum - 5), -1):
-      context = clean_lines.elided[i] + context
-  if Match(r'.*\b[_A-Z][_A-Z0-9]*\s*\((?:\([^()]*\)|[^()])*$', context):
-    return False
-
-  # operator++(int) and operator--(int)
-  if context.endswith(' operator++') or context.endswith(' operator--'):
-    return False
-
-  # A single unnamed argument for a function tends to look like old
-  # style cast.  If we see those, don't issue warnings for deprecated
-  # casts, instead issue warnings for unnamed arguments where
-  # appropriate.
-  #
-  # These are things that we want warnings for, since the style guide
-  # explicitly require all parameters to be named:
-  #   Function(int);
-  #   Function(int) {
-  #   ConstMember(int) const;
-  #   ConstMember(int) const {
-  #   ExceptionMember(int) throw (...);
-  #   ExceptionMember(int) throw (...) {
-  #   PureVirtual(int) = 0;
-  #   [](int) -> bool {
-  #
-  # These are functions of some sort, where the compiler would be fine
-  # if they had named parameters, but people often omit those
-  # identifiers to reduce clutter:
-  #   (FunctionPointer)(int);
-  #   (FunctionPointer)(int) = value;
-  #   Function((function_pointer_arg)(int))
-  #   Function((function_pointer_arg)(int), int param)
-  #   <TemplateArgument(int)>;
-  #   <(FunctionPointerTemplateArgument)(int)>;
-  remainder = line[match.end(0):]
-  if Match(r'^\s*(?:;|const\b|throw\b|final\b|override\b|[=>{),]|->)',
-           remainder):
-    # Looks like an unnamed parameter.
-
-    # Don't warn on any kind of template arguments.
-    if Match(r'^\s*>', remainder):
-      return False
-
-    # Don't warn on assignments to function pointers, but keep warnings for
-    # unnamed parameters to pure virtual functions.  Note that this pattern
-    # will also pass on assignments of "0" to function pointers, but the
-    # preferred values for those would be "nullptr" or "NULL".
-    matched_zero = Match(r'^\s=\s*(\S+)\s*;', remainder)
-    if matched_zero and matched_zero.group(1) != '0':
-      return False
-
-    # Don't warn on function pointer declarations.  For this we need
-    # to check what came before the "(type)" string.
-    if Match(r'.*\)\s*$', line[0:match.start(0)]):
-      return False
-
-    # Don't warn if the parameter is named with block comments, e.g.:
-    #  Function(int /*unused_param*/);
-    raw_line = clean_lines.raw_lines[linenum]
-    if '/*' in raw_line:
-      return False
-
-    # Passed all filters, issue warning here.
-    error(filename, linenum, 'readability/function', 3,
-          'All parameters should be named in a function')
-    return True
-
-  # At this point, all that should be left is actual casts.
-  error(filename, linenum, 'readability/casting', 4,
-        'Using C-style cast.  Use %s<%s>(...) instead' %
-        (cast_type, match.group(1)))
-
-  return True
-
-
-def ExpectingFunctionArgs(clean_lines, linenum):
-  """Checks whether where function type arguments are expected.
-
-  Args:
-    clean_lines: A CleansedLines instance containing the file.
-    linenum: The number of the line to check.
-
-  Returns:
-    True if the line at 'linenum' is inside something that expects arguments
-    of function types.
-  """
-  line = clean_lines.elided[linenum]
-  return (Match(r'^\s*MOCK_(CONST_)?METHOD\d+(_T)?\(', line) or
-          (linenum >= 2 and
-           (Match(r'^\s*MOCK_(?:CONST_)?METHOD\d+(?:_T)?\((?:\S+,)?\s*$',
-                  clean_lines.elided[linenum - 1]) or
-            Match(r'^\s*MOCK_(?:CONST_)?METHOD\d+(?:_T)?\(\s*$',
-                  clean_lines.elided[linenum - 2]) or
-            Search(r'\bstd::m?function\s*\<\s*$',
-                   clean_lines.elided[linenum - 1]))))
-
-
-_HEADERS_CONTAINING_TEMPLATES = (
-    ('<deque>', ('deque',)),
-    ('<functional>', ('unary_function', 'binary_function',
-                      'plus', 'minus', 'multiplies', 'divides', 'modulus',
-                      'negate',
-                      'equal_to', 'not_equal_to', 'greater', 'less',
-                      'greater_equal', 'less_equal',
-                      'logical_and', 'logical_or', 'logical_not',
-                      'unary_negate', 'not1', 'binary_negate', 'not2',
-                      'bind1st', 'bind2nd',
-                      'pointer_to_unary_function',
-                      'pointer_to_binary_function',
-                      'ptr_fun',
-                      'mem_fun_t', 'mem_fun', 'mem_fun1_t', 'mem_fun1_ref_t',
-                      'mem_fun_ref_t',
-                      'const_mem_fun_t', 'const_mem_fun1_t',
-                      'const_mem_fun_ref_t', 'const_mem_fun1_ref_t',
-                      'mem_fun_ref',
-                     )),
-    ('<limits>', ('numeric_limits',)),
-    ('<list>', ('list',)),
-    ('<map>', ('map', 'multimap',)),
-    ('<memory>', ('allocator',)),
-    ('<queue>', ('queue', 'priority_queue',)),
-    ('<set>', ('set', 'multiset',)),
-    ('<stack>', ('stack',)),
-    ('<string>', ('char_traits', 'basic_string',)),
-    ('<tuple>', ('tuple',)),
-    ('<utility>', ('pair',)),
-    ('<vector>', ('vector',)),
-
-    # gcc extensions.
-    # Note: std::hash is their hash, ::hash is our hash
-    ('<hash_map>', ('hash_map', 'hash_multimap',)),
-    ('<hash_set>', ('hash_set', 'hash_multiset',)),
-    ('<slist>', ('slist',)),
-    )
-
-_RE_PATTERN_STRING = re.compile(r'\bstring\b')
-
-_re_pattern_algorithm_header = []
-for _template in ('copy', 'max', 'min', 'min_element', 'sort', 'swap',
-                  'transform'):
-  # Match max<type>(..., ...), max(..., ...), but not foo->max, foo.max or
-  # type::max().
-  _re_pattern_algorithm_header.append(
-      (re.compile(r'[^>.]\b' + _template + r'(<.*?>)?\([^\)]'),
-       _template,
-       '<algorithm>'))
-
-_re_pattern_templates = []
-for _header, _templates in _HEADERS_CONTAINING_TEMPLATES:
-  for _template in _templates:
-    _re_pattern_templates.append(
-        (re.compile(r'(\<|\b)' + _template + r'\s*\<'),
-         _template + '<>',
-         _header))
-
-
-def FilesBelongToSameModule(filename_cc, filename_h):
-  """Check if these two filenames belong to the same module.
-
-  The concept of a 'module' here is a as follows:
-  foo.h, foo-inl.h, foo.cc, foo_test.cc and foo_unittest.cc belong to the
-  same 'module' if they are in the same directory.
-  some/path/public/xyzzy and some/path/internal/xyzzy are also considered
-  to belong to the same module here.
-
-  If the filename_cc contains a longer path than the filename_h, for example,
-  '/absolute/path/to/base/sysinfo.cc', and this file would include
-  'base/sysinfo.h', this function also produces the prefix needed to open the
-  header. This is used by the caller of this function to more robustly open the
-  header file. We don't have access to the real include paths in this context,
-  so we need this guesswork here.
-
-  Known bugs: tools/base/bar.cc and base/bar.h belong to the same module
-  according to this implementation. Because of this, this function gives
-  some false positives. This should be sufficiently rare in practice.
-
-  Args:
-    filename_cc: is the path for the .cc file
-    filename_h: is the path for the header path
-
-  Returns:
-    Tuple with a bool and a string:
-    bool: True if filename_cc and filename_h belong to the same module.
-    string: the additional prefix needed to open the header file.
-  """
-
-  if not filename_cc.endswith('.cc'):
-    return (False, '')
-  filename_cc = filename_cc[:-len('.cc')]
-  if filename_cc.endswith('_unittest'):
-    filename_cc = filename_cc[:-len('_unittest')]
-  elif filename_cc.endswith('_test'):
-    filename_cc = filename_cc[:-len('_test')]
-  filename_cc = filename_cc.replace('/public/', '/')
-  filename_cc = filename_cc.replace('/internal/', '/')
-
-  if not filename_h.endswith('.h'):
-    return (False, '')
-  filename_h = filename_h[:-len('.h')]
-  if filename_h.endswith('-inl'):
-    filename_h = filename_h[:-len('-inl')]
-  filename_h = filename_h.replace('/public/', '/')
-  filename_h = filename_h.replace('/internal/', '/')
-
-  files_belong_to_same_module = filename_cc.endswith(filename_h)
-  common_path = ''
-  if files_belong_to_same_module:
-    common_path = filename_cc[:-len(filename_h)]
-  return files_belong_to_same_module, common_path
-
-
-def UpdateIncludeState(filename, include_dict, io=codecs):
-  """Fill up the include_dict with new includes found from the file.
-
-  Args:
-    filename: the name of the header to read.
-    include_dict: a dictionary in which the headers are inserted.
-    io: The io factory to use to read the file. Provided for testability.
-
-  Returns:
-    True if a header was successfully added. False otherwise.
-  """
-  headerfile = None
-  try:
-    headerfile = io.open(filename, 'r', 'utf8', 'replace')
-  except IOError:
-    return False
-  linenum = 0
-  for line in headerfile:
-    linenum += 1
-    clean_line = CleanseComments(line)
-    match = _RE_PATTERN_INCLUDE.search(clean_line)
-    if match:
-      include = match.group(2)
-      include_dict.setdefault(include, linenum)
-  return True
-
-
-def CheckForIncludeWhatYouUse(filename, clean_lines, include_state, error,
-                              io=codecs):
-  """Reports for missing stl includes.
-
-  This function will output warnings to make sure you are including the headers
-  necessary for the stl containers and functions that you use. We only give one
-  reason to include a header. For example, if you use both equal_to<> and
-  less<> in a .h file, only one (the latter in the file) of these will be
-  reported as a reason to include the <functional>.
-
-  Args:
-    filename: The name of the current file.
-    clean_lines: A CleansedLines instance containing the file.
-    include_state: An _IncludeState instance.
-    error: The function to call with any errors found.
-    io: The IO factory to use to read the header file. Provided for unittest
-        injection.
-  """
-  required = {}  # A map of header name to linenumber and the template entity.
-                 # Example of required: { '<functional>': (1219, 'less<>') }
-
-  for linenum in xrange(clean_lines.NumLines()):
-    line = clean_lines.elided[linenum]
-    if not line or line[0] == '#':
-      continue
-
-    # String is special -- it is a non-templatized type in STL.
-    matched = _RE_PATTERN_STRING.search(line)
-    if matched:
-      # Don't warn about strings in non-STL namespaces:
-      # (We check only the first match per line; good enough.)
-      prefix = line[:matched.start()]
-      if prefix.endswith('std::') or not prefix.endswith('::'):
-        required['<string>'] = (linenum, 'string')
-
-    for pattern, template, header in _re_pattern_algorithm_header:
-      if pattern.search(line):
-        required[header] = (linenum, template)
-
-    # The following function is just a speed up, no semantics are changed.
-    if not '<' in line:  # Reduces the cpu time usage by skipping lines.
-      continue
-
-    for pattern, template, header in _re_pattern_templates:
-      if pattern.search(line):
-        required[header] = (linenum, template)
-
-  # The policy is that if you #include something in foo.h you don't need to
-  # include it again in foo.cc. Here, we will look at possible includes.
-  # Let's flatten the include_state include_list and copy it into a dictionary.
-  include_dict = dict([item for sublist in include_state.include_list
-                       for item in sublist])
-
-  # Did we find the header for this file (if any) and successfully load it?
-  header_found = False
-
-  # Use the absolute path so that matching works properly.
-  abs_filename = FileInfo(filename).FullName()
-
-  # For Emacs's flymake.
-  # If cpplint is invoked from Emacs's flymake, a temporary file is generated
-  # by flymake and that file name might end with '_flymake.cc'. In that case,
-  # restore original file name here so that the corresponding header file can be
-  # found.
-  # e.g. If the file name is 'foo_flymake.cc', we should search for 'foo.h'
-  # instead of 'foo_flymake.h'
-  abs_filename = re.sub(r'_flymake\.cc$', '.cc', abs_filename)
-
-  # include_dict is modified during iteration, so we iterate over a copy of
-  # the keys.
-  header_keys = include_dict.keys()
-  for header in header_keys:
-    (same_module, common_path) = FilesBelongToSameModule(abs_filename, header)
-    fullpath = common_path + header
-    if same_module and UpdateIncludeState(fullpath, include_dict, io):
-      header_found = True
-
-  # If we can't find the header file for a .cc, assume it's because we don't
-  # know where to look. In that case we'll give up as we're not sure they
-  # didn't include it in the .h file.
-  # TODO(unknown): Do a better job of finding .h files so we are confident that
-  # not having the .h file means there isn't one.
-  if filename.endswith('.cc') and not header_found:
-    return
-
-  # All the lines have been processed, report the errors found.
-  for required_header_unstripped in required:
-    template = required[required_header_unstripped][1]
-    if required_header_unstripped.strip('<>"') not in include_dict:
-      error(filename, required[required_header_unstripped][0],
-            'build/include_what_you_use', 4,
-            'Add #include ' + required_header_unstripped + ' for ' + template)
-
-
-_RE_PATTERN_EXPLICIT_MAKEPAIR = re.compile(r'\bmake_pair\s*<')
-
-
-def CheckMakePairUsesDeduction(filename, clean_lines, linenum, error):
-  """Check that make_pair's template arguments are deduced.
-
-  G++ 4.6 in C++11 mode fails badly if make_pair's template arguments are
-  specified explicitly, and such use isn't intended in any case.
-
-  Args:
-    filename: The name of the current file.
-    clean_lines: A CleansedLines instance containing the file.
-    linenum: The number of the line to check.
-    error: The function to call with any errors found.
-  """
-  line = clean_lines.elided[linenum]
-  match = _RE_PATTERN_EXPLICIT_MAKEPAIR.search(line)
-  if match:
-    error(filename, linenum, 'build/explicit_make_pair',
-          4,  # 4 = high confidence
-          'For C++11-compatibility, omit template arguments from make_pair'
-          ' OR use pair directly OR if appropriate, construct a pair directly')
-
-
-def CheckDefaultLambdaCaptures(filename, clean_lines, linenum, error):
-  """Check that default lambda captures are not used.
-
-  Args:
-    filename: The name of the current file.
-    clean_lines: A CleansedLines instance containing the file.
-    linenum: The number of the line to check.
-    error: The function to call with any errors found.
-  """
-  line = clean_lines.elided[linenum]
-
-  # A lambda introducer specifies a default capture if it starts with "[="
-  # or if it starts with "[&" _not_ followed by an identifier.
-  match = Match(r'^(.*)\[\s*(?:=|&[^\w])', line)
-  if match:
-    # Found a potential error, check what comes after the lambda-introducer.
-    # If it's not open parenthesis (for lambda-declarator) or open brace
-    # (for compound-statement), it's not a lambda.
-    line, _, pos = CloseExpression(clean_lines, linenum, len(match.group(1)))
-    if pos >= 0 and Match(r'^\s*[{(]', line[pos:]):
-      error(filename, linenum, 'build/c++11',
-            4,  # 4 = high confidence
-            'Default lambda captures are an unapproved C++ feature.')
-
-
-def CheckRedundantVirtual(filename, clean_lines, linenum, error):
-  """Check if line contains a redundant "virtual" function-specifier.
-
-  Args:
-    filename: The name of the current file.
-    clean_lines: A CleansedLines instance containing the file.
-    linenum: The number of the line to check.
-    error: The function to call with any errors found.
-  """
-  # Look for "virtual" on current line.
-  line = clean_lines.elided[linenum]
-  virtual = Match(r'^(.*)(\bvirtual\b)(.*)$', line)
-  if not virtual: return
-
-  # Ignore "virtual" keywords that are near access-specifiers.  These
-  # are only used in class base-specifier and do not apply to member
-  # functions.
-  if (Search(r'\b(public|protected|private)\s+$', virtual.group(1)) or
-      Match(r'^\s+(public|protected|private)\b', virtual.group(3))):
-    return
-
-  # Ignore the "virtual" keyword from virtual base classes.  Usually
-  # there is a column on the same line in these cases (virtual base
-  # classes are rare in google3 because multiple inheritance is rare).
-  if Match(r'^.*[^:]:[^:].*$', line): return
-
-  # Look for the next opening parenthesis.  This is the start of the
-  # parameter list (possibly on the next line shortly after virtual).
-  # TODO(unknown): doesn't work if there are virtual functions with
-  # decltype() or other things that use parentheses, but csearch suggests
-  # that this is rare.
-  end_col = -1
-  end_line = -1
-  start_col = len(virtual.group(2))
-  for start_line in xrange(linenum, min(linenum + 3, clean_lines.NumLines())):
-    line = clean_lines.elided[start_line][start_col:]
-    parameter_list = Match(r'^([^(]*)\(', line)
-    if parameter_list:
-      # Match parentheses to find the end of the parameter list
-      (_, end_line, end_col) = CloseExpression(
-          clean_lines, start_line, start_col + len(parameter_list.group(1)))
-      break
-    start_col = 0
-
-  if end_col < 0:
-    return  # Couldn't find end of parameter list, give up
-
-  # Look for "override" or "final" after the parameter list
-  # (possibly on the next few lines).
-  for i in xrange(end_line, min(end_line + 3, clean_lines.NumLines())):
-    line = clean_lines.elided[i][end_col:]
-    match = Search(r'\b(override|final)\b', line)
-    if match:
-      error(filename, linenum, 'readability/inheritance', 4,
-            ('"virtual" is redundant since function is '
-             'already declared as "%s"' % match.group(1)))
-
-    # Set end_col to check whole lines after we are done with the
-    # first line.
-    end_col = 0
-    if Search(r'[^\w]\s*$', line):
-      break
-
-
-def CheckRedundantOverrideOrFinal(filename, clean_lines, linenum, error):
-  """Check if line contains a redundant "override" or "final" virt-specifier.
-
-  Args:
-    filename: The name of the current file.
-    clean_lines: A CleansedLines instance containing the file.
-    linenum: The number of the line to check.
-    error: The function to call with any errors found.
-  """
-  # Look for closing parenthesis nearby.  We need one to confirm where
-  # the declarator ends and where the virt-specifier starts to avoid
-  # false positives.
-  line = clean_lines.elided[linenum]
-  declarator_end = line.rfind(')')
-  if declarator_end >= 0:
-    fragment = line[declarator_end:]
-  else:
-    if linenum > 1 and clean_lines.elided[linenum - 1].rfind(')') >= 0:
-      fragment = line
-    else:
-      return
-
-  # Check that at most one of "override" or "final" is present, not both
-  if Search(r'\boverride\b', fragment) and Search(r'\bfinal\b', fragment):
-    error(filename, linenum, 'readability/inheritance', 4,
-          ('"override" is redundant since function is '
-           'already declared as "final"'))
-
-
-
-
-# Returns true if we are at a new block, and it is directly
-# inside of a namespace.
-def IsBlockInNameSpace(nesting_state, is_forward_declaration):
-  """Checks that the new block is directly in a namespace.
-
-  Args:
-    nesting_state: The _NestingState object that contains info about our state.
-    is_forward_declaration: If the class is a forward declared class.
-  Returns:
-    Whether or not the new block is directly in a namespace.
-  """
-  if is_forward_declaration:
-    if len(nesting_state.stack) >= 1 and (
-        isinstance(nesting_state.stack[-1], _NamespaceInfo)):
-      return True
-    else:
-      return False
-
-  return (len(nesting_state.stack) > 1 and
-          nesting_state.stack[-1].check_namespace_indentation and
-          isinstance(nesting_state.stack[-2], _NamespaceInfo))
-
-
-def ShouldCheckNamespaceIndentation(nesting_state, is_namespace_indent_item,
-                                    raw_lines_no_comments, linenum):
-  """This method determines if we should apply our namespace indentation check.
-
-  Args:
-    nesting_state: The current nesting state.
-    is_namespace_indent_item: If we just put a new class on the stack, True.
-      If the top of the stack is not a class, or we did not recently
-      add the class, False.
-    raw_lines_no_comments: The lines without the comments.
-    linenum: The current line number we are processing.
-
-  Returns:
-    True if we should apply our namespace indentation check. Currently, it
-    only works for classes and namespaces inside of a namespace.
-  """
-
-  is_forward_declaration = IsForwardClassDeclaration(raw_lines_no_comments,
-                                                     linenum)
-
-  if not (is_namespace_indent_item or is_forward_declaration):
-    return False
-
-  # If we are in a macro, we do not want to check the namespace indentation.
-  if IsMacroDefinition(raw_lines_no_comments, linenum):
-    return False
-
-  return IsBlockInNameSpace(nesting_state, is_forward_declaration)
-
-
-# Call this method if the line is directly inside of a namespace.
-# If the line above is blank (excluding comments) or the start of
-# an inner namespace, it cannot be indented.
-def CheckItemIndentationInNamespace(filename, raw_lines_no_comments, linenum,
-                                    error):
-  line = raw_lines_no_comments[linenum]
-  if Match(r'^\s+', line):
-    error(filename, linenum, 'runtime/indentation_namespace', 4,
-          'Do not indent within a namespace')
-
-
-def ProcessLine(filename, file_extension, clean_lines, line,
-                include_state, function_state, nesting_state, error,
-                extra_check_functions=[]):
-  """Processes a single line in the file.
-
-  Args:
-    filename: Filename of the file that is being processed.
-    file_extension: The extension (dot not included) of the file.
-    clean_lines: An array of strings, each representing a line of the file,
-                 with comments stripped.
-    line: Number of line being processed.
-    include_state: An _IncludeState instance in which the headers are inserted.
-    function_state: A _FunctionState instance which counts function lines, etc.
-    nesting_state: A NestingState instance which maintains information about
-                   the current stack of nested blocks being parsed.
-    error: A callable to which errors are reported, which takes 4 arguments:
-           filename, line number, error level, and message
-    extra_check_functions: An array of additional check functions that will be
-                           run on each source line. Each function takes 4
-                           arguments: filename, clean_lines, line, error
-  """
-  raw_lines = clean_lines.raw_lines
-  ParseNolintSuppressions(filename, raw_lines[line], line, error)
-  nesting_state.Update(filename, clean_lines, line, error)
-  CheckForNamespaceIndentation(filename, nesting_state, clean_lines, line,
-                               error)
-  if nesting_state.InAsmBlock(): return
-  CheckForFunctionLengths(filename, clean_lines, line, function_state, error)
-  CheckForMultilineCommentsAndStrings(filename, clean_lines, line, error)
-  CheckStyle(filename, clean_lines, line, file_extension, nesting_state, error)
-  CheckLanguage(filename, clean_lines, line, file_extension, include_state,
-                nesting_state, error)
-  CheckForNonConstReference(filename, clean_lines, line, nesting_state, error)
-  CheckForNonStandardConstructs(filename, clean_lines, line,
-                                nesting_state, error)
-  CheckVlogArguments(filename, clean_lines, line, error)
-  CheckPosixThreading(filename, clean_lines, line, error)
-  CheckInvalidIncrement(filename, clean_lines, line, error)
-  CheckMakePairUsesDeduction(filename, clean_lines, line, error)
-  CheckDefaultLambdaCaptures(filename, clean_lines, line, error)
-  CheckRedundantVirtual(filename, clean_lines, line, error)
-  CheckRedundantOverrideOrFinal(filename, clean_lines, line, error)
-  for check_fn in extra_check_functions:
-    check_fn(filename, clean_lines, line, error)
-
-def FlagCxx11Features(filename, clean_lines, linenum, error):
-  """Flag those c++11 features that we only allow in certain places.
-
-  Args:
-    filename: The name of the current file.
-    clean_lines: A CleansedLines instance containing the file.
-    linenum: The number of the line to check.
-    error: The function to call with any errors found.
-  """
-  line = clean_lines.elided[linenum]
-
-  # Flag unapproved C++11 headers.
-  include = Match(r'\s*#\s*include\s+[<"]([^<"]+)[">]', line)
-  if include and include.group(1) in ('cfenv',
-                                      'condition_variable',
-                                      'fenv.h',
-                                      'future',
-                                      'mutex',
-                                      'thread',
-                                      'chrono',
-                                      'ratio',
-                                      'regex',
-                                      'system_error',
-                                     ):
-    error(filename, linenum, 'build/c++11', 5,
-          ('<%s> is an unapproved C++11 header.') % include.group(1))
-
-  # The only place where we need to worry about C++11 keywords and library
-  # features in preprocessor directives is in macro definitions.
-  if Match(r'\s*#', line) and not Match(r'\s*#\s*define\b', line): return
-
-  # These are classes and free functions.  The classes are always
-  # mentioned as std::*, but we only catch the free functions if
-  # they're not found by ADL.  They're alphabetical by header.
-  for top_name in (
-      # type_traits
-      'alignment_of',
-      'aligned_union',
-      ):
-    if Search(r'\bstd::%s\b' % top_name, line):
-      error(filename, linenum, 'build/c++11', 5,
-            ('std::%s is an unapproved C++11 class or function.  Send c-style '
-             'an example of where it would make your code more readable, and '
-             'they may let you use it.') % top_name)
-
-
-def ProcessFileData(filename, file_extension, lines, error,
-                    extra_check_functions=[]):
-  """Performs lint checks and reports any errors to the given error function.
-
-  Args:
-    filename: Filename of the file that is being processed.
-    file_extension: The extension (dot not included) of the file.
-    lines: An array of strings, each representing a line of the file, with the
-           last element being empty if the file is terminated with a newline.
-    error: A callable to which errors are reported, which takes 4 arguments:
-           filename, line number, error level, and message
-    extra_check_functions: An array of additional check functions that will be
-                           run on each source line. Each function takes 4
-                           arguments: filename, clean_lines, line, error
-  """
-  lines = (['// marker so line numbers and indices both start at 1'] + lines +
-           ['// marker so line numbers end in a known way'])
-
-  include_state = _IncludeState()
-  function_state = _FunctionState()
-  nesting_state = NestingState()
-
-  ResetNolintSuppressions()
-
-  CheckForCopyright(filename, lines, error)
-
-  RemoveMultiLineComments(filename, lines, error)
-  clean_lines = CleansedLines(lines)
-
-  if file_extension == 'h':
-    CheckForHeaderGuard(filename, clean_lines, error)
-
-  for line in xrange(clean_lines.NumLines()):
-    ProcessLine(filename, file_extension, clean_lines, line,
-                include_state, function_state, nesting_state, error,
-                extra_check_functions)
-    FlagCxx11Features(filename, clean_lines, line, error)
-  nesting_state.CheckCompletedBlocks(filename, error)
-
-  CheckForIncludeWhatYouUse(filename, clean_lines, include_state, error)
-
-  # Check that the .cc file has included its header if it exists.
-  if file_extension == 'cc':
-    CheckHeaderFileIncluded(filename, include_state, error)
-
-  # We check here rather than inside ProcessLine so that we see raw
-  # lines rather than "cleaned" lines.
-  CheckForBadCharacters(filename, lines, error)
-
-  CheckForNewlineAtEOF(filename, lines, error)
-
-def ProcessConfigOverrides(filename):
-  """ Loads the configuration files and processes the config overrides.
-
-  Args:
-    filename: The name of the file being processed by the linter.
-
-  Returns:
-    False if the current |filename| should not be processed further.
-  """
-
-  abs_filename = os.path.abspath(filename)
-  cfg_filters = []
-  keep_looking = True
-  while keep_looking:
-    abs_path, base_name = os.path.split(abs_filename)
-    if not base_name:
-      break  # Reached the root directory.
-
-    cfg_file = os.path.join(abs_path, "CPPLINT.cfg")
-    abs_filename = abs_path
-    if not os.path.isfile(cfg_file):
-      continue
-
-    try:
-      with open(cfg_file) as file_handle:
-        for line in file_handle:
-          line, _, _ = line.partition('#')  # Remove comments.
-          if not line.strip():
-            continue
-
-          name, _, val = line.partition('=')
-          name = name.strip()
-          val = val.strip()
-          if name == 'set noparent':
-            keep_looking = False
-          elif name == 'filter':
-            cfg_filters.append(val)
-          elif name == 'exclude_files':
-            # When matching exclude_files pattern, use the base_name of
-            # the current file name or the directory name we are processing.
-            # For example, if we are checking for lint errors in /foo/bar/baz.cc
-            # and we found the .cfg file at /foo/CPPLINT.cfg, then the config
-            # file's "exclude_files" filter is meant to be checked against "bar"
-            # and not "baz" nor "bar/baz.cc".
-            if base_name:
-              pattern = re.compile(val)
-              if pattern.match(base_name):
-                sys.stderr.write('Ignoring "%s": file excluded by "%s". '
-                                 'File path component "%s" matches '
-                                 'pattern "%s"\n' %
-                                 (filename, cfg_file, base_name, val))
-                return False
-          elif name == 'linelength':
-            global _line_length
-            try:
-                _line_length = int(val)
-            except ValueError:
-                sys.stderr.write('Line length must be numeric.')
-          else:
-            sys.stderr.write(
-                'Invalid configuration option (%s) in file %s\n' %
-                (name, cfg_file))
-
-    except IOError:
-      sys.stderr.write(
-          "Skipping config file '%s': Can't open for reading\n" % cfg_file)
-      keep_looking = False
-
-  # Apply all the accumulated filters in reverse order (top-level directory
-  # config options having the least priority).
-  for filter in reversed(cfg_filters):
-     _AddFilters(filter)
-
-  return True
-
-
-def ProcessFile(filename, vlevel, extra_check_functions=[]):
-  """Does google-lint on a single file.
-
-  Args:
-    filename: The name of the file to parse.
-
-    vlevel: The level of errors to report.  Every error of confidence
-    >= verbose_level will be reported.  0 is a good default.
-
-    extra_check_functions: An array of additional check functions that will be
-                           run on each source line. Each function takes 4
-                           arguments: filename, clean_lines, line, error
-  """
-
-  _SetVerboseLevel(vlevel)
-  _BackupFilters()
-
-  if not ProcessConfigOverrides(filename):
-    _RestoreFilters()
-    return
-
-  lf_lines = []
-  crlf_lines = []
-  try:
-    # Support the UNIX convention of using "-" for stdin.  Note that
-    # we are not opening the file with universal newline support
-    # (which codecs doesn't support anyway), so the resulting lines do
-    # contain trailing '\r' characters if we are reading a file that
-    # has CRLF endings.
-    # If after the split a trailing '\r' is present, it is removed
-    # below.
-    if filename == '-':
-      lines = codecs.StreamReaderWriter(sys.stdin,
-                                        codecs.getreader('utf8'),
-                                        codecs.getwriter('utf8'),
-                                        'replace').read().split('\n')
-    else:
-      lines = codecs.open(filename, 'r', 'utf8', 'replace').read().split('\n')
-
-    # Remove trailing '\r'.
-    # The -1 accounts for the extra trailing blank line we get from split()
-    for linenum in range(len(lines) - 1):
-      if lines[linenum].endswith('\r'):
-        lines[linenum] = lines[linenum].rstrip('\r')
-        crlf_lines.append(linenum + 1)
-      else:
-        lf_lines.append(linenum + 1)
-
-  except IOError:
-    sys.stderr.write(
-        "Skipping input '%s': Can't open for reading\n" % filename)
-    _RestoreFilters()
-    return
-
-  # Note, if no dot is found, this will give the entire filename as the ext.
-  file_extension = filename[filename.rfind('.') + 1:]
-
-  # When reading from stdin, the extension is unknown, so no cpplint tests
-  # should rely on the extension.
-  if filename != '-' and file_extension not in _valid_extensions:
-    sys.stderr.write('Ignoring %s; not a valid file name '
-                     '(%s)\n' % (filename, ', '.join(_valid_extensions)))
-  else:
-    ProcessFileData(filename, file_extension, lines, Error,
-                    extra_check_functions)
-
-    # If end-of-line sequences are a mix of LF and CR-LF, issue
-    # warnings on the lines with CR.
-    #
-    # Don't issue any warnings if all lines are uniformly LF or CR-LF,
-    # since critique can handle these just fine, and the style guide
-    # doesn't dictate a particular end of line sequence.
-    #
-    # We can't depend on os.linesep to determine what the desired
-    # end-of-line sequence should be, since that will return the
-    # server-side end-of-line sequence.
-    if lf_lines and crlf_lines:
-      # Warn on every line with CR.  An alternative approach might be to
-      # check whether the file is mostly CRLF or just LF, and warn on the
-      # minority, we bias toward LF here since most tools prefer LF.
-      for linenum in crlf_lines:
-        Error(filename, linenum, 'whitespace/newline', 1,
-              'Unexpected \\r (^M) found; better to use only \\n')
-
-  sys.stderr.write('Done processing %s\n' % filename)
-  _RestoreFilters()
-
-
-def PrintUsage(message):
-  """Prints a brief usage string and exits, optionally with an error message.
-
-  Args:
-    message: The optional error message.
-  """
-  sys.stderr.write(_USAGE)
-  if message:
-    sys.exit('\nFATAL ERROR: ' + message)
-  else:
-    sys.exit(1)
-
-
-def PrintCategories():
-  """Prints a list of all the error-categories used by error messages.
-
-  These are the categories used to filter messages via --filter.
-  """
-  sys.stderr.write(''.join('  %s\n' % cat for cat in _ERROR_CATEGORIES))
-  sys.exit(0)
-
-
-def ParseArguments(args):
-  """Parses the command line arguments.
-
-  This may set the output format and verbosity level as side-effects.
-
-  Args:
-    args: The command line arguments:
-
-  Returns:
-    The list of filenames to lint.
-  """
-  try:
-    (opts, filenames) = getopt.getopt(args, '', ['help', 'output=', 'verbose=',
-                                                 'counting=',
-                                                 'filter=',
-                                                 'root=',
-                                                 'linelength=',
-                                                 'extensions='])
-  except getopt.GetoptError:
-    PrintUsage('Invalid arguments.')
-
-  verbosity = _VerboseLevel()
-  output_format = _OutputFormat()
-  filters = ''
-  counting_style = ''
-
-  for (opt, val) in opts:
-    if opt == '--help':
-      PrintUsage(None)
-    elif opt == '--output':
-      if val not in ('emacs', 'vs7', 'eclipse'):
-        PrintUsage('The only allowed output formats are emacs, vs7 and eclipse.')
-      output_format = val
-    elif opt == '--verbose':
-      verbosity = int(val)
-    elif opt == '--filter':
-      filters = val
-      if not filters:
-        PrintCategories()
-    elif opt == '--counting':
-      if val not in ('total', 'toplevel', 'detailed'):
-        PrintUsage('Valid counting options are total, toplevel, and detailed')
-      counting_style = val
-    elif opt == '--root':
-      global _root
-      _root = val
-    elif opt == '--linelength':
-      global _line_length
-      try:
-          _line_length = int(val)
-      except ValueError:
-          PrintUsage('Line length must be digits.')
-    elif opt == '--extensions':
-      global _valid_extensions
-      try:
-          _valid_extensions = set(val.split(','))
-      except ValueError:
-          PrintUsage('Extensions must be comma seperated list.')
-
-  if not filenames:
-    PrintUsage('No files were specified.')
-
-  _SetOutputFormat(output_format)
-  _SetVerboseLevel(verbosity)
-  _SetFilters(filters)
-  _SetCountingStyle(counting_style)
-
-  return filenames
-
-
-def main():
-  filenames = ParseArguments(sys.argv[1:])
-
-  # Change stderr to write with replacement characters so we don't die
-  # if we try to print something containing non-ASCII characters.
-  sys.stderr = codecs.StreamReaderWriter(sys.stderr,
-                                         codecs.getreader('utf8'),
-                                         codecs.getwriter('utf8'),
-                                         'replace')
-
-  _cpplint_state.ResetErrorCounts()
-  for filename in filenames:
-    ProcessFile(filename, _cpplint_state.verbose_level)
-  _cpplint_state.PrintErrorCounts()
-
-  sys.exit(_cpplint_state.error_count > 0)
-
-
-if __name__ == '__main__':
-  main()
diff --git a/build-support/run-clang-format.sh b/build-support/run-clang-format.sh
deleted file mode 100755
index 01ddab2..0000000
--- a/build-support/run-clang-format.sh
+++ /dev/null
@@ -1,42 +0,0 @@
-#!/bin/bash
-#
-# 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.
-#
-# Runs clang format in the given directory
-# Arguments:
-#   $1 - Path to the source tree
-#   $2 - Path to the clang format binary
-#   $3 - Apply fixes (will raise an error if false and not there where changes)
-#   $ARGN - Files to run clang format on
-#
-SOURCE_DIR=$1
-shift
-CLANG_FORMAT=$1
-shift
-APPLY_FIXES=$1
-shift
-
-# clang format will only find its configuration if we are in
-# the source tree or in a path relative to the source tree
-pushd $SOURCE_DIR
-if [ "$APPLY_FIXES" == "1" ]; then
-  $CLANG_FORMAT -i $@
-else
-
-  NUM_CORRECTIONS=`$CLANG_FORMAT -output-replacements-xml  $@ | grep offset | wc -l`
-  if [ "$NUM_CORRECTIONS" -gt "0" ]; then
-    echo "clang-format suggested changes, please run 'make format'!!!!"
-    exit 1
-  fi
-fi
-popd
diff --git a/build-support/run-clang-tidy.sh b/build-support/run-clang-tidy.sh
deleted file mode 100755
index 2a4b1c0..0000000
--- a/build-support/run-clang-tidy.sh
+++ /dev/null
@@ -1,40 +0,0 @@
-#!/bin/bash
-#
-# 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.
-#
-#
-# Runs clang format in the given directory
-# Arguments:
-#   $1 - Path to the clang tidy binary
-#   $2 - Path to the compile_commands.json to use
-#   $3 - Apply fixes (will raise an error if false and not there where changes)
-#   $ARGN - Files to run clang-tidy on
-#
-CLANG_TIDY=$1
-shift
-COMPILE_COMMANDS=$1
-shift
-APPLY_FIXES=$1
-shift
-
-# clang format will only find its configuration if we are in
-# the source tree or in a path relative to the source tree
-if [ "$APPLY_FIXES" == "1" ]; then
-  $CLANG_TIDY -p $COMPILE_COMMANDS -fix  $@
-else
-  NUM_CORRECTIONS=`$CLANG_TIDY -p $COMPILE_COMMANDS $@ 2>&1 | grep -v Skipping | grep "warnings* generated" | wc -l`
-  if [ "$NUM_CORRECTIONS" -gt "0" ]; then
-    echo "clang-tidy had suggested fixes.  Please fix these!!!"
-    exit 1
-  fi
-fi
diff --git a/build-support/run-test.sh b/build-support/run-test.sh
deleted file mode 100755
index 7c3d8f6..0000000
--- a/build-support/run-test.sh
+++ /dev/null
@@ -1,229 +0,0 @@
-#!/bin/bash
-#
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you 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.
-#
-# Script which wraps running a test and redirects its output to a
-# test log directory.
-#
-# Arguments:
-#    $1 - Base path for logs/artifacts.
-#    $2 - type of test (e.g. test or benchmark)
-#    $3 - path to executable
-#    $ARGN - arguments for executable
-#
-
-OUTPUT_ROOT=$1
-shift
-ROOT=$(cd $(dirname $BASH_SOURCE)/..; pwd)
-
-TEST_LOGDIR=$OUTPUT_ROOT/build/$1-logs
-mkdir -p $TEST_LOGDIR
-
-RUN_TYPE=$1
-shift
-TEST_DEBUGDIR=$OUTPUT_ROOT/build/$RUN_TYPE-debug
-mkdir -p $TEST_DEBUGDIR
-
-TEST_DIRNAME=$(cd $(dirname $1); pwd)
-TEST_FILENAME=$(basename $1)
-shift
-TEST_EXECUTABLE="$TEST_DIRNAME/$TEST_FILENAME"
-TEST_NAME=$(echo $TEST_FILENAME | perl -pe 's/\..+?$//') # Remove path and extension (if any).
-
-# We run each test in its own subdir to avoid core file related races.
-TEST_WORKDIR=$OUTPUT_ROOT/build/test-work/$TEST_NAME
-mkdir -p $TEST_WORKDIR
-pushd $TEST_WORKDIR >/dev/null || exit 1
-rm -f *
-
-set -o pipefail
-
-LOGFILE=$TEST_LOGDIR/$TEST_NAME.txt
-XMLFILE=$TEST_LOGDIR/$TEST_NAME.xml
-
-TEST_EXECUTION_ATTEMPTS=1
-
-# Remove both the uncompressed output, so the developer doesn't accidentally get confused
-# and read output from a prior test run.
-rm -f $LOGFILE $LOGFILE.gz
-
-pipe_cmd=cat
-
-# Allow for collecting core dumps.
-PARQUET_TEST_ULIMIT_CORE=${PARQUET_TEST_ULIMIT_CORE:-0}
-ulimit -c $PARQUET_TEST_ULIMIT_CORE
-
-
-function setup_sanitizers() {
-  # Sets environment variables for different sanitizers (it configures how) the run_tests. Function works.
-
-  # Configure TSAN (ignored if this isn't a TSAN build).
-  #
-  # Deadlock detection (new in clang 3.5) is disabled because:
-  # 1. The clang 3.5 deadlock detector crashes in some unit tests. It
-  #    needs compiler-rt commits c4c3dfd, 9a8efe3, and possibly others.
-  # 2. Many unit tests report lock-order-inversion warnings; they should be
-  #    fixed before reenabling the detector.
-  TSAN_OPTIONS="$TSAN_OPTIONS detect_deadlocks=0"
-  TSAN_OPTIONS="$TSAN_OPTIONS suppressions=$ROOT/build-support/tsan-suppressions.txt"
-  TSAN_OPTIONS="$TSAN_OPTIONS history_size=7"
-  export TSAN_OPTIONS
-
-  # Enable leak detection even under LLVM 3.4, where it was disabled by default.
-  # This flag only takes effect when running an ASAN build.
-  ASAN_OPTIONS="$ASAN_OPTIONS detect_leaks=1"
-  export ASAN_OPTIONS
-
-  # Set up suppressions for LeakSanitizer
-  LSAN_OPTIONS="$LSAN_OPTIONS suppressions=$ROOT/build-support/lsan-suppressions.txt"
-  export LSAN_OPTIONS
-
-  # Suppressions require symbolization. We'll default to using the symbolizer in
-  # thirdparty.
-  if [ -z "$ASAN_SYMBOLIZER_PATH" ]; then
-    export ASAN_SYMBOLIZER_PATH=$(find $NATIVE_TOOLCHAIN/llvm-3.7.0/bin -name llvm-symbolizer)
-  fi
-}
-
-function run_test() {
-  # Run gtest style tests with sanitizers if they are setup appropriately.
-
-  # gtest won't overwrite old junit test files, resulting in a build failure
-  # even when retries are successful.
-  rm -f $XMLFILE
-
-  # This is needed for test execution on macOS with shared arrow linkage build
-  # via external project.
-  export LD_LIBRARY_PATH=${TEST_DIRNAME}:$LD_LIBRARY_PATH
-  $TEST_EXECUTABLE "$@" 2>&1 \
-    | c++filt \
-    | $ROOT/build-support/stacktrace_addr2line.pl $TEST_EXECUTABLE \
-    | $pipe_cmd 2>&1 | tee $LOGFILE
-  STATUS=$?
-
-  # TSAN doesn't always exit with a non-zero exit code due to a bug:
-  # mutex errors don't get reported through the normal error reporting infrastructure.
-  # So we make sure to detect this and exit 1.
-  #
-  # Additionally, certain types of failures won't show up in the standard JUnit
-  # XML output from gtest. We assume that gtest knows better than us and our
-  # regexes in most cases, but for certain errors we delete the resulting xml
-  # file and let our own post-processing step regenerate it.
-  export GREP=$(which egrep)
-  if zgrep --silent "ThreadSanitizer|Leak check.*detected leaks" $LOGFILE ; then
-    echo ThreadSanitizer or leak check failures in $LOGFILE
-    STATUS=1
-    rm -f $XMLFILE
-  fi
-}
-
-function post_process_tests() {
-  # If we have a LeakSanitizer report, and XML reporting is configured, add a new test
-  # case result to the XML file for the leak report. Otherwise Jenkins won't show
-  # us which tests had LSAN errors.
-  if zgrep --silent "ERROR: LeakSanitizer: detected memory leaks" $LOGFILE ; then
-      echo Test had memory leaks. Editing XML
-      perl -p -i -e '
-      if (m#</testsuite>#) {
-        print "<testcase name=\"LeakSanitizer\" status=\"run\" classname=\"LSAN\">\n";
-        print "  <failure message=\"LeakSanitizer failed\" type=\"\">\n";
-        print "    See txt log file for details\n";
-        print "  </failure>\n";
-        print "</testcase>\n";
-      }' $XMLFILE
-  fi
-}
-
-function run_other() {
-  # Generic run function for test like executables that aren't actually gtest
-  $TEST_EXECUTABLE "$@" 2>&1 | $pipe_cmd > $LOGFILE
-  STATUS=$?
-}
-
-if [ $RUN_TYPE = "test" ]; then
-    setup_sanitizers
-fi
-
-# Run the actual test.
-for ATTEMPT_NUMBER in $(seq 1 $TEST_EXECUTION_ATTEMPTS) ; do
-  if [ $ATTEMPT_NUMBER -lt $TEST_EXECUTION_ATTEMPTS ]; then
-    # If the test fails, the test output may or may not be left behind,
-    # depending on whether the test cleaned up or exited immediately. Either
-    # way we need to clean it up. We do this by comparing the data directory
-    # contents before and after the test runs, and deleting anything new.
-    #
-    # The comm program requires that its two inputs be sorted.
-    TEST_TMPDIR_BEFORE=$(find $TEST_TMPDIR -maxdepth 1 -type d | sort)
-  fi
-
-  if [ $ATTEMPT_NUMBER -lt $TEST_EXECUTION_ATTEMPTS ]; then
-    # Now delete any new test output.
-    TEST_TMPDIR_AFTER=$(find $TEST_TMPDIR -maxdepth 1 -type d | sort)
-    DIFF=$(comm -13 <(echo "$TEST_TMPDIR_BEFORE") \
-                    <(echo "$TEST_TMPDIR_AFTER"))
-    for DIR in $DIFF; do
-      # Multiple tests may be running concurrently. To avoid deleting the
-      # wrong directories, constrain to only directories beginning with the
-      # test name.
-      #
-      # This may delete old test directories belonging to this test, but
-      # that's not typically a concern when rerunning flaky tests.
-      if [[ $DIR =~ ^$TEST_TMPDIR/$TEST_NAME ]]; then
-        echo Deleting leftover flaky test directory "$DIR"
-        rm -Rf "$DIR"
-      fi
-    done
-  fi
-  echo "Running $TEST_NAME, redirecting output into $LOGFILE" \
-       "(attempt ${ATTEMPT_NUMBER}/$TEST_EXECUTION_ATTEMPTS)"
-  if [ $RUN_TYPE = "test" ]; then
-    run_test $*
-  else
-    run_other $*
-  fi
-  if [ "$STATUS" -eq "0" ]; then
-    break
-  elif [ "$ATTEMPT_NUMBER" -lt "$TEST_EXECUTION_ATTEMPTS" ]; then
-    echo Test failed attempt number $ATTEMPT_NUMBER
-    echo Will retry...
-  fi
-done
-
-if [ $RUN_TYPE = "test" ]; then
-  post_process_tests
-fi
-
-# Capture and compress core file and binary.
-COREFILES=$(ls | grep ^core)
-if [ -n "$COREFILES" ]; then
-  echo Found core dump. Saving executable and core files.
-  gzip < $TEST_EXECUTABLE > "$TEST_DEBUGDIR/$TEST_NAME.gz" || exit $?
-  for COREFILE in $COREFILES; do
-    gzip < $COREFILE > "$TEST_DEBUGDIR/$TEST_NAME.$COREFILE.gz" || exit $?
-  done
-  # Pull in any .so files as well.
-  for LIB in $(ldd $TEST_EXECUTABLE | grep $ROOT | awk '{print $3}'); do
-    LIB_NAME=$(basename $LIB)
-    gzip < $LIB > "$TEST_DEBUGDIR/$LIB_NAME.gz" || exit $?
-  done
-fi
-
-popd
-rm -Rf $TEST_WORKDIR
-
-exit $STATUS
diff --git a/build-support/run_clang_format.py b/build-support/run_clang_format.py
deleted file mode 100755
index 6dec34b..0000000
--- a/build-support/run_clang_format.py
+++ /dev/null
@@ -1,78 +0,0 @@
-#!/usr/bin/env python
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you 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.
-
-import fnmatch
-import os
-import subprocess
-import sys
-
-if len(sys.argv) < 4:
-    sys.stderr.write("Usage: %s $CLANG_FORMAT_VERSION exclude_globs.txt "
-                     "$source_dir\n" %
-                     sys.argv[0])
-    sys.exit(1)
-
-CLANG_FORMAT = sys.argv[1]
-EXCLUDE_GLOBS_FILENAME = sys.argv[2]
-SOURCE_DIR = sys.argv[3]
-
-if len(sys.argv) > 4:
-    CHECK_FORMAT = int(sys.argv[4]) == 1
-else:
-    CHECK_FORMAT = False
-
-
-exclude_globs = [line.strip() for line in open(EXCLUDE_GLOBS_FILENAME, "r")]
-
-files_to_format = []
-matches = []
-for directory, subdirs, files in os.walk(SOURCE_DIR):
-    for name in files:
-        name = os.path.join(directory, name)
-        if not (name.endswith('.h') or name.endswith('.cc')):
-            continue
-
-        excluded = False
-        for g in exclude_globs:
-            if fnmatch.fnmatch(name, g):
-                excluded = True
-                break
-        if not excluded:
-            files_to_format.append(name)
-
-if CHECK_FORMAT:
-    output = subprocess.check_output([CLANG_FORMAT, '-output-replacements-xml']
-                                     + files_to_format,
-                                     stderr=subprocess.STDOUT).decode('utf8')
-
-    to_fix = []
-    for line in output.split('\n'):
-        if 'offset' in line:
-            to_fix.append(line)
-
-    if len(to_fix) > 0:
-        print("clang-format checks failed, run 'make format' to fix")
-        sys.exit(-1)
-else:
-    try:
-        cmd = [CLANG_FORMAT, '-i'] + files_to_format
-        subprocess.check_output(cmd, stderr=subprocess.STDOUT)
-    except Exception as e:
-        print(e)
-        print(' '.join(cmd))
-        raise
diff --git a/build-support/stacktrace_addr2line.pl b/build-support/stacktrace_addr2line.pl
deleted file mode 100755
index f407247..0000000
--- a/build-support/stacktrace_addr2line.pl
+++ /dev/null
@@ -1,95 +0,0 @@
-#!/usr/bin/env perl
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you 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.
-#######################################################################
-# This script will convert a stack trace with addresses:
-#     @           0x5fb015 kudu::master::Master::Init()
-#     @           0x5c2d38 kudu::master::MiniMaster::StartOnPorts()
-#     @           0x5c31fa kudu::master::MiniMaster::Start()
-#     @           0x58270a kudu::MiniCluster::Start()
-#     @           0x57dc71 kudu::CreateTableStressTest::SetUp()
-# To one with line numbers:
-#     @           0x5fb015 kudu::master::Master::Init() at /home/mpercy/src/kudu/src/master/master.cc:54
-#     @           0x5c2d38 kudu::master::MiniMaster::StartOnPorts() at /home/mpercy/src/kudu/src/master/mini_master.cc:52
-#     @           0x5c31fa kudu::master::MiniMaster::Start() at /home/mpercy/src/kudu/src/master/mini_master.cc:33
-#     @           0x58270a kudu::MiniCluster::Start() at /home/mpercy/src/kudu/src/integration-tests/mini_cluster.cc:48
-#     @           0x57dc71 kudu::CreateTableStressTest::SetUp() at /home/mpercy/src/kudu/src/integration-tests/create-table-stress-test.cc:61
-#
-# If the script detects that the output is not symbolized, it will also attempt
-# to determine the function names, i.e. it will convert:
-#     @           0x5fb015
-#     @           0x5c2d38
-#     @           0x5c31fa
-# To:
-#     @           0x5fb015 kudu::master::Master::Init() at /home/mpercy/src/kudu/src/master/master.cc:54
-#     @           0x5c2d38 kudu::master::MiniMaster::StartOnPorts() at /home/mpercy/src/kudu/src/master/mini_master.cc:52
-#     @           0x5c31fa kudu::master::MiniMaster::Start() at /home/mpercy/src/kudu/src/master/mini_master.cc:33
-#######################################################################
-use strict;
-use warnings;
-
-if (!@ARGV) {
-  die <<EOF
-Usage: $0 executable [stack-trace-file]
-
-This script will read addresses from a file containing stack traces and
-will convert the addresses that conform to the pattern " @ 0x123456" to line
-numbers by calling addr2line on the provided executable.
-If no stack-trace-file is specified, it will take input from stdin.
-EOF
-}
-
-# el6 and other older systems don't support the -p flag,
-# so we do our own "pretty" parsing.
-sub parse_addr2line_output($$) {
-  defined(my $output = shift) or die;
-  defined(my $lookup_func_name = shift) or die;
-  my @lines = grep { $_ ne '' } split("\n", $output);
-  my $pretty_str = '';
-  if ($lookup_func_name) {
-    $pretty_str .= ' ' . $lines[0];
-  }
-  $pretty_str .= ' at ' . $lines[1];
-  return $pretty_str;
-}
-
-my $binary = shift @ARGV;
-if (! -x $binary || ! -r $binary) {
-  die "Error: Cannot access executable ($binary)";
-}
-
-# Cache lookups to speed processing of files with repeated trace addresses.
-my %addr2line_map = ();
-
-# Disable stdout buffering
-$| = 1;
-
-# Reading from <ARGV> is magical in Perl.
-while (defined(my $input = <ARGV>)) {
-  if ($input =~ /^\s+\@\s+(0x[[:xdigit:]]{6,})(?:\s+(\S+))?/) {
-    my $addr = $1;
-    my $lookup_func_name = (!defined $2);
-    if (!exists($addr2line_map{$addr})) {
-      $addr2line_map{$addr} = `addr2line -ifC -e $binary $addr`;
-    }
-    chomp $input;
-    $input .= parse_addr2line_output($addr2line_map{$addr}, $lookup_func_name) . "\n";
-  }
-  print $input;
-}
-
-exit 0;
diff --git a/ci/before_script_travis.sh b/ci/before_script_travis.sh
deleted file mode 100755
index ce0234c..0000000
--- a/ci/before_script_travis.sh
+++ /dev/null
@@ -1,47 +0,0 @@
-#!/usr/bin/env bash
-
-#  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. See accompanying LICENSE file.
-
-if [ $TRAVIS_OS_NAME == "osx" ]; then
-  brew update > /dev/null
-  brew install boost
-  brew install openssl
-  brew install bison
-  export OPENSSL_ROOT_DIR=/usr/local/opt/openssl
-  export LD_LIBRARY_PATH=/usr/local/opt/openssl/lib:$LD_LIBRARY_PATH
-  export PATH="/usr/local/opt/bison/bin:$PATH"
-else
-  # Use a C++11 compiler on Linux
-  export CC="gcc-4.9"
-  export CXX="g++-4.9"
-fi
-
-export PARQUET_TEST_DATA=$TRAVIS_BUILD_DIR/data
-
-CMAKE_COMMON_FLAGS="-DPARQUET_BUILD_WARNING_LEVEL=CHECKIN"
-
-if [ $PARQUET_TRAVIS_VALGRIND == "1" ]; then
-  CMAKE_COMMON_FLAGS="$CMAKE_COMMON_FLAGS -DPARQUET_TEST_MEMCHECK=ON"
-fi
-
-if [ $TRAVIS_OS_NAME == "linux" ]; then
-    cmake $CMAKE_COMMON_FLAGS \
-          -DPARQUET_CXXFLAGS="$PARQUET_CXXFLAGS" \
-          -DPARQUET_BUILD_BENCHMARKS=ON \
-          -DPARQUET_GENERATE_COVERAGE=1 \
-          $TRAVIS_BUILD_DIR
-else
-    cmake $CMAKE_COMMON_FLAGS \
-          -DPARQUET_CXXFLAGS="$PARQUET_CXXFLAGS" \
-          $TRAVIS_BUILD_DIR
-fi
diff --git a/ci/msvc-build.bat b/ci/msvc-build.bat
deleted file mode 100644
index 7a50c85..0000000
--- a/ci/msvc-build.bat
+++ /dev/null
@@ -1,77 +0,0 @@
-@rem Licensed to the Apache Software Foundation (ASF) under one
-@rem or more contributor license agreements.  See the NOTICE file
-@rem distributed with this work for additional information
-@rem regarding copyright ownership.  The ASF licenses this file
-@rem to you under the Apache License, Version 2.0 (the
-@rem "License"); you may not use this file except in compliance
-@rem with the License.  You may obtain a copy of the License at
-@rem
-@rem   http://www.apache.org/licenses/LICENSE-2.0
-@rem
-@rem Unless required by applicable law or agreed to in writing,
-@rem software distributed under the License is distributed on an
-@rem "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-@rem KIND, either express or implied.  See the License for the
-@rem specific language governing permissions and limitations
-@rem under the License.
-
-@echo on
-
-mkdir build
-cd build
-
-SET PARQUET_TEST_DATA=%APPVEYOR_BUILD_FOLDER%\data
-set PARQUET_CXXFLAGS=/MP
-
-set PARQUET_USE_STATIC_CRT_OPTION=OFF
-if "%USE_STATIC_CRT%" == "ON" (
-      set PARQUET_USE_STATIC_CRT_OPTION=ON
-)
-
-if NOT "%CONFIGURATION%" == "Debug" (
-  set PARQUET_CXXFLAGS="%PARQUET_CXXFLAGS% /WX"
-)
-
-if "%GENERATOR%"=="NMake Makefiles" set need_vcvarsall=1
-
-if defined need_vcvarsall (
-    @rem Select desired compiler version
-    if "%APPVEYOR_BUILD_WORKER_IMAGE%" == "Visual Studio 2017" (
-        call "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvarsall.bat" amd64
-    ) else (
-        call "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" amd64
-    )
-)
-
-if "%CONFIGURATION%" == "Toolchain" (
-  conda install -y boost-cpp=1.63 thrift-cpp=0.11.0 ^
-      brotli=1.0.2 zlib=1.2.11 snappy=1.1.7 lz4-c=1.8.0 zstd=1.3.3 ^
-      -c conda-forge || exit /B
-
-  set ARROW_BUILD_TOOLCHAIN=%MINICONDA%/Library
-  set PARQUET_BUILD_TOOLCHAIN=%MINICONDA%/Library
-
-  cmake -G "%GENERATOR%" ^
-      -DCMAKE_BUILD_TYPE=Release ^
-      -DPARQUET_BOOST_USE_SHARED=OFF ^
-      -DPARQUET_CXXFLAGS=%PARQUET_CXXFLAGS% ^
-      .. || exit /B
-
-  cmake --build . --config Release || exit /B
-)
-
-if NOT "%CONFIGURATION%" == "Toolchain" (
-  cmake -G "%GENERATOR%" ^
-        -DCMAKE_BUILD_TYPE=%CONFIGURATION% ^
-        -DPARQUET_BOOST_USE_SHARED=OFF ^
-        -DPARQUET_CXXFLAGS=%PARQUET_CXXFLAGS% ^
-        -DPARQUET_USE_STATIC_CRT=%PARQUET_USE_STATIC_CRT_OPTION% ^
-        .. || exit /B
-
-  cmake --build . --config %CONFIGURATION% || exit /B
-)
-
-if NOT "%CONFIGURATION%" == "Debug" (
-    @rem Tests are too slow and/or hang in debug mode
-    ctest -VV || exit /B
-)
diff --git a/ci/travis_script_cpp.sh b/ci/travis_script_cpp.sh
deleted file mode 100755
index 3031363..0000000
--- a/ci/travis_script_cpp.sh
+++ /dev/null
@@ -1,50 +0,0 @@
-#!/usr/bin/env bash
-
-#  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. See accompanying LICENSE file.
-
-set -xe
-
-: ${CPP_BUILD_DIR=$TRAVIS_BUILD_DIR/parquet-build}
-
-# Check licenses according to Apache policy
-pushd $TRAVIS_BUILD_DIR
-git archive HEAD -o parquet-cpp-src.tar.gz
-$TRAVIS_BUILD_DIR/dev/release/run-rat.sh parquet-cpp-src.tar.gz
-popd
-
-pushd $CPP_BUILD_DIR
-
-make lint
-
-# PARQUET-626: disabled check for now
-# if [ $TRAVIS_OS_NAME == "linux" ]; then
-#   make check-format
-#   make check-clang-tidy
-# fi
-
-if [ $TRAVIS_OS_NAME == "linux" ]; then
-  make -j4
-  ctest -j2 -VV -L unittest
-# Current cpp-coveralls version 0.4 throws an error (PARQUET-1075) on Travis CI. Pin to last working version
-  sudo pip install cpp_coveralls==0.3.12
-  export PARQUET_ROOT=$TRAVIS_BUILD_DIR
-  $TRAVIS_BUILD_DIR/ci/upload_coverage.sh
-else
-  make -j4
-  BUILD_TYPE=debug
-  EXECUTABLE_DIR=$CPP_BUILD_DIR/$BUILD_TYPE
-  export LD_LIBRARY_PATH=$EXECUTABLE_DIR:$LD_LIBRARY_PATH
-  ctest -j2 -VV -L unittest
-fi
-
-popd
diff --git a/ci/travis_script_static.sh b/ci/travis_script_static.sh
deleted file mode 100755
index 8af574e..0000000
--- a/ci/travis_script_static.sh
+++ /dev/null
@@ -1,90 +0,0 @@
-#!/usr/bin/env bash
-
-#  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. See accompanying LICENSE file.
-
-set -xe
-
-# Use a C++11 compiler on Linux
-export CC="gcc-4.9"
-export CXX="g++-4.9"
-
-# ----------------------------------------------------------------------
-# Set up external toolchain
-
-MINICONDA_URL="https://repo.continuum.io/miniconda/Miniconda3-latest-Linux-x86_64.sh"
-export MINICONDA=$HOME/miniconda
-wget -O miniconda.sh $MINICONDA_URL
-bash miniconda.sh -b -p $MINICONDA
-export PATH="$MINICONDA/bin:$PATH"
-export CPP_TOOLCHAIN=$TRAVIS_BUILD_DIR/cpp-toolchain
-
-conda update -y -q conda
-conda config --set auto_update_conda false
-conda info -a
-
-conda config --set show_channel_urls True
-
-# Help with SSL timeouts to S3
-conda config --set remote_connect_timeout_secs 12
-
-conda info -a
-
-conda create -y -q -p $CPP_TOOLCHAIN \
-      boost-cpp thrift-cpp=0.10.0 cmake git \
-      -c conda-forge
-
-source activate $CPP_TOOLCHAIN
-
-# ----------------------------------------------------------------------
-
-: ${CPP_BUILD_DIR=$TRAVIS_BUILD_DIR/parquet-build}
-export PARQUET_TEST_DATA=$TRAVIS_BUILD_DIR/data
-export PARQUET_BUILD_TOOLCHAIN=$CPP_TOOLCHAIN
-export LD_LIBRARY_PATH=$CPP_TOOLCHAIN/lib:$LD_LIBRARY_PATH
-export BOOST_ROOT=$CPP_TOOLCHAIN
-export PARQUET_TEST_DATA=$TRAVIS_BUILD_DIR/data
-
-ARROW_EP=$TRAVIS_BUILD_DIR/parquet-build/arrow_ep-prefix/src/arrow_ep-build
-BROTLI_EP=$ARROW_EP/brotli_ep/src/brotli_ep-install/lib/x86_64-linux-gnu
-
-export SNAPPY_STATIC_LIB=$ARROW_EP/snappy_ep/src/snappy_ep-install/lib/libsnappy.a
-export BROTLI_STATIC_LIB_ENC=$BROTLI_EP/libbrotlienc.a
-export BROTLI_STATIC_LIB_DEC=$BROTLI_EP/libbrotlidec.a
-export BROTLI_STATIC_LIB_COMMON=$BROTLI_EP/libbrotlicommon.a
-export ZLIB_STATIC_LIB=$ARROW_EP/zlib_ep/src/zlib_ep-install/lib/libz.a
-export LZ4_STATIC_LIB=$ARROW_EP/lz4_ep-prefix/src/lz4_ep/lib/liblz4.a
-export ZSTD_STATIC_LIB=$ARROW_EP/zstd_ep-prefix/src/zstd_ep/lib/libzstd.a
-
-CMAKE_COMMON_FLAGS="-DPARQUET_BUILD_WARNING_LEVEL=CHECKIN"
-
-if [ $PARQUET_TRAVIS_VALGRIND == "1" ]; then
-  CMAKE_COMMON_FLAGS="$CMAKE_COMMON_FLAGS -DPARQUET_TEST_MEMCHECK=ON"
-fi
-
-cmake $CMAKE_COMMON_FLAGS \
-      -DPARQUET_CXXFLAGS="$PARQUET_CXXFLAGS" \
-      -DPARQUET_ARROW_LINKAGE="static" \
-      -DPARQUET_BUILD_SHARED=OFF \
-      -DPARQUET_BOOST_USE_SHARED=OFF \
-      -DPARQUET_THRIFT_USE_BOOST=ON \
-      -DPARQUET_BUILD_BENCHMARKS=ON \
-      -DPARQUET_BUILD_EXAMPLES=ON \
-      -DPARQUET_GENERATE_COVERAGE=1 \
-      $TRAVIS_BUILD_DIR
-
-pushd $CPP_BUILD_DIR
-
-make -j4 VERBOSE=1
-ctest -j2 -VV -L unittest
-
-popd
diff --git a/ci/travis_script_toolchain.sh b/ci/travis_script_toolchain.sh
deleted file mode 100755
index e94552c..0000000
--- a/ci/travis_script_toolchain.sh
+++ /dev/null
@@ -1,88 +0,0 @@
-#!/usr/bin/env bash
-
-#  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. See accompanying LICENSE file.
-
-set -xe
-
-# Use a C++11 compiler on Linux
-export CC="gcc-4.9"
-export CXX="g++-4.9"
-
-# ----------------------------------------------------------------------
-# Set up external toolchain
-
-MINICONDA_URL="https://repo.continuum.io/miniconda/Miniconda3-latest-Linux-x86_64.sh"
-export MINICONDA=$HOME/miniconda
-wget -O miniconda.sh $MINICONDA_URL
-bash miniconda.sh -b -p $MINICONDA
-export PATH="$MINICONDA/bin:$PATH"
-export CPP_TOOLCHAIN=$TRAVIS_BUILD_DIR/cpp-toolchain
-
-conda update -y -q conda
-conda config --set auto_update_conda false
-conda info -a
-
-conda config --set show_channel_urls True
-
-# Help with SSL timeouts to S3
-conda config --set remote_connect_timeout_secs 12
-
-conda info -a
-
-conda create -y -q -p $CPP_TOOLCHAIN \
-      boost-cpp thrift-cpp=0.11.0 cmake git \
-      -c conda-forge
-
-# ----------------------------------------------------------------------
-
-: ${CPP_BUILD_DIR=$TRAVIS_BUILD_DIR/parquet-build}
-export PARQUET_TEST_DATA=$TRAVIS_BUILD_DIR/data
-export PARQUET_BUILD_TOOLCHAIN=$CPP_TOOLCHAIN
-export LD_LIBRARY_PATH=$CPP_TOOLCHAIN/lib:$LD_LIBRARY_PATH
-export BOOST_ROOT=$CPP_TOOLCHAIN
-
-CMAKE_COMMON_FLAGS="-DPARQUET_BUILD_WARNING_LEVEL=CHECKIN"
-
-if [ $PARQUET_TRAVIS_VALGRIND == "1" ]; then
-  CMAKE_COMMON_FLAGS="$CMAKE_COMMON_FLAGS -DPARQUET_TEST_MEMCHECK=ON"
-fi
-
-cmake $CMAKE_COMMON_FLAGS \
-      -DPARQUET_CXXFLAGS=-Werror \
-      -DPARQUET_GENERATE_COVERAGE=1 \
-      -DCMAKE_INSTALL_PREFIX=$CPP_TOOLCHAIN \
-      $TRAVIS_BUILD_DIR
-
-pushd $CPP_BUILD_DIR
-
-make -j4
-make install
-ctest -j2 -VV -L unittest
-
-popd
-
-# Build and run the parquet::arrow example. This also tests the usage of parquet-cpp as a library.
-
-pushd $TRAVIS_BUILD_DIR/examples/parquet-arrow
-mkdir build
-pushd build
-
-export ARROW_HOME=$CPP_TOOLCHAIN
-export PARQUET_HOME=$CPP_TOOLCHAIN
-
-cmake ..
-make VERBOSE=1
-./parquet-arrow-reader-writer
-
-popd
-popd
diff --git a/ci/upload_coverage.sh b/ci/upload_coverage.sh
deleted file mode 100755
index 73b37c2..0000000
--- a/ci/upload_coverage.sh
+++ /dev/null
@@ -1,44 +0,0 @@
-#!/usr/bin/env bash
-
-#  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. See accompanying LICENSE file.
-
-set -e
-set -x
-
-ROOT_DIR=$(cd "$(dirname "$BASH_SOURCE")"; pwd)
-
-mkdir coverage_artifacts
-python $ROOT_DIR/../build-support/collect_coverage.py CMakeFiles/parquet.dir/src/ coverage_artifacts
-
-cd coverage_artifacts
-
-ls -l
-
-echo $PARQUET_ROOT
-
-coveralls --gcov $(which gcov-4.9) \
-    --gcov-options '\-l' --root '' \
-    --include $PARQUET_ROOT \
-    --exclude $PARQUET_ROOT/parquet-build/thirdparty \
-    --exclude $PARQUET_ROOT/parquet-build/arrow_ep \
-    --exclude $PARQUET_ROOT/parquet-build/brotli_ep \
-    --exclude $PARQUET_ROOT/parquet-build/brotli_ep-prefix \
-    --exclude $PARQUET_ROOT/parquet-build/gbenchmark_ep \
-    --exclude $PARQUET_ROOT/parquet-build/googletest_ep-prefix \
-    --exclude $PARQUET_ROOT/parquet-build/snappy_ep \
-    --exclude $PARQUET_ROOT/parquet-build/snappy_ep-prefix \
-    --exclude $PARQUET_ROOT/parquet-build/zlib_ep \
-    --exclude $PARQUET_ROOT/parquet-build/zlib_ep-prefix \
-    --exclude $PARQUET_ROOT/build \
-    --exclude $PARQUET_ROOT/src/parquet/thrift \
-    --exclude /usr
diff --git a/cmake_modules/ArrowExternalProject.cmake b/cmake_modules/ArrowExternalProject.cmake
deleted file mode 100644
index 51eeca5..0000000
--- a/cmake_modules/ArrowExternalProject.cmake
+++ /dev/null
@@ -1,75 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you 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.
-
-set(ARROW_PREFIX "${BUILD_OUTPUT_ROOT_DIRECTORY}")
-set(ARROW_INCLUDE_DIR "${ARROW_PREFIX}/include")
-set(ARROW_LIB_DIR "${ARROW_PREFIX}")
-if (MSVC)
-  set(ARROW_SHARED_LIB "${ARROW_PREFIX}/bin/arrow.dll")
-  set(ARROW_SHARED_IMPLIB "${ARROW_LIB_DIR}/arrow.lib")
-  set(ARROW_STATIC_LIB "${ARROW_LIB_DIR}/arrow_static.lib")
-else()
-  set(ARROW_SHARED_LIB "${ARROW_LIB_DIR}/libarrow${CMAKE_SHARED_LIBRARY_SUFFIX}")
-  set(ARROW_STATIC_LIB "${ARROW_LIB_DIR}/libarrow.a")
-endif()
-
-set(ARROW_CMAKE_ARGS
-  -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
-  -DCMAKE_CXX_FLAGS=${EP_CXX_FLAGS}
-  -DCMAKE_C_FLAGS=${EP_C_FLAGS}
-  -DCMAKE_INSTALL_PREFIX=${ARROW_PREFIX}
-  -DCMAKE_INSTALL_LIBDIR=${ARROW_LIB_DIR}
-  -DARROW_JEMALLOC=OFF
-  -DARROW_IPC=OFF
-  -DARROW_WITH_LZ4=ON
-  -DARROW_WITH_ZSTD=ON
-  -DARROW_BUILD_SHARED=${PARQUET_BUILD_SHARED}
-  -DARROW_BOOST_USE_SHARED=${PARQUET_BOOST_USE_SHARED}
-  -DARROW_BUILD_TESTS=OFF)
-
-if (MSVC AND PARQUET_USE_STATIC_CRT)
-  set(ARROW_CMAKE_ARGS ${ARROW_CMAKE_ARGS} -DARROW_USE_STATIC_CRT=ON)
-endif()
-
-if ("$ENV{PARQUET_ARROW_VERSION}" STREQUAL "")
-  # This can be a tag or changeset
-  set(ARROW_VERSION "170dc75468efbad2286c630b9103d1aacdb6bada")
-else()
-  set(ARROW_VERSION "$ENV{PARQUET_ARROW_VERSION}")
-endif()
-message(STATUS "Building Apache Arrow from commit: ${ARROW_VERSION}")
-
-set(ARROW_URL "https://github.com/apache/arrow/archive/${ARROW_VERSION}.tar.gz")
-
-if (CMAKE_VERSION VERSION_GREATER "3.7")
-  set(ARROW_CONFIGURE SOURCE_SUBDIR "cpp" CMAKE_ARGS ${ARROW_CMAKE_ARGS})
-else()
-  set(ARROW_CONFIGURE CONFIGURE_COMMAND "${CMAKE_COMMAND}" -G "${CMAKE_GENERATOR}"
-    ${ARROW_CMAKE_ARGS} "${CMAKE_CURRENT_BINARY_DIR}/arrow_ep-prefix/src/arrow_ep/cpp")
-endif()
-
-ExternalProject_Add(arrow_ep
-  URL ${ARROW_URL}
-  ${ARROW_CONFIGURE}
-  BUILD_BYPRODUCTS "${ARROW_SHARED_LIB}" "${ARROW_STATIC_LIB}")
-
-if (MSVC)
-  ExternalProject_Add_Step(arrow_ep copy_dll_step
-    DEPENDEES install
-    COMMAND ${CMAKE_COMMAND} -E make_directory ${BUILD_OUTPUT_ROOT_DIRECTORY}
-    COMMAND ${CMAKE_COMMAND} -E copy ${ARROW_SHARED_LIB} ${BUILD_OUTPUT_ROOT_DIRECTORY})
-endif()
diff --git a/cmake_modules/BuildUtils.cmake b/cmake_modules/BuildUtils.cmake
deleted file mode 100644
index 1ce891c..0000000
--- a/cmake_modules/BuildUtils.cmake
+++ /dev/null
@@ -1,112 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you 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.
-
-function(ADD_LIB LIB_NAME)
-  set(options)
-  set(one_value_args SHARED_LINK_FLAGS ABI_VERSION SO_VERSION LIB_BUILD_SHARED LIB_BUILD_STATIC)
-  set(multi_value_args SOURCES STATIC_LINK_LIBS STATIC_PRIVATE_LINK_LIBS SHARED_LINK_LIBS SHARED_PRIVATE_LINK_LIBS DEPENDENCIES)
-  cmake_parse_arguments(ARG "${options}" "${one_value_args}" "${multi_value_args}" ${ARGN})
-  if(ARG_UNPARSED_ARGUMENTS)
-    message(SEND_ERROR "Error: unrecognized arguments: ${ARG_UNPARSED_ARGUMENTS}")
-  endif()
-
-  add_library(${LIB_NAME}_objlib OBJECT
-    ${ARG_SOURCES})
-
-  if (ARG_DEPENDENCIES)
-    add_dependencies(${LIB_NAME}_objlib ${ARG_DEPENDENCIES})
-  endif()
-
-  # Necessary to make static linking into other shared libraries work properly
-  set_property(TARGET ${LIB_NAME}_objlib PROPERTY POSITION_INDEPENDENT_CODE 1)
-
-  set(RUNTIME_INSTALL_DIR bin)
-
-  if (ARG_LIB_BUILD_SHARED)
-    add_library(${LIB_NAME}_shared SHARED $<TARGET_OBJECTS:${LIB_NAME}_objlib>)
-
-    if(APPLE)
-      # On OS X, you can avoid linking at library load time and instead
-      # expecting that the symbols have been loaded separately. This happens
-      # with libpython* where there can be conflicts between system Python and
-      # the Python from a thirdparty distribution
-      set(ARG_SHARED_LINK_FLAGS
-        "-undefined dynamic_lookup ${ARG_SHARED_LINK_FLAGS}")
-    endif()
-
-    set_target_properties(${LIB_NAME}_shared
-      PROPERTIES
-      LIBRARY_OUTPUT_DIRECTORY "${BUILD_OUTPUT_ROOT_DIRECTORY}"
-      RUNTIME_OUTPUT_DIRECTORY "${BUILD_OUTPUT_ROOT_DIRECTORY}"
-      PDB_OUTPUT_DIRECTORY "${BUILD_OUTPUT_ROOT_DIRECTORY}"
-      LINK_FLAGS "${ARG_SHARED_LINK_FLAGS}"
-      OUTPUT_NAME ${LIB_NAME}
-      VERSION "${ARG_ABI_VERSION}"
-      SOVERSION "${ARG_SO_VERSION}")
-
-    if (ARG_SHARED_LINK_LIBS OR ARG_SHARED_PRIVATE_LINK_LIBS)
-      target_link_libraries(${LIB_NAME}_shared
-        LINK_PUBLIC ${ARG_SHARED_LINK_LIBS}
-        LINK_PRIVATE ${ARG_SHARED_PRIVATE_LINK_LIBS})
-    endif()
-
-    if (PARQUET_RPATH_ORIGIN)
-        if (APPLE)
-            set(_lib_install_rpath "@loader_path")
-        else()
-            set(_lib_install_rpath "\$ORIGIN")
-        endif()
-        set_target_properties(${LIB_NAME}_shared PROPERTIES
-            INSTALL_RPATH ${_lib_install_rpath})
-    elseif (APPLE)
-      set_target_properties(${LIB_NAME}_shared
-        PROPERTIES
-        BUILD_WITH_INSTALL_RPATH ON
-        INSTALL_NAME_DIR "@rpath")
-    endif()
-
-    install(TARGETS ${LIB_NAME}_shared
-      RUNTIME DESTINATION ${RUNTIME_INSTALL_DIR}
-      LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
-      ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
-  endif()
-
-  if (ARG_LIB_BUILD_STATIC)
-    if (MSVC)
-      set(LIB_NAME_STATIC ${LIB_NAME}_static)
-    else()
-      set(LIB_NAME_STATIC ${LIB_NAME})
-    endif()
-    add_library(${LIB_NAME}_static STATIC $<TARGET_OBJECTS:${LIB_NAME}_objlib>)
-    set_target_properties(${LIB_NAME}_static
-      PROPERTIES
-      LIBRARY_OUTPUT_DIRECTORY "${BUILD_OUTPUT_ROOT_DIRECTORY}"
-      OUTPUT_NAME ${LIB_NAME_STATIC})
-
-    if (ARG_STATIC_LINK_LIBS OR ARG_STATIC_PRIVATE_LINK_LIBS)
-      target_link_libraries(${LIB_NAME}_static
-        LINK_PUBLIC ${ARG_STATIC_LINK_LIBS}
-        LINK_PRIVATE ${ARG_STATIC_PRIVATE_LINK_LIBS})
-    endif()
-
-    install(TARGETS ${LIB_NAME}_static
-      RUNTIME DESTINATION ${RUNTIME_INSTALL_DIR}
-      LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
-      ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
-  endif()
-
-endfunction()
diff --git a/cmake_modules/CompilerInfo.cmake b/cmake_modules/CompilerInfo.cmake
deleted file mode 100644
index 654a0d8..0000000
--- a/cmake_modules/CompilerInfo.cmake
+++ /dev/null
@@ -1,63 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you 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.
-#
-# Sets COMPILER_FAMILY to 'clang' or 'gcc' or 'msvc'
-# Sets COMPILER_VERSION to the version
-if(NOT MSVC)
-  set(COMPILER_GET_VERSION_SWITCH "-v")
-endif()
-
-execute_process(COMMAND "${CMAKE_CXX_COMPILER}" ${COMPILER_GET_VERSION_SWITCH}
-                OUTPUT_VARIABLE COMPILER_VERSION_FULL
-                ERROR_VARIABLE COMPILER_VERSION_FULL)
-message(STATUS "Compiler id: ${CMAKE_CXX_COMPILER_ID}")
-string(TOLOWER "${COMPILER_VERSION_FULL}" COMPILER_VERSION_FULL_LOWER)
-
-if(MSVC)
-  set(COMPILER_FAMILY "msvc")
-  if ("${COMPILER_VERSION_FULL}" MATCHES ".*Microsoft \\(R\\) C/C\\+\\+ Optimizing Compiler Version 19.*x64")
-    string(REGEX REPLACE ".*Optimizing Compiler Version ([0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+).*" "\\1"
-      COMPILER_VERSION "${COMPILER_VERSION_FULL}")
-  elseif(NOT "${COMPILER_VERSION_FULL}" STREQUAL "")
-    message(FATAL_ERROR "Not supported MSVC compiler:\n${COMPILER_VERSION_FULL}\n"
-      "Supported MSVC versions: Visual Studio 2015 2017 x64")
-  endif()
-
-# clang on Linux and Mac OS X before 10.9
-elseif("${COMPILER_VERSION_FULL}" MATCHES ".*clang version.*")
-  set(COMPILER_FAMILY "clang")
-  string(REGEX REPLACE ".*clang version ([0-9]+\\.[0-9]+).*" "\\1"
-    COMPILER_VERSION "${COMPILER_VERSION_FULL}")
-# clang on Mac OS X 10.9 and later
-elseif("${COMPILER_VERSION_FULL}" MATCHES ".*based on LLVM.*")
-  set(COMPILER_FAMILY "clang")
-  string(REGEX REPLACE ".*based on LLVM ([0-9]+\\.[0.9]+).*" "\\1"
-    COMPILER_VERSION "${COMPILER_VERSION_FULL}")
-
-# clang on Mac OS X, XCode 7+.
-elseif("${COMPILER_VERSION_FULL}" MATCHES ".*clang-.*")
-  set(COMPILER_FAMILY "clang")
-  set(COMPILER_VERSION "4.0")
-# gcc
-elseif("${COMPILER_VERSION_FULL_LOWER}" MATCHES ".*gcc[ -]version.*")
-  set(COMPILER_FAMILY "gcc")
-  string(REGEX REPLACE ".*gcc[ -]version ([0-9\\.]+).*" "\\1"
-      COMPILER_VERSION "${COMPILER_VERSION_FULL_LOWER}")
-else()
-  message(FATAL_ERROR "Unknown compiler. Version info:\n${COMPILER_VERSION_FULL}")
-endif()
-message("Selected compiler ${COMPILER_FAMILY} ${COMPILER_VERSION}")
diff --git a/cmake_modules/FindArrow.cmake b/cmake_modules/FindArrow.cmake
deleted file mode 100644
index b63b1af..0000000
--- a/cmake_modules/FindArrow.cmake
+++ /dev/null
@@ -1,123 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you 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.
-
-# - Find ARROW (arrow/api.h, libarrow.a, libarrow.so)
-# This module defines
-#  ARROW_INCLUDE_DIR, directory containing headers
-#  ARROW_STATIC_LIB, path to libarrow.a
-#  ARROW_SHARED_LIB, path to libarrow's shared library
-#  ARROW_FOUND, whether arrow has been found
-
-if (DEFINED ENV{ARROW_HOME})
-  set(ARROW_HOME "$ENV{ARROW_HOME}")
-endif()
-
-if ("${ARROW_HOME}" STREQUAL "")
-  # PARQUET-955. If the user has set $ARROW_HOME in the environment, we respect
-  # this, otherwise try to locate the pkgconfig in the system environment
-  pkg_check_modules(ARROW arrow)
-  if (ARROW_FOUND)
-    # We found the pkgconfig
-    set(ARROW_INCLUDE_DIR ${ARROW_INCLUDE_DIRS})
-
-    if (COMMAND pkg_get_variable)
-      pkg_get_variable(ARROW_ABI_VERSION arrow abi_version)
-    else()
-      set(ARROW_ABI_VERSION "")
-    endif()
-    if (ARROW_ABI_VERSION STREQUAL "")
-      set(ARROW_SHARED_LIB_SUFFIX "")
-    else()
-      set(ARROW_SHARED_LIB_SUFFIX ".${ARROW_ABI_VERSION}")
-    endif()
-
-    set(ARROW_LIB_NAME ${CMAKE_SHARED_LIBRARY_PREFIX}arrow)
-
-    if (APPLE)
-      set(ARROW_SHARED_LIB ${ARROW_LIBDIR}/${ARROW_LIB_NAME}${ARROW_SHARED_LIB_SUFFIX}${CMAKE_SHARED_LIBRARY_SUFFIX})
-    else()
-      set(ARROW_SHARED_LIB ${ARROW_LIBDIR}/${ARROW_LIB_NAME}${CMAKE_SHARED_LIBRARY_SUFFIX}${ARROW_SHARED_LIB_SUFFIX})
-    endif()
-    set(ARROW_STATIC_LIB ${ARROW_LIBDIR}/${ARROW_LIB_NAME}${CMAKE_STATIC_LIBRARY_SUFFIX})
-  endif()
-else()
-  set(ARROW_HOME "${ARROW_HOME}")
-
-  if (MSVC AND NOT ARROW_MSVC_STATIC_LIB_SUFFIX)
-    set(ARROW_MSVC_STATIC_LIB_SUFFIX _static)
-  endif()
-
-  set(ARROW_SEARCH_HEADER_PATHS
-    ${ARROW_HOME}/include
-    )
-
-  set(ARROW_SEARCH_LIB_PATH
-    ${ARROW_HOME}/lib
-    )
-
-  find_path(ARROW_INCLUDE_DIR arrow/array.h PATHS
-    ${ARROW_SEARCH_HEADER_PATHS}
-    # make sure we don't accidentally pick up a different version
-    NO_DEFAULT_PATH
-    )
-
-  find_library(ARROW_LIB_PATH NAMES arrow arrow${ARROW_MSVC_STATIC_LIB_SUFFIX}
-    PATHS
-    ${ARROW_SEARCH_LIB_PATH}
-    NO_DEFAULT_PATH)
-
-  if (ARROW_INCLUDE_DIR AND (PARQUET_MINIMAL_DEPENDENCY OR ARROW_LIB_PATH))
-    set(ARROW_FOUND TRUE)
-    set(ARROW_HEADER_NAME arrow/api.h)
-    set(ARROW_HEADER ${ARROW_INCLUDE_DIR}/${ARROW_HEADER_NAME})
-    set(ARROW_LIB_NAME arrow)
-
-    get_filename_component(ARROW_LIBS ${ARROW_LIB_PATH} DIRECTORY)
-    set(ARROW_STATIC_LIB ${ARROW_LIBS}/${CMAKE_STATIC_LIBRARY_PREFIX}${ARROW_LIB_NAME}${ARROW_MSVC_STATIC_LIB_SUFFIX}${CMAKE_STATIC_LIBRARY_SUFFIX})
-    set(ARROW_SHARED_LIB ${ARROW_LIBS}/${CMAKE_SHARED_LIBRARY_PREFIX}${ARROW_LIB_NAME}${CMAKE_SHARED_LIBRARY_SUFFIX})
-    set(ARROW_SHARED_IMPLIB ${ARROW_LIBS}/${ARROW_LIB_NAME}.lib)
-  endif ()
-endif()
-
-if (ARROW_FOUND)
-  if (NOT Arrow_FIND_QUIETLY)
-    message(STATUS "Arrow include path: ${ARROW_INCLUDE_DIR}")
-    if (PARQUET_MINIMAL_DEPENDENCY)
-      message(STATUS "Found the Arrow header: ${ARROW_HEADER}")
-    else ()
-      message(STATUS "Found the Arrow library: ${ARROW_LIB_PATH}")
-    endif ()
-  endif ()
-else()
-  if (NOT Arrow_FIND_QUIETLY)
-    set(ARROW_ERR_MSG "Could not find the Arrow library. Looked for headers")
-    set(ARROW_ERR_MSG "${ARROW_ERR_MSG} in ${ARROW_SEARCH_HEADER_PATHS}, and for libs")
-    set(ARROW_ERR_MSG "${ARROW_ERR_MSG} in ${ARROW_SEARCH_LIB_PATH}")
-    if (Arrow_FIND_REQUIRED)
-      message(FATAL_ERROR "${ARROW_ERR_MSG}")
-    else (Arrow_FIND_REQUIRED)
-      message(STATUS "${ARROW_ERR_MSG}")
-    endif (Arrow_FIND_REQUIRED)
-  endif ()
-endif()
-
-mark_as_advanced(
-  ARROW_FOUND
-  ARROW_INCLUDE_DIR
-  ARROW_STATIC_LIB
-  ARROW_SHARED_LIB
-)
diff --git a/cmake_modules/FindBrotli.cmake b/cmake_modules/FindBrotli.cmake
deleted file mode 100644
index f2e714c..0000000
--- a/cmake_modules/FindBrotli.cmake
+++ /dev/null
@@ -1,116 +0,0 @@
-#
-# 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.
-#
-# Tries to find Brotli headers and libraries.
-#
-# Usage of this module as follows:
-#
-#  find_package(Brotli)
-#
-# Variables used by this module, they can change the default behaviour and need
-# to be set before calling find_package:
-#
-#  Brotli_HOME - When set, this path is inspected instead of standard library
-#                locations as the root of the Brotli installation.
-#                The environment variable BROTLI_HOME overrides this veriable.
-#
-# This module defines
-#  BROTLI_INCLUDE_DIR, directory containing headers
-#  BROTLI_LIBS, directory containing brotli libraries
-#  BROTLI_STATIC_LIB, path to libbrotli.a
-#  BROTLI_SHARED_LIB, path to libbrotli's shared library
-#  BROTLI_FOUND, whether brotli has been found
-
-if( NOT "${BROTLI_HOME}" STREQUAL "")
-    file( TO_CMAKE_PATH "${BROTLI_HOME}" _native_path )
-    list( APPEND _brotli_roots ${_native_path} )
-elseif ( Brotli_HOME )
-    list( APPEND _brotli_roots ${Brotli_HOME} )
-endif()
-
-find_path( BROTLI_INCLUDE_DIR NAMES brotli/decode.h
-  PATHS ${_brotli_roots}
-  NO_DEFAULT_PATH
-  PATH_SUFFIXES "include" )
-
-find_library( BROTLI_LIBRARY_ENC NAMES libbrotlienc.a brotlienc
-  PATHS ${_brotli_roots}
-  NO_DEFAULT_PATH
-  PATH_SUFFIXES "lib/${CMAKE_LIBRARY_ARCHITECTURE}" "lib" )
-
-find_library( BROTLI_LIBRARY_DEC NAMES libbrotlidec.a brotlidec
-  PATHS ${_brotli_roots}
-  NO_DEFAULT_PATH
-  PATH_SUFFIXES "lib/${CMAKE_LIBRARY_ARCHITECTURE}" "lib" )
-
-find_library( BROTLI_LIBRARY_COMMON NAMES libbrotlicommon.a brotlicommon
-  PATHS ${_brotli_roots}
-  NO_DEFAULT_PATH
-  PATH_SUFFIXES "lib/${CMAKE_LIBRARY_ARCHITECTURE}" "lib" )
-
-set(BROTLI_LIBRARIES ${BROTLI_LIBRARY_ENC} ${BROTLI_LIBRARY_DEC}
-    ${BROTLI_LIBRARY_COMMON})
-
-if (BROTLI_INCLUDE_DIR AND (PARQUET_MINIMAL_DEPENDENCY OR BROTLI_LIBRARIES))
-  set(BROTLI_FOUND TRUE)
-  get_filename_component( BROTLI_LIBS ${BROTLI_LIBRARY_ENC} PATH )
-  set(BROTLI_LIB_NAME brotli)
-  if (MSVC AND NOT BROTLI_MSVC_STATIC_LIB_SUFFIX)
-    set(BROTLI_MSVC_STATIC_LIB_SUFFIX _static)
-  endif()
-  set(BROTLI_STATIC_LIB
-      ${BROTLI_LIBS}/${CMAKE_STATIC_LIBRARY_PREFIX}${BROTLI_LIB_NAME}enc${BROTLI_MSVC_STATIC_LIB_SUFFIX}${CMAKE_STATIC_LIBRARY_SUFFIX}
-      ${BROTLI_LIBS}/${CMAKE_STATIC_LIBRARY_PREFIX}${BROTLI_LIB_NAME}dec${BROTLI_MSVC_STATIC_LIB_SUFFIX}${CMAKE_STATIC_LIBRARY_SUFFIX}
-      ${BROTLI_LIBS}/${CMAKE_STATIC_LIBRARY_PREFIX}${BROTLI_LIB_NAME}common${BROTLI_MSVC_STATIC_LIB_SUFFIX}${CMAKE_STATIC_LIBRARY_SUFFIX})
-  set(BROTLI_STATIC_LIBRARY_ENC ${BROTLI_LIBS}/${CMAKE_STATIC_LIBRARY_PREFIX}${BROTLI_LIB_NAME}enc${BROTLI_MSVC_STATIC_LIB_SUFFIX}${CMAKE_STATIC_LIBRARY_SUFFIX})
-  set(BROTLI_STATIC_LIBRARY_DEC ${BROTLI_LIBS}/${CMAKE_STATIC_LIBRARY_PREFIX}${BROTLI_LIB_NAME}dec${BROTLI_MSVC_STATIC_LIB_SUFFIX}${CMAKE_STATIC_LIBRARY_SUFFIX})
-  set(BROTLI_STATIC_LIBRARY_COMMON ${BROTLI_LIBS}/${CMAKE_STATIC_LIBRARY_PREFIX}${BROTLI_LIB_NAME}common${BROTLI_MSVC_STATIC_LIB_SUFFIX}${CMAKE_STATIC_LIBRARY_SUFFIX})
-  set(BROTLI_SHARED_LIB
-      ${BROTLI_LIBS}/${CMAKE_SHARED_LIBRARY_PREFIX}${BROTLI_LIB_NAME}enc${CMAKE_SHARED_LIBRARY_SUFFIX}
-      ${BROTLI_LIBS}/${CMAKE_SHARED_LIBRARY_PREFIX}${BROTLI_LIB_NAME}dec${CMAKE_SHARED_LIBRARY_SUFFIX}
-      ${BROTLI_LIBS}/${CMAKE_SHARED_LIBRARY_PREFIX}${BROTLI_LIB_NAME}common${CMAKE_SHARED_LIBRARY_SUFFIX})
-else ()
-  set(BROTLI_FOUND FALSE)
-endif ()
-
-if (BROTLI_FOUND)
-  if (NOT Brotli_FIND_QUIETLY)
-    if (PARQUET_MINIMAL_DEPENDENCY)
-      message(STATUS "Found the Brotli headers: ${BROTLI_INCLUDE_DIR}")
-    else ()
-      message(STATUS "Found the Brotli library: ${BROTLI_LIBRARIES}")
-    endif ()
-  endif ()
-else ()
-  if (NOT Brotli_FIND_QUIETLY)
-    set(BROTLI_ERR_MSG "Could not find the Brotli library. Looked in ")
-    if ( _brotli_roots )
-      set(BROTLI_ERR_MSG "${BROTLI_ERR_MSG} in ${_brotli_roots}.")
-    else ()
-      set(BROTLI_ERR_MSG "${BROTLI_ERR_MSG} system search paths.")
-    endif ()
-    if (Brotli_FIND_REQUIRED)
-      message(FATAL_ERROR "${BROTLI_ERR_MSG}")
-    else (Brotli_FIND_REQUIRED)
-      message(STATUS "${BROTLI_ERR_MSG}")
-    endif (Brotli_FIND_REQUIRED)
-  endif ()
-endif ()
-
-mark_as_advanced(
-  BROTLI_INCLUDE_DIR
-  BROTLI_LIBS
-  BROTLI_LIBRARIES
-  BROTLI_STATIC_LIB
-  BROTLI_SHARED_LIB
-)
diff --git a/cmake_modules/FindClangTools.cmake b/cmake_modules/FindClangTools.cmake
deleted file mode 100644
index 56e2dd7..0000000
--- a/cmake_modules/FindClangTools.cmake
+++ /dev/null
@@ -1,118 +0,0 @@
-#
-# 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.
-#
-# Tries to find the clang-tidy and clang-format modules
-#
-# Usage of this module as follows:
-#
-#  find_package(ClangTools)
-#
-# Variables used by this module, they can change the default behaviour and need
-# to be set before calling find_package:
-#
-#  ClangToolsBin_HOME -
-#   When set, this path is inspected instead of standard library binary locations
-#   to find clang-tidy and clang-format
-#
-# This module defines
-#  CLANG_TIDY_BIN, The  path to the clang tidy binary
-#  CLANG_TIDY_FOUND, Whether clang tidy was found
-#  CLANG_FORMAT_BIN, The path to the clang format binary
-#  CLANG_TIDY_FOUND, Whether clang format was found
-
-if (DEFINED ENV{HOMEBREW_PREFIX})
-  set(HOMEBREW_PREFIX "${ENV{HOMEBREW_PREFIX}")
-else()
-  set(HOMEBREW_PREFIX "/usr/local")
-endif()
-
-find_program(CLANG_TIDY_BIN
-  NAMES clang-tidy-4.0
-  clang-tidy-3.9
-  clang-tidy-3.8
-  clang-tidy-3.7
-  clang-tidy-3.6
-  clang-tidy
-  PATHS ${ClangTools_PATH} $ENV{CLANG_TOOLS_PATH} /usr/local/bin /usr/bin "${HOMEBREW_PREFIX}/bin"
-        NO_DEFAULT_PATH
-)
-
-if ( "${CLANG_TIDY_BIN}" STREQUAL "CLANG_TIDY_BIN-NOTFOUND" )
-  set(CLANG_TIDY_FOUND 0)
-  message("clang-tidy not found")
-else()
-  set(CLANG_TIDY_FOUND 1)
-  message("clang-tidy found at ${CLANG_TIDY_BIN}")
-endif()
-
-if (CLANG_FORMAT_VERSION)
-    find_program(CLANG_FORMAT_BIN
-      NAMES clang-format-${CLANG_FORMAT_VERSION}
-      PATHS
-            ${ClangTools_PATH}
-            $ENV{CLANG_TOOLS_PATH}
-            /usr/local/bin /usr/bin "${HOMEBREW_PREFIX}/bin"
-            NO_DEFAULT_PATH
-    )
-
-    # If not found yet, search alternative locations
-    if (("${CLANG_FORMAT_BIN}" STREQUAL "CLANG_FORMAT_BIN-NOTFOUND") AND APPLE)
-        # Homebrew ships older LLVM versions in /usr/local/opt/llvm@version/
-        STRING(REGEX REPLACE "^([0-9]+)\\.[0-9]+" "\\1" CLANG_FORMAT_MAJOR_VERSION "${CLANG_FORMAT_VERSION}")
-        STRING(REGEX REPLACE "^[0-9]+\\.([0-9]+)" "\\1" CLANG_FORMAT_MINOR_VERSION "${CLANG_FORMAT_VERSION}")
-        if ("${CLANG_FORMAT_MINOR_VERSION}" STREQUAL "0")
-            find_program(CLANG_FORMAT_BIN
-              NAMES clang-format
-              PATHS "${HOMEBREW_PREFIX}/opt/llvm@${CLANG_FORMAT_MAJOR_VERSION}/bin"
-                    NO_DEFAULT_PATH
-            )
-        else()
-            find_program(CLANG_FORMAT_BIN
-              NAMES clang-format
-              PATHS "${HOMEBREW_PREFIX}/opt/llvm@${CLANG_FORMAT_VERSION}/bin"
-                    NO_DEFAULT_PATH
-            )
-        endif()
-
-        if ("${CLANG_FORMAT_BIN}" STREQUAL "CLANG_FORMAT_BIN-NOTFOUND")
-          # binary was still not found, look into Cellar
-          file(GLOB CLANG_FORMAT_PATH "${HOMEBREW_PREFIX}/Cellar/llvm/${CLANG_FORMAT_VERSION}.*")
-          find_program(CLANG_FORMAT_BIN
-            NAMES clang-format
-            PATHS "${CLANG_FORMAT_PATH}/bin"
-                  NO_DEFAULT_PATH
-          )
-        endif()
-    endif()
-else()
-    find_program(CLANG_FORMAT_BIN
-      NAMES clang-format-6.0
-      clang-format-5.0
-      clang-format-4.0
-      clang-format-3.9
-      clang-format-3.8
-      clang-format-3.7
-      clang-format-3.6
-      clang-format
-      PATHS ${ClangTools_PATH} $ENV{CLANG_TOOLS_PATH} /usr/local/bin /usr/bin "${HOMEBREW_PREFIX}/bin"
-            NO_DEFAULT_PATH
-    )
-endif()
-
-if ( "${CLANG_FORMAT_BIN}" STREQUAL "CLANG_FORMAT_BIN-NOTFOUND" )
-  set(CLANG_FORMAT_FOUND 0)
-  message("clang-format not found")
-else()
-  set(CLANG_FORMAT_FOUND 1)
-  message("clang-format found at ${CLANG_FORMAT_BIN}")
-endif()
diff --git a/cmake_modules/FindGBenchmark.cmake b/cmake_modules/FindGBenchmark.cmake
deleted file mode 100644
index 3e46a60..0000000
--- a/cmake_modules/FindGBenchmark.cmake
+++ /dev/null
@@ -1,88 +0,0 @@
-#
-# 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.
-#
-# Tries to find Google benchmark headers and libraries.
-#
-# Usage of this module as follows:
-#
-#  find_package(GBenchark)
-#
-# Variables used by this module, they can change the default behaviour and need
-# to be set before calling find_package:
-#
-#  GBenchmark_HOME - When set, this path is inspected instead of standard library
-#                    locations as the root of the benchark installation.
-#                    The environment variable GBENCHMARK_HOME overrides this veriable.
-#
-# This module defines
-#  GBENCHMARK_INCLUDE_DIR, directory containing benchmark header directory
-#  GBENCHMARK_LIBS, directory containing benchmark libraries
-#  GBENCHMARK_STATIC_LIB, path to libbenchmark.a
-#  GBENCHMARK_FOUND, whether gbenchmark has been found
-
-if( NOT "$ENV{GBENCHMARK_HOME}" STREQUAL "")
-    file( TO_CMAKE_PATH "$ENV{GBENCHMARK_HOME}" _native_path )
-    list( APPEND _gbenchmark_roots ${_native_path} )
-elseif ( GBenchmark_HOME )
-    list( APPEND _gbenchmark_roots ${GBenchmark_HOME} )
-endif()
-
-# Try the parameterized roots, if they exist
-if ( _gbenchmark_roots )
-    find_path( GBENCHMARK_INCLUDE_DIR NAMES benchmark/benchmark.h 
-        PATHS ${_gbenchmark_roots} NO_DEFAULT_PATH
-        PATH_SUFFIXES "include" )
-    find_library( GBENCHMARK_LIBRARIES NAMES benchmark
-        PATHS ${_gbenchmark_roots} NO_DEFAULT_PATH
-        PATH_SUFFIXES "lib" )
-else ()
-    find_path( GBENCHMARK_INCLUDE_DIR NAMES benchmark/benchmark.hh )
-    find_library( GBENCHMARK_LIBRARIES NAMES benchmark )
-endif ()
-
-
-if (GBENCHMARK_INCLUDE_DIR AND GBENCHMARK_LIBRARIES)
-  set(GBENCHMARK_FOUND TRUE)
-  get_filename_component( GBENCHMARK_LIBS ${GBENCHMARK_LIBRARIES} PATH )
-  set(GBENCHMARK_LIB_NAME libbenchmark)
-  set(GBENCHMARK_STATIC_LIB ${GBENCHMARK_LIBS}/${GBENCHMARK_LIB_NAME}.a)
-else ()
-  set(GBENCHMARK_FOUND FALSE)
-endif ()
-
-if (GBENCHMARK_FOUND)
-  if (NOT GBenchmark_FIND_QUIETLY)
-    message(STATUS "Found the GBenchmark library: ${GBENCHMARK_LIBRARIES}")
-  endif ()
-else ()
-  if (NOT GBenchmark_FIND_QUIETLY)
-    set(GBENCHMARK_ERR_MSG "Could not find the GBenchmark library. Looked in ")
-    if ( _gbenchmark_roots )
-      set(GBENCHMARK_ERR_MSG "${GBENCHMARK_ERR_MSG} in ${_gbenchmark_roots}.")
-    else ()
-      set(GBENCHMARK_ERR_MSG "${GBENCHMARK_ERR_MSG} system search paths.")
-    endif ()
-    if (GBenchmark_FIND_REQUIRED)
-      message(FATAL_ERROR "${GBENCHMARK_ERR_MSG}")
-    else (GBenchmark_FIND_REQUIRED)
-      message(STATUS "${GBENCHMARK_ERR_MSG}")
-    endif (GBenchmark_FIND_REQUIRED)
-  endif ()
-endif ()
-
-mark_as_advanced(
-  GBENCHMARK_INCLUDE_DIR
-  GBENCHMARK_LIBS
-  GBENCHMARK_LIBRARIES
-  GBENCHMARK_STATIC_LIB
-)
diff --git a/cmake_modules/FindGTest.cmake b/cmake_modules/FindGTest.cmake
deleted file mode 100644
index c6ea16b..0000000
--- a/cmake_modules/FindGTest.cmake
+++ /dev/null
@@ -1,94 +0,0 @@
-#
-# 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.
-#
-# Tries to find GTest headers and libraries.
-#
-# Usage of this module as follows:
-#
-#  find_package(GTest)
-#
-# Variables used by this module, they can change the default behaviour and need
-# to be set before calling find_package:
-#
-#  GTest_HOME - When set, this path is inspected instead of standard library
-#                locations as the root of the GTest installation.
-#                The environment variable GTEST_HOME overrides this veriable.
-#
-# This module defines
-#  GTEST_INCLUDE_DIR, directory containing headers
-#  GTEST_LIBS, directory containing gtest libraries
-#  GTEST_STATIC_LIB, path to libgtest.a
-#  GTEST_MAIN_STATIC_LIB, path to libgtest_main.a
-#  GTEST_SHARED_LIB, path to libgtest's shared library
-#  GTEST_FOUND, whether gtest has been found
-
-if( NOT "$ENV{GTEST_HOME}" STREQUAL "")
-    file( TO_CMAKE_PATH "$ENV{GTEST_HOME}" _native_path )
-    list( APPEND _gtest_roots ${_native_path} )
-elseif ( GTest_HOME )
-    list( APPEND _gtest_roots ${GTest_HOME} )
-endif()
-
-# Try the parameterized roots, if they exist
-if ( _gtest_roots )
-    find_path( GTEST_INCLUDE_DIR NAMES gtest/gtest.h
-        PATHS ${_gtest_roots} NO_DEFAULT_PATH
-        PATH_SUFFIXES "include" )
-    find_library( GTEST_LIBRARIES NAMES gtest gtest_main
-        PATHS ${_gtest_roots} NO_DEFAULT_PATH
-        PATH_SUFFIXES "lib" )
-else ()
-    find_path( GTEST_INCLUDE_DIR NAMES gtest/gtest.h )
-    find_library( GTEST_LIBRARIES NAMES gtest )
-endif ()
-
-
-if (GTEST_INCLUDE_DIR AND GTEST_LIBRARIES)
-  set(GTEST_FOUND TRUE)
-  get_filename_component( GTEST_LIBS ${GTEST_LIBRARIES} PATH )
-  set(GTEST_LIB_NAME gtest)
-  set(GTEST_STATIC_LIB ${GTEST_LIBS}/${CMAKE_STATIC_LIBRARY_PREFIX}${GTEST_LIB_NAME}${CMAKE_STATIC_LIBRARY_SUFFIX})
-  set(GTEST_MAIN_STATIC_LIB ${GTEST_LIBS}/${CMAKE_STATIC_LIBRARY_PREFIX}${GTEST_LIB_NAME}_main${CMAKE_STATIC_LIBRARY_SUFFIX})
-  set(GTEST_SHARED_LIB ${GTEST_LIBS}/${CMAKE_SHARED_LIBRARY_PREFIX}${GTEST_LIB_NAME}${CMAKE_SHARED_LIBRARY_SUFFIX})
-else ()
-  set(GTEST_FOUND FALSE)
-endif ()
-
-if (GTEST_FOUND)
-  if (NOT GTest_FIND_QUIETLY)
-    message(STATUS "Found the GTest library: ${GTEST_LIBRARIES}")
-  endif ()
-else ()
-  if (NOT GTest_FIND_QUIETLY)
-    set(GTEST_ERR_MSG "Could not find the GTest library. Looked in ")
-    if ( _gtest_roots )
-      set(GTEST_ERR_MSG "${GTEST_ERR_MSG} in ${_gtest_roots}.")
-    else ()
-      set(GTEST_ERR_MSG "${GTEST_ERR_MSG} system search paths.")
-    endif ()
-    if (GTest_FIND_REQUIRED)
-      message(FATAL_ERROR "${GTEST_ERR_MSG}")
-    else (GTest_FIND_REQUIRED)
-      message(STATUS "${GTEST_ERR_MSG}")
-    endif (GTest_FIND_REQUIRED)
-  endif ()
-endif ()
-
-mark_as_advanced(
-  GTEST_INCLUDE_DIR
-  GTEST_LIBS
-  GTEST_LIBRARIES
-  GTEST_STATIC_LIB
-  GTEST_MAIN_STATIC_LIB
-  GTEST_SHARED_LIB
-)
diff --git a/cmake_modules/FindSnappy.cmake b/cmake_modules/FindSnappy.cmake
deleted file mode 100644
index 867963c..0000000
--- a/cmake_modules/FindSnappy.cmake
+++ /dev/null
@@ -1,94 +0,0 @@
-#
-# 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.
-#
-# Tries to find Snappy headers and libraries.
-#
-# Usage of this module as follows:
-#
-#  find_package(Snappy)
-#
-# Variables used by this module, they can change the default behaviour and need
-# to be set before calling find_package:
-#
-#  Snappy_HOME - When set, this path is inspected instead of standard library
-#                locations as the root of the Snappy installation.
-#                The environment variable SNAPPY_HOME overrides this variable.
-#
-# This module defines
-#  SNAPPY_INCLUDE_DIR, directory containing headers
-#  SNAPPY_LIBS, directory containing snappy libraries
-#  SNAPPY_STATIC_LIB, path to libsnappy.a
-#  SNAPPY_SHARED_LIB, path to libsnappy's shared library
-#  SNAPPY_FOUND, whether snappy has been found
-
-if( NOT "${SNAPPY_HOME}" STREQUAL "")
-    file( TO_CMAKE_PATH "${SNAPPY_HOME}" _native_path )
-    list( APPEND _snappy_roots ${_native_path} )
-elseif ( Snappy_HOME )
-    list( APPEND _snappy_roots ${Snappy_HOME} )
-endif()
-
-message(STATUS "SNAPPY_HOME: ${SNAPPY_HOME}")
-find_path(SNAPPY_INCLUDE_DIR snappy.h HINTS
-  ${_snappy_roots}
-  NO_DEFAULT_PATH
-  PATH_SUFFIXES "include")
-
-find_library( SNAPPY_LIBRARIES NAMES snappy PATHS
-  ${_snappy_roots}
-  NO_DEFAULT_PATH
-  PATH_SUFFIXES "lib")
-
-if (SNAPPY_INCLUDE_DIR AND (PARQUET_MINIMAL_DEPENDENCY OR SNAPPY_LIBRARIES))
-  set(SNAPPY_FOUND TRUE)
-  get_filename_component( SNAPPY_LIBS ${SNAPPY_LIBRARIES} PATH )
-  set(SNAPPY_HEADER_NAME snappy.h)
-  set(SNAPPY_HEADER ${SNAPPY_INCLUDE_DIR}/${SNAPPY_HEADER_NAME})
-  set(SNAPPY_LIB_NAME snappy)
-  set(SNAPPY_STATIC_LIB ${SNAPPY_LIBS}/${CMAKE_STATIC_LIBRARY_PREFIX}${SNAPPY_LIB_NAME}${SNAPPY_MSVC_STATIC_LIB_SUFFIX}${CMAKE_STATIC_LIBRARY_SUFFIX})
-  set(SNAPPY_SHARED_LIB ${SNAPPY_LIBS}/${CMAKE_SHARED_LIBRARY_PREFIX}${SNAPPY_LIB_NAME}${CMAKE_SHARED_LIBRARY_SUFFIX})
-else ()
-  set(SNAPPY_FOUND FALSE)
-endif ()
-
-if (SNAPPY_FOUND)
-  if (NOT Snappy_FIND_QUIETLY)
-    if (PARQUET_MINIMAL_DEPENDENCY)
-      message(STATUS "Found the Snappy header: ${SNAPPY_HEADER}")
-    else ()
-      message(STATUS "Found the Snappy library: ${SNAPPY_LIBRARIES}")
-    endif ()
-  endif ()
-else ()
-  if (NOT Snappy_FIND_QUIETLY)
-    set(SNAPPY_ERR_MSG "Could not find the Snappy library. Looked in ")
-    if ( _snappy_roots )
-      set(SNAPPY_ERR_MSG "${SNAPPY_ERR_MSG} in ${_snappy_roots}.")
-    else ()
-      set(SNAPPY_ERR_MSG "${SNAPPY_ERR_MSG} system search paths.")
-    endif ()
-    if (Snappy_FIND_REQUIRED)
-      message(FATAL_ERROR "${SNAPPY_ERR_MSG}")
-    else (Snappy_FIND_REQUIRED)
-      message(STATUS "${SNAPPY_ERR_MSG}")
-    endif (Snappy_FIND_REQUIRED)
-  endif ()
-endif ()
-
-mark_as_advanced(
-  SNAPPY_INCLUDE_DIR
-  SNAPPY_LIBS
-  SNAPPY_LIBRARIES
-  SNAPPY_STATIC_LIB
-  SNAPPY_SHARED_LIB
-)
diff --git a/cmake_modules/FindThrift.cmake b/cmake_modules/FindThrift.cmake
deleted file mode 100644
index 25f5082..0000000
--- a/cmake_modules/FindThrift.cmake
+++ /dev/null
@@ -1,102 +0,0 @@
-# Copyright 2012 Cloudera Inc.
-#
-# 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.
-
-# - Find Thrift (a cross platform RPC lib/tool)
-#
-# Variables used by this module, they can change the default behaviour and need
-# to be set before calling find_package:
-#
-#  Thrift_HOME - When set, this path is inspected instead of standard library
-#                locations as the root of the Thrift installation.
-#                The environment variable THRIFT_HOME overrides this variable.
-#
-# This module defines
-#  THRIFT_VERSION, version string of ant if found
-#  THRIFT_INCLUDE_DIR, where to find THRIFT headers
-#  THRIFT_CONTRIB_DIR, where contrib thrift files (e.g. fb303.thrift) are installed
-#  THRIFT_STATIC_LIB, THRIFT static library
-#  THRIFT_FOUND, If false, do not try to use ant
-
-# prefer the thrift version supplied in THRIFT_HOME
-if( NOT "${THRIFT_HOME}" STREQUAL "")
-    file( TO_CMAKE_PATH "${THRIFT_HOME}" _native_path )
-    list( APPEND _thrift_roots ${_native_path} )
-elseif ( Thrift_HOME )
-    list( APPEND _thrift_roots ${Thrift_HOME} )
-endif()
-
-message(STATUS "THRIFT_HOME: ${THRIFT_HOME}")
-find_path(THRIFT_INCLUDE_DIR thrift/Thrift.h HINTS
-  ${_thrift_roots}
-  NO_DEFAULT_PATH
-  PATH_SUFFIXES "include"
-)
-
-find_path(THRIFT_CONTRIB_DIR share/fb303/if/fb303.thrift HINTS
-  ${_thrift_roots}
-  NO_DEFAULT_PATH
-)
-
-if (MSVC AND NOT THRIFT_MSVC_STATIC_LIB_SUFFIX)
-  set(THRIFT_MSVC_STATIC_LIB_SUFFIX md)
-endif()
-
-find_library(THRIFT_STATIC_LIB NAMES
-  ${CMAKE_STATIC_LIBRARY_PREFIX}thrift${THRIFT_MSVC_STATIC_LIB_SUFFIX}${CMAKE_STATIC_LIBRARY_SUFFIX}
-  HINTS ${_thrift_roots}
-  NO_DEFAULT_PATH
-  PATH_SUFFIXES "lib/${CMAKE_LIBRARY_ARCHITECTURE}" "lib"
-)
-
-find_program(THRIFT_COMPILER thrift HINTS
-  ${_thrift_roots}
-  NO_DEFAULT_PATH
-  PATH_SUFFIXES "bin"
-)
-
-if (THRIFT_STATIC_LIB)
-  set(THRIFT_FOUND TRUE)
-  exec_program(${THRIFT_COMPILER}
-    ARGS -version OUTPUT_VARIABLE THRIFT_VERSION RETURN_VALUE THRIFT_RETURN)
-else ()
-  set(THRIFT_FOUND FALSE)
-endif ()
-
-if (THRIFT_FOUND)
-  if (NOT Thrift_FIND_QUIETLY)
-    message(STATUS "Thrift version: ${THRIFT_VERSION}")
-  endif ()
-else ()
-  if (NOT Thrift_FIND_QUIETLY)
-    set(THRIFT_ERR_MSG "Thrift compiler/libraries NOT found: ${THRIFT_RETURN}")
-    set(THRIFT_ERR_MSG "${THRIFT_ERR_MSG} (${THRIFT_INCLUDE_DIR}, ${THRIFT_STATIC_LIB}).")
-    if ( _thrift_roots )
-      set(THRIFT_ERR_MSG "${THRIFT_ERR_MSG} Looked in ${_thrift_roots}.")
-    else ()
-      set(THRIFT_ERR_MSG "${THRIFT_ERR_MSG} Looked in system search paths.")
-    endif ()
-    if ( Thrift_FIND_REQUIRED )
-      message(FATAL_ERROR "${THRIFT_ERR_MSG}")
-    else ()
-      message(STATUS "${THRIFT_ERR_MSG}")
-    endif ()
-  endif ()
-endif ()
-
-
-mark_as_advanced(
-  THRIFT_STATIC_LIB
-  THRIFT_COMPILER
-  THRIFT_INCLUDE_DIR
-)
diff --git a/cmake_modules/FindZLIB.cmake b/cmake_modules/FindZLIB.cmake
deleted file mode 100644
index 78b84f2..0000000
--- a/cmake_modules/FindZLIB.cmake
+++ /dev/null
@@ -1,105 +0,0 @@
-#
-# 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.
-#
-# Tries to find ZLIB headers and libraries.
-#
-# Usage of this module as follows:
-#
-#  find_package(ZLIB)
-#
-# Variables used by this module, they can change the default behaviour and need
-# to be set before calling find_package:
-#
-#  ZLIB_HOME - When set, this path is inspected instead of standard library
-#             locations as the root of the ZLIB installation.
-#             The environment variable ZLIB_HOME overrides this variable.
-#
-# - Find ZLIB (zlib.h, libz.a, libz.so, and libz.so.1)
-# This module defines
-#  ZLIB_INCLUDE_DIR, directory containing headers
-#  ZLIB_LIBS, directory containing zlib libraries
-#  ZLIB_STATIC_LIB, path to libz.a
-#  ZLIB_SHARED_LIB, path to libz's shared library
-#  ZLIB_FOUND, whether zlib has been found
-
-if( NOT "${ZLIB_HOME}" STREQUAL "")
-    file( TO_CMAKE_PATH "${ZLIB_HOME}" _native_path )
-    list( APPEND _zlib_roots ${_native_path} )
-elseif ( ZLIB_HOME )
-    list( APPEND _zlib_roots ${ZLIB_HOME} )
-endif()
-
-# Try the parameterized roots, if they exist
-if ( _zlib_roots )
-    find_path( ZLIB_INCLUDE_DIR NAMES zlib.h
-        PATHS ${_zlib_roots} NO_DEFAULT_PATH
-        PATH_SUFFIXES "include" )
-    find_library( ZLIB_LIBRARIES NAMES libz.a zlib
-        PATHS ${_zlib_roots} NO_DEFAULT_PATH
-        PATH_SUFFIXES "lib" )
-else ()
-    find_path( ZLIB_INCLUDE_DIR NAMES zlib.h )
-    # Only look for the static library
-    find_library( ZLIB_LIBRARIES NAMES libz.a zlib )
-endif ()
-
-
-if (ZLIB_INCLUDE_DIR AND (PARQUET_MINIMAL_DEPENDENCY OR ZLIB_LIBRARIES))
-  set(ZLIB_FOUND TRUE)
-  get_filename_component( ZLIB_LIBS ${ZLIB_LIBRARIES} PATH )
-  set(ZLIB_HEADER_NAME zlib.h)
-  set(ZLIB_HEADER ${ZLIB_INCLUDE_DIR}/${ZLIB_HEADER_NAME})
-  set(ZLIB_LIB_NAME z)
-  if (MSVC)
-    if (NOT ZLIB_MSVC_STATIC_LIB_SUFFIX)
-      set(ZLIB_MSVC_STATIC_LIB_SUFFIX libstatic)
-    endif()
-    set(ZLIB_MSVC_SHARED_LIB_SUFFIX lib)
-  endif()
-  set(ZLIB_STATIC_LIB ${ZLIB_LIBS}/${CMAKE_STATIC_LIBRARY_PREFIX}${ZLIB_LIB_NAME}${ZLIB_MSVC_STATIC_LIB_SUFFIX}${CMAKE_STATIC_LIBRARY_SUFFIX})
-  set(ZLIB_SHARED_LIB ${ZLIB_LIBS}/${CMAKE_SHARED_LIBRARY_PREFIX}${ZLIB_LIB_NAME}${ZLIB_MSVC_SHARED_LIB_SUFFIX}${CMAKE_SHARED_LIBRARY_SUFFIX})
-else ()
-  set(ZLIB_FOUND FALSE)
-endif ()
-
-if (ZLIB_FOUND)
-  if (NOT ZLIB_FIND_QUIETLY)
-    if (PARQUET_MINIMAL_DEPENDENCY)
-      message(STATUS "Found the ZLIB header: ${ZLIB_HEADER}")
-    else()
-      message(STATUS "Found the ZLIB library: ${ZLIB_LIBRARIES}")
-    endif ()
-  endif ()
-else ()
-  if (NOT ZLIB_FIND_QUIETLY)
-    set(ZLIB_ERR_MSG "Could not find the ZLIB library. Looked in ")
-    if ( _zlib_roots )
-      set(ZLIB_ERR_MSG "${ZLIB_ERR_MSG} in ${_zlib_roots}.")
-    else ()
-      set(ZLIB_ERR_MSG "${ZLIB_ERR_MSG} system search paths.")
-    endif ()
-    if (ZLIB_FIND_REQUIRED)
-      message(FATAL_ERROR "${ZLIB_ERR_MSG}")
-    else (ZLIB_FIND_REQUIRED)
-      message(STATUS "${ZLIB_ERR_MSG}")
-    endif (ZLIB_FIND_REQUIRED)
-  endif ()
-endif ()
-
-mark_as_advanced(
-  ZLIB_INCLUDE_DIR
-  ZLIB_LIBS
-  ZLIB_LIBRARIES
-  ZLIB_STATIC_LIB
-  ZLIB_SHARED_LIB
-)
diff --git a/cmake_modules/SetupCxxFlags.cmake b/cmake_modules/SetupCxxFlags.cmake
deleted file mode 100644
index 0029501..0000000
--- a/cmake_modules/SetupCxxFlags.cmake
+++ /dev/null
@@ -1,248 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you 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.
-
-# Check if the target architecture and compiler supports some special
-# instruction sets that would boost performance.
-include(CheckCXXCompilerFlag)
-# x86/amd64 compiler flags
-CHECK_CXX_COMPILER_FLAG("-msse3" CXX_SUPPORTS_SSE3)
-# power compiler flags
-CHECK_CXX_COMPILER_FLAG("-maltivec" CXX_SUPPORTS_ALTIVEC)
-
-# compiler flags that are common across debug/release builds
-
-if (MSVC)
-  # TODO(wesm): Change usages of C runtime functions that MSVC says are
-  # insecure, like std::getenv
-  add_definitions(-D_CRT_SECURE_NO_WARNINGS)
-
-  # Use __declspec(dllexport) during library build, other users of the Parquet
-  # headers will see dllimport
-  add_definitions(-DPARQUET_EXPORTING)
-
-  if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
-    # clang-cl
-    set(CXX_COMMON_FLAGS "-EHsc")
-  elseif(${CMAKE_CXX_COMPILER_VERSION} VERSION_LESS 19)
-    message(FATAL_ERROR "Only MSVC 2015 (Version 19.0) and later are supported
-    by Parquet. Found version ${CMAKE_CXX_COMPILER_VERSION}.")
-  else()
-    # Fix annoying D9025 warning
-    string(REPLACE "/W3" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
-
-    # Set desired warning level (e.g. set /W4 for more warnings)
-    set(CXX_COMMON_FLAGS "/W3")
-  endif()
-
-  if (PARQUET_USE_STATIC_CRT)
-    foreach (c_flag CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_RELEASE CMAKE_CXX_FLAGS_DEBUG
-                    CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO
-                    CMAKE_C_FLAGS CMAKE_C_FLAGS_RELEASE CMAKE_C_FLAGS_DEBUG
-                    CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELWITHDEBINFO)
-      string(REPLACE "/MD" "-MT" ${c_flag} "${${c_flag}}")
-    endforeach()
-  endif()
-else()
-  # Common flags set below with warning level
-  set(CXX_COMMON_FLAGS "")
-endif()
-
-# Build warning level (CHECKIN, EVERYTHING, etc.)
-
-# if no build warning level is specified, default to development warning level
-if (NOT PARQUET_BUILD_WARNING_LEVEL)
-  set(PARQUET_BUILD_WARNING_LEVEL Production)
-endif(NOT PARQUET_BUILD_WARNING_LEVEL)
-
-string(TOUPPER ${PARQUET_BUILD_WARNING_LEVEL} UPPERCASE_BUILD_WARNING_LEVEL)
-
-if ("${UPPERCASE_BUILD_WARNING_LEVEL}" STREQUAL "CHECKIN")
-  # Pre-checkin builds
-  if ("${COMPILER_FAMILY}" STREQUAL "msvc")
-    string(REPLACE "/W3" "" CXX_COMMON_FLAGS "${CXX_COMMON_FLAGS}")
-    set(CXX_COMMON_FLAGS "${CXX_COMMON_FLAGS} /W3")
-    # Treat all compiler warnings as errors
-    set(CXX_COMMON_FLAGS "${CXX_COMMON_FLAGS} /WX")
-  elseif ("${COMPILER_FAMILY}" STREQUAL "clang")
-    set(CXX_COMMON_FLAGS "${CXX_COMMON_FLAGS} -Weverything -Wno-c++98-compat \
--Wno-c++98-compat-pedantic -Wno-deprecated -Wno-deprecated-declarations \
--Wno-weak-vtables -Wno-padded -Wno-comma -Wno-unused-parameter -Wno-undef \
--Wno-shadow -Wno-switch-enum -Wno-exit-time-destructors \
--Wno-global-constructors -Wno-weak-template-vtables -Wno-undefined-reinterpret-cast \
--Wno-implicit-fallthrough -Wno-unreachable-code-return \
--Wno-documentation-deprecated-sync \
--Wno-float-equal -Wno-missing-prototypes \
--Wno-old-style-cast -Wno-covered-switch-default \
--Wno-format-nonliteral -Wno-missing-noreturn \
--Wno-cast-align -Wno-vla-extension -Wno-shift-sign-overflow \
--Wno-used-but-marked-unused -Wno-missing-variable-declarations \
--Wno-gnu-zero-variadic-macro-arguments -Wconversion -Wno-sign-conversion \
--Wno-disabled-macro-expansion -Wno-shorten-64-to-32")
-
-    message(STATUS "Clang version: ${COMPILER_VERSION}")
-
-    # Version numbers where warnings are introduced
-    if ("${COMPILER_VERSION}" VERSION_GREATER "3.3")
-      set(CXX_COMMON_FLAGS "${CXX_COMMON_FLAGS} -Wno-gnu-folding-constant")
-    endif()
-    if ("${COMPILER_VERSION}" VERSION_GREATER "3.6")
-      set(CXX_COMMON_FLAGS "${CXX_COMMON_FLAGS} -Wno-reserved-id-macro")
-      set(CXX_COMMON_FLAGS "${CXX_COMMON_FLAGS} -Wno-range-loop-analysis")
-    endif()
-    if ("${COMPILER_VERSION}" VERSION_GREATER "3.7")
-      set(CXX_COMMON_FLAGS "${CXX_COMMON_FLAGS} -Wno-double-promotion")
-    endif()
-    if ("${COMPILER_VERSION}" VERSION_GREATER "3.8")
-      set(CXX_COMMON_FLAGS "${CXX_COMMON_FLAGS} -Wno-undefined-func-template")
-    endif()
-
-    if ("${COMPILER_VERSION}" VERSION_GREATER "4.0")
-      set(CXX_COMMON_FLAGS "${CXX_COMMON_FLAGS} -Wno-unused-template \
--Wno-zero-as-null-pointer-constant")
-    endif()
-
-    # Treat all compiler warnings as errors
-    set(CXX_COMMON_FLAGS "${CXX_COMMON_FLAGS} -Wno-unknown-warning-option -Werror")
-  elseif ("${COMPILER_FAMILY}" STREQUAL "gcc")
-    set(CXX_COMMON_FLAGS "${CXX_COMMON_FLAGS} -Wall \
--Wno-deprecated-declarations -Wconversion -Wno-sign-conversion")
-    # Treat all compiler warnings as errors
-    set(CXX_COMMON_FLAGS "${CXX_COMMON_FLAGS} -Werror")
-  else()
-    message(FATAL_ERROR "Unknown compiler. Version info:\n${COMPILER_VERSION_FULL}")
-  endif()
-elseif ("${UPPERCASE_BUILD_WARNING_LEVEL}" STREQUAL "EVERYTHING")
-  # Pedantic builds for fixing warnings
-  if ("${COMPILER_FAMILY}" STREQUAL "msvc")
-    string(REPLACE "/W3" "" CXX_COMMON_FLAGS "${CXX_COMMON_FLAGS}")
-    set(CXX_COMMON_FLAGS "${CXX_COMMON_FLAGS} /Wall")
-    # https://docs.microsoft.com/en-us/cpp/build/reference/compiler-option-warning-level
-    # /wdnnnn disables a warning where "nnnn" is a warning number
-    # Treat all compiler warnings as errors
-    set(CXX_COMMON_FLAGS "${CXX_COMMON_FLAGS}  /WX")
-  elseif ("${COMPILER_FAMILY}" STREQUAL "clang")
-    set(CXX_COMMON_FLAGS "${CXX_COMMON_FLAGS} -Weverything -Wno-c++98-compat -Wno-c++98-compat-pedantic")
-    # Treat all compiler warnings as errors
-    set(CXX_COMMON_FLAGS "${CXX_COMMON_FLAGS} -Werror")
-  elseif ("${COMPILER_FAMILY}" STREQUAL "gcc")
-    set(CXX_COMMON_FLAGS "${CXX_COMMON_FLAGS} -Wall -Wpedantic -Wextra -Wno-unused-parameter")
-    # Treat all compiler warnings as errors
-    set(CXX_COMMON_FLAGS "${CXX_COMMON_FLAGS} -Werror")
-  else()
-    message(FATAL_ERROR "Unknown compiler. Version info:\n${COMPILER_VERSION_FULL}")
-  endif()
-else()
-  # Production builds (warning are not treated as errors)
-  if ("${COMPILER_FAMILY}" STREQUAL "msvc")
-    # https://docs.microsoft.com/en-us/cpp/build/reference/compiler-option-warning-level
-    # TODO: Enable /Wall and disable individual warnings until build compiles without errors
-    # /wdnnnn disables a warning where "nnnn" is a warning number
-    string(REPLACE "/W3" "" CXX_COMMON_FLAGS "${CXX_COMMON_FLAGS}")
-    set(CXX_COMMON_FLAGS "${CXX_COMMON_FLAGS} /W3")
-  elseif ("${COMPILER_FAMILY}" STREQUAL "clang")
-    set(CXX_COMMON_FLAGS "${CXX_COMMON_FLAGS} -Wall")
-  elseif ("${COMPILER_FAMILY}" STREQUAL "gcc")
-    set(CXX_COMMON_FLAGS "${CXX_COMMON_FLAGS} -Wall")
-  else()
-    message(FATAL_ERROR "Unknown compiler. Version info:\n${COMPILER_VERSION_FULL}")
-  endif()
-endif()
-
-# if build warning flags is set, add to CXX_COMMON_FLAGS
-if (BUILD_WARNING_FLAGS)
-  # Use BUILD_WARNING_FLAGS with BUILD_WARNING_LEVEL=everything to disable
-  # warnings (use with Clang's -Weverything flag to find potential errors)
-  set(CXX_COMMON_FLAGS "${CXX_COMMON_FLAGS} ${BUILD_WARNING_FLAGS}")
-endif(BUILD_WARNING_FLAGS)
-
-if ("${COMPILER_FAMILY}" STREQUAL "clang")
-  # Using Clang with ccache causes a bunch of spurious warnings that are
-  # purportedly fixed in the next version of ccache. See the following for details:
-  #
-  #   http://petereisentraut.blogspot.com/2011/05/ccache-and-clang.html
-  #   http://petereisentraut.blogspot.com/2011/09/ccache-and-clang-part-2.html
-  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Qunused-arguments")
-  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CMAKE_CLANG_OPTIONS}")
-endif()
-
-if (NOT ("${COMPILER_FAMILY}" STREQUAL "msvc"))
-set(CXX_COMMON_FLAGS "${CXX_COMMON_FLAGS} -std=c++11")
-endif()
-
-if ("${COMPILER_FAMILY}" STREQUAL "msvc")
-  # Support large object code
-  set(CXX_COMMON_FLAGS "${CXX_COMMON_FLAGS} /bigobj")
-
-  # MSVC version of -Wno-deprecated
-  set(CXX_COMMON_FLAGS "${CXX_COMMON_FLAGS} /wd4996")
-endif()
-
-if (PARQUET_USE_SSE)
-  SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=native")
-  add_definitions(-DPARQUET_USE_SSE)
-endif()
-
-if (APPLE)
-  # Depending on the default OSX_DEPLOYMENT_TARGET (< 10.9), libstdc++ may be
-  # the default standard library which does not support C++11. libc++ is the
-  # default from 10.9 onward.
-  set(CXX_COMMON_FLAGS "${CXX_COMMON_FLAGS} -stdlib=libc++")
-endif()
-
-# compiler flags for different build types (run 'cmake -DCMAKE_BUILD_TYPE=<type> .')
-# For all builds:
-# For CMAKE_BUILD_TYPE=Debug
-#   -ggdb: Enable gdb debugging
-# For CMAKE_BUILD_TYPE=FastDebug
-#   Same as DEBUG, except with some optimizations on.
-# For CMAKE_BUILD_TYPE=Release
-#   -O3: Enable all compiler optimizations
-#   Debug symbols are stripped for reduced binary size. Add
-#   -DPARQUET_CXXFLAGS="-g" to add them
-if (NOT MSVC)
-  set(CXX_FLAGS_DEBUG "-ggdb -O0")
-  set(CXX_FLAGS_FASTDEBUG "-ggdb -O1")
-  set(CXX_FLAGS_RELEASE "-O3 -DNDEBUG")
-endif()
-
-set(CXX_FLAGS_PROFILE_GEN "${CXX_FLAGS_RELEASE} -fprofile-generate")
-set(CXX_FLAGS_PROFILE_BUILD "${CXX_FLAGS_RELEASE} -fprofile-use")
-
-# if no build build type is specified, default to debug builds
-if (NOT CMAKE_BUILD_TYPE)
-  set(CMAKE_BUILD_TYPE Debug)
-endif(NOT CMAKE_BUILD_TYPE)
-
-string (TOUPPER ${CMAKE_BUILD_TYPE} CMAKE_BUILD_TYPE)
-
-# Set compile flags based on the build type.
-message("Configured for ${CMAKE_BUILD_TYPE} build (set with cmake -DCMAKE_BUILD_TYPE={release,debug,...})")
-if ("${CMAKE_BUILD_TYPE}" STREQUAL "DEBUG")
-  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CXX_FLAGS_DEBUG}")
-elseif ("${CMAKE_BUILD_TYPE}" STREQUAL "FASTDEBUG")
-  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CXX_FLAGS_FASTDEBUG}")
-elseif ("${CMAKE_BUILD_TYPE}" STREQUAL "RELEASE")
-  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CXX_FLAGS_RELEASE}")
-elseif ("${CMAKE_BUILD_TYPE}" STREQUAL "PROFILE_GEN")
-  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CXX_FLAGS_PROFILE_GEN}")
-elseif ("${CMAKE_BUILD_TYPE}" STREQUAL "PROFILE_BUILD")
-  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CXX_FLAGS_PROFILE_BUILD}")
-else()
-  message(FATAL_ERROR "Unknown build type: ${CMAKE_BUILD_TYPE}")
-endif ()
-
-message(STATUS "Build Type: ${CMAKE_BUILD_TYPE}")
diff --git a/cmake_modules/SnappyCMakeLists.txt b/cmake_modules/SnappyCMakeLists.txt
deleted file mode 100644
index 0348eb1..0000000
--- a/cmake_modules/SnappyCMakeLists.txt
+++ /dev/null
@@ -1,99 +0,0 @@
-# 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.
-#
-# Originally import from the Snappy repository with the following license:
-#
-# Copyright 2008 Google Inc. All Rights Reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-#
-#     * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-#     * Redistributions in binary form must reproduce the above
-# copyright notice, this list of conditions and the following disclaimer
-# in the documentation and/or other materials provided with the
-# distribution.
-#     * Neither the name of Google Inc. nor the names of its
-# contributors may be used to endorse or promote products derived from
-# this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
-PROJECT(snappy)
-
-INCLUDE(CheckIncludeFiles)
-INCLUDE(CMakePackageConfigHelpers)
-
-CHECK_INCLUDE_FILES("stdint.h" HAVE_STDINT_H)
-CHECK_INCLUDE_FILES("stddef.h" HAVE_STDDEF_H)
-CHECK_INCLUDE_FILES("sys/uio.h" HAVE_SYS_UIO_H)
-
-if (NOT HAVE_SYS_UIO_H)
-  set(HAVE_SYS_UIO_H 0)
-endif()
-
-if (NOT HAVE_STDINT_H)
-  set(HAVE_STDINT_H 0)
-endif()
-
-if (NOT HAVE_STDDEF_H)
-  set(HAVE_STDDEF_H 0)
-endif()
-
-set(ac_cv_have_stdint_h ${HAVE_STDINT_H})
-set(ac_cv_have_stddef_h ${HAVE_STDDEF_H})
-set(ac_cv_have_sys_uio_h ${HAVE_SYS_UIO_H})
-CONFIGURE_FILE(${snappy_SOURCE_DIR}/snappy-stubs-public.h.in
-               snappy-stubs-public.h)
-
-if (WIN32)
-  ADD_DEFINITIONS(-D_CRT_SECURE_NO_WARNINGS)
-endif()
-
-set(SNAPPY_SRCS snappy.cc
-  snappy-c.cc
-  snappy-stubs-internal.cc
-  snappy-sinksource.cc
-  snappy.h
-  snappy-c.h
-  snappy-sinksource.h
-  snappy-stubs-public.h)
-
-add_library(snappy SHARED ${SNAPPY_SRCS})
-add_library(snappystatic STATIC ${SNAPPY_SRCS})
-
-TARGET_COMPILE_DEFINITIONS(snappy PRIVATE -DHAVE_CONFIG_H)
-TARGET_COMPILE_DEFINITIONS(snappystatic PRIVATE -DHAVE_CONFIG_H)
-
-install(FILES snappy.h
-  snappy-c.h
-  snappy-sinksource.h
-  ${snappy_BINARY_DIR}/snappy-stubs-public.h
-  DESTINATION include)
-
-install(TARGETS snappy snappystatic
-  RUNTIME DESTINATION bin
-  LIBRARY DESTINATION lib
-  ARCHIVE DESTINATION lib)
diff --git a/cmake_modules/SnappyConfig.h b/cmake_modules/SnappyConfig.h
deleted file mode 100644
index 5764deb..0000000
--- a/cmake_modules/SnappyConfig.h
+++ /dev/null
@@ -1,55 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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.
-//
-// Originally import from the Snappy repository with the following license:
-//
-// Copyright 2008 Google Inc. All Rights Reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#ifndef SNAPPY_CONFIG_H
-#define SNAPPY_CONFIG_H 1
-
-#if defined(_MSC_VER) && (_MSC_VER <= 1900)
-typedef __int64 ssize_t;
-#endif
-
-#endif
diff --git a/cmake_modules/ThirdpartyToolchain.cmake b/cmake_modules/ThirdpartyToolchain.cmake
deleted file mode 100644
index 1934742..0000000
--- a/cmake_modules/ThirdpartyToolchain.cmake
+++ /dev/null
@@ -1,419 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you 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.
-
-set(GTEST_VERSION "1.8.0")
-set(GBENCHMARK_VERSION "1.1.0")
-set(THRIFT_VENDOR_VERSION "0.11.0")
-
-string(TOUPPER ${CMAKE_BUILD_TYPE} UPPERCASE_BUILD_TYPE)
-
-set(EP_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_${UPPERCASE_BUILD_TYPE}}")
-set(EP_C_FLAGS "${CMAKE_C_FLAGS} ${CMAKE_C_FLAGS_${UPPERCASE_BUILD_TYPE}}")
-
-if (NOT MSVC)
-  # Set -fPIC on all external projects
-  set(EP_CXX_FLAGS "${EP_CXX_FLAGS} -fPIC")
-  set(EP_C_FLAGS "${EP_C_FLAGS} -fPIC")
-endif()
-
-if (NOT PARQUET_VERBOSE_THIRDPARTY_BUILD)
-  set(EP_LOG_OPTIONS
-    LOG_CONFIGURE 1
-    LOG_BUILD 1
-    LOG_INSTALL 1
-    LOG_DOWNLOAD 1)
-  set(Boost_DEBUG FALSE)
-else()
-  set(EP_LOG_OPTIONS)
-  set(Boost_DEBUG TRUE)
-endif()
-
-# ----------------------------------------------------------------------
-# Configure toolchain with environment variables, if the exist
-
-if (NOT "$ENV{PARQUET_BUILD_TOOLCHAIN}" STREQUAL "")
-  set(THRIFT_HOME "$ENV{PARQUET_BUILD_TOOLCHAIN}")
-  set(ARROW_HOME "$ENV{PARQUET_BUILD_TOOLCHAIN}")
-
-  if (NOT DEFINED ENV{BOOST_ROOT})
-    # Since we have to set this in the environment, we check whether
-    # $BOOST_ROOT is defined inside here
-    set(ENV{BOOST_ROOT} "$ENV{PARQUET_BUILD_TOOLCHAIN}")
-  endif()
-endif()
-
-if (DEFINED ENV{THRIFT_HOME})
-  set(THRIFT_HOME "$ENV{THRIFT_HOME}")
-endif()
-
-# ----------------------------------------------------------------------
-# Boost
-
-# find boost headers and libs
-set(Boost_USE_MULTITHREADED ON)
-if (MSVC AND PARQUET_USE_STATIC_CRT)
-  set(Boost_USE_STATIC_RUNTIME ON)
-endif()
-if (MSVC)
-  # disable autolinking in boost
-  add_definitions(-DBOOST_ALL_NO_LIB)
-endif()
-if (PARQUET_BOOST_USE_SHARED)
-  # Find shared Boost libraries.
-  set(Boost_USE_STATIC_LIBS OFF)
-
-  if (MSVC)
-    # force all boost libraries to dynamic link
-    add_definitions(-DBOOST_ALL_DYN_LINK)
-    find_package(Boost COMPONENTS regex system REQUIRED)
-  else()
-    find_package(Boost COMPONENTS regex REQUIRED)
-  endif()
-
-  if ("${UPPERCASE_BUILD_TYPE}" STREQUAL "DEBUG")
-    set(BOOST_SHARED_REGEX_LIBRARY ${Boost_REGEX_LIBRARY_DEBUG})
-    if (MSVC)
-      set(BOOST_SHARED_SYSTEM_LIBRARY ${Boost_SYSTEM_LIBRARY_DEBUG})
-    endif()
-  else()
-    set(BOOST_SHARED_REGEX_LIBRARY ${Boost_REGEX_LIBRARY_RELEASE})
-    if (MSVC)
-      set(BOOST_SHARED_SYSTEM_LIBRARY ${Boost_SYSTEM_LIBRARY_RELEASE})
-    endif()
-  endif()
-else()
-  # Find static Boost libraries.
-  set(Boost_USE_STATIC_LIBS ON)
-  if (MSVC)
-    find_package(Boost COMPONENTS regex system filesystem REQUIRED)
-  else()
-    find_package(Boost COMPONENTS regex REQUIRED)
-  endif()
-  if ("${UPPERCASE_BUILD_TYPE}" STREQUAL "DEBUG")
-    set(BOOST_STATIC_REGEX_LIBRARY ${Boost_REGEX_LIBRARY_DEBUG})
-    if (MSVC)
-      set(BOOST_STATIC_SYSTEM_LIBRARY ${Boost_SYSTEM_LIBRARY_DEBUG})
-      set(BOOST_STATIC_FILESYSTEM_LIBRARY ${Boost_FILESYSTEM_LIBRARY_DEBUG})
-    endif()
-  else()
-    set(BOOST_STATIC_REGEX_LIBRARY ${Boost_REGEX_LIBRARY_RELEASE})
-    if (MSVC)
-      set(BOOST_STATIC_SYSTEM_LIBRARY ${Boost_SYSTEM_LIBRARY_RELEASE})
-      set(BOOST_STATIC_FILESYSTEM_LIBRARY ${Boost_FILESYSTEM_LIBRARY_RELEASE})
-    endif()
-  endif()
-endif()
-
-message(STATUS "Boost include dir: " ${Boost_INCLUDE_DIRS})
-message(STATUS "Boost libraries: " ${Boost_LIBRARIES})
-if (PARQUET_BOOST_USE_SHARED)
-  add_library(boost_shared_regex SHARED IMPORTED)
-  if (MSVC)
-    set_target_properties(boost_shared_regex
-                          PROPERTIES IMPORTED_IMPLIB "${BOOST_SHARED_REGEX_LIBRARY}")
-  else()
-    set_target_properties(boost_shared_regex
-                          PROPERTIES IMPORTED_LOCATION "${BOOST_SHARED_REGEX_LIBRARY}")
-  endif()
-  if (MSVC)
-    add_library(boost_shared_system SHARED IMPORTED)
-    set_target_properties(boost_shared_system
-                          PROPERTIES IMPORTED_IMPLIB "${BOOST_SHARED_SYSTEM_LIBRARY}")
-  endif()
-else()
-  add_library(boost_static_regex STATIC IMPORTED)
-  set_target_properties(boost_static_regex PROPERTIES IMPORTED_LOCATION ${BOOST_STATIC_REGEX_LIBRARY})
-  if (MSVC)
-    add_library(boost_static_system STATIC IMPORTED)
-    set_target_properties(boost_static_system PROPERTIES IMPORTED_LOCATION ${BOOST_STATIC_SYSTEM_LIBRARY})
-    add_library(boost_static_filesystem STATIC IMPORTED)
-    set_target_properties(boost_static_filesystem PROPERTIES IMPORTED_LOCATION ${BOOST_STATIC_FILESYSTEM_LIBRARY})
-  endif()
-endif()
-
-include_directories(SYSTEM ${Boost_INCLUDE_DIRS})
-set(LIBS ${LIBS} ${Boost_LIBRARIES})
-
-# ----------------------------------------------------------------------
-# ZLIB
-
-# ----------------------------------------------------------------------
-# Thrift
-
-# find thrift headers and libs
-find_package(Thrift)
-
-if (NOT THRIFT_FOUND)
-  set(ZLIB_PREFIX "${CMAKE_CURRENT_BINARY_DIR}/zlib_ep/src/zlib_ep-install")
-  set(ZLIB_HOME "${ZLIB_PREFIX}")
-  set(ZLIB_INCLUDE_DIR "${ZLIB_PREFIX}/include")
-  if (MSVC)
-    if (${UPPERCASE_BUILD_TYPE} STREQUAL "DEBUG")
-      set(ZLIB_STATIC_LIB_NAME zlibstaticd.lib)
-    else()
-      set(ZLIB_STATIC_LIB_NAME zlibstatic.lib)
-    endif()
-  else()
-    set(ZLIB_STATIC_LIB_NAME libz.a)
-  endif()
-  set(ZLIB_STATIC_LIB "${ZLIB_PREFIX}/lib/${ZLIB_STATIC_LIB_NAME}")
-  set(ZLIB_CMAKE_ARGS -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
-    -DCMAKE_INSTALL_PREFIX=${ZLIB_PREFIX}
-    -DCMAKE_C_FLAGS=${EP_C_FLAGS}
-    -DBUILD_SHARED_LIBS=OFF)
-  ExternalProject_Add(zlib_ep
-    URL "http://zlib.net/fossils/zlib-1.2.8.tar.gz"
-    BUILD_BYPRODUCTS "${ZLIB_STATIC_LIB}"
-    ${ZLIB_BUILD_BYPRODUCTS}
-    ${EP_LOG_OPTIONS}
-    CMAKE_ARGS ${ZLIB_CMAKE_ARGS})
-
-  set(THRIFT_PREFIX "${CMAKE_CURRENT_BINARY_DIR}/thrift_ep/src/thrift_ep-install")
-  set(THRIFT_HOME "${THRIFT_PREFIX}")
-  set(THRIFT_INCLUDE_DIR "${THRIFT_PREFIX}/include")
-  set(THRIFT_COMPILER "${THRIFT_PREFIX}/bin/thrift")
-  set(THRIFT_CMAKE_ARGS "-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}"
-                        "-DCMAKE_CXX_FLAGS=${EP_CXX_FLAGS}"
-                        "-DCMAKE_C_FLAGS=${EP_C_FLAGS}"
-                        "-DCMAKE_INSTALL_PREFIX=${THRIFT_PREFIX}"
-                        "-DCMAKE_INSTALL_RPATH=${THRIFT_PREFIX}/lib"
-                        "-DBUILD_SHARED_LIBS=OFF"
-                        "-DBUILD_TESTING=OFF"
-                        "-DBUILD_EXAMPLES=OFF"
-                        "-DBUILD_TUTORIALS=OFF"
-                        "-DWITH_QT4=OFF"
-                        "-DWITH_C_GLIB=OFF"
-                        "-DWITH_JAVA=OFF"
-                        "-DWITH_PYTHON=OFF"
-                        "-DWITH_HASKELL=OFF"
-                        "-DWITH_CPP=ON"
-                        "-DWITH_STATIC_LIB=ON"
-                        "-DWITH_LIBEVENT=OFF"
-                        )
-
-  # Thrift also uses boost. Forward important boost settings if there were ones passed.
-  if (DEFINED BOOST_ROOT)
-    set(THRIFT_CMAKE_ARGS ${THRIFT_CMAKE_ARGS} "-DBOOST_ROOT=${BOOST_ROOT}")
-  endif()
-  if (DEFINED Boost_NAMESPACE)
-    set(THRIFT_CMAKE_ARGS ${THRIFT_CMAKE_ARGS} "-DBoost_NAMESPACE=${Boost_NAMESPACE}")
-  endif()
-
-  set(THRIFT_STATIC_LIB_NAME "${CMAKE_STATIC_LIBRARY_PREFIX}thrift")
-  if (MSVC)
-    if (PARQUET_USE_STATIC_CRT)
-      set(THRIFT_STATIC_LIB_NAME "${THRIFT_STATIC_LIB_NAME}mt")
-      set(THRIFT_CMAKE_ARGS ${THRIFT_CMAKE_ARGS} "-DWITH_MT=ON")
-    else()
-      set(THRIFT_STATIC_LIB_NAME "${THRIFT_STATIC_LIB_NAME}md")
-      set(THRIFT_CMAKE_ARGS ${THRIFT_CMAKE_ARGS} "-DWITH_MT=OFF")
-    endif()
-  endif()
-  if (${UPPERCASE_BUILD_TYPE} STREQUAL "DEBUG")
-    set(THRIFT_STATIC_LIB_NAME "${THRIFT_STATIC_LIB_NAME}d")
-  endif()
-  set(THRIFT_STATIC_LIB "${THRIFT_PREFIX}/lib/${THRIFT_STATIC_LIB_NAME}${CMAKE_STATIC_LIBRARY_SUFFIX}")
-
-  if (MSVC)
-    set(WINFLEXBISON_VERSION 2.4.9)
-    set(WINFLEXBISON_PREFIX "${CMAKE_CURRENT_BINARY_DIR}/winflexbison_ep/src/winflexbison_ep-install")
-    ExternalProject_Add(winflexbison_ep
-      URL https://github.com/lexxmark/winflexbison/releases/download/v.${WINFLEXBISON_VERSION}/win_flex_bison-${WINFLEXBISON_VERSION}.zip
-      URL_HASH MD5=a2e979ea9928fbf8567e995e9c0df765
-      SOURCE_DIR ${WINFLEXBISON_PREFIX}
-      CONFIGURE_COMMAND ""
-      BUILD_COMMAND ""
-      INSTALL_COMMAND ""
-      ${EP_LOG_OPTIONS})
-    set(THRIFT_DEPENDENCIES ${THRIFT_DEPENDENCIES} winflexbison_ep)
-
-    set(THRIFT_CMAKE_ARGS "-DFLEX_EXECUTABLE=${WINFLEXBISON_PREFIX}/win_flex.exe"
-                          "-DBISON_EXECUTABLE=${WINFLEXBISON_PREFIX}/win_bison.exe"
-                          "-DZLIB_INCLUDE_DIR=${ZLIB_INCLUDE_DIR}"
-                          "-DZLIB_LIBRARY=${ZLIB_STATIC_LIB}"
-                          "-DWITH_SHARED_LIB=OFF"
-                          "-DWITH_PLUGIN=OFF"
-                          ${THRIFT_CMAKE_ARGS})
-    set(THRIFT_DEPENDENCIES ${THRIFT_DEPENDENCIES} zlib_ep)
-  elseif (APPLE)
-    if (DEFINED BISON_EXECUTABLE)
-      set(THRIFT_CMAKE_ARGS "-DBISON_EXECUTABLE=${BISON_EXECUTABLE}"
-                            ${THRIFT_CMAKE_ARGS})
-    endif()
-  endif()
-
-  ExternalProject_Add(thrift_ep
-    URL "http://archive.apache.org/dist/thrift/${THRIFT_VENDOR_VERSION}/thrift-${THRIFT_VENDOR_VERSION}.tar.gz"
-    BUILD_BYPRODUCTS "${THRIFT_STATIC_LIB}" "${THRIFT_COMPILER}"
-    CMAKE_ARGS ${THRIFT_CMAKE_ARGS}
-    DEPENDS ${THRIFT_DEPENDENCIES}
-    ${EP_LOG_OPTIONS})
-
-  set(THRIFT_VENDORED 1)
-else()
-  set(THRIFT_VENDORED 0)
-endif()
-
-include_directories(SYSTEM ${THRIFT_INCLUDE_DIR} ${THRIFT_INCLUDE_DIR}/thrift)
-message(STATUS "Thrift include dir: ${THRIFT_INCLUDE_DIR}")
-message(STATUS "Thrift static library: ${THRIFT_STATIC_LIB}")
-message(STATUS "Thrift compiler: ${THRIFT_COMPILER}")
-message(STATUS "Thrift version: ${THRIFT_VERSION}")
-add_library(thriftstatic STATIC IMPORTED)
-set_target_properties(thriftstatic PROPERTIES IMPORTED_LOCATION ${THRIFT_STATIC_LIB})
-
-if (THRIFT_VENDORED)
-  add_dependencies(thriftstatic thrift_ep)
-endif()
-
-if (PARQUET_THRIFT_USE_BOOST)
-  add_definitions(-DPARQUET_THRIFT_USE_BOOST)
-  message(STATUS "Using Boost in Thrift header")
-endif()
-
-## GTest
-if(PARQUET_BUILD_TESTS AND NOT IGNORE_OPTIONAL_PACKAGES)
-  add_custom_target(unittest ctest -L unittest)
-
-  if("$ENV{GTEST_HOME}" STREQUAL "")
-    if(APPLE)
-      set(GTEST_CMAKE_CXX_FLAGS "${EP_CXX_FLAGS} -DGTEST_USE_OWN_TR1_TUPLE=1 -Wno-unused-value -Wno-ignored-attributes")
-    elseif(MSVC)
-      # Workaround https://github.com/google/googletest/issues/1111 until
-      # a new gtest version is released
-      set(GTEST_CMAKE_CXX_FLAGS "${EP_CXX_FLAGS} -D_SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING")
-    else()
-      set(GTEST_CMAKE_CXX_FLAGS "${EP_CXX_FLAGS}")
-    endif()
-
-    set(GTEST_PREFIX "${CMAKE_CURRENT_BINARY_DIR}/googletest_ep-prefix/src/googletest_ep")
-    set(GTEST_INCLUDE_DIR "${GTEST_PREFIX}/include")
-    set(GTEST_STATIC_LIB
-      "${GTEST_PREFIX}/lib/${CMAKE_STATIC_LIBRARY_PREFIX}gtest${CMAKE_STATIC_LIBRARY_SUFFIX}")
-    set(GTEST_MAIN_STATIC_LIB
-      "${GTEST_PREFIX}/lib/${CMAKE_STATIC_LIBRARY_PREFIX}gtest_main${CMAKE_STATIC_LIBRARY_SUFFIX}")
-
-    set(GTEST_CMAKE_ARGS -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
-                         -DCMAKE_INSTALL_PREFIX=${GTEST_PREFIX}
-                         -DCMAKE_CXX_FLAGS=${GTEST_CMAKE_CXX_FLAGS})
-
-    if (MSVC AND NOT PARQUET_USE_STATIC_CRT)
-      set(GTEST_CMAKE_ARGS ${GTEST_CMAKE_ARGS} -Dgtest_force_shared_crt=ON)
-    endif()
-
-    ExternalProject_Add(googletest_ep
-      URL "https://github.com/google/googletest/archive/release-${GTEST_VERSION}.tar.gz"
-      BUILD_BYPRODUCTS "${GTEST_STATIC_LIB}" "${GTEST_MAIN_STATIC_LIB}"
-      CMAKE_ARGS ${GTEST_CMAKE_ARGS}
-      ${EP_LOG_OPTIONS})
-    set(GTEST_VENDORED 1)
-  else()
-    find_package(GTest REQUIRED)
-    set(GTEST_VENDORED 0)
-  endif()
-
-  message(STATUS "GTest include dir: ${GTEST_INCLUDE_DIR}")
-  message(STATUS "GTest static library: ${GTEST_STATIC_LIB}")
-  include_directories(SYSTEM ${GTEST_INCLUDE_DIR})
-
-  add_library(gtest STATIC IMPORTED)
-  set_target_properties(gtest PROPERTIES IMPORTED_LOCATION ${GTEST_STATIC_LIB})
-
-  add_library(gtest_main STATIC IMPORTED)
-  set_target_properties(gtest_main PROPERTIES IMPORTED_LOCATION
-    ${GTEST_MAIN_STATIC_LIB})
-
-  if(GTEST_VENDORED)
-    add_dependencies(gtest googletest_ep)
-    add_dependencies(gtest_main googletest_ep)
-  endif()
-endif()
-
-## Google Benchmark
-if ("$ENV{GBENCHMARK_HOME}" STREQUAL "")
-  set(GBENCHMARK_HOME ${THIRDPARTY_DIR}/installed)
-endif()
-
-if(PARQUET_BUILD_BENCHMARKS AND NOT IGNORE_OPTIONAL_PACKAGES)
-  add_custom_target(runbenchmark ctest -L benchmark)
-
-  if("$ENV{GBENCHMARK_HOME}" STREQUAL "")
-    set(GBENCHMARK_PREFIX "${CMAKE_CURRENT_BINARY_DIR}/gbenchmark_ep/src/gbenchmark_ep-install")
-    set(GBENCHMARK_INCLUDE_DIR "${GBENCHMARK_PREFIX}/include")
-    set(GBENCHMARK_STATIC_LIB "${GBENCHMARK_PREFIX}/lib/${CMAKE_STATIC_LIBRARY_PREFIX}benchmark${CMAKE_STATIC_LIBRARY_SUFFIX}")
-    set(GBENCHMARK_CMAKE_ARGS
-          "-DCMAKE_INSTALL_PREFIX:PATH=${GBENCHMARK_PREFIX}"
-          "-DBENCHMARK_ENABLE_TESTING=OFF"
-          "-DCMAKE_CXX_FLAGS=${EP_CXX_FLAGS}")
-    if (MSVC)
-      set(GBENCHMARK_CMAKE_ARGS ${GBENCHMARK_CMAKE_ARGS} "-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}")
-    else()
-      set(GBENCHMARK_CMAKE_ARGS ${GBENCHMARK_CMAKE_ARGS} "-DCMAKE_BUILD_TYPE=Release")
-    endif()
-    if (APPLE)
-      set(GBENCHMARK_CMAKE_ARGS ${GBENCHMARK_CMAKE_ARGS} "-DBENCHMARK_USE_LIBCXX=ON")
-    endif()
-
-    ExternalProject_Add(gbenchmark_ep
-      URL "https://github.com/google/benchmark/archive/v${GBENCHMARK_VERSION}.tar.gz"
-      BUILD_BYPRODUCTS "${GBENCHMARK_STATIC_LIB}"
-      CMAKE_ARGS ${GBENCHMARK_CMAKE_ARGS}
-      ${EP_LOG_OPTIONS})
-    set(GBENCHMARK_VENDORED 1)
-  else()
-    find_package(GBenchmark REQUIRED)
-    set(GBENCHMARK_VENDORED 0)
-  endif()
-
-  message(STATUS "GBenchmark include dir: ${GBENCHMARK_INCLUDE_DIR}")
-  message(STATUS "GBenchmark static library: ${GBENCHMARK_STATIC_LIB}")
-  include_directories(SYSTEM ${GBENCHMARK_INCLUDE_DIR})
-  add_library(gbenchmark STATIC IMPORTED)
-  set_target_properties(gbenchmark PROPERTIES IMPORTED_LOCATION ${GBENCHMARK_STATIC_LIB})
-
-  if(GBENCHMARK_VENDORED)
-    add_dependencies(gbenchmark gbenchmark_ep)
-  endif()
-endif()
-
-# ----------------------------------------------------------------------
-# Apache Arrow
-
-find_package(Arrow)
-if (NOT ARROW_FOUND)
-  include(ArrowExternalProject)
-  set(ARROW_VENDORED 1)
-else()
-  set(ARROW_VENDORED 0)
-endif()
-
-include_directories(SYSTEM ${ARROW_INCLUDE_DIR})
-add_library(arrow SHARED IMPORTED)
-if(MSVC)
-  set_target_properties(arrow
-                        PROPERTIES IMPORTED_IMPLIB "${ARROW_SHARED_IMPLIB}")
-else()
-  set_target_properties(arrow
-                        PROPERTIES IMPORTED_LOCATION "${ARROW_SHARED_LIB}")
-endif()
-add_library(arrow_static STATIC IMPORTED)
-set_target_properties(arrow_static PROPERTIES IMPORTED_LOCATION ${ARROW_STATIC_LIB})
-
-if (ARROW_VENDORED)
-  add_dependencies(arrow arrow_ep)
-  add_dependencies(arrow_static arrow_ep)
-endif()
diff --git a/cmake_modules/clean-all.cmake b/cmake_modules/clean-all.cmake
deleted file mode 100644
index 38e61da..0000000
--- a/cmake_modules/clean-all.cmake
+++ /dev/null
@@ -1,31 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you 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.
-
-set(cmake_generated ${CMAKE_BINARY_DIR}/CMakeCache.txt
-                    ${CMAKE_BINARY_DIR}/CTestTestfile.cmake
-                    ${CMAKE_BINARY_DIR}/cmake_install.cmake
-                    ${CMAKE_BINARY_DIR}/Makefile
-                    ${CMAKE_BINARY_DIR}/CMakeFiles
-)
-
-foreach(file ${cmake_generated})
-
-  if (EXISTS ${file})
-     file(REMOVE_RECURSE ${file})
-  endif()
-
-endforeach(file)
diff --git a/cmake_modules/parquet-cppConfig.cmake.in b/cmake_modules/parquet-cppConfig.cmake.in
deleted file mode 100644
index 47021d0..0000000
--- a/cmake_modules/parquet-cppConfig.cmake.in
+++ /dev/null
@@ -1,32 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you 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.
-
-set(PARQUET-CPP_VERSION x.y.z)
-
-@PACKAGE_INIT@
-
-set_and_check(PARQUET-CPP_INCLUDE_DIR "@PACKAGE_CMAKE_INSTALL_INCLUDEDIR@")
-set_and_check(PARQUET-CPP_LIB_DIR "@PACKAGE_CMAKE_INSTALL_LIBDIR@")
-
-set(_TMP_SUFFIX ${CMAKE_FIND_LIBRARY_SUFFIXES})
-FIND_LIBRARY(PARQUET_LIBRARY NAMES parquet PATHS ${PARQUET-CPP_LIB_DIR})
-set(PARQUET-CPP_LIBRARIES ${PARQUET_LIBRARY})
-
-set(CMAKE_FIND_LIBRARY_SUFFIXES ".a")
-FIND_LIBRARY(PARQUET_STATIC_LIBRARY NAMES parquet PATHS ${PARQUET-CPP_LIB_DIR})
-set(PARQUET-CPP_STATIC_LIBRARIES ${PARQUET_STATIC_LIBRARY})
-set(CMAKE_FIND_LIBRARY_SUFFIXES ${_TMP_SUFFIX})
diff --git a/data/alltypes_dictionary.parquet b/data/alltypes_dictionary.parquet
deleted file mode 100755
index e6da6ab..0000000
--- a/data/alltypes_dictionary.parquet
+++ /dev/null
Binary files differ
diff --git a/data/alltypes_plain.parquet b/data/alltypes_plain.parquet
deleted file mode 100755
index a63f5dc..0000000
--- a/data/alltypes_plain.parquet
+++ /dev/null
Binary files differ
diff --git a/data/alltypes_plain.snappy.parquet b/data/alltypes_plain.snappy.parquet
deleted file mode 100755
index 9809d67..0000000
--- a/data/alltypes_plain.snappy.parquet
+++ /dev/null
Binary files differ
diff --git a/data/bloom_filter.bin b/data/bloom_filter.bin
deleted file mode 100644
index c0e30ce..0000000
--- a/data/bloom_filter.bin
+++ /dev/null
Binary files differ
diff --git a/data/fixed_length_decimal.parquet b/data/fixed_length_decimal.parquet
deleted file mode 100644
index 69fce53..0000000
--- a/data/fixed_length_decimal.parquet
+++ /dev/null
Binary files differ
diff --git a/data/fixed_length_decimal_legacy.parquet b/data/fixed_length_decimal_legacy.parquet
deleted file mode 100644
index b0df62a..0000000
--- a/data/fixed_length_decimal_legacy.parquet
+++ /dev/null
Binary files differ
diff --git a/data/int32_decimal.parquet b/data/int32_decimal.parquet
deleted file mode 100644
index 5bf2d4e..0000000
--- a/data/int32_decimal.parquet
+++ /dev/null
Binary files differ
diff --git a/data/int64_decimal.parquet b/data/int64_decimal.parquet
deleted file mode 100644
index 5043bca..0000000
--- a/data/int64_decimal.parquet
+++ /dev/null
Binary files differ
diff --git a/data/nation.dict-malformed.parquet b/data/nation.dict-malformed.parquet
deleted file mode 100644
index 5008ac0..0000000
--- a/data/nation.dict-malformed.parquet
+++ /dev/null
Binary files differ
diff --git a/dev/README.md b/dev/README.md
deleted file mode 100644
index d567672..0000000
--- a/dev/README.md
+++ /dev/null
@@ -1,88 +0,0 @@
-<!---
-  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. See accompanying LICENSE file.
--->
-
-# Parquet Developer Scripts
-This directory contains scripts useful to developers when packaging,
-testing, or committing to Parquet.
-
-Merging a pull request requires being a committer on the project.
-
-* How to merge a Pull request:
-have an apache and apache-github remote setup
-```
-git remote add apache-github https://github.com/apache/parquet-cpp.git
-git remote add apache git@github.com:apache/parquet-cpp.git
-```
-run the following command
-```
-dev/merge_parquet_pr.py
-```
-
-Note:
-* The parent directory of your parquet repository must be called parquet-cpp
-* Without jira-python installed you'll have to close the JIRA manually
-
-example output:
-```
-Which pull request would you like to merge? (e.g. 34):
-```
-Type the pull request number (from https://github.com/apache/parquet-cpp/pulls) and hit enter.
-```
-=== Pull Request #X ===
-title	Blah Blah Blah
-source	repo/branch
-target	master
-url	https://api.github.com/repos/apache/parquet-cpp/pulls/X
-
-Proceed with merging pull request #3? (y/n): 
-```
-If this looks good, type y and hit enter.
-```
-From git-wip-us.apache.org:/repos/asf/parquet-cpp.git
- * [new branch]      master     -> PR_TOOL_MERGE_PR_3_MASTER
-Switched to branch 'PR_TOOL_MERGE_PR_3_MASTER'
-
-Merge complete (local ref PR_TOOL_MERGE_PR_3_MASTER). Push to apache? (y/n):
-```
-A local branch with the merge has been created.
-type y and hit enter to push it to apache master
-```
-Counting objects: 67, done.
-Delta compression using up to 4 threads.
-Compressing objects: 100% (26/26), done.
-Writing objects: 100% (36/36), 5.32 KiB, done.
-Total 36 (delta 17), reused 0 (delta 0)
-To git-wip-us.apache.org:/repos/asf/parquet-cpp.git
-   b767ac4..485658a  PR_TOOL_MERGE_PR_X_MASTER -> master
-Restoring head pointer to b767ac4e
-Note: checking out 'b767ac4e'.
-
-You are in 'detached HEAD' state. You can look around, make experimental
-changes and commit them, and you can discard any commits you make in this
-state without impacting any branches by performing another checkout.
-
-If you want to create a new branch to retain commits you create, you may
-do so (now or later) by using -b with the checkout command again. Example:
-
-  git checkout -b new_branch_name
-
-HEAD is now at b767ac4... Update README.md
-Deleting local branch PR_TOOL_MERGE_PR_X
-Deleting local branch PR_TOOL_MERGE_PR_X_MASTER
-Pull request #X merged!
-Merge hash: 485658a5
-
-Would you like to pick 485658a5 into another branch? (y/n):
-```
-For now just say n as we have 1 branch
diff --git a/dev/committers-guide.md b/dev/committers-guide.md
deleted file mode 100644
index f3fddfd..0000000
--- a/dev/committers-guide.md
+++ /dev/null
@@ -1,118 +0,0 @@
-<!---
-  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. See accompanying LICENSE file.
-
-  Original imported from Apache Aurora.
--->
-
-Committer's Guide
-=================
-
-Information for official Apache Parquet committers.
-
-Setting up your email account
------------------------------
-Once your Apache ID has been set up you can configure your account and add ssh keys and setup an
-email forwarding address at
-
-    http://id.apache.org
-
-Additional instructions for setting up your new committer email can be found at
-
-    http://www.apache.org/dev/user-email.html
-
-The recommended setup is to configure all services (mailing lists, JIRA) to send
-emails to your @apache.org email address.
-
-
-Creating a gpg key for releases
--------------------------------
-In order to create a release candidate you will need a gpg key published to an external key server
-and that key will need to be added to our KEYS file as well.
-
-1. Create a key:
-
-               gpg --gen-key
-
-2. Add your gpg key to the Apache Parquet {format,mr,cpp} KEYS file:
-
-               git clone git@github.com:apache/parquet-cpp.git
-               (gpg --list-sigs <KEY ID> && gpg --armor --export <KEY ID>) >> KEYS
-               git add KEYS && git commit -m "Adding gpg key for <APACHE ID>"
-               ./rbt post -o -g
-
-3. Publish the key to an external key server:
-
-               gpg --keyserver pgp.mit.edu --send-keys <KEY ID>
-
-4. Update the changes to the KEYS file to the Apache Parquet svn dist locations listed below:
-
-               https://dist.apache.org/repos/dist/dev/parquet/KEYS
-               https://dist.apache.org/repos/dist/release/parquet/KEYS
-
-5. Add your key to git config for use with the release scripts:
-
-               git config --global user.signingkey <KEY ID>
-
-
-Creating a release
-------------------
-The following will guide you through the steps to create a release candidate, vote, and finally an
-official Apache Parquet C++ release. Before starting your gpg key should be in the KEYS file and you
-must have access to commit to the dist.a.o repositories.
-
-1. Ensure that all issues resolved for this release candidate are tagged with the correct Fix
-Version in JIRA, the changelog script will use this to generate the CHANGELOG in step #2.
-To assign the fix version:
-
-    * Look up the [previous release date](https://issues.apache.org/jira/browse/parquet/?selectedTab=com.atlassian.jira.jira-projects-plugin:versions-panel).
-    * Query all issues resolved after that release date: `project = PARQUET AND status in (resolved, Closed) and fixVersion is empty and resolutiondate >= "YYYY/MM/DD"`
-    * In the upper right corner of the query result, select Tools > Bulk Edit.
-    * Select all issues > edit issue > set 'Change Fix Version/s' to the release version.
-    * Make sure to uncheck 'Send mail for this update' at the bottom.
-
-2. Prepare RELEASE-NOTES.md for the release. This just boils down to removing the "(Not yet
-released)" suffix from the impending release.
-
-2. Create a release candidate. This will automatically update the CHANGELOG and commit it, create a
-branch and update the current version within the trunk. To create a minor version update and publish
-it run
-
-               ./dev/release/release-candidate -l m -p
-
-3. Update, if necessary, the draft email created from the `release-candidate` script in step #2 and
-send the [VOTE] email to the dev@ mailing list. You can verify the release signature and checksums
-by running
-
-               ./dev/release/verify-release-candidate
-
-4. Wait for the vote to complete. If the vote fails close the vote by replying to the initial [VOTE]
-email sent in step #3 by editing the subject to [RESULT][VOTE] ... and noting the failure reason
-(example [here](http://markmail.org/message/d4d6xtvj7vgwi76f)). You'll also need to manually revert
-the commits generated by the release candidate script that incremented the snapshot version and
-updated the changelog. Once that is done, now address any issues and go back to step #1 and run
-again, this time you will use the -r flag to increment the release candidate version. This will
-automatically clean up the release candidate rc0 branch and source distribution.
-
-               ./dev/release/release-candidate -l m -r 1 -p
-
-5. Once the vote has successfully passed create the release
-
-**IMPORTANT: make sure to use the correct release at this final step (e.g.: `-r 1` if rc1 candidate
-has been voted for). Once the release tag is pushed it will be very hard to undo due to remote
-git pre-receive hook explicitly forbidding release tag manipulations.**
-
-               ./dev/release/release
-
-6. Update the draft email created fom the `release` script in step #5 to include the Apache ID's for
-all binding votes and send the [RESULT][VOTE] email to the dev@ mailing list.
-
diff --git a/dev/merge_parquet_pr.py b/dev/merge_parquet_pr.py
deleted file mode 100755
index dcb7af6..0000000
--- a/dev/merge_parquet_pr.py
+++ /dev/null
@@ -1,354 +0,0 @@
-#!/usr/bin/env python
-
-#
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-#
-
-# Utility for creating well-formed pull request merges and pushing them to Apache.
-#   usage: ./apache-pr-merge.py    (see config env vars below)
-#
-# This utility assumes you already have local a Parquet git folder and that you
-# have added remotes corresponding to both (i) the github apache Parquet
-# mirror and (ii) the apache git repo.
-
-import json
-import os
-import re
-import subprocess
-import sys
-import tempfile
-import urllib2
-import getpass
-
-try:
-    import jira.client
-    JIRA_IMPORTED = True
-except ImportError:
-    JIRA_IMPORTED = False
-
-# Location of your Parquet git development area
-PARQUET_HOME = os.path.abspath(__file__).rsplit("/", 2)[0]
-PROJECT_NAME = PARQUET_HOME.rsplit("/", 1)[1]
-print "PARQUET_HOME = " + PARQUET_HOME
-print "PROJECT_NAME = " + PROJECT_NAME
-
-# Remote name which points to the Gihub site
-PR_REMOTE_NAME = os.environ.get("PR_REMOTE_NAME", "apache-github")
-# Remote name which points to Apache git
-PUSH_REMOTE_NAME = os.environ.get("PUSH_REMOTE_NAME", "apache")
-# ASF JIRA username
-JIRA_USERNAME = os.environ.get("JIRA_USERNAME")
-# ASF JIRA password
-JIRA_PASSWORD = os.environ.get("JIRA_PASSWORD")
-
-GITHUB_BASE = "https://github.com/apache/" + PROJECT_NAME + "/pull"
-GITHUB_API_BASE = "https://api.github.com/repos/apache/" + PROJECT_NAME
-JIRA_BASE = "https://issues.apache.org/jira/browse"
-JIRA_API_BASE = "https://issues.apache.org/jira"
-# Prefix added to temporary branches
-BRANCH_PREFIX = "PR_TOOL"
-
-os.chdir(PARQUET_HOME)
-
-
-def get_json(url):
-    try:
-        return json.load(urllib2.urlopen(url))
-    except urllib2.HTTPError as e:
-        print "Unable to fetch URL, exiting: %s" % url
-        sys.exit(-1)
-
-
-def fail(msg):
-    print msg
-    clean_up()
-    sys.exit(-1)
-
-
-def run_cmd(cmd):
-    if isinstance(cmd, list):
-        return subprocess.check_output(cmd)
-    else:
-        return subprocess.check_output(cmd.split(" "))
-
-
-def continue_maybe(prompt):
-    result = raw_input("\n%s (y/n): " % prompt)
-    if result.lower() != "y":
-        fail("Okay, exiting")
-
-
-original_head = run_cmd("git rev-parse HEAD")[:8]
-
-
-def clean_up():
-    print "Restoring head pointer to %s" % original_head
-    run_cmd("git checkout %s" % original_head)
-
-    branches = run_cmd("git branch").replace(" ", "").split("\n")
-
-    for branch in filter(lambda x: x.startswith(BRANCH_PREFIX), branches):
-        print "Deleting local branch %s" % branch
-        run_cmd("git branch -D %s" % branch)
-
-
-# merge the requested PR and return the merge hash
-def merge_pr(pr_num, target_ref):
-    pr_branch_name = "%s_MERGE_PR_%s" % (BRANCH_PREFIX, pr_num)
-    target_branch_name = "%s_MERGE_PR_%s_%s" % (BRANCH_PREFIX, pr_num, target_ref.upper())
-    run_cmd("git fetch %s pull/%s/head:%s" % (PR_REMOTE_NAME, pr_num, pr_branch_name))
-    run_cmd("git fetch %s %s:%s" % (PUSH_REMOTE_NAME, target_ref, target_branch_name))
-    run_cmd("git checkout %s" % target_branch_name)
-
-    had_conflicts = False
-    try:
-        run_cmd(['git', 'merge', pr_branch_name, '--squash'])
-    except Exception as e:
-        msg = "Error merging: %s\nWould you like to manually fix-up this merge?" % e
-        continue_maybe(msg)
-        msg = "Okay, please fix any conflicts and 'git add' conflicting files... Finished?"
-        continue_maybe(msg)
-        had_conflicts = True
-
-    commit_authors = run_cmd(['git', 'log', 'HEAD..%s' % pr_branch_name,
-                             '--pretty=format:%an <%ae>']).split("\n")
-    distinct_authors = sorted(set(commit_authors),
-                              key=lambda x: commit_authors.count(x), reverse=True)
-    primary_author = distinct_authors[0]
-    commits = run_cmd(['git', 'log', 'HEAD..%s' % pr_branch_name,
-                      '--pretty=format:%h [%an] %s']).split("\n\n")
-
-    merge_message_flags = []
-
-    merge_message_flags += ["-m", title]
-    if body != None:
-        merge_message_flags += ["-m", body]
-
-    authors = "\n".join(["Author: %s" % a for a in distinct_authors])
-
-    merge_message_flags += ["-m", authors]
-
-    if had_conflicts:
-        committer_name = run_cmd("git config --get user.name").strip()
-        committer_email = run_cmd("git config --get user.email").strip()
-        message = "This patch had conflicts when merged, resolved by\nCommitter: %s <%s>" % (
-            committer_name, committer_email)
-        merge_message_flags += ["-m", message]
-
-    # The string "Closes #%s" string is required for GitHub to correctly close the PR
-    merge_message_flags += [
-        "-m",
-        "Closes #%s from %s and squashes the following commits:" % (pr_num, pr_repo_desc)]
-    for c in commits:
-        merge_message_flags += ["-m", c]
-
-    run_cmd(['git', 'commit', '--author="%s"' % primary_author] + merge_message_flags)
-
-    continue_maybe("Merge complete (local ref %s). Push to %s?" % (
-        target_branch_name, PUSH_REMOTE_NAME))
-
-    try:
-        run_cmd('git push %s %s:%s' % (PUSH_REMOTE_NAME, target_branch_name, target_ref))
-    except Exception as e:
-        clean_up()
-        fail("Exception while pushing: %s" % e)
-
-    merge_hash = run_cmd("git rev-parse %s" % target_branch_name)[:8]
-    clean_up()
-    print("Pull request #%s merged!" % pr_num)
-    print("Merge hash: %s" % merge_hash)
-    return merge_hash
-
-
-def cherry_pick(pr_num, merge_hash, default_branch):
-    pick_ref = raw_input("Enter a branch name [%s]: " % default_branch)
-    if pick_ref == "":
-        pick_ref = default_branch
-
-    pick_branch_name = "%s_PICK_PR_%s_%s" % (BRANCH_PREFIX, pr_num, pick_ref.upper())
-
-    run_cmd("git fetch %s %s:%s" % (PUSH_REMOTE_NAME, pick_ref, pick_branch_name))
-    run_cmd("git checkout %s" % pick_branch_name)
-    run_cmd("git cherry-pick -sx %s" % merge_hash)
-
-    continue_maybe("Pick complete (local ref %s). Push to %s?" % (
-        pick_branch_name, PUSH_REMOTE_NAME))
-
-    try:
-        run_cmd('git push %s %s:%s' % (PUSH_REMOTE_NAME, pick_branch_name, pick_ref))
-    except Exception as e:
-        clean_up()
-        fail("Exception while pushing: %s" % e)
-
-    pick_hash = run_cmd("git rev-parse %s" % pick_branch_name)[:8]
-    clean_up()
-
-    print("Pull request #%s picked into %s!" % (pr_num, pick_ref))
-    print("Pick hash: %s" % pick_hash)
-    return pick_ref
-
-
-def fix_version_from_branch(branch, versions):
-    # Note: Assumes this is a sorted (newest->oldest) list of un-released versions
-    if branch == "master":
-        return versions[0]
-    else:
-        branch_ver = branch.replace("branch-", "")
-        return filter(lambda x: x.name.startswith(branch_ver), versions)[-1]
-
-def exctract_jira_id(title):
-    m = re.search('^(PARQUET-[0-9]+):.*$', title)
-    if m and m.groups > 0:
-        return m.group(1)
-    else:
-        fail("PR title should be prefixed by a jira id \"PARQUET-XXX: ...\", found: \"%s\"" % title)
-
-def check_jira(title):
-    jira_id = exctract_jira_id(title)
-    asf_jira = jira.client.JIRA({'server': JIRA_API_BASE},
-                                basic_auth=(JIRA_USERNAME, JIRA_PASSWORD))
-    try:
-        issue = asf_jira.issue(jira_id)
-    except Exception as e:
-        fail("ASF JIRA could not find %s\n%s" % (jira_id, e))
-
-def resolve_jira(title, merge_branches, comment):
-    asf_jira = jira.client.JIRA({'server': JIRA_API_BASE},
-                                basic_auth=(JIRA_USERNAME, JIRA_PASSWORD))
-
-    default_jira_id = exctract_jira_id(title)
-
-    jira_id = raw_input("Enter a JIRA id [%s]: " % default_jira_id)
-    if jira_id == "":
-        jira_id = default_jira_id
-
-    try:
-        issue = asf_jira.issue(jira_id)
-    except Exception as e:
-        fail("ASF JIRA could not find %s\n%s" % (jira_id, e))
-
-    cur_status = issue.fields.status.name
-    cur_summary = issue.fields.summary
-    cur_assignee = issue.fields.assignee
-    if cur_assignee is None:
-        cur_assignee = "NOT ASSIGNED!!!"
-    else:
-        cur_assignee = cur_assignee.displayName
-
-    if cur_status == "Resolved" or cur_status == "Closed":
-        fail("JIRA issue %s already has status '%s'" % (jira_id, cur_status))
-    print ("=== JIRA %s ===" % jira_id)
-    print ("summary\t\t%s\nassignee\t%s\nstatus\t\t%s\nurl\t\t%s/%s\n" % (
-        cur_summary, cur_assignee, cur_status, JIRA_BASE, jira_id))
-
-    versions = asf_jira.project_versions("PARQUET")
-    versions = sorted(versions, key=lambda x: x.name, reverse=True)
-    versions = filter(lambda x: x.raw['released'] is False, versions)
-
-    default_fix_versions = map(lambda x: fix_version_from_branch(x, versions).name, merge_branches)
-    for v in default_fix_versions:
-        # Handles the case where we have forked a release branch but not yet made the release.
-        # In this case, if the PR is committed to the master branch and the release branch, we
-        # only consider the release branch to be the fix version. E.g. it is not valid to have
-        # both 1.1.0 and 1.0.0 as fix versions.
-        (major, minor, patch) = v.split(".")
-        if patch == "0":
-            previous = "%s.%s.%s" % (major, int(minor) - 1, 0)
-            if previous in default_fix_versions:
-                default_fix_versions = filter(lambda x: x != v, default_fix_versions)
-    default_fix_versions = ",".join(default_fix_versions)
-
-    fix_versions = raw_input("Enter comma-separated fix version(s) [%s]: " % default_fix_versions)
-    if fix_versions == "":
-        fix_versions = default_fix_versions
-    fix_versions = fix_versions.replace(" ", "").split(",")
-
-    def get_version_json(version_str):
-        return filter(lambda v: v.name == version_str, versions)[0].raw
-
-    jira_fix_versions = map(lambda v: get_version_json(v), fix_versions)
-
-    resolve = filter(lambda a: a['name'] == "Resolve Issue", asf_jira.transitions(jira_id))[0]
-    asf_jira.transition_issue(
-        jira_id, resolve["id"], fixVersions=jira_fix_versions, comment=comment)
-
-    print "Succesfully resolved %s with fixVersions=%s!" % (jira_id, fix_versions)
-
-
-if not JIRA_USERNAME:
-    JIRA_USERNAME =  raw_input("Env JIRA_USERNAME not set, please enter your JIRA username:")
-
-if not JIRA_PASSWORD:
-    JIRA_PASSWORD =  getpass.getpass("Env JIRA_PASSWORD not set, please enter your JIRA password:")
-
-branches = get_json("%s/branches" % GITHUB_API_BASE)
-branch_names = filter(lambda x: x.startswith("branch-"), [x['name'] for x in branches])
-# Assumes branch names can be sorted lexicographically
-# Julien: I commented this out as we don't have any "branch-*" branch yet
-#latest_branch = sorted(branch_names, reverse=True)[0]
-
-pr_num = raw_input("Which pull request would you like to merge? (e.g. 34): ")
-pr = get_json("%s/pulls/%s" % (GITHUB_API_BASE, pr_num))
-
-url = pr["url"]
-title = pr["title"]
-check_jira(title)
-body = pr["body"]
-target_ref = pr["base"]["ref"]
-user_login = pr["user"]["login"]
-base_ref = pr["head"]["ref"]
-pr_repo_desc = "%s/%s" % (user_login, base_ref)
-
-if pr["merged"] is True:
-    print "Pull request %s has already been merged, assuming you want to backport" % pr_num
-    merge_commit_desc = run_cmd([
-        'git', 'log', '--merges', '--first-parent',
-        '--grep=pull request #%s' % pr_num, '--oneline']).split("\n")[0]
-    if merge_commit_desc == "":
-        fail("Couldn't find any merge commit for #%s, you may need to update HEAD." % pr_num)
-
-    merge_hash = merge_commit_desc[:7]
-    message = merge_commit_desc[8:]
-
-    print "Found: %s" % message
-    maybe_cherry_pick(pr_num, merge_hash, latest_branch)
-    sys.exit(0)
-
-if not bool(pr["mergeable"]):
-    msg = "Pull request %s is not mergeable in its current form.\n" % pr_num + \
-        "Continue? (experts only!)"
-    continue_maybe(msg)
-
-print ("\n=== Pull Request #%s ===" % pr_num)
-print ("title\t%s\nsource\t%s\ntarget\t%s\nurl\t%s" % (
-    title, pr_repo_desc, target_ref, url))
-continue_maybe("Proceed with merging pull request #%s?" % pr_num)
-
-merged_refs = [target_ref]
-
-merge_hash = merge_pr(pr_num, target_ref)
-
-pick_prompt = "Would you like to pick %s into another branch?" % merge_hash
-while raw_input("\n%s (y/n): " % pick_prompt).lower() == "y":
-    merged_refs = merged_refs + [cherry_pick(pr_num, merge_hash, latest_branch)]
-
-if JIRA_IMPORTED:
-    continue_maybe("Would you like to update the associated JIRA?")
-    jira_comment = "Issue resolved by pull request %s\n[%s/%s]" % (pr_num, GITHUB_BASE, pr_num)
-    resolve_jira(title, merged_refs, jira_comment)
-else:
-    print "Could not find jira-python library. Run 'sudo pip install jira-python' to install."
-    print "Exiting without trying to close the associated JIRA."
diff --git a/dev/release/README.md b/dev/release/README.md
deleted file mode 100644
index 142ab64..0000000
--- a/dev/release/README.md
+++ /dev/null
@@ -1,30 +0,0 @@
-<!---
-  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. See accompanying LICENSE file.
--->
-
-
-How to release
-==============
-
-1. Do a fresh `git clone` of the repository using the ASF git as origin.
-2. Set the git author to your gpg signing key using `git config --local user.email "<mail>"`.
-3. Create an RC using `./dev/release/release-candidate -r <rcNum> -v <version>` starting with `rcNum=0`.
-   You could first do a dry-run by adding `-p` at the end.
-4. Check that the uploaded RC is valid using `./dev/release/verify-release-candidate <version> <rcNum>`.
-5. Send the generated mail to dev@parquet.apache.org.
-6. Wait for the vote to end, either proceed to the next step or abort the RC and continue with the
-   necessary fixes.
-7. In the release SVN, copy the contents of the RC folder into the release folder.
-8. Delete the previous `parquet-cpp` release from SVN.
-9. Cherry-pick the commits in the `master-after-X` branch into master.
-10. Send out the release mail to `dev@parquet.apache.org` and `announce@apache.org`.
diff --git a/dev/release/changelog b/dev/release/changelog
deleted file mode 100755
index d6ed9f2..0000000
--- a/dev/release/changelog
+++ /dev/null
@@ -1,155 +0,0 @@
-#!/usr/bin/env ruby
-#
-# 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.
-#
-# Updates the CHANGELOG for the specified Apache Parquet C++ release, if no
-# version override is specified then .parquetcppversion will be read and used.
-# The version string will need to match the Apache Parquet C++ jira tickets
-# fixVersion to generate this list.
-#
-require 'rubygems'
-require 'json'
-require 'uri'
-require 'net/http'
-require 'net/https'
-require 'openssl'
-require 'tempfile'
-
-def http_post(uri, params={}, headers={}, body=nil, debug=false)
-  http = Net::HTTP.new(uri.host, uri.port)
-  http.set_debug_output($stdout) if debug
-  if uri.scheme == "https" || uri.port == 443
-    http.use_ssl = true
-    http.verify_mode = OpenSSL::SSL::VERIFY_NONE
-  end
-  response = nil
-
-  begin
-    request = Net::HTTP::Post.new(uri.request_uri)
-    request.set_form_data(params) if (params && params.size > 1)
-    request.basic_auth uri.user, uri.password if uri.user
-    request.body = body if body
-
-    headers.each_pair do |name, value|
-      request[name] = value
-    end
-
-    response = http.request(request)
-  rescue Exception => e
-    raise "Error posting to #{uri.to_s}. #{e}"
-  end
-
-  response
-end
-
-def get_jira_issues_for_query(url, jql, startAt=0, maxResults=100)
-  puts(jql)
-  begin
-    request_body = { :jql => jql, :startAt => startAt, :maxResults => maxResults}
-    response = http_post(
-      URI(url),
-      {},
-      {"content-type" => 'application/json', "accept" => "application/json"},
-      request_body.to_json
-    )
-  rescue StandardError => e
-    raise "Error executing jql query: #{jql}. #{e}"
-  end
-
-  begin
-    results = JSON.parse(response.body)
-  rescue StandardError => e
-    raise "Error parsing json result"
-  end
-
-  results
-end
-
-def get_all_jira_issues_for_query(url, jql)
-  startAt = 0
-  maxResults = 100
-
-  results = []
-  begin
-    res = get_jira_issues_for_query(url, jql, startAt, maxResults)
-    results.concat(res['issues']) if res && res.has_key?('issues')
-    startAt = startAt + maxResults
-  end until (results.size() == res['total'] )
-
-  results
-end
-
-base_dir = `git rev-parse --show-toplevel`.strip
-
-# Get the current version from the .parquetcppversion file if no version override is provided
-version = nil
-if ARGV[0].nil?
-  version = nil
-  Dir.chdir(base_dir) do
-    version = File.read('.parquetcppversion').strip
-  end
-else
-  version = ARGV[0]
-end
-
-raise "Unable to read .parquetcppversion" if version.nil?
-
-jira_base_url = "https://issues.apache.org/jira"
-jira_search_url = "/rest/api/2/search"
-jira_url = jira_base_url + jira_search_url
-
-jql="project=PARQUET " \
-    "AND fixVersion='cpp-#{version}' " \
-    "AND status = Resolved " \
-    "AND resolution in (Fixed, Done) " \
-    "ORDER BY issuetype DESC"
-
-# Fetch all the issues available for the given jql query
-results = get_all_jira_issues_for_query(jira_url, jql)
-
-changelog = {}
-# Loop through and add all results
-results.each do |issue|
-  key = issue['key']
-  summary = issue['fields']['summary']
-  type = issue['fields']['issuetype']['name']
-
-  changelog_entry = "[#{key}] - #{summary}"
-
-  if !changelog[type].nil?
-    changelog[type] << changelog_entry
-  else
-    changelog[type] = [changelog_entry]
-  end
-end
-
-# Merge the new updates and the existing changelog
-tmpfile = Tempfile.open('parquet-cpp.changelog')
-begin
-  tmpfile.puts "Parquet C++ #{version}", "-" * 80
-  changelog.keys.sort.each do |type|
-    tmpfile.puts "## #{type}"
-    changelog[type].each { |entry| tmpfile.puts "    * #{entry}" }
-    tmpfile.puts ""
-  end
-  # Append all the existing CHANGELOG entries and write the new CHANGELOG file
-  tmpfile.puts ""
-  changelog_file = File.join(base_dir, 'CHANGELOG')
-  tmpfile.write File.read(changelog_file) if File.exist?(changelog_file)
-  tmpfile.rewind
-  tmpfile.flush
-  File.open(changelog_file,"w+") {|f|  f.write(tmpfile.read) }
-ensure
-  tmpfile.close
-  tmpfile.unlink
-end
diff --git a/dev/release/release-candidate b/dev/release/release-candidate
deleted file mode 100755
index 88aa27a..0000000
--- a/dev/release/release-candidate
+++ /dev/null
@@ -1,316 +0,0 @@
-#!/bin/bash
-#
-# 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.
-#
-#
-# This script is used to create a release candidate. It will update the current
-# .parquetcppversion as well as creates a tag for the new release candidate and
-# publishes the source distribution and signatures to be voted on.
-#
-#   master~1 (0.5.0-snapshot) ----- master (0.6.0-snapshot)
-#                             \---- 0.5.0 (0.5.0)
-#
-# A email template will be generated after successfully generating a release
-# candidate which will need to be sent to the dev@ and private@ mailing lists.
-#
-set -o errexit
-set -o nounset
-
-rc_number=0
-override_version=''
-parquetcpp_git_web_url='https://gitbox.apache.org/repos/asf?p=parquet-cpp.git'
-parquet_svn_dist_url='https://dist.apache.org/repos/dist/dev/parquet'
-
-function print_help_and_exit {
-cat <<EOF
-Apache Parquet C++ release candidate tool.
-
-Usage: $0 [-h] [-l p|m|M] [-r #] [-p | publish]
-
-  -h  Print this help message and exit
-  -l  Increment level, must be one of:
-        p, patch (default)
-        m, minor
-        M, major
-  -v  Override the existing version in .parquetcppversion
-  -r  Release candidate number (default: 0)
-  -p  Publish the release candidate (default: dry-run, does not publish anything)
-EOF
-exit 0
-}
-
-publish=0
-increment_level="patch"
-rc_number=0
-while getopts ":hl:v:r:p" opt; do
-  case $opt in
-    l)
-      case ${OPTARG} in
-        'p' | 'patch') increment_level='patch' ;;
-        'm' | 'minor') increment_level='minor' ;;
-        'M' | 'major') increment_level='major' ;;
-         *) echo 'Unknown increment level'; exit 1 ;;
-      esac
-      ;;
-    r)
-      rc_number=${OPTARG}
-      ;;
-    p)
-      publish=1
-      ;;
-    h)
-      print_help_and_exit
-      ;;
-    v)
-      override_version=${OPTARG}
-      ;;
-    *  )
-      echo "Unknown option: -$OPTARG"
-      print_help_and_exit
-      ;;
-  esac
-done
-
-shift $(($OPTIND - 1))
-if [[ "${1:-dry-run}" == "publish" ]]; then
-  publish=1
-fi
-
-# Update local repository
-git fetch --all -q
-git fetch --tags -q
-
-# Verify that this is a clean repository
-if [[ -n "`git status --porcelain`" ]]; then
-  echo "ERROR: Please run from a clean git repository."
-  exit 1
-elif [[ "`git rev-parse --abbrev-ref HEAD`" != "master" ]]; then
-  echo "ERROR: This script must be run from master."
-  exit 1
-fi
-
-if [[ ! -f .parquetcppversion ]]; then
-  echo "Warrning: This script must be run from the root of the repository"
-  exit 1
-fi
-
-# Calculate the new version string
-current_version=$(cat .parquetcppversion | tr '[a-z]' '[A-Z]')
-if ! [[ $current_version =~ .*-SNAPSHOT ]]; then
-  echo "ERROR: .parquetcppversion is required to contain 'SNAPSHOT', it is ${current_version}"
-  exit 1
-else
-  if [[ $override_version != "" ]]; then
-    current_version=$override_version
-  fi
-
-  major=`echo $current_version | cut -d. -f1`
-  minor=`echo $current_version | cut -d. -f2`
-  patch=`echo $current_version | cut -d. -f3 | cut -d- -f1`
-
-  current_version="${major}.${minor}.${patch}"
-
-  if [[ $increment_level == "patch" ]]; then
-    new_master_version="${major}.${minor}.$((patch + 1))"
-  elif [[ $increment_level == "minor" ]]; then
-    new_master_version="${major}.$((minor + 1)).0"
-  elif [[ $increment_level == "major" ]]; then
-    new_master_version="$((major + 1)).0.0"
-  else
-    echo "Unknown release increment ${increment_level}"
-    exit 1
-  fi
-
-  new_snapshot_version="${new_master_version}-SNAPSHOT"
-fi
-
-# Add the rc tag to the current version
-rc_version="${current_version}-rc${rc_number}"
-version_tag="apache-parquet-cpp-${current_version}"
-rc_version_tag="apache-parquet-cpp-${rc_version}"
-
-echo
-echo "Generating release candidate ${rc_version_tag}"
-echo
-
-# Make sure the tag does not exist
-if git rev-parse ${version_tag} >/dev/null 2>&1; then
-  echo "ERROR: tag ${version_tag} exists."
-  exit 1
-fi
-
-if git rev-parse ${rc_version_tag} >/dev/null 2>&1; then
-  echo "ERROR: tag ${rc_version_tag} exists."
-  exit 1
-fi
-
-# Reset instructions
-current_git_rev=$(git rev-parse HEAD)
-function print_reset_instructions {
-cat <<EOF
-To roll back your local repo you will need to run:
-
-  git checkout master
-  git reset --hard ${current_git_rev}
-  git tag -d ${rc_version_tag}
-  git branch -D stage_${rc_version}
-EOF
-}
-
-# If anything goes wrong from here then print roll back instructions before exiting.
-function print_rollback_instructions {
-  echo "ERROR: Looks like something has failed while creating the release candidate."
-  print_reset_instructions
-}
-trap print_rollback_instructions EXIT
-
-# All check are now complete, before we start alert if we are in dry-run
-if [[ $publish == 0 ]]; then
-  echo "Performing dry-run, run with '-p' when you are ready to run and publish a release candidate"
-fi
-
-# This should be a clean repo we are working against. Run clean just to ensure it is.
-git clean -fdxq
-
-echo "Generating changelog"
-./dev/release/changelog $current_version
-git add CHANGELOG
-git commit -m "Updating CHANGELOG for ${current_version} release."
-
-echo "Committing updated .parquetcppversion on master"
-echo $new_snapshot_version > .parquetcppversion
-git add .parquetcppversion
-git commit -m "Incrementing snapshot version to ${new_snapshot_version}."
-
-echo "Creating ${rc_version} staging branch"
-git checkout -b "stage_${rc_version}"
-
-echo "Updating .parquetcppversion on staging branch"
-# Increment the version and create a branch
-echo ${current_version} > .parquetcppversion
-git add .parquetcppversion
-git commit -m "Updating .parquetcppversion to ${current_version}."
-
-# Build the source distribution from the new branch
-echo "Building the source distribution"
-dist_dir=dist
-dist_name="${version_tag}"
-
-mkdir -p ${dist_dir}
-git archive --prefix=${dist_name}/ -o ${dist_dir}/${dist_name}.tar.gz HEAD
-pushd ${dist_dir}
-  # Sign the tarball.
-  echo "Signing the distribution"
-  gpg --armor --output ${dist_name}.tar.gz.asc --detach-sig ${dist_name}.tar.gz
-
-  # Create the checksums
-  echo "Creating checksums"
-  gpg --print-md MD5 ${dist_name}.tar.gz > ${dist_name}.tar.gz.md5
-  sha1sum ${dist_name}.tar.gz > ${dist_name}.tar.gz.sha1
-  sha256sum ${dist_name}.tar.gz > ${dist_name}.tar.gz.sha256
-  sha512sum ${dist_name}.tar.gz > ${dist_name}.tar.gz.sha512
-popd
-
-parquet_svn_rc_url="${parquet_svn_dist_url}/apache-parquet-cpp-${rc_version}"
-
-# Publish release candidate to svn and commit and push the new git tag
-if [[ $publish == 1 ]]; then
-  echo "Publishing release candidate to ${parquet_svn_rc_url}"
-  svn mkdir ${parquet_svn_rc_url} -m "parquet-cpp-${current_version} release candidate ${rc_version}"
-  svn co --depth=empty ${parquet_svn_rc_url} ${dist_dir}
-  pushd ${dist_dir}
-  svn add ${dist_name}*
-  svn ci -m "parquet-cpp-${current_version} release candidate ${rc_version}"
-  popd
-
-  echo "Creating tag ${rc_version_tag}"
-  git tag -s ${rc_version_tag} \
-    -m "Apache Parquet C++ ${current_version} release candidate ${rc_version}"
-  git push origin "${rc_version_tag}"
-
-  echo "Pushing updated .parquetcppversion to master"
-  git checkout master
-  git push origin "master:master-after-${rc_version_tag}"
-fi
-
-echo "Done creating the release candidate. The following draft email has been created"
-echo "to send to the dev@parquet.apache.org mailing list"
-echo
-
-# Create the email template for the release candidate to be sent to the mailing lists.
-if [[ $(uname) == Darwin ]]; then
-  vote_end=$(date -v+3d)
-else
-  vote_end=$(date -d+3days)
-fi
-
-MESSAGE=$(cat <<__EOF__
-To: dev@parquet.apache.org
-Subject: [VOTE] Release Apache Parquet C++ ${current_version} RC${rc_number}
-
-All,
-
-I propose that we accept the following release candidate as the official
-Apache Parquet C++ ${current_version} release.
-
-Parquet C++ ${rc_version} includes the following:
----
-The CHANGELOG for the release is available at:
-${parquetcpp_git_web_url}&f=CHANGELOG&hb=${rc_version_tag}
-
-The tag used to create the release candidate is:
-${parquetcpp_git_web_url};a=shortlog;h=refs/tags/${rc_version_tag}
-
-The release candidate is available at:
-${parquet_svn_rc_url}/${dist_name}.tar.gz
-
-The MD5 checksum of the release candidate can be found at:
-${parquet_svn_rc_url}/${dist_name}.tar.gz.md5
-
-The signature of the release candidate can be found at:
-${parquet_svn_rc_url}/${dist_name}.tar.gz.asc
-
-The GPG key used to sign the release are available at:
-${parquet_svn_dist_url}/KEYS
-
-The release is based on the commit hash ${current_git_rev}.
-
-Please download, verify, and test.
-
-The vote will close on ${vote_end}
-
-[ ] +1 Release this as Apache Parquet C++ ${current_version}
-[ ] +0
-[ ] -1 Do not release this as Apache Parquet C++ ${current_version} because...
-
-__EOF__
-)
-
-echo "--------------------------------------------------------------------------------"
-echo
-echo "${MESSAGE}"
-echo
-echo "--------------------------------------------------------------------------------"
-echo
-
-# Print reset instructions if this was a dry-run
-if [[ $publish == 0 ]]; then
-  echo
-  echo "This was a dry run, nothing has been published."
-  echo
-  print_reset_instructions
-fi
-
-# Unset error message handler and exit
-trap '' EXIT
-exit 0
diff --git a/dev/release/run-rat.sh b/dev/release/run-rat.sh
deleted file mode 100755
index 2f0d4ff..0000000
--- a/dev/release/run-rat.sh
+++ /dev/null
@@ -1,49 +0,0 @@
-#!/bin/bash
-#
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you 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.
-#
-
-# download apache rat
-curl -s https://repo1.maven.org/maven2/org/apache/rat/apache-rat/0.12/apache-rat-0.12.jar > apache-rat-0.12.jar
-
-RAT="java -jar apache-rat-0.12.jar -d "
-
-# generate the rat report
-# Ignore symlinks as RAT does not seem to understand them.
-$RAT $1 \
-  -e ".*" \
-  -e mman.h \
-  -e "*_generated.h" \
-  -e asan_symbolize.py \
-  -e cpplint.py \
-  -e pax_global_header \
-  -e clang_format_exclusions.txt \
-  -e ArrowExternalProject.cmake \
-  -e FindArrow.cmake \
-  > rat.txt
-cat rat.txt
-UNAPPROVED=`cat rat.txt  | grep "Unknown Licenses" | head -n 1 | cut -d " " -f 1`
-
-if [ "0" -eq "${UNAPPROVED}" ]; then
-  echo "No unnaproved licenses"
-else
-  echo "${UNAPPROVED} unapproved licences. Check rat report: rat.txt"
-  exit 1
-fi
-
-
diff --git a/dev/release/verify-release-candidate b/dev/release/verify-release-candidate
deleted file mode 100755
index 8555b8a..0000000
--- a/dev/release/verify-release-candidate
+++ /dev/null
@@ -1,97 +0,0 @@
-#!/usr/bin/env bash
-#
-# 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.
-#
-#
-# Downloads a release candidate and verifies that it passes binary
-# verification (signature and checksums) and test suites.
-#
-set -ex
-
-HERE=$(cd `dirname "${BASH_SOURCE[0]:-$0}"` && pwd)
-
-parquet_svn_dev_dist_url='https://dist.apache.org/repos/dist/dev/parquet'
-
-download_dist_file() {
-  curl -f -O ${parquet_svn_dev_dist_url}/$1
-}
-
-download_rc_file() {
-  download_dist_file apache-parquet-cpp-${verify_version}-rc${verify_rc_num}/$1
-}
-
-import_gpg_keys() {
-  download_dist_file KEYS
-  gpg --import KEYS
-}
-
-fetch_archive() {
-  local dist_name=$1
-  download_rc_file ${dist_name}.tar.gz
-  download_rc_file ${dist_name}.tar.gz.asc
-  download_rc_file ${dist_name}.tar.gz.md5
-  download_rc_file ${dist_name}.tar.gz.sha512
-  gpg --verify ${dist_name}.tar.gz.asc ${dist_name}.tar.gz
-  gpg --print-md MD5 ${dist_name}.tar.gz | diff - ${dist_name}.tar.gz.md5
-  if [ "$(uname)" == "Darwin" ]; then
-    shasum -a 512 ${dist_name}.tar.gz | diff - ${dist_name}.tar.gz.sha512
-  else
-    sha512sum ${dist_name}.tar.gz | diff - ${dist_name}.tar.gz.sha512
-  fi
-}
-
-run_tests() {
-  # Build
-  mkdir -p build
-  cd build
-  cmake ..
-  make -j5
-
-  # Test
-  export PARQUET_TEST_DATA=$(dirname $(pwd))/data
-  make unittest
-}
-
-setup_tempdir() {
-  cleanup() {
-    rm -fr "$TMPDIR"
-  }
-  trap cleanup EXIT
-  TMPDIR=$(mktemp -d -t "$1.XXXXX")
-}
-
-case $# in
-  2) verify_version="$1"
-     verify_rc_num="$2"
-     ;;
-
-  *) echo "Usage: $0 VERSION RC_NUM"
-     echo "Example to test 1.3.0-rc2: $0 1.3.0 2"
-     exit 1
-     ;;
-esac
-
-setup_tempdir "parquet-cpp-$verify_version"
-echo "Working in sandbox $TMPDIR"
-cd $TMPDIR
-
-import_gpg_keys
-
-dist_name="apache-parquet-cpp-${verify_version}"
-fetch_archive $dist_name
-tar xvzf ${dist_name}.tar.gz
-cd ${dist_name}
-run_tests
-
-echo 'Release candidate looks good!'
-exit 0
diff --git a/dev/release/verify-release-candidate.bat b/dev/release/verify-release-candidate.bat
deleted file mode 100644
index b5aaa8a..0000000
--- a/dev/release/verify-release-candidate.bat
+++ /dev/null
@@ -1,54 +0,0 @@
-@rem Licensed to the Apache Software Foundation (ASF) under one
-@rem or more contributor license agreements.  See the NOTICE file
-@rem distributed with this work for additional information
-@rem regarding copyright ownership.  The ASF licenses this file
-@rem to you under the Apache License, Version 2.0 (the
-@rem "License"); you may not use this file except in compliance
-@rem with the License.  You may obtain a copy of the License at
-@rem
-@rem   http://www.apache.org/licenses/LICENSE-2.0
-@rem
-@rem Unless required by applicable law or agreed to in writing,
-@rem software distributed under the License is distributed on an
-@rem "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-@rem KIND, either express or implied.  See the License for the
-@rem specific language governing permissions and limitations
-@rem under the License.
-
-@rem Then run from the directory containing the RC tarball
-@rem
-@rem verify-release-candidate.bat apache-parquet-cpp-%VERSION%
-
-@echo on
-
-if not exist "C:\tmp\" mkdir C:\tmp
-if exist "C:\tmp\parquet-verify-release" rd C:\tmp\parquet-verify-release /s /q
-if not exist "C:\tmp\parquet-verify-release" mkdir C:\tmp\parquet-verify-release
-
-tar xvf %1.tar.gz -C "C:/tmp/"
-
-set GENERATOR=Visual Studio 14 2015 Win64
-set CONFIGURATION=release
-set PARQUET_SOURCE=C:\tmp\%1
-set INSTALL_DIR=C:\tmp\%1\install
-
-pushd %PARQUET_SOURCE%
-
-set PARQUET_TEST_DATA=%PARQUET_SOURCE%\data
-
-set PARQUET_HOME=%INSTALL_DIR%
-set PATH=%INSTALL_DIR%\bin;%PATH%
-
-mkdir build
-pushd build
-
-cmake -G "%GENERATOR%" ^
-      -DCMAKE_INSTALL_PREFIX=%PARQUET_HOME% ^
-      -DPARQUET_BOOST_USE_SHARED=OFF ^
-      -DCMAKE_BUILD_TYPE=%CONFIGURATION% ^
-      -DPARQUET_CXXFLAGS="/WX /MP" ^
-      ..  || exit /B
-cmake --build . --target INSTALL --config %CONFIGURATION%  || exit /B
-
-ctest -VV  || exit /B
-popd
diff --git a/docs/Windows.md b/docs/Windows.md
deleted file mode 100644
index 8de04f6..0000000
--- a/docs/Windows.md
+++ /dev/null
@@ -1,142 +0,0 @@
-<!---
-  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. See accompanying LICENSE file.
--->
-
-# Building parquet-cpp on Windows
-
-## Fast setup of building requirements with conda and conda-forge
-
-A convenient and tested way to set up thirdparty dependencies is to use the
-conda package manager.
-Please feel free to extend this document with others ways to setup
-development environment for parquet-cpp.
-
-### conda and package toolchain
-
-[Miniconda][1] is a minimal Python distribution including the conda package
-manager. To get started, download and install a 64-bit distribution.
-
-We recommend using packages from [conda-forge][2].
-Launch cmd.exe and run following to bootstrap a build environment:
-
-```shell
-conda create -n parquet-dev cmake git boost-cpp curl zlib snappy brotli thrift-cpp -c conda-forge
-```
-
-To allow cmake to pick up 3rd party dependencies, you should set
-`PARQUET_BUILD_TOOLCHAIN` environment variable to contain `Library` folder
-path of new created on previous step `parquet-dev` conda environment.
-For instance, if `Miniconda` was installed to default destination, `Library`
-folder path for `parquet-dev` conda environment will be as following:
-
-```shell
-C:\Users\YOUR_USER_NAME\Miniconda3\envs\parquet-dev\Library
-```
-
-As alternative to `PARQUET_BUILD_TOOLCHAIN`, it's possible to configure path
-to each 3rd party dependency separately by setting appropriate environment
-variable:
-
-`BOOST_ROOT` variable with path to `boost` installation  
-`THRIFT_HOME` variable with path to `thrift-cpp` installation  
-`SNAPPY_HOME` variable with path to `snappy` installation  
-`ZLIB_HOME` variable with path to `zlib` installation  
-`BROTLI_HOME` variable with path to `brotli` installation  
-`ARROW_HOME` variable with path to `arrow` installation
-
-### Customize static libraries names lookup of 3rd party dependencies 
-
-If you decided to use pre-built 3rd party dependencies libs, it's possible to
-configure parquet-cpp cmake build script to search for customized names of 3rd
-party static libs.
-
-`zlib`. Pass `-DPARQUET_ZLIB_VENDORED=OFF` to enable lookup of custom zlib
-build. Set `ZLIB_HOME` environment variable. Pass
-`-DZLIB_MSVC_STATIC_LIB_SUFFIX=%ZLIB_SUFFIX%` to link with z%ZLIB_SUFFIX%.lib
-
-`arrow`. Set `ARROW_HOME` environment variable. Pass
-`-DARROW_MSVC_STATIC_LIB_SUFFIX=%ARROW_SUFFIX%` to link with
-arrow%ARROW_SUFFIX%.lib
-
-`brotli`. Set `BROTLY_HOME` environment variable. Pass
-`-DBROTLI_MSVC_STATIC_LIB_SUFFIX=%BROTLI_SUFFIX%` to link with
-brotli*%BROTLI_SUFFIX%.lib.
-
-`snappy`. Set `SNAPPY_HOME` environment variable. Pass
-`-DSNAPPY_MSVC_STATIC_LIB_SUFFIX=%SNAPPY_SUFFIX%` to link with
-snappy%SNAPPY_SUFFIX%.lib.
-
-`thrift`. Set `THRIFT_HOME` environment variable. Pass
-`-DTHRIFT_MSVC_STATIC_LIB_SUFFIX=%THRIFT_SUFFIX%` to link with
-thrift*%THRIFT_SUFFIX%.lib.
-
-### Visual Studio
-
-Microsoft provides the free Visual Studio Community edition. Once you have
-Visual Studio installed, you should configure cmd.exe environment to be able
-to find Visual Studio's build toolchain by running following commands:
-
-#### Visual Studio 2015
-
-```"C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" amd64```
-
-#### Visual Studio 2017
-
-```"C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\Tools\VsDevCmd.bat" -arch=amd64```
-
-It's easiest to configure a console emulator like [cmder][3] to automatically
-launch this when starting a new development console.
-
-## Building with NMake
-
-Activate your conda build environment:
-
-```
-activate parquet-dev
-```
-
-Change working directory in cmd.exe to the root directory of parquet-cpp and
-do an out of source build using `nmake`:
-
-```
-cd %PARQUET_ROOT_SOURCES_DIRECTORY%
-mkdir build
-cd build
-cmake -G "NMake Makefiles" -DCMAKE_BUILD_TYPE=Release ..
-nmake
-```
-
-## Building with Visual Studio cmake generator
-
-Activate your conda build environment:
-
-```
-activate parquet-dev
-```
-
-Change working directory in cmd.exe to the root directory of parquet-cpp and
-do an out of source build:
-
-```
-cd %PARQUET_ROOT_SOURCES_DIRECTORY%
-mkdir build
-cd build
-cmake -G "Visual Studio 14 2015 Win64" -DCMAKE_BUILD_TYPE=Release ..
-cmake --build . --config Release
-```
-
-When using conda, only release builds are currently supported.
-
-[1]: https://conda.io/miniconda.html
-[2]: https://conda-forge.github.io/
-[3]: http://cmder.net/
\ No newline at end of file
diff --git a/examples/low-level-api/CMakeLists.txt b/examples/low-level-api/CMakeLists.txt
deleted file mode 100644
index 64ba110..0000000
--- a/examples/low-level-api/CMakeLists.txt
+++ /dev/null
@@ -1,25 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you 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.
-
-if (PARQUET_BUILD_EXECUTABLES)
-  add_executable(reader-writer reader-writer.cc)
-  add_executable(reader-writer2 reader-writer2.cc)
-  target_include_directories(reader-writer PRIVATE .)
-  target_include_directories(reader-writer2 PRIVATE .)
-  target_link_libraries(reader-writer parquet_static)
-  target_link_libraries(reader-writer2 parquet_static)
-endif()
diff --git a/examples/low-level-api/reader-writer.cc b/examples/low-level-api/reader-writer.cc
deleted file mode 100644
index 09cd137..0000000
--- a/examples/low-level-api/reader-writer.cc
+++ /dev/null
@@ -1,409 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements. See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership. The ASF licenses this file
-// to you 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.
-
-#include <cassert>
-#include <fstream>
-#include <iostream>
-#include <memory>
-
-#include <reader_writer.h>
-
-/*
- * This example describes writing and reading Parquet Files in C++ and serves as a
- * reference to the API.
- * The file contains all the physical data types supported by Parquet.
- * This example uses the RowGroupWriter API that supports writing RowGroups optimized for
- *memory consumption
- **/
-
-/* Parquet is a structured columnar file format
- * Parquet File = "Parquet data" + "Parquet Metadata"
- * "Parquet data" is simply a vector of RowGroups. Each RowGroup is a batch of rows in a
- * columnar layout
- * "Parquet Metadata" contains the "file schema" and attributes of the RowGroups and their
- * Columns
- * "file schema" is a tree where each node is either a primitive type (leaf nodes) or a
- * complex (nested) type (internal nodes)
- * For specific details, please refer the format here:
- * https://github.com/apache/parquet-format/blob/master/LogicalTypes.md
- **/
-
-constexpr int NUM_ROWS_PER_ROW_GROUP = 500;
-const char PARQUET_FILENAME[] = "parquet_cpp_example.parquet";
-
-int main(int argc, char** argv) {
-  /**********************************************************************************
-                             PARQUET WRITER EXAMPLE
-  **********************************************************************************/
-  // parquet::REQUIRED fields do not need definition and repetition level values
-  // parquet::OPTIONAL fields require only definition level values
-  // parquet::REPEATED fields require both definition and repetition level values
-  try {
-    // Create a local file output stream instance.
-    using FileClass = ::arrow::io::FileOutputStream;
-    std::shared_ptr<FileClass> out_file;
-    PARQUET_THROW_NOT_OK(FileClass::Open(PARQUET_FILENAME, &out_file));
-
-    // Setup the parquet schema
-    std::shared_ptr<GroupNode> schema = SetupSchema();
-
-    // Add writer properties
-    parquet::WriterProperties::Builder builder;
-    builder.compression(parquet::Compression::SNAPPY);
-    std::shared_ptr<parquet::WriterProperties> props = builder.build();
-
-    // Create a ParquetFileWriter instance
-    std::shared_ptr<parquet::ParquetFileWriter> file_writer =
-        parquet::ParquetFileWriter::Open(out_file, schema, props);
-
-    // Append a RowGroup with a specific number of rows.
-    parquet::RowGroupWriter* rg_writer = file_writer->AppendRowGroup();
-
-    // Write the Bool column
-    parquet::BoolWriter* bool_writer =
-        static_cast<parquet::BoolWriter*>(rg_writer->NextColumn());
-    for (int i = 0; i < NUM_ROWS_PER_ROW_GROUP; i++) {
-      bool value = ((i % 2) == 0) ? true : false;
-      bool_writer->WriteBatch(1, nullptr, nullptr, &value);
-    }
-
-    // Write the Int32 column
-    parquet::Int32Writer* int32_writer =
-        static_cast<parquet::Int32Writer*>(rg_writer->NextColumn());
-    for (int i = 0; i < NUM_ROWS_PER_ROW_GROUP; i++) {
-      int32_t value = i;
-      int32_writer->WriteBatch(1, nullptr, nullptr, &value);
-    }
-
-    // Write the Int64 column. Each row has repeats twice.
-    parquet::Int64Writer* int64_writer =
-        static_cast<parquet::Int64Writer*>(rg_writer->NextColumn());
-    for (int i = 0; i < 2 * NUM_ROWS_PER_ROW_GROUP; i++) {
-      int64_t value = i * 1000 * 1000;
-      value *= 1000 * 1000;
-      int16_t definition_level = 1;
-      int16_t repetition_level = 0;
-      if ((i % 2) == 0) {
-        repetition_level = 1;  // start of a new record
-      }
-      int64_writer->WriteBatch(1, &definition_level, &repetition_level, &value);
-    }
-
-    // Write the INT96 column.
-    parquet::Int96Writer* int96_writer =
-        static_cast<parquet::Int96Writer*>(rg_writer->NextColumn());
-    for (int i = 0; i < NUM_ROWS_PER_ROW_GROUP; i++) {
-      parquet::Int96 value;
-      value.value[0] = i;
-      value.value[1] = i + 1;
-      value.value[2] = i + 2;
-      int96_writer->WriteBatch(1, nullptr, nullptr, &value);
-    }
-
-    // Write the Float column
-    parquet::FloatWriter* float_writer =
-        static_cast<parquet::FloatWriter*>(rg_writer->NextColumn());
-    for (int i = 0; i < NUM_ROWS_PER_ROW_GROUP; i++) {
-      float value = static_cast<float>(i) * 1.1f;
-      float_writer->WriteBatch(1, nullptr, nullptr, &value);
-    }
-
-    // Write the Double column
-    parquet::DoubleWriter* double_writer =
-        static_cast<parquet::DoubleWriter*>(rg_writer->NextColumn());
-    for (int i = 0; i < NUM_ROWS_PER_ROW_GROUP; i++) {
-      double value = i * 1.1111111;
-      double_writer->WriteBatch(1, nullptr, nullptr, &value);
-    }
-
-    // Write the ByteArray column. Make every alternate values NULL
-    parquet::ByteArrayWriter* ba_writer =
-        static_cast<parquet::ByteArrayWriter*>(rg_writer->NextColumn());
-    for (int i = 0; i < NUM_ROWS_PER_ROW_GROUP; i++) {
-      parquet::ByteArray value;
-      char hello[FIXED_LENGTH] = "parquet";
-      hello[7] = static_cast<char>(static_cast<int>('0') + i / 100);
-      hello[8] = static_cast<char>(static_cast<int>('0') + (i / 10) % 10);
-      hello[9] = static_cast<char>(static_cast<int>('0') + i % 10);
-      if (i % 2 == 0) {
-        int16_t definition_level = 1;
-        value.ptr = reinterpret_cast<const uint8_t*>(&hello[0]);
-        value.len = FIXED_LENGTH;
-        ba_writer->WriteBatch(1, &definition_level, nullptr, &value);
-      } else {
-        int16_t definition_level = 0;
-        ba_writer->WriteBatch(1, &definition_level, nullptr, nullptr);
-      }
-    }
-
-    // Write the FixedLengthByteArray column
-    parquet::FixedLenByteArrayWriter* flba_writer =
-        static_cast<parquet::FixedLenByteArrayWriter*>(rg_writer->NextColumn());
-    for (int i = 0; i < NUM_ROWS_PER_ROW_GROUP; i++) {
-      parquet::FixedLenByteArray value;
-      char v = static_cast<char>(i);
-      char flba[FIXED_LENGTH] = {v, v, v, v, v, v, v, v, v, v};
-      value.ptr = reinterpret_cast<const uint8_t*>(&flba[0]);
-
-      flba_writer->WriteBatch(1, nullptr, nullptr, &value);
-    }
-
-    // Close the ParquetFileWriter
-    file_writer->Close();
-
-    // Write the bytes to file
-    DCHECK(out_file->Close().ok());
-  } catch (const std::exception& e) {
-    std::cerr << "Parquet write error: " << e.what() << std::endl;
-    return -1;
-  }
-
-  /**********************************************************************************
-                             PARQUET READER EXAMPLE
-  **********************************************************************************/
-
-  try {
-    // Create a ParquetReader instance
-    std::unique_ptr<parquet::ParquetFileReader> parquet_reader =
-        parquet::ParquetFileReader::OpenFile(PARQUET_FILENAME, false);
-
-    // Get the File MetaData
-    std::shared_ptr<parquet::FileMetaData> file_metadata = parquet_reader->metadata();
-
-    // Get the number of RowGroups
-    int num_row_groups = file_metadata->num_row_groups();
-    assert(num_row_groups == 1);
-
-    // Get the number of Columns
-    int num_columns = file_metadata->num_columns();
-    assert(num_columns == 8);
-
-    // Iterate over all the RowGroups in the file
-    for (int r = 0; r < num_row_groups; ++r) {
-      // Get the RowGroup Reader
-      std::shared_ptr<parquet::RowGroupReader> row_group_reader =
-          parquet_reader->RowGroup(r);
-
-      int64_t values_read = 0;
-      int64_t rows_read = 0;
-      int16_t definition_level;
-      int16_t repetition_level;
-      int i;
-      std::shared_ptr<parquet::ColumnReader> column_reader;
-
-      // Get the Column Reader for the boolean column
-      column_reader = row_group_reader->Column(0);
-      parquet::BoolReader* bool_reader =
-          static_cast<parquet::BoolReader*>(column_reader.get());
-
-      // Read all the rows in the column
-      i = 0;
-      while (bool_reader->HasNext()) {
-        bool value;
-        // Read one value at a time. The number of rows read is returned. values_read
-        // contains the number of non-null rows
-        rows_read = bool_reader->ReadBatch(1, nullptr, nullptr, &value, &values_read);
-        // Ensure only one value is read
-        assert(rows_read == 1);
-        // There are no NULL values in the rows written
-        assert(values_read == 1);
-        // Verify the value written
-        bool expected_value = ((i % 2) == 0) ? true : false;
-        assert(value == expected_value);
-        i++;
-      }
-
-      // Get the Column Reader for the Int32 column
-      column_reader = row_group_reader->Column(1);
-      parquet::Int32Reader* int32_reader =
-          static_cast<parquet::Int32Reader*>(column_reader.get());
-      // Read all the rows in the column
-      i = 0;
-      while (int32_reader->HasNext()) {
-        int32_t value;
-        // Read one value at a time. The number of rows read is returned. values_read
-        // contains the number of non-null rows
-        rows_read = int32_reader->ReadBatch(1, nullptr, nullptr, &value, &values_read);
-        // Ensure only one value is read
-        assert(rows_read == 1);
-        // There are no NULL values in the rows written
-        assert(values_read == 1);
-        // Verify the value written
-        assert(value == i);
-        i++;
-      }
-
-      // Get the Column Reader for the Int64 column
-      column_reader = row_group_reader->Column(2);
-      parquet::Int64Reader* int64_reader =
-          static_cast<parquet::Int64Reader*>(column_reader.get());
-      // Read all the rows in the column
-      i = 0;
-      while (int64_reader->HasNext()) {
-        int64_t value;
-        // Read one value at a time. The number of rows read is returned. values_read
-        // contains the number of non-null rows
-        rows_read = int64_reader->ReadBatch(1, &definition_level, &repetition_level,
-                                            &value, &values_read);
-        // Ensure only one value is read
-        assert(rows_read == 1);
-        // There are no NULL values in the rows written
-        assert(values_read == 1);
-        // Verify the value written
-        int64_t expected_value = i * 1000 * 1000;
-        expected_value *= 1000 * 1000;
-        assert(value == expected_value);
-        if ((i % 2) == 0) {
-          assert(repetition_level == 1);
-        } else {
-          assert(repetition_level == 0);
-        }
-        i++;
-      }
-
-      // Get the Column Reader for the Int96 column
-      column_reader = row_group_reader->Column(3);
-      parquet::Int96Reader* int96_reader =
-          static_cast<parquet::Int96Reader*>(column_reader.get());
-      // Read all the rows in the column
-      i = 0;
-      while (int96_reader->HasNext()) {
-        parquet::Int96 value;
-        // Read one value at a time. The number of rows read is returned. values_read
-        // contains the number of non-null rows
-        rows_read = int96_reader->ReadBatch(1, nullptr, nullptr, &value, &values_read);
-        // Ensure only one value is read
-        assert(rows_read == 1);
-        // There are no NULL values in the rows written
-        assert(values_read == 1);
-        // Verify the value written
-        parquet::Int96 expected_value;
-        expected_value.value[0] = i;
-        expected_value.value[1] = i + 1;
-        expected_value.value[2] = i + 2;
-        for (int j = 0; j < 3; j++) {
-          assert(value.value[j] == expected_value.value[j]);
-        }
-        i++;
-      }
-
-      // Get the Column Reader for the Float column
-      column_reader = row_group_reader->Column(4);
-      parquet::FloatReader* float_reader =
-          static_cast<parquet::FloatReader*>(column_reader.get());
-      // Read all the rows in the column
-      i = 0;
-      while (float_reader->HasNext()) {
-        float value;
-        // Read one value at a time. The number of rows read is returned. values_read
-        // contains the number of non-null rows
-        rows_read = float_reader->ReadBatch(1, nullptr, nullptr, &value, &values_read);
-        // Ensure only one value is read
-        assert(rows_read == 1);
-        // There are no NULL values in the rows written
-        assert(values_read == 1);
-        // Verify the value written
-        float expected_value = static_cast<float>(i) * 1.1f;
-        assert(value == expected_value);
-        i++;
-      }
-
-      // Get the Column Reader for the Double column
-      column_reader = row_group_reader->Column(5);
-      parquet::DoubleReader* double_reader =
-          static_cast<parquet::DoubleReader*>(column_reader.get());
-      // Read all the rows in the column
-      i = 0;
-      while (double_reader->HasNext()) {
-        double value;
-        // Read one value at a time. The number of rows read is returned. values_read
-        // contains the number of non-null rows
-        rows_read = double_reader->ReadBatch(1, nullptr, nullptr, &value, &values_read);
-        // Ensure only one value is read
-        assert(rows_read == 1);
-        // There are no NULL values in the rows written
-        assert(values_read == 1);
-        // Verify the value written
-        double expected_value = i * 1.1111111;
-        assert(value == expected_value);
-        i++;
-      }
-
-      // Get the Column Reader for the ByteArray column
-      column_reader = row_group_reader->Column(6);
-      parquet::ByteArrayReader* ba_reader =
-          static_cast<parquet::ByteArrayReader*>(column_reader.get());
-      // Read all the rows in the column
-      i = 0;
-      while (ba_reader->HasNext()) {
-        parquet::ByteArray value;
-        // Read one value at a time. The number of rows read is returned. values_read
-        // contains the number of non-null rows
-        rows_read =
-            ba_reader->ReadBatch(1, &definition_level, nullptr, &value, &values_read);
-        // Ensure only one value is read
-        assert(rows_read == 1);
-        // Verify the value written
-        char expected_value[FIXED_LENGTH] = "parquet";
-        expected_value[7] = static_cast<char>('0' + i / 100);
-        expected_value[8] = static_cast<char>('0' + (i / 10) % 10);
-        expected_value[9] = static_cast<char>('0' + i % 10);
-        if (i % 2 == 0) {  // only alternate values exist
-          // There are no NULL values in the rows written
-          assert(values_read == 1);
-          assert(value.len == FIXED_LENGTH);
-          assert(memcmp(value.ptr, &expected_value[0], FIXED_LENGTH) == 0);
-          assert(definition_level == 1);
-        } else {
-          // There are NULL values in the rows written
-          assert(values_read == 0);
-          assert(definition_level == 0);
-        }
-        i++;
-      }
-
-      // Get the Column Reader for the FixedLengthByteArray column
-      column_reader = row_group_reader->Column(7);
-      parquet::FixedLenByteArrayReader* flba_reader =
-          static_cast<parquet::FixedLenByteArrayReader*>(column_reader.get());
-      // Read all the rows in the column
-      i = 0;
-      while (flba_reader->HasNext()) {
-        parquet::FixedLenByteArray value;
-        // Read one value at a time. The number of rows read is returned. values_read
-        // contains the number of non-null rows
-        rows_read = flba_reader->ReadBatch(1, nullptr, nullptr, &value, &values_read);
-        // Ensure only one value is read
-        assert(rows_read == 1);
-        // There are no NULL values in the rows written
-        assert(values_read == 1);
-        // Verify the value written
-        char v = static_cast<char>(i);
-        char expected_value[FIXED_LENGTH] = {v, v, v, v, v, v, v, v, v, v};
-        assert(memcmp(value.ptr, &expected_value[0], FIXED_LENGTH) == 0);
-        i++;
-      }
-    }
-  } catch (const std::exception& e) {
-    std::cerr << "Parquet read error: " << e.what() << std::endl;
-    return -1;
-  }
-
-  std::cout << "Parquet Writing and Reading Complete" << std::endl;
-
-  return 0;
-}
diff --git a/examples/low-level-api/reader-writer2.cc b/examples/low-level-api/reader-writer2.cc
deleted file mode 100644
index dded5fa..0000000
--- a/examples/low-level-api/reader-writer2.cc
+++ /dev/null
@@ -1,430 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements. See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership. The ASF licenses this file
-// to you 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.
-
-#include <cassert>
-#include <fstream>
-#include <iostream>
-#include <memory>
-
-#include <reader_writer.h>
-
-/*
- * This example describes writing and reading Parquet Files in C++ and serves as a
- * reference to the API.
- * The file contains all the physical data types supported by Parquet.
- * This example uses the RowGroupWriter API that supports writing RowGroups based on a
- *certain size
- **/
-
-/* Parquet is a structured columnar file format
- * Parquet File = "Parquet data" + "Parquet Metadata"
- * "Parquet data" is simply a vector of RowGroups. Each RowGroup is a batch of rows in a
- * columnar layout
- * "Parquet Metadata" contains the "file schema" and attributes of the RowGroups and their
- * Columns
- * "file schema" is a tree where each node is either a primitive type (leaf nodes) or a
- * complex (nested) type (internal nodes)
- * For specific details, please refer the format here:
- * https://github.com/apache/parquet-format/blob/master/LogicalTypes.md
- **/
-
-constexpr int NUM_ROWS = 2500000;
-constexpr int64_t ROW_GROUP_SIZE = 16 * 1024 * 1024;  // 16 MB
-const char PARQUET_FILENAME[] = "parquet_cpp_example2.parquet";
-
-int main(int argc, char** argv) {
-  /**********************************************************************************
-                             PARQUET WRITER EXAMPLE
-  **********************************************************************************/
-  // parquet::REQUIRED fields do not need definition and repetition level values
-  // parquet::OPTIONAL fields require only definition level values
-  // parquet::REPEATED fields require both definition and repetition level values
-  try {
-    // Create a local file output stream instance.
-    using FileClass = ::arrow::io::FileOutputStream;
-    std::shared_ptr<FileClass> out_file;
-    PARQUET_THROW_NOT_OK(FileClass::Open(PARQUET_FILENAME, &out_file));
-
-    // Setup the parquet schema
-    std::shared_ptr<GroupNode> schema = SetupSchema();
-
-    // Add writer properties
-    parquet::WriterProperties::Builder builder;
-    builder.compression(parquet::Compression::SNAPPY);
-    std::shared_ptr<parquet::WriterProperties> props = builder.build();
-
-    // Create a ParquetFileWriter instance
-    std::shared_ptr<parquet::ParquetFileWriter> file_writer =
-        parquet::ParquetFileWriter::Open(out_file, schema, props);
-
-    // Append a BufferedRowGroup to keep the RowGroup open until a certain size
-    parquet::RowGroupWriter* rg_writer = file_writer->AppendBufferedRowGroup();
-
-    int num_columns = file_writer->num_columns();
-    std::vector<int64_t> buffered_values_estimate(num_columns, 0);
-    for (int i = 0; i < NUM_ROWS; i++) {
-      int64_t estimated_bytes = 0;
-      // Get the estimated size of the values that are not written to a page yet
-      for (int n = 0; n < num_columns; n++) {
-        estimated_bytes += buffered_values_estimate[n];
-      }
-
-      // We need to consider the compressed pages
-      // as well as the values that are not compressed yet
-      if ((rg_writer->total_bytes_written() + rg_writer->total_compressed_bytes() +
-           estimated_bytes) > ROW_GROUP_SIZE) {
-        rg_writer->Close();
-        std::fill(buffered_values_estimate.begin(), buffered_values_estimate.end(), 0);
-        rg_writer = file_writer->AppendBufferedRowGroup();
-      }
-
-      int col_id = 0;
-      // Write the Bool column
-      parquet::BoolWriter* bool_writer =
-          static_cast<parquet::BoolWriter*>(rg_writer->column(col_id));
-      bool bool_value = ((i % 2) == 0) ? true : false;
-      bool_writer->WriteBatch(1, nullptr, nullptr, &bool_value);
-      buffered_values_estimate[col_id] = bool_writer->EstimatedBufferedValueBytes();
-
-      // Write the Int32 column
-      col_id++;
-      parquet::Int32Writer* int32_writer =
-          static_cast<parquet::Int32Writer*>(rg_writer->column(col_id));
-      int32_t int32_value = i;
-      int32_writer->WriteBatch(1, nullptr, nullptr, &int32_value);
-      buffered_values_estimate[col_id] = int32_writer->EstimatedBufferedValueBytes();
-
-      // Write the Int64 column. Each row has repeats twice.
-      col_id++;
-      parquet::Int64Writer* int64_writer =
-          static_cast<parquet::Int64Writer*>(rg_writer->column(col_id));
-      int64_t int64_value1 = 2 * i;
-      int16_t definition_level = 1;
-      int16_t repetition_level = 0;
-      int64_writer->WriteBatch(1, &definition_level, &repetition_level, &int64_value1);
-      int64_t int64_value2 = (2 * i + 1);
-      repetition_level = 1;  // start of a new record
-      int64_writer->WriteBatch(1, &definition_level, &repetition_level, &int64_value2);
-      buffered_values_estimate[col_id] = int64_writer->EstimatedBufferedValueBytes();
-
-      // Write the INT96 column.
-      col_id++;
-      parquet::Int96Writer* int96_writer =
-          static_cast<parquet::Int96Writer*>(rg_writer->column(col_id));
-      parquet::Int96 int96_value;
-      int96_value.value[0] = i;
-      int96_value.value[1] = i + 1;
-      int96_value.value[2] = i + 2;
-      int96_writer->WriteBatch(1, nullptr, nullptr, &int96_value);
-      buffered_values_estimate[col_id] = int96_writer->EstimatedBufferedValueBytes();
-
-      // Write the Float column
-      col_id++;
-      parquet::FloatWriter* float_writer =
-          static_cast<parquet::FloatWriter*>(rg_writer->column(col_id));
-      float float_value = static_cast<float>(i) * 1.1f;
-      float_writer->WriteBatch(1, nullptr, nullptr, &float_value);
-      buffered_values_estimate[col_id] = float_writer->EstimatedBufferedValueBytes();
-
-      // Write the Double column
-      col_id++;
-      parquet::DoubleWriter* double_writer =
-          static_cast<parquet::DoubleWriter*>(rg_writer->column(col_id));
-      double double_value = i * 1.1111111;
-      double_writer->WriteBatch(1, nullptr, nullptr, &double_value);
-      buffered_values_estimate[col_id] = double_writer->EstimatedBufferedValueBytes();
-
-      // Write the ByteArray column. Make every alternate values NULL
-      col_id++;
-      parquet::ByteArrayWriter* ba_writer =
-          static_cast<parquet::ByteArrayWriter*>(rg_writer->column(col_id));
-      parquet::ByteArray ba_value;
-      char hello[FIXED_LENGTH] = "parquet";
-      hello[7] = static_cast<char>(static_cast<int>('0') + i / 100);
-      hello[8] = static_cast<char>(static_cast<int>('0') + (i / 10) % 10);
-      hello[9] = static_cast<char>(static_cast<int>('0') + i % 10);
-      if (i % 2 == 0) {
-        int16_t definition_level = 1;
-        ba_value.ptr = reinterpret_cast<const uint8_t*>(&hello[0]);
-        ba_value.len = FIXED_LENGTH;
-        ba_writer->WriteBatch(1, &definition_level, nullptr, &ba_value);
-      } else {
-        int16_t definition_level = 0;
-        ba_writer->WriteBatch(1, &definition_level, nullptr, nullptr);
-      }
-      buffered_values_estimate[col_id] = ba_writer->EstimatedBufferedValueBytes();
-
-      // Write the FixedLengthByteArray column
-      col_id++;
-      parquet::FixedLenByteArrayWriter* flba_writer =
-          static_cast<parquet::FixedLenByteArrayWriter*>(rg_writer->column(col_id));
-      parquet::FixedLenByteArray flba_value;
-      char v = static_cast<char>(i);
-      char flba[FIXED_LENGTH] = {v, v, v, v, v, v, v, v, v, v};
-      flba_value.ptr = reinterpret_cast<const uint8_t*>(&flba[0]);
-
-      flba_writer->WriteBatch(1, nullptr, nullptr, &flba_value);
-      buffered_values_estimate[col_id] = flba_writer->EstimatedBufferedValueBytes();
-    }
-
-    // Close the RowGroupWriter
-    rg_writer->Close();
-    // Close the ParquetFileWriter
-    file_writer->Close();
-
-    // Write the bytes to file
-    DCHECK(out_file->Close().ok());
-  } catch (const std::exception& e) {
-    std::cerr << "Parquet write error: " << e.what() << std::endl;
-    return -1;
-  }
-
-  /**********************************************************************************
-                             PARQUET READER EXAMPLE
-  **********************************************************************************/
-
-  try {
-    // Create a ParquetReader instance
-    std::unique_ptr<parquet::ParquetFileReader> parquet_reader =
-        parquet::ParquetFileReader::OpenFile(PARQUET_FILENAME, false);
-
-    // Get the File MetaData
-    std::shared_ptr<parquet::FileMetaData> file_metadata = parquet_reader->metadata();
-
-    int num_row_groups = file_metadata->num_row_groups();
-
-    // Get the number of Columns
-    int num_columns = file_metadata->num_columns();
-    assert(num_columns == 8);
-
-    std::vector<int> col_row_counts(num_columns, 0);
-
-    // Iterate over all the RowGroups in the file
-    for (int r = 0; r < num_row_groups; ++r) {
-      // Get the RowGroup Reader
-      std::shared_ptr<parquet::RowGroupReader> row_group_reader =
-          parquet_reader->RowGroup(r);
-
-      assert(row_group_reader->metadata()->total_byte_size() < ROW_GROUP_SIZE);
-
-      int64_t values_read = 0;
-      int64_t rows_read = 0;
-      int16_t definition_level;
-      int16_t repetition_level;
-      std::shared_ptr<parquet::ColumnReader> column_reader;
-      int col_id = 0;
-
-      // Get the Column Reader for the boolean column
-      column_reader = row_group_reader->Column(col_id);
-      parquet::BoolReader* bool_reader =
-          static_cast<parquet::BoolReader*>(column_reader.get());
-
-      // Read all the rows in the column
-      while (bool_reader->HasNext()) {
-        bool value;
-        // Read one value at a time. The number of rows read is returned. values_read
-        // contains the number of non-null rows
-        rows_read = bool_reader->ReadBatch(1, nullptr, nullptr, &value, &values_read);
-        // Ensure only one value is read
-        assert(rows_read == 1);
-        // There are no NULL values in the rows written
-        assert(values_read == 1);
-        // Verify the value written
-        bool expected_value = ((col_row_counts[col_id] % 2) == 0) ? true : false;
-        assert(value == expected_value);
-        col_row_counts[col_id]++;
-      }
-
-      // Get the Column Reader for the Int32 column
-      col_id++;
-      column_reader = row_group_reader->Column(col_id);
-      parquet::Int32Reader* int32_reader =
-          static_cast<parquet::Int32Reader*>(column_reader.get());
-      // Read all the rows in the column
-      while (int32_reader->HasNext()) {
-        int32_t value;
-        // Read one value at a time. The number of rows read is returned. values_read
-        // contains the number of non-null rows
-        rows_read = int32_reader->ReadBatch(1, nullptr, nullptr, &value, &values_read);
-        // Ensure only one value is read
-        assert(rows_read == 1);
-        // There are no NULL values in the rows written
-        assert(values_read == 1);
-        // Verify the value written
-        assert(value == col_row_counts[col_id]);
-        col_row_counts[col_id]++;
-      }
-
-      // Get the Column Reader for the Int64 column
-      col_id++;
-      column_reader = row_group_reader->Column(col_id);
-      parquet::Int64Reader* int64_reader =
-          static_cast<parquet::Int64Reader*>(column_reader.get());
-      // Read all the rows in the column
-      while (int64_reader->HasNext()) {
-        int64_t value;
-        // Read one value at a time. The number of rows read is returned. values_read
-        // contains the number of non-null rows
-        rows_read = int64_reader->ReadBatch(1, &definition_level, &repetition_level,
-                                            &value, &values_read);
-        // Ensure only one value is read
-        assert(rows_read == 1);
-        // There are no NULL values in the rows written
-        assert(values_read == 1);
-        // Verify the value written
-        int64_t expected_value = col_row_counts[col_id];
-        assert(value == expected_value);
-        if ((col_row_counts[col_id] % 2) == 0) {
-          assert(repetition_level == 0);
-        } else {
-          assert(repetition_level == 1);
-        }
-        col_row_counts[col_id]++;
-      }
-
-      // Get the Column Reader for the Int96 column
-      col_id++;
-      column_reader = row_group_reader->Column(col_id);
-      parquet::Int96Reader* int96_reader =
-          static_cast<parquet::Int96Reader*>(column_reader.get());
-      // Read all the rows in the column
-      while (int96_reader->HasNext()) {
-        parquet::Int96 value;
-        // Read one value at a time. The number of rows read is returned. values_read
-        // contains the number of non-null rows
-        rows_read = int96_reader->ReadBatch(1, nullptr, nullptr, &value, &values_read);
-        // Ensure only one value is read
-        assert(rows_read == 1);
-        // There are no NULL values in the rows written
-        assert(values_read == 1);
-        // Verify the value written
-        parquet::Int96 expected_value;
-        expected_value.value[0] = col_row_counts[col_id];
-        expected_value.value[1] = col_row_counts[col_id] + 1;
-        expected_value.value[2] = col_row_counts[col_id] + 2;
-        for (int j = 0; j < 3; j++) {
-          assert(value.value[j] == expected_value.value[j]);
-        }
-        col_row_counts[col_id]++;
-      }
-
-      // Get the Column Reader for the Float column
-      col_id++;
-      column_reader = row_group_reader->Column(col_id);
-      parquet::FloatReader* float_reader =
-          static_cast<parquet::FloatReader*>(column_reader.get());
-      // Read all the rows in the column
-      while (float_reader->HasNext()) {
-        float value;
-        // Read one value at a time. The number of rows read is returned. values_read
-        // contains the number of non-null rows
-        rows_read = float_reader->ReadBatch(1, nullptr, nullptr, &value, &values_read);
-        // Ensure only one value is read
-        assert(rows_read == 1);
-        // There are no NULL values in the rows written
-        assert(values_read == 1);
-        // Verify the value written
-        float expected_value = static_cast<float>(col_row_counts[col_id]) * 1.1f;
-        assert(value == expected_value);
-        col_row_counts[col_id]++;
-      }
-
-      // Get the Column Reader for the Double column
-      col_id++;
-      column_reader = row_group_reader->Column(col_id);
-      parquet::DoubleReader* double_reader =
-          static_cast<parquet::DoubleReader*>(column_reader.get());
-      // Read all the rows in the column
-      while (double_reader->HasNext()) {
-        double value;
-        // Read one value at a time. The number of rows read is returned. values_read
-        // contains the number of non-null rows
-        rows_read = double_reader->ReadBatch(1, nullptr, nullptr, &value, &values_read);
-        // Ensure only one value is read
-        assert(rows_read == 1);
-        // There are no NULL values in the rows written
-        assert(values_read == 1);
-        // Verify the value written
-        double expected_value = col_row_counts[col_id] * 1.1111111;
-        assert(value == expected_value);
-        col_row_counts[col_id]++;
-      }
-
-      // Get the Column Reader for the ByteArray column
-      col_id++;
-      column_reader = row_group_reader->Column(col_id);
-      parquet::ByteArrayReader* ba_reader =
-          static_cast<parquet::ByteArrayReader*>(column_reader.get());
-      // Read all the rows in the column
-      while (ba_reader->HasNext()) {
-        parquet::ByteArray value;
-        // Read one value at a time. The number of rows read is returned. values_read
-        // contains the number of non-null rows
-        rows_read =
-            ba_reader->ReadBatch(1, &definition_level, nullptr, &value, &values_read);
-        // Ensure only one value is read
-        assert(rows_read == 1);
-        // Verify the value written
-        char expected_value[FIXED_LENGTH] = "parquet";
-        expected_value[7] = static_cast<char>('0' + col_row_counts[col_id] / 100);
-        expected_value[8] = static_cast<char>('0' + (col_row_counts[col_id] / 10) % 10);
-        expected_value[9] = static_cast<char>('0' + col_row_counts[col_id] % 10);
-        if (col_row_counts[col_id] % 2 == 0) {  // only alternate values exist
-          // There are no NULL values in the rows written
-          assert(values_read == 1);
-          assert(value.len == FIXED_LENGTH);
-          assert(memcmp(value.ptr, &expected_value[0], FIXED_LENGTH) == 0);
-          assert(definition_level == 1);
-        } else {
-          // There are NULL values in the rows written
-          assert(values_read == 0);
-          assert(definition_level == 0);
-        }
-        col_row_counts[col_id]++;
-      }
-
-      // Get the Column Reader for the FixedLengthByteArray column
-      col_id++;
-      column_reader = row_group_reader->Column(col_id);
-      parquet::FixedLenByteArrayReader* flba_reader =
-          static_cast<parquet::FixedLenByteArrayReader*>(column_reader.get());
-      // Read all the rows in the column
-      while (flba_reader->HasNext()) {
-        parquet::FixedLenByteArray value;
-        // Read one value at a time. The number of rows read is returned. values_read
-        // contains the number of non-null rows
-        rows_read = flba_reader->ReadBatch(1, nullptr, nullptr, &value, &values_read);
-        // Ensure only one value is read
-        assert(rows_read == 1);
-        // There are no NULL values in the rows written
-        assert(values_read == 1);
-        // Verify the value written
-        char v = static_cast<char>(col_row_counts[col_id]);
-        char expected_value[FIXED_LENGTH] = {v, v, v, v, v, v, v, v, v, v};
-        assert(memcmp(value.ptr, &expected_value[0], FIXED_LENGTH) == 0);
-        col_row_counts[col_id]++;
-      }
-    }
-  } catch (const std::exception& e) {
-    std::cerr << "Parquet read error: " << e.what() << std::endl;
-    return -1;
-  }
-
-  std::cout << "Parquet Writing and Reading Complete" << std::endl;
-
-  return 0;
-}
diff --git a/examples/low-level-api/reader_writer.h b/examples/low-level-api/reader_writer.h
deleted file mode 100644
index 3fda0cf..0000000
--- a/examples/low-level-api/reader_writer.h
+++ /dev/null
@@ -1,71 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements. See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership. The ASF licenses this file
-// to you 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.
-
-#include <arrow/io/file.h>
-#include <arrow/util/logging.h>
-
-#include <parquet/api/reader.h>
-#include <parquet/api/writer.h>
-
-using parquet::LogicalType;
-using parquet::Repetition;
-using parquet::Type;
-using parquet::schema::GroupNode;
-using parquet::schema::PrimitiveNode;
-
-constexpr int FIXED_LENGTH = 10;
-
-static std::shared_ptr<GroupNode> SetupSchema() {
-  parquet::schema::NodeVector fields;
-  // Create a primitive node named 'boolean_field' with type:BOOLEAN,
-  // repetition:REQUIRED
-  fields.push_back(PrimitiveNode::Make("boolean_field", Repetition::REQUIRED,
-                                       Type::BOOLEAN, LogicalType::NONE));
-
-  // Create a primitive node named 'int32_field' with type:INT32, repetition:REQUIRED,
-  // logical type:TIME_MILLIS
-  fields.push_back(PrimitiveNode::Make("int32_field", Repetition::REQUIRED, Type::INT32,
-                                       LogicalType::TIME_MILLIS));
-
-  // Create a primitive node named 'int64_field' with type:INT64, repetition:REPEATED
-  fields.push_back(PrimitiveNode::Make("int64_field", Repetition::REPEATED, Type::INT64,
-                                       LogicalType::NONE));
-
-  fields.push_back(PrimitiveNode::Make("int96_field", Repetition::REQUIRED, Type::INT96,
-                                       LogicalType::NONE));
-
-  fields.push_back(PrimitiveNode::Make("float_field", Repetition::REQUIRED, Type::FLOAT,
-                                       LogicalType::NONE));
-
-  fields.push_back(PrimitiveNode::Make("double_field", Repetition::REQUIRED, Type::DOUBLE,
-                                       LogicalType::NONE));
-
-  // Create a primitive node named 'ba_field' with type:BYTE_ARRAY, repetition:OPTIONAL
-  fields.push_back(PrimitiveNode::Make("ba_field", Repetition::OPTIONAL, Type::BYTE_ARRAY,
-                                       LogicalType::NONE));
-
-  // Create a primitive node named 'flba_field' with type:FIXED_LEN_BYTE_ARRAY,
-  // repetition:REQUIRED, field_length = FIXED_LENGTH
-  fields.push_back(PrimitiveNode::Make("flba_field", Repetition::REQUIRED,
-                                       Type::FIXED_LEN_BYTE_ARRAY, LogicalType::NONE,
-                                       FIXED_LENGTH));
-
-  // Create a GroupNode named 'schema' using the primitive nodes defined above
-  // This GroupNode is the root node of the schema tree
-  return std::static_pointer_cast<GroupNode>(
-      GroupNode::Make("schema", Repetition::REQUIRED, fields));
-}
diff --git a/examples/parquet-arrow/CMakeLists.txt b/examples/parquet-arrow/CMakeLists.txt
deleted file mode 100644
index 897fcfb..0000000
--- a/examples/parquet-arrow/CMakeLists.txt
+++ /dev/null
@@ -1,78 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you 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.
-
-# Require cmake that supports BYPRODUCTS in add_custom_command, ExternalProject_Add [1].
-cmake_minimum_required(VERSION 3.2.0)
-
-project(parquet-arrow-example)
-
-include(ExternalProject)
-include(FindPkgConfig)
-include(GNUInstallDirs)
-
-set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake_modules")
-
-# This ensures that things like gnu++11 get passed correctly
-set(CMAKE_CXX_STANDARD 11)
-
-# We require a C++11 compliant compiler
-set(CMAKE_CXX_STANDARD_REQUIRED ON)
-
-# We want to link dynamically against Arrow and Parquet
-set(PARQUET_BUILD_SHARED ON)
-
-
-# First search the packages in the system. If they are not found, use CMake's
-# ExternalProject mechanism to build them locally.
-find_package(Arrow)
-if (NOT ARROW_FOUND)
-  # set compile output directory
-  if (NOT CMAKE_BUILD_TYPE)
-    set(CMAKE_BUILD_TYPE Debug)
-  endif(NOT CMAKE_BUILD_TYPE)
-  string (TOLOWER ${CMAKE_BUILD_TYPE} BUILD_SUBDIR_NAME)
-  # If build in-source, create the latest symlink. If build out-of-source, which is
-  # preferred, simply output the binaries in the build folder
-  if (${CMAKE_SOURCE_DIR} STREQUAL "${CMAKE_CURRENT_BINARY_DIR}")
-    set(BUILD_OUTPUT_ROOT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/build/${BUILD_SUBDIR_NAME}")
-    # Link build/latest to the current build directory, to avoid developers
-    # accidentally running the latest debug build when in fact they're building
-    # release builds.
-    FILE(MAKE_DIRECTORY ${BUILD_OUTPUT_ROOT_DIRECTORY})
-    if (NOT APPLE)
-      set(MORE_ARGS "-T")
-    endif()
-  EXECUTE_PROCESS(COMMAND ln ${MORE_ARGS} -sf ${BUILD_OUTPUT_ROOT_DIRECTORY}
-    ${CMAKE_CURRENT_BINARY_DIR}/build/latest)
-  else()
-    set(BUILD_OUTPUT_ROOT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${BUILD_SUBDIR_NAME}")
-  endif()
-
-  include(ArrowExternalProject)
-  set(ARROW_VENDORED 1)
-else()
-  set(ARROW_VENDORED 0)
-endif()
-find_package(Parquet)
-
-include_directories(SYSTEM ${ARROW_INCLUDE_DIR} ${PARQUET_INCLUDE_DIR})
-
-add_executable(parquet-arrow-reader-writer src/reader-writer.cc)
-target_link_libraries(parquet-arrow-reader-writer ${PARQUET_SHARED_LIB} ${ARROW_SHARED_LIB})
-if (ARROW_VENDORED)
-  add_dependencies(parquet-arrow-reader-writer arrow_ep)
-endif()
diff --git a/examples/parquet-arrow/README.md b/examples/parquet-arrow/README.md
deleted file mode 100644
index e99819f..0000000
--- a/examples/parquet-arrow/README.md
+++ /dev/null
@@ -1,20 +0,0 @@
-<!---
-  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. See accompanying LICENSE file.
--->
-
-Using parquet-cpp with the arrow interface
-==========================================
-
-This folder contains an example project that shows how to setup a CMake project
-that consumes `parquet-cpp` as a library as well as how you can use the
-`parquet/arrow` interface to reading and write Apache Parquet files.
diff --git a/examples/parquet-arrow/cmake_modules/ArrowExternalProject.cmake b/examples/parquet-arrow/cmake_modules/ArrowExternalProject.cmake
deleted file mode 120000
index b535f6e..0000000
--- a/examples/parquet-arrow/cmake_modules/ArrowExternalProject.cmake
+++ /dev/null
@@ -1 +0,0 @@
-../../../cmake_modules/ArrowExternalProject.cmake
\ No newline at end of file
diff --git a/examples/parquet-arrow/cmake_modules/FindArrow.cmake b/examples/parquet-arrow/cmake_modules/FindArrow.cmake
deleted file mode 120000
index 6c451ce..0000000
--- a/examples/parquet-arrow/cmake_modules/FindArrow.cmake
+++ /dev/null
@@ -1 +0,0 @@
-../../../cmake_modules/FindArrow.cmake
\ No newline at end of file
diff --git a/examples/parquet-arrow/cmake_modules/FindParquet.cmake b/examples/parquet-arrow/cmake_modules/FindParquet.cmake
deleted file mode 100644
index 8bbe05f..0000000
--- a/examples/parquet-arrow/cmake_modules/FindParquet.cmake
+++ /dev/null
@@ -1,145 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you 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.
-
-# - Find PARQUET (parquet/parquet.h, libparquet.a, libparquet.so)
-# This module defines
-#  PARQUET_INCLUDE_DIR, directory containing headers
-#  PARQUET_LIBS, directory containing parquet libraries
-#  PARQUET_STATIC_LIB, path to libparquet.a
-#  PARQUET_SHARED_LIB, path to libparquet's shared library
-#  PARQUET_SHARED_IMP_LIB, path to libparquet's import library (MSVC only)
-#  PARQUET_FOUND, whether parquet has been found
-
-include(FindPkgConfig)
-
-if(NOT "$ENV{PARQUET_HOME}" STREQUAL "")
-    set(PARQUET_HOME "$ENV{PARQUET_HOME}")
-endif()
-
-if (MSVC)
-  SET(CMAKE_FIND_LIBRARY_SUFFIXES ".lib" ".dll")
-
-  if (MSVC AND NOT PARQUET_MSVC_STATIC_LIB_SUFFIX)
-    set(PARQUET_MSVC_STATIC_LIB_SUFFIX "_static")
-  endif()
-
-  find_library(PARQUET_SHARED_LIBRARIES NAMES parquet
-    PATHS ${PARQUET_HOME} NO_DEFAULT_PATH
-    PATH_SUFFIXES "bin" )
-
-  get_filename_component(PARQUET_SHARED_LIBS ${PARQUET_SHARED_LIBRARIES} PATH )
-endif ()
-
-if(PARQUET_HOME)
-    set(PARQUET_SEARCH_HEADER_PATHS
-        ${PARQUET_HOME}/include
-        )
-    set(PARQUET_SEARCH_LIB_PATH
-        ${PARQUET_HOME}/lib
-        )
-    find_path(PARQUET_INCLUDE_DIR parquet/api/reader.h PATHS
-        ${PARQUET_SEARCH_HEADER_PATHS}
-        # make sure we don't accidentally pick up a different version
-        NO_DEFAULT_PATH
-        )
-    find_library(PARQUET_LIBRARIES NAMES parquet
-        PATHS ${PARQUET_HOME} NO_DEFAULT_PATH
-        PATH_SUFFIXES "lib")
-    get_filename_component(PARQUET_LIBS ${PARQUET_LIBRARIES} PATH )
-
-    # Try to autodiscover the Parquet ABI version
-    get_filename_component(PARQUET_LIB_REALPATH ${PARQUET_LIBRARIES} REALPATH)
-    get_filename_component(PARQUET_EXT_REALPATH ${PARQUET_LIB_REALPATH} EXT)
-    string(REGEX MATCH ".([0-9]+.[0-9]+.[0-9]+)" HAS_ABI_VERSION ${PARQUET_EXT_REALPATH})
-    if (HAS_ABI_VERSION)
-      if (APPLE)
-        string(REGEX REPLACE ".([0-9]+.[0-9]+.[0-9]+).dylib" "\\1" PARQUET_ABI_VERSION ${PARQUET_EXT_REALPATH})
-      else()
-        string(REGEX REPLACE ".so.([0-9]+.[0-9]+.[0-9]+)" "\\1" PARQUET_ABI_VERSION ${PARQUET_EXT_REALPATH})
-      endif()
-      string(REGEX REPLACE "([0-9]+).[0-9]+.[0-9]+" "\\1" PARQUET_SO_VERSION ${PARQUET_ABI_VERSION})
-    else()
-      set(PARQUET_ABI_VERSION "1.0.0")
-      set(PARQUET_SO_VERSION "1")
-    endif()
-else()
-    pkg_check_modules(PARQUET parquet)
-    if (PARQUET_FOUND)
-        pkg_get_variable(PARQUET_ABI_VERSION parquet abi_version)
-        message(STATUS "Parquet C++ ABI version: ${PARQUET_ABI_VERSION}")
-        pkg_get_variable(PARQUET_SO_VERSION parquet so_version)
-        message(STATUS "Parquet C++ SO version: ${PARQUET_SO_VERSION}")
-        set(PARQUET_INCLUDE_DIR ${PARQUET_INCLUDE_DIRS})
-        set(PARQUET_LIBS ${PARQUET_LIBRARY_DIRS})
-        set(PARQUET_SEARCH_LIB_PATH ${PARQUET_LIBRARY_DIRS})
-        message(STATUS "Searching for parquet libs in: ${PARQUET_SEARCH_LIB_PATH}")
-        find_library(PARQUET_LIBRARIES NAMES parquet
-            PATHS ${PARQUET_SEARCH_LIB_PATH} NO_DEFAULT_PATH)
-    else()
-        find_path(PARQUET_INCLUDE_DIR NAMES parquet/api/reader.h )
-        find_library(PARQUET_LIBRARIES NAMES parquet)
-        get_filename_component(PARQUET_LIBS ${PARQUET_LIBRARIES} PATH )
-    endif()
-endif()
-
-if (PARQUET_INCLUDE_DIR AND PARQUET_LIBRARIES)
-  set(PARQUET_FOUND TRUE)
-  set(PARQUET_LIB_NAME parquet)
-  if (MSVC)
-    set(PARQUET_STATIC_LIB "${PARQUET_LIBS}/${PARQUET_LIB_NAME}${PARQUET_MSVC_STATIC_LIB_SUFFIX}${CMAKE_STATIC_LIBRARY_SUFFIX}")
-    set(PARQUET_SHARED_LIB "${PARQUET_SHARED_LIBS}/${PARQUET_LIB_NAME}${CMAKE_SHARED_LIBRARY_SUFFIX}")
-    set(PARQUET_SHARED_IMP_LIB "${PARQUET_LIBS}/${PARQUET_LIB_NAME}.lib")
-  else()
-    set(PARQUET_STATIC_LIB ${PARQUET_LIBS}/${CMAKE_STATIC_LIBRARY_PREFIX}${PARQUET_LIB_NAME}.a)
-    set(PARQUET_SHARED_LIB ${PARQUET_LIBS}/${CMAKE_SHARED_LIBRARY_PREFIX}${PARQUET_LIB_NAME}${CMAKE_SHARED_LIBRARY_SUFFIX})
-  endif()
-else ()
-  set(PARQUET_FOUND FALSE)
-endif ()
-
-if (PARQUET_FOUND)
-  if (NOT Parquet_FIND_QUIETLY)
-    message(STATUS "Found the Parquet library: ${PARQUET_LIBRARIES}")
-  endif ()
-else ()
-  if (NOT Parquet_FIND_QUIETLY)
-    if (NOT PARQUET_FOUND)
-      set(PARQUET_ERR_MSG "${PARQUET_ERR_MSG} Could not find the parquet library.")
-    endif()
-
-    set(PARQUET_ERR_MSG "${PARQUET_ERR_MSG} Looked in ")
-    if ( _parquet_roots )
-      set(PARQUET_ERR_MSG "${PARQUET_ERR_MSG} in ${_parquet_roots}.")
-    else ()
-      set(PARQUET_ERR_MSG "${PARQUET_ERR_MSG} system search paths.")
-    endif ()
-    if (Parquet_FIND_REQUIRED)
-      message(FATAL_ERROR "${PARQUET_ERR_MSG}")
-    else (Parquet_FIND_REQUIRED)
-      message(STATUS "${PARQUET_ERR_MSG}")
-    endif (Parquet_FIND_REQUIRED)
-  endif ()
-endif ()
-
-mark_as_advanced(
-  PARQUET_FOUND
-  PARQUET_INCLUDE_DIR
-  PARQUET_LIBS
-  PARQUET_LIBRARIES
-  PARQUET_STATIC_LIB
-  PARQUET_SHARED_LIB
-)
diff --git a/examples/parquet-arrow/src/reader-writer.cc b/examples/parquet-arrow/src/reader-writer.cc
deleted file mode 100644
index f333cab..0000000
--- a/examples/parquet-arrow/src/reader-writer.cc
+++ /dev/null
@@ -1,134 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements. See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership. The ASF licenses this file
-// to you 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.
-
-#include <arrow/api.h>
-#include <arrow/io/api.h>
-#include <parquet/arrow/reader.h>
-#include <parquet/arrow/writer.h>
-#include <parquet/exception.h>
-
-// #0 Build dummy data to pass around
-// To have some input data, we first create an Arrow Table that holds
-// some data.
-std::shared_ptr<arrow::Table> generate_table() {
-  arrow::Int64Builder i64builder;
-  PARQUET_THROW_NOT_OK(i64builder.Append({1, 2, 3, 4, 5}));
-  std::shared_ptr<arrow::Array> i64array;
-  PARQUET_THROW_NOT_OK(i64builder.Finish(&i64array));
-
-  arrow::StringBuilder strbuilder;
-  PARQUET_THROW_NOT_OK(strbuilder.Append("some"));
-  PARQUET_THROW_NOT_OK(strbuilder.Append("string"));
-  PARQUET_THROW_NOT_OK(strbuilder.Append("content"));
-  PARQUET_THROW_NOT_OK(strbuilder.Append("in"));
-  PARQUET_THROW_NOT_OK(strbuilder.Append("rows"));
-  std::shared_ptr<arrow::Array> strarray;
-  PARQUET_THROW_NOT_OK(strbuilder.Finish(&strarray));
-
-  std::shared_ptr<arrow::Schema> schema = arrow::schema(
-      {arrow::field("int", arrow::int64()), arrow::field("str", arrow::utf8())});
-
-  return arrow::Table::Make(schema, {i64array, strarray});
-}
-
-// #1 Write out the data as a Parquet file
-void write_parquet_file(const arrow::Table& table) {
-  std::shared_ptr<arrow::io::FileOutputStream> outfile;
-  PARQUET_THROW_NOT_OK(
-      arrow::io::FileOutputStream::Open("parquet-arrow-example.parquet", &outfile));
-  // The last argument to the function call is the size of the RowGroup in
-  // the parquet file. Normally you would choose this to be rather large but
-  // for the example, we use a small value to have multiple RowGroups.
-  PARQUET_THROW_NOT_OK(
-      parquet::arrow::WriteTable(table, arrow::default_memory_pool(), outfile, 3));
-}
-
-// #2: Fully read in the file
-void read_whole_file() {
-  std::cout << "Reading parquet-arrow-example.parquet at once" << std::endl;
-  std::shared_ptr<arrow::io::ReadableFile> infile;
-  PARQUET_THROW_NOT_OK(arrow::io::ReadableFile::Open(
-      "parquet-arrow-example.parquet", arrow::default_memory_pool(), &infile));
-
-  std::unique_ptr<parquet::arrow::FileReader> reader;
-  PARQUET_THROW_NOT_OK(
-      parquet::arrow::OpenFile(infile, arrow::default_memory_pool(), &reader));
-  std::shared_ptr<arrow::Table> table;
-  PARQUET_THROW_NOT_OK(reader->ReadTable(&table));
-  std::cout << "Loaded " << table->num_rows() << " rows in " << table->num_columns()
-            << " columns." << std::endl;
-}
-
-// #3: Read only a single RowGroup of the parquet file
-void read_single_rowgroup() {
-  std::cout << "Reading first RowGroup of parquet-arrow-example.parquet" << std::endl;
-  std::shared_ptr<arrow::io::ReadableFile> infile;
-  PARQUET_THROW_NOT_OK(arrow::io::ReadableFile::Open(
-      "parquet-arrow-example.parquet", arrow::default_memory_pool(), &infile));
-
-  std::unique_ptr<parquet::arrow::FileReader> reader;
-  PARQUET_THROW_NOT_OK(
-      parquet::arrow::OpenFile(infile, arrow::default_memory_pool(), &reader));
-  std::shared_ptr<arrow::Table> table;
-  PARQUET_THROW_NOT_OK(reader->RowGroup(0)->ReadTable(&table));
-  std::cout << "Loaded " << table->num_rows() << " rows in " << table->num_columns()
-            << " columns." << std::endl;
-}
-
-// #4: Read only a single column of the whole parquet file
-void read_single_column() {
-  std::cout << "Reading first column of parquet-arrow-example.parquet" << std::endl;
-  std::shared_ptr<arrow::io::ReadableFile> infile;
-  PARQUET_THROW_NOT_OK(arrow::io::ReadableFile::Open(
-      "parquet-arrow-example.parquet", arrow::default_memory_pool(), &infile));
-
-  std::unique_ptr<parquet::arrow::FileReader> reader;
-  PARQUET_THROW_NOT_OK(
-      parquet::arrow::OpenFile(infile, arrow::default_memory_pool(), &reader));
-  std::shared_ptr<arrow::Array> array;
-  PARQUET_THROW_NOT_OK(reader->ReadColumn(0, &array));
-  PARQUET_THROW_NOT_OK(arrow::PrettyPrint(*array, 4, &std::cout));
-  std::cout << std::endl;
-}
-
-// #5: Read only a single column of a RowGroup (this is known as ColumnChunk)
-//     from the Parquet file.
-void read_single_column_chunk() {
-  std::cout << "Reading first ColumnChunk of the first RowGroup of "
-               "parquet-arrow-example.parquet"
-            << std::endl;
-  std::shared_ptr<arrow::io::ReadableFile> infile;
-  PARQUET_THROW_NOT_OK(arrow::io::ReadableFile::Open(
-      "parquet-arrow-example.parquet", arrow::default_memory_pool(), &infile));
-
-  std::unique_ptr<parquet::arrow::FileReader> reader;
-  PARQUET_THROW_NOT_OK(
-      parquet::arrow::OpenFile(infile, arrow::default_memory_pool(), &reader));
-  std::shared_ptr<arrow::Array> array;
-  PARQUET_THROW_NOT_OK(reader->RowGroup(0)->Column(0)->Read(&array));
-  PARQUET_THROW_NOT_OK(arrow::PrettyPrint(*array, 4, &std::cout));
-  std::cout << std::endl;
-}
-
-int main(int argc, char** argv) {
-  std::shared_ptr<arrow::Table> table = generate_table();
-  write_parquet_file(*table);
-  read_whole_file();
-  read_single_rowgroup();
-  read_single_column();
-  read_single_column_chunk();
-}
diff --git a/src/parquet/.gitignore b/src/parquet/.gitignore
deleted file mode 100644
index 0695270..0000000
--- a/src/parquet/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-parquet_constants.*
-parquet_types.*
\ No newline at end of file
diff --git a/src/parquet/CMakeLists.txt b/src/parquet/CMakeLists.txt
deleted file mode 100644
index 93a242c..0000000
--- a/src/parquet/CMakeLists.txt
+++ /dev/null
@@ -1,72 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you 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.
-
-# Headers: top level
-install(FILES
-  bloom_filter.h
-  column_reader.h
-  column_page.h
-  column_scanner.h
-  column_writer.h
-  encoding.h
-  exception.h
-  file_reader.h
-  file_writer.h
-  hasher.h
-  metadata.h
-  murmur3.h
-  printer.h
-  properties.h
-  schema.h
-  statistics.h
-  types.h
-  DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/parquet")
-
-configure_file(parquet_version.h.in
-  "${CMAKE_CURRENT_SOURCE_DIR}/parquet_version.h"
-  @ONLY)
-
-install(FILES
-  "${CMAKE_CURRENT_SOURCE_DIR}/parquet_version.h"
-  DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/parquet")
-
-# pkg-config support
-configure_file(parquet.pc.in
-  "${CMAKE_CURRENT_BINARY_DIR}/parquet.pc"
-  @ONLY)
-
-install(FILES
-  "${CMAKE_CURRENT_BINARY_DIR}/parquet.pc"
-  DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig/")
-
-ADD_PARQUET_TEST(bloom_filter-test)
-ADD_PARQUET_TEST(column_reader-test)
-ADD_PARQUET_TEST(column_scanner-test)
-ADD_PARQUET_TEST(column_writer-test)
-ADD_PARQUET_TEST(file-deserialize-test)
-ADD_PARQUET_TEST(file-serialize-test)
-ADD_PARQUET_TEST(properties-test)
-ADD_PARQUET_TEST(statistics-test)
-ADD_PARQUET_TEST(encoding-test)
-ADD_PARQUET_TEST(metadata-test)
-ADD_PARQUET_TEST(public-api-test)
-ADD_PARQUET_TEST(types-test)
-ADD_PARQUET_TEST(reader-test)
-ADD_PARQUET_TEST(schema-test)
-
-ADD_PARQUET_BENCHMARK(column-io-benchmark)
-ADD_PARQUET_BENCHMARK(encoding-benchmark)
diff --git a/src/parquet/README b/src/parquet/README
deleted file mode 100644
index fc16a46..0000000
--- a/src/parquet/README
+++ /dev/null
@@ -1,10 +0,0 @@
-The CompatibilityTest of bloom_filter-test.cc is used to test cross compatibility of
-Bloom filters between parquet-mr and parquet-cpp. It reads the Bloom filter binary
-generated by the Bloom filter class in the parquet-mr project and tests whether the
-values inserted before could be filtered or not.
-
-The Bloom filter binary is generated by three steps from Parquet-mr:
-Step 1: Construct a Bloom filter with 1024 bytes of bitset.
-Step 2: Insert hashes of "hello", "parquet", "bloom", "filter" strings to Bloom filter
-by calling hash and insert APIs.
-Step 3: Call writeTo API to write to File.
diff --git a/src/parquet/api/CMakeLists.txt b/src/parquet/api/CMakeLists.txt
deleted file mode 100644
index 79fc716..0000000
--- a/src/parquet/api/CMakeLists.txt
+++ /dev/null
@@ -1,24 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you 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.
-
-# Headers: public api
-install(FILES
-  io.h
-  reader.h
-  writer.h
-  schema.h
-  DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/parquet/api")
diff --git a/src/parquet/api/io.h b/src/parquet/api/io.h
deleted file mode 100644
index 96d3bc0..0000000
--- a/src/parquet/api/io.h
+++ /dev/null
@@ -1,24 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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.
-
-#ifndef PARQUET_API_IO_H
-#define PARQUET_API_IO_H
-
-#include "parquet/exception.h"
-#include "parquet/util/memory.h"
-
-#endif  // PARQUET_API_IO_H
diff --git a/src/parquet/api/reader.h b/src/parquet/api/reader.h
deleted file mode 100644
index 505654f..0000000
--- a/src/parquet/api/reader.h
+++ /dev/null
@@ -1,35 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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.
-
-#ifndef PARQUET_API_READER_H
-#define PARQUET_API_READER_H
-
-// Column reader API
-#include "parquet/column_reader.h"
-#include "parquet/column_scanner.h"
-#include "parquet/exception.h"
-#include "parquet/file_reader.h"
-#include "parquet/metadata.h"
-#include "parquet/printer.h"
-
-// Schemas
-#include "parquet/api/schema.h"
-
-// IO
-#include "parquet/api/io.h"
-
-#endif  // PARQUET_API_READER_H
diff --git a/src/parquet/api/schema.h b/src/parquet/api/schema.h
deleted file mode 100644
index 2e6c3b3..0000000
--- a/src/parquet/api/schema.h
+++ /dev/null
@@ -1,24 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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.
-
-#ifndef PARQUET_API_SCHEMA_H
-#define PARQUET_API_SCHEMA_H
-
-// Schemas
-#include "parquet/schema.h"
-
-#endif  // PARQUET_API_SCHEMA_H
diff --git a/src/parquet/api/writer.h b/src/parquet/api/writer.h
deleted file mode 100644
index 3b4e42f..0000000
--- a/src/parquet/api/writer.h
+++ /dev/null
@@ -1,27 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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.
-
-#ifndef PARQUET_API_WRITER_H
-#define PARQUET_API_WRITER_H
-
-#include "parquet/api/io.h"
-#include "parquet/api/schema.h"
-#include "parquet/column_writer.h"
-#include "parquet/exception.h"
-#include "parquet/file_writer.h"
-
-#endif  // PARQUET_API_WRITER_H
diff --git a/src/parquet/arrow/CMakeLists.txt b/src/parquet/arrow/CMakeLists.txt
deleted file mode 100644
index 616555f..0000000
--- a/src/parquet/arrow/CMakeLists.txt
+++ /dev/null
@@ -1,30 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you 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.
-
-ADD_PARQUET_TEST(arrow-schema-test)
-ADD_PARQUET_TEST(arrow-reader-writer-test)
-
-if(PARQUET_BUILD_BENCHMARKS)
-  ADD_PARQUET_BENCHMARK(arrow-reader-writer-benchmark)
-endif()
-
-# Headers: top level
-install(FILES
-  reader.h
-  schema.h
-  writer.h
-  DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/parquet/arrow")
diff --git a/src/parquet/arrow/arrow-reader-writer-benchmark.cc b/src/parquet/arrow/arrow-reader-writer-benchmark.cc
deleted file mode 100644
index 41cb88d..0000000
--- a/src/parquet/arrow/arrow-reader-writer-benchmark.cc
+++ /dev/null
@@ -1,263 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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.
-
-#include "benchmark/benchmark.h"
-
-#include <iostream>
-
-#include "parquet/arrow/reader.h"
-#include "parquet/arrow/writer.h"
-#include "parquet/column_reader.h"
-#include "parquet/column_writer.h"
-#include "parquet/file_reader.h"
-#include "parquet/file_writer.h"
-#include "parquet/util/memory.h"
-
-#include "arrow/api.h"
-
-using arrow::BooleanBuilder;
-using arrow::NumericBuilder;
-
-#define EXIT_NOT_OK(s)                                        \
-  do {                                                        \
-    ::arrow::Status _s = (s);                                 \
-    if (ARROW_PREDICT_FALSE(!_s.ok())) {                      \
-      std::cout << "Exiting: " << _s.ToString() << std::endl; \
-      exit(EXIT_FAILURE);                                     \
-    }                                                         \
-  } while (0)
-
-namespace parquet {
-
-using arrow::FileReader;
-using arrow::WriteTable;
-using schema::PrimitiveNode;
-
-namespace benchmark {
-
-// This should result in multiple pages for most primitive types
-constexpr int64_t BENCHMARK_SIZE = 10 * 1024 * 1024;
-
-template <typename ParquetType>
-struct benchmark_traits {};
-
-template <>
-struct benchmark_traits<Int32Type> {
-  using arrow_type = ::arrow::Int32Type;
-};
-
-template <>
-struct benchmark_traits<Int64Type> {
-  using arrow_type = ::arrow::Int64Type;
-};
-
-template <>
-struct benchmark_traits<DoubleType> {
-  using arrow_type = ::arrow::DoubleType;
-};
-
-template <>
-struct benchmark_traits<BooleanType> {
-  using arrow_type = ::arrow::BooleanType;
-};
-
-template <typename ParquetType>
-using ArrowType = typename benchmark_traits<ParquetType>::arrow_type;
-
-template <typename ParquetType>
-std::shared_ptr<ColumnDescriptor> MakeSchema(Repetition::type repetition) {
-  auto node = PrimitiveNode::Make("int64", repetition, ParquetType::type_num);
-  return std::make_shared<ColumnDescriptor>(node, repetition != Repetition::REQUIRED,
-                                            repetition == Repetition::REPEATED);
-}
-
-template <bool nullable, typename ParquetType>
-void SetBytesProcessed(::benchmark::State& state) {
-  int64_t bytes_processed =
-      state.iterations() * BENCHMARK_SIZE * sizeof(typename ParquetType::c_type);
-  if (nullable) {
-    bytes_processed += state.iterations() * BENCHMARK_SIZE * sizeof(int16_t);
-  }
-  state.SetBytesProcessed(bytes_processed);
-}
-
-template <typename ParquetType>
-std::shared_ptr<::arrow::Table> TableFromVector(
-    const std::vector<typename ParquetType::c_type>& vec, bool nullable) {
-  ::arrow::TypePtr type = std::make_shared<ArrowType<ParquetType>>();
-  NumericBuilder<ArrowType<ParquetType>> builder;
-  if (nullable) {
-    std::vector<uint8_t> valid_bytes(BENCHMARK_SIZE, 0);
-    int n = {0};
-    std::generate(valid_bytes.begin(), valid_bytes.end(), [&n] { return n++ % 2; });
-    EXIT_NOT_OK(builder.AppendValues(vec.data(), vec.size(), valid_bytes.data()));
-  } else {
-    EXIT_NOT_OK(builder.AppendValues(vec.data(), vec.size(), nullptr));
-  }
-  std::shared_ptr<::arrow::Array> array;
-  EXIT_NOT_OK(builder.Finish(&array));
-
-  auto field = ::arrow::field("column", type, nullable);
-  auto schema = ::arrow::schema({field});
-  auto column = std::make_shared<::arrow::Column>(field, array);
-  return ::arrow::Table::Make(schema, {column});
-}
-
-template <>
-std::shared_ptr<::arrow::Table> TableFromVector<BooleanType>(const std::vector<bool>& vec,
-                                                             bool nullable) {
-  BooleanBuilder builder;
-  if (nullable) {
-    std::vector<bool> valid_bytes(BENCHMARK_SIZE, 0);
-    int n = {0};
-    std::generate(valid_bytes.begin(), valid_bytes.end(),
-                  [&n] { return (n++ % 2) != 0; });
-    EXIT_NOT_OK(builder.AppendValues(vec, valid_bytes));
-  } else {
-    EXIT_NOT_OK(builder.AppendValues(vec));
-  }
-  std::shared_ptr<::arrow::Array> array;
-  EXIT_NOT_OK(builder.Finish(&array));
-
-  auto field = ::arrow::field("column", ::arrow::boolean(), nullable);
-  auto schema = std::make_shared<::arrow::Schema>(
-      std::vector<std::shared_ptr<::arrow::Field>>({field}));
-  auto column = std::make_shared<::arrow::Column>(field, array);
-  return ::arrow::Table::Make(schema, {column});
-}
-
-template <bool nullable, typename ParquetType>
-static void BM_WriteColumn(::benchmark::State& state) {
-  std::vector<typename ParquetType::c_type> values(BENCHMARK_SIZE, 128);
-  std::shared_ptr<::arrow::Table> table = TableFromVector<ParquetType>(values, nullable);
-
-  while (state.KeepRunning()) {
-    auto output = std::make_shared<InMemoryOutputStream>();
-    EXIT_NOT_OK(
-        WriteTable(*table, ::arrow::default_memory_pool(), output, BENCHMARK_SIZE));
-  }
-  SetBytesProcessed<nullable, ParquetType>(state);
-}
-
-BENCHMARK_TEMPLATE2(BM_WriteColumn, false, Int32Type);
-BENCHMARK_TEMPLATE2(BM_WriteColumn, true, Int32Type);
-
-BENCHMARK_TEMPLATE2(BM_WriteColumn, false, Int64Type);
-BENCHMARK_TEMPLATE2(BM_WriteColumn, true, Int64Type);
-
-BENCHMARK_TEMPLATE2(BM_WriteColumn, false, DoubleType);
-BENCHMARK_TEMPLATE2(BM_WriteColumn, true, DoubleType);
-
-BENCHMARK_TEMPLATE2(BM_WriteColumn, false, BooleanType);
-BENCHMARK_TEMPLATE2(BM_WriteColumn, true, BooleanType);
-
-template <bool nullable, typename ParquetType>
-static void BM_ReadColumn(::benchmark::State& state) {
-  std::vector<typename ParquetType::c_type> values(BENCHMARK_SIZE, 128);
-  std::shared_ptr<::arrow::Table> table = TableFromVector<ParquetType>(values, nullable);
-  auto output = std::make_shared<InMemoryOutputStream>();
-  EXIT_NOT_OK(WriteTable(*table, ::arrow::default_memory_pool(), output, BENCHMARK_SIZE));
-  std::shared_ptr<Buffer> buffer = output->GetBuffer();
-
-  while (state.KeepRunning()) {
-    auto reader =
-        ParquetFileReader::Open(std::make_shared<::arrow::io::BufferReader>(buffer));
-    FileReader filereader(::arrow::default_memory_pool(), std::move(reader));
-    std::shared_ptr<::arrow::Table> table;
-    EXIT_NOT_OK(filereader.ReadTable(&table));
-  }
-  SetBytesProcessed<nullable, ParquetType>(state);
-}
-
-BENCHMARK_TEMPLATE2(BM_ReadColumn, false, Int32Type);
-BENCHMARK_TEMPLATE2(BM_ReadColumn, true, Int32Type);
-
-BENCHMARK_TEMPLATE2(BM_ReadColumn, false, Int64Type);
-BENCHMARK_TEMPLATE2(BM_ReadColumn, true, Int64Type);
-
-BENCHMARK_TEMPLATE2(BM_ReadColumn, false, DoubleType);
-BENCHMARK_TEMPLATE2(BM_ReadColumn, true, DoubleType);
-
-BENCHMARK_TEMPLATE2(BM_ReadColumn, false, BooleanType);
-BENCHMARK_TEMPLATE2(BM_ReadColumn, true, BooleanType);
-
-static void BM_ReadIndividualRowGroups(::benchmark::State& state) {
-  std::vector<int64_t> values(BENCHMARK_SIZE, 128);
-  std::shared_ptr<::arrow::Table> table = TableFromVector<Int64Type>(values, true);
-  auto output = std::make_shared<InMemoryOutputStream>();
-  // This writes 10 RowGroups
-  EXIT_NOT_OK(
-      WriteTable(*table, ::arrow::default_memory_pool(), output, BENCHMARK_SIZE / 10));
-  std::shared_ptr<Buffer> buffer = output->GetBuffer();
-
-  while (state.KeepRunning()) {
-    auto reader =
-        ParquetFileReader::Open(std::make_shared<::arrow::io::BufferReader>(buffer));
-    FileReader filereader(::arrow::default_memory_pool(), std::move(reader));
-
-    std::vector<std::shared_ptr<::arrow::Table>> tables;
-    for (int i = 0; i < filereader.num_row_groups(); i++) {
-      // Only read the even numbered RowGroups
-      if ((i % 2) == 0) {
-        std::shared_ptr<::arrow::Table> table;
-        EXIT_NOT_OK(filereader.RowGroup(i)->ReadTable(&table));
-        tables.push_back(table);
-      }
-    }
-
-    std::shared_ptr<::arrow::Table> final_table;
-    EXIT_NOT_OK(ConcatenateTables(tables, &final_table));
-  }
-  SetBytesProcessed<true, Int64Type>(state);
-}
-
-BENCHMARK(BM_ReadIndividualRowGroups);
-
-static void BM_ReadMultipleRowGroups(::benchmark::State& state) {
-  std::vector<int64_t> values(BENCHMARK_SIZE, 128);
-  std::shared_ptr<::arrow::Table> table = TableFromVector<Int64Type>(values, true);
-  auto output = std::make_shared<InMemoryOutputStream>();
-  // This writes 10 RowGroups
-  EXIT_NOT_OK(
-      WriteTable(*table, ::arrow::default_memory_pool(), output, BENCHMARK_SIZE / 10));
-  std::shared_ptr<Buffer> buffer = output->GetBuffer();
-
-  while (state.KeepRunning()) {
-    auto reader =
-        ParquetFileReader::Open(std::make_shared<::arrow::io::BufferReader>(buffer));
-    FileReader filereader(::arrow::default_memory_pool(), std::move(reader));
-
-    std::vector<std::shared_ptr<::arrow::Table>> tables;
-    std::vector<int> rgs;
-    for (int i = 0; i < filereader.num_row_groups(); i++) {
-      // Only read the even numbered RowGroups
-      if ((i % 2) == 0) {
-        rgs.push_back(i);
-      }
-    }
-
-    std::shared_ptr<::arrow::Table> table;
-    EXIT_NOT_OK(filereader.ReadRowGroups(rgs, &table));
-  }
-  SetBytesProcessed<true, Int64Type>(state);
-}
-
-BENCHMARK(BM_ReadMultipleRowGroups);
-
-}  // namespace benchmark
-
-}  // namespace parquet
diff --git a/src/parquet/arrow/arrow-reader-writer-test.cc b/src/parquet/arrow/arrow-reader-writer-test.cc
deleted file mode 100644
index 5f4e123..0000000
--- a/src/parquet/arrow/arrow-reader-writer-test.cc
+++ /dev/null
@@ -1,2376 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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.
-
-#ifdef _MSC_VER
-#pragma warning(push)
-// Disable forcing value to bool warnings
-#pragma warning(disable : 4800)
-#endif
-
-#include "gtest/gtest.h"
-
-#include <arrow/compute/api.h>
-#include <cstdint>
-#include <functional>
-#include <sstream>
-#include <vector>
-
-#include "parquet/api/reader.h"
-#include "parquet/api/writer.h"
-
-#include "parquet/arrow/reader.h"
-#include "parquet/arrow/schema.h"
-#include "parquet/arrow/test-util.h"
-#include "parquet/arrow/writer.h"
-
-#include "parquet/file_writer.h"
-
-#include "parquet/util/test-common.h"
-
-#include "arrow/api.h"
-#include "arrow/test-util.h"
-#include "arrow/type_traits.h"
-#include "arrow/util/decimal.h"
-
-using arrow::Array;
-using arrow::ArrayVisitor;
-using arrow::Buffer;
-using arrow::ChunkedArray;
-using arrow::Column;
-using arrow::DataType;
-using arrow::default_memory_pool;
-using arrow::ListArray;
-using arrow::PrimitiveArray;
-using arrow::ResizableBuffer;
-using arrow::Status;
-using arrow::Table;
-using arrow::TimeUnit;
-using arrow::compute::Datum;
-using arrow::compute::DictionaryEncode;
-using arrow::compute::FunctionContext;
-using arrow::io::BufferReader;
-
-using arrow::randint;
-using arrow::random_is_valid;
-
-using ArrowId = ::arrow::Type;
-using ParquetType = parquet::Type;
-using parquet::arrow::FromParquetSchema;
-using parquet::schema::GroupNode;
-using parquet::schema::NodePtr;
-using parquet::schema::PrimitiveNode;
-
-using ColumnVector = std::vector<std::shared_ptr<arrow::Column>>;
-
-namespace parquet {
-namespace arrow {
-
-static constexpr int SMALL_SIZE = 100;
-#ifdef PARQUET_VALGRIND
-static constexpr int LARGE_SIZE = 1000;
-#else
-static constexpr int LARGE_SIZE = 10000;
-#endif
-
-static constexpr uint32_t kDefaultSeed = 0;
-
-LogicalType::type get_logical_type(const ::DataType& type) {
-  switch (type.id()) {
-    case ArrowId::UINT8:
-      return LogicalType::UINT_8;
-    case ArrowId::INT8:
-      return LogicalType::INT_8;
-    case ArrowId::UINT16:
-      return LogicalType::UINT_16;
-    case ArrowId::INT16:
-      return LogicalType::INT_16;
-    case ArrowId::UINT32:
-      return LogicalType::UINT_32;
-    case ArrowId::INT32:
-      return LogicalType::INT_32;
-    case ArrowId::UINT64:
-      return LogicalType::UINT_64;
-    case ArrowId::INT64:
-      return LogicalType::INT_64;
-    case ArrowId::STRING:
-      return LogicalType::UTF8;
-    case ArrowId::DATE32:
-      return LogicalType::DATE;
-    case ArrowId::DATE64:
-      return LogicalType::DATE;
-    case ArrowId::TIMESTAMP: {
-      const auto& ts_type = static_cast<const ::arrow::TimestampType&>(type);
-      switch (ts_type.unit()) {
-        case TimeUnit::MILLI:
-          return LogicalType::TIMESTAMP_MILLIS;
-        case TimeUnit::MICRO:
-          return LogicalType::TIMESTAMP_MICROS;
-        default:
-          DCHECK(false) << "Only MILLI and MICRO units supported for Arrow timestamps "
-                           "with Parquet.";
-      }
-    }
-    case ArrowId::TIME32:
-      return LogicalType::TIME_MILLIS;
-    case ArrowId::TIME64:
-      return LogicalType::TIME_MICROS;
-    case ArrowId::DICTIONARY: {
-      const ::arrow::DictionaryType& dict_type =
-          static_cast<const ::arrow::DictionaryType&>(type);
-      return get_logical_type(*dict_type.dictionary()->type());
-    }
-    case ArrowId::DECIMAL:
-      return LogicalType::DECIMAL;
-    default:
-      break;
-  }
-  return LogicalType::NONE;
-}
-
-ParquetType::type get_physical_type(const ::DataType& type) {
-  switch (type.id()) {
-    case ArrowId::BOOL:
-      return ParquetType::BOOLEAN;
-    case ArrowId::UINT8:
-    case ArrowId::INT8:
-    case ArrowId::UINT16:
-    case ArrowId::INT16:
-    case ArrowId::UINT32:
-    case ArrowId::INT32:
-      return ParquetType::INT32;
-    case ArrowId::UINT64:
-    case ArrowId::INT64:
-      return ParquetType::INT64;
-    case ArrowId::FLOAT:
-      return ParquetType::FLOAT;
-    case ArrowId::DOUBLE:
-      return ParquetType::DOUBLE;
-    case ArrowId::BINARY:
-      return ParquetType::BYTE_ARRAY;
-    case ArrowId::STRING:
-      return ParquetType::BYTE_ARRAY;
-    case ArrowId::FIXED_SIZE_BINARY:
-    case ArrowId::DECIMAL:
-      return ParquetType::FIXED_LEN_BYTE_ARRAY;
-    case ArrowId::DATE32:
-      return ParquetType::INT32;
-    case ArrowId::DATE64:
-      // Convert to date32 internally
-      return ParquetType::INT32;
-    case ArrowId::TIME32:
-      return ParquetType::INT32;
-    case ArrowId::TIME64:
-      return ParquetType::INT64;
-    case ArrowId::TIMESTAMP:
-      return ParquetType::INT64;
-    case ArrowId::DICTIONARY: {
-      const ::arrow::DictionaryType& dict_type =
-          static_cast<const ::arrow::DictionaryType&>(type);
-      return get_physical_type(*dict_type.dictionary()->type());
-    }
-    default:
-      break;
-  }
-  DCHECK(false) << "cannot reach this code";
-  return ParquetType::INT32;
-}
-
-template <typename TestType>
-struct test_traits {};
-
-template <>
-struct test_traits<::arrow::BooleanType> {
-  static constexpr ParquetType::type parquet_enum = ParquetType::BOOLEAN;
-  static uint8_t const value;
-};
-
-const uint8_t test_traits<::arrow::BooleanType>::value(1);
-
-template <>
-struct test_traits<::arrow::UInt8Type> {
-  static constexpr ParquetType::type parquet_enum = ParquetType::INT32;
-  static uint8_t const value;
-};
-
-const uint8_t test_traits<::arrow::UInt8Type>::value(64);
-
-template <>
-struct test_traits<::arrow::Int8Type> {
-  static constexpr ParquetType::type parquet_enum = ParquetType::INT32;
-  static int8_t const value;
-};
-
-const int8_t test_traits<::arrow::Int8Type>::value(-64);
-
-template <>
-struct test_traits<::arrow::UInt16Type> {
-  static constexpr ParquetType::type parquet_enum = ParquetType::INT32;
-  static uint16_t const value;
-};
-
-const uint16_t test_traits<::arrow::UInt16Type>::value(1024);
-
-template <>
-struct test_traits<::arrow::Int16Type> {
-  static constexpr ParquetType::type parquet_enum = ParquetType::INT32;
-  static int16_t const value;
-};
-
-const int16_t test_traits<::arrow::Int16Type>::value(-1024);
-
-template <>
-struct test_traits<::arrow::UInt32Type> {
-  static constexpr ParquetType::type parquet_enum = ParquetType::INT32;
-  static uint32_t const value;
-};
-
-const uint32_t test_traits<::arrow::UInt32Type>::value(1024);
-
-template <>
-struct test_traits<::arrow::Int32Type> {
-  static constexpr ParquetType::type parquet_enum = ParquetType::INT32;
-  static int32_t const value;
-};
-
-const int32_t test_traits<::arrow::Int32Type>::value(-1024);
-
-template <>
-struct test_traits<::arrow::UInt64Type> {
-  static constexpr ParquetType::type parquet_enum = ParquetType::INT64;
-  static uint64_t const value;
-};
-
-const uint64_t test_traits<::arrow::UInt64Type>::value(1024);
-
-template <>
-struct test_traits<::arrow::Int64Type> {
-  static constexpr ParquetType::type parquet_enum = ParquetType::INT64;
-  static int64_t const value;
-};
-
-const int64_t test_traits<::arrow::Int64Type>::value(-1024);
-
-template <>
-struct test_traits<::arrow::TimestampType> {
-  static constexpr ParquetType::type parquet_enum = ParquetType::INT64;
-  static int64_t const value;
-};
-
-const int64_t test_traits<::arrow::TimestampType>::value(14695634030000);
-
-template <>
-struct test_traits<::arrow::Date32Type> {
-  static constexpr ParquetType::type parquet_enum = ParquetType::INT32;
-  static int32_t const value;
-};
-
-const int32_t test_traits<::arrow::Date32Type>::value(170000);
-
-template <>
-struct test_traits<::arrow::FloatType> {
-  static constexpr ParquetType::type parquet_enum = ParquetType::FLOAT;
-  static float const value;
-};
-
-const float test_traits<::arrow::FloatType>::value(2.1f);
-
-template <>
-struct test_traits<::arrow::DoubleType> {
-  static constexpr ParquetType::type parquet_enum = ParquetType::DOUBLE;
-  static double const value;
-};
-
-const double test_traits<::arrow::DoubleType>::value(4.2);
-
-template <>
-struct test_traits<::arrow::StringType> {
-  static constexpr ParquetType::type parquet_enum = ParquetType::BYTE_ARRAY;
-  static std::string const value;
-};
-
-template <>
-struct test_traits<::arrow::BinaryType> {
-  static constexpr ParquetType::type parquet_enum = ParquetType::BYTE_ARRAY;
-  static std::string const value;
-};
-
-template <>
-struct test_traits<::arrow::FixedSizeBinaryType> {
-  static constexpr ParquetType::type parquet_enum = ParquetType::FIXED_LEN_BYTE_ARRAY;
-  static std::string const value;
-};
-
-const std::string test_traits<::arrow::StringType>::value("Test");              // NOLINT
-const std::string test_traits<::arrow::BinaryType>::value("\x00\x01\x02\x03");  // NOLINT
-const std::string test_traits<::arrow::FixedSizeBinaryType>::value("Fixed");    // NOLINT
-
-template <typename T>
-using ParquetDataType = DataType<test_traits<T>::parquet_enum>;
-
-template <typename T>
-using ParquetWriter = TypedColumnWriter<ParquetDataType<T>>;
-
-void WriteTableToBuffer(const std::shared_ptr<Table>& table, int64_t row_group_size,
-                        const std::shared_ptr<ArrowWriterProperties>& arrow_properties,
-                        std::shared_ptr<Buffer>* out) {
-  auto sink = std::make_shared<InMemoryOutputStream>();
-
-  ASSERT_OK_NO_THROW(WriteTable(*table, ::arrow::default_memory_pool(), sink,
-                                row_group_size, default_writer_properties(),
-                                arrow_properties));
-  *out = sink->GetBuffer();
-}
-
-namespace internal {
-
-void AssertArraysEqual(const Array& expected, const Array& actual) {
-  if (!actual.Equals(expected)) {
-    std::stringstream pp_result;
-    std::stringstream pp_expected;
-
-    EXPECT_OK(::arrow::PrettyPrint(actual, 0, &pp_result));
-    EXPECT_OK(::arrow::PrettyPrint(expected, 0, &pp_expected));
-    FAIL() << "Got: \n" << pp_result.str() << "\nExpected: \n" << pp_expected.str();
-  }
-}
-
-}  // namespace internal
-
-void AssertChunkedEqual(const ChunkedArray& expected, const ChunkedArray& actual) {
-  ASSERT_EQ(expected.num_chunks(), actual.num_chunks()) << "# chunks unequal";
-  if (!actual.Equals(expected)) {
-    std::stringstream pp_result;
-    std::stringstream pp_expected;
-
-    for (int i = 0; i < actual.num_chunks(); ++i) {
-      auto c1 = actual.chunk(i);
-      auto c2 = expected.chunk(i);
-      if (!c1->Equals(*c2)) {
-        EXPECT_OK(::arrow::PrettyPrint(*c1, 0, &pp_result));
-        EXPECT_OK(::arrow::PrettyPrint(*c2, 0, &pp_expected));
-        FAIL() << "Chunk " << i << " Got: " << pp_result.str()
-               << "\nExpected: " << pp_expected.str();
-      }
-    }
-  }
-}
-
-void PrintColumn(const Column& col, std::stringstream* ss) {
-  const ChunkedArray& carr = *col.data();
-  for (int i = 0; i < carr.num_chunks(); ++i) {
-    auto c1 = carr.chunk(i);
-    *ss << "Chunk " << i << std::endl;
-    EXPECT_OK(::arrow::PrettyPrint(*c1, 0, ss));
-    *ss << std::endl;
-  }
-}
-
-void DoSimpleRoundtrip(const std::shared_ptr<Table>& table, bool use_threads,
-                       int64_t row_group_size, const std::vector<int>& column_subset,
-                       std::shared_ptr<Table>* out,
-                       const std::shared_ptr<ArrowWriterProperties>& arrow_properties =
-                           default_arrow_writer_properties()) {
-  std::shared_ptr<Buffer> buffer;
-  ASSERT_NO_FATAL_FAILURE(
-      WriteTableToBuffer(table, row_group_size, arrow_properties, &buffer));
-
-  std::unique_ptr<FileReader> reader;
-  ASSERT_OK_NO_THROW(OpenFile(std::make_shared<BufferReader>(buffer),
-                              ::arrow::default_memory_pool(),
-                              ::parquet::default_reader_properties(), nullptr, &reader));
-
-  reader->set_use_threads(use_threads);
-
-  if (column_subset.size() > 0) {
-    ASSERT_OK_NO_THROW(reader->ReadTable(column_subset, out));
-  } else {
-    // Read everything
-    ASSERT_OK_NO_THROW(reader->ReadTable(out));
-  }
-}
-
-void CheckSimpleRoundtrip(const std::shared_ptr<Table>& table, int64_t row_group_size,
-                          const std::shared_ptr<ArrowWriterProperties>& arrow_properties =
-                              default_arrow_writer_properties()) {
-  std::shared_ptr<Table> result;
-  DoSimpleRoundtrip(table, false /* use_threads */, row_group_size, {}, &result,
-                    arrow_properties);
-  ASSERT_NO_FATAL_FAILURE(::arrow::AssertTablesEqual(*table, *result, false));
-}
-
-static std::shared_ptr<GroupNode> MakeSimpleSchema(const ::DataType& type,
-                                                   Repetition::type repetition) {
-  int32_t byte_width = -1;
-  int32_t precision = -1;
-  int32_t scale = -1;
-
-  switch (type.id()) {
-    case ::arrow::Type::DICTIONARY: {
-      const auto& dict_type = static_cast<const ::arrow::DictionaryType&>(type);
-      const ::DataType& values_type = *dict_type.dictionary()->type();
-      switch (values_type.id()) {
-        case ::arrow::Type::FIXED_SIZE_BINARY:
-          byte_width =
-              static_cast<const ::arrow::FixedSizeBinaryType&>(values_type).byte_width();
-          break;
-        case ::arrow::Type::DECIMAL: {
-          const auto& decimal_type =
-              static_cast<const ::arrow::Decimal128Type&>(values_type);
-          precision = decimal_type.precision();
-          scale = decimal_type.scale();
-          byte_width = DecimalSize(precision);
-        } break;
-        default:
-          break;
-      }
-    } break;
-    case ::arrow::Type::FIXED_SIZE_BINARY:
-      byte_width = static_cast<const ::arrow::FixedSizeBinaryType&>(type).byte_width();
-      break;
-    case ::arrow::Type::DECIMAL: {
-      const auto& decimal_type = static_cast<const ::arrow::Decimal128Type&>(type);
-      precision = decimal_type.precision();
-      scale = decimal_type.scale();
-      byte_width = DecimalSize(precision);
-    } break;
-    default:
-      break;
-  }
-  auto pnode = PrimitiveNode::Make("column1", repetition, get_physical_type(type),
-                                   get_logical_type(type), byte_width, precision, scale);
-  NodePtr node_ =
-      GroupNode::Make("schema", Repetition::REQUIRED, std::vector<NodePtr>({pnode}));
-  return std::static_pointer_cast<GroupNode>(node_);
-}
-
-template <typename TestType>
-class TestParquetIO : public ::testing::Test {
- public:
-  virtual void SetUp() {}
-
-  std::unique_ptr<ParquetFileWriter> MakeWriter(
-      const std::shared_ptr<GroupNode>& schema) {
-    sink_ = std::make_shared<InMemoryOutputStream>();
-    return ParquetFileWriter::Open(sink_, schema);
-  }
-
-  void ReaderFromSink(std::unique_ptr<FileReader>* out) {
-    std::shared_ptr<Buffer> buffer = sink_->GetBuffer();
-    ASSERT_OK_NO_THROW(OpenFile(std::make_shared<BufferReader>(buffer),
-                                ::arrow::default_memory_pool(),
-                                ::parquet::default_reader_properties(), nullptr, out));
-  }
-
-  void ReadSingleColumnFile(std::unique_ptr<FileReader> file_reader,
-                            std::shared_ptr<Array>* out) {
-    std::unique_ptr<ColumnReader> column_reader;
-    ASSERT_OK_NO_THROW(file_reader->GetColumn(0, &column_reader));
-    ASSERT_NE(nullptr, column_reader.get());
-
-    ASSERT_OK(column_reader->NextBatch(SMALL_SIZE, out));
-    ASSERT_NE(nullptr, out->get());
-  }
-
-  void ReadAndCheckSingleColumnFile(const Array& values) {
-    std::shared_ptr<Array> out;
-
-    std::unique_ptr<FileReader> reader;
-    ReaderFromSink(&reader);
-    ReadSingleColumnFile(std::move(reader), &out);
-
-    internal::AssertArraysEqual(values, *out);
-  }
-
-  void ReadTableFromFile(std::unique_ptr<FileReader> reader,
-                         std::shared_ptr<Table>* out) {
-    ASSERT_OK_NO_THROW(reader->ReadTable(out));
-    auto key_value_metadata =
-        reader->parquet_reader()->metadata()->key_value_metadata().get();
-    ASSERT_EQ(nullptr, key_value_metadata);
-    ASSERT_NE(nullptr, out->get());
-  }
-
-  void PrepareListTable(int64_t size, bool nullable_lists, bool nullable_elements,
-                        int64_t null_count, std::shared_ptr<Table>* out) {
-    std::shared_ptr<Array> values;
-    ASSERT_OK(NullableArray<TestType>(size * size, nullable_elements ? null_count : 0,
-                                      kDefaultSeed, &values));
-    // Also test that slice offsets are respected
-    values = values->Slice(5, values->length() - 5);
-    std::shared_ptr<ListArray> lists;
-    ASSERT_OK(MakeListArray(values, size, nullable_lists ? null_count : 0,
-                            nullable_elements, &lists));
-    *out = MakeSimpleTable(lists->Slice(3, size - 6), nullable_lists);
-  }
-
-  // Prepare table of empty lists, with null values array (ARROW-2744)
-  void PrepareEmptyListsTable(int64_t size, std::shared_ptr<Table>* out) {
-    std::shared_ptr<Array> lists;
-    ASSERT_OK(MakeEmptyListsArray(size, &lists));
-    *out = MakeSimpleTable(lists, true /* nullable_lists */);
-  }
-
-  void PrepareListOfListTable(int64_t size, bool nullable_parent_lists,
-                              bool nullable_lists, bool nullable_elements,
-                              int64_t null_count, std::shared_ptr<Table>* out) {
-    std::shared_ptr<Array> values;
-    ASSERT_OK(NullableArray<TestType>(size * 6, nullable_elements ? null_count : 0,
-                                      kDefaultSeed, &values));
-    std::shared_ptr<ListArray> lists;
-    ASSERT_OK(MakeListArray(values, size * 3, nullable_lists ? null_count : 0,
-                            nullable_elements, &lists));
-    std::shared_ptr<ListArray> parent_lists;
-    ASSERT_OK(MakeListArray(lists, size, nullable_parent_lists ? null_count : 0,
-                            nullable_lists, &parent_lists));
-    *out = MakeSimpleTable(parent_lists, nullable_parent_lists);
-  }
-
-  void ReadAndCheckSingleColumnTable(const std::shared_ptr<Array>& values) {
-    std::shared_ptr<::arrow::Table> out;
-    std::unique_ptr<FileReader> reader;
-    ReaderFromSink(&reader);
-    ReadTableFromFile(std::move(reader), &out);
-    ASSERT_EQ(1, out->num_columns());
-    ASSERT_EQ(values->length(), out->num_rows());
-
-    std::shared_ptr<ChunkedArray> chunked_array = out->column(0)->data();
-    ASSERT_EQ(1, chunked_array->num_chunks());
-    auto result = chunked_array->chunk(0);
-
-    internal::AssertArraysEqual(*values, *result);
-  }
-
-  void CheckRoundTrip(const std::shared_ptr<Table>& table) {
-    CheckSimpleRoundtrip(table, table->num_rows());
-  }
-
-  template <typename ArrayType>
-  void WriteColumn(const std::shared_ptr<GroupNode>& schema,
-                   const std::shared_ptr<ArrayType>& values) {
-    FileWriter writer(::arrow::default_memory_pool(), MakeWriter(schema));
-    ASSERT_OK_NO_THROW(writer.NewRowGroup(values->length()));
-    ASSERT_OK_NO_THROW(writer.WriteColumnChunk(*values));
-    ASSERT_OK_NO_THROW(writer.Close());
-    // writer.Close() should be idempotent
-    ASSERT_OK_NO_THROW(writer.Close());
-  }
-
-  std::shared_ptr<InMemoryOutputStream> sink_;
-};
-
-// We have separate tests for UInt32Type as this is currently the only type
-// where a roundtrip does not yield the identical Array structure.
-// There we write an UInt32 Array but receive an Int64 Array as result for
-// Parquet version 1.0.
-
-typedef ::testing::Types<
-    ::arrow::BooleanType, ::arrow::UInt8Type, ::arrow::Int8Type, ::arrow::UInt16Type,
-    ::arrow::Int16Type, ::arrow::Int32Type, ::arrow::UInt64Type, ::arrow::Int64Type,
-    ::arrow::Date32Type, ::arrow::FloatType, ::arrow::DoubleType, ::arrow::StringType,
-    ::arrow::BinaryType, ::arrow::FixedSizeBinaryType, DecimalWithPrecisionAndScale<1>,
-    DecimalWithPrecisionAndScale<3>, DecimalWithPrecisionAndScale<5>,
-    DecimalWithPrecisionAndScale<7>, DecimalWithPrecisionAndScale<10>,
-    DecimalWithPrecisionAndScale<12>, DecimalWithPrecisionAndScale<15>,
-    DecimalWithPrecisionAndScale<17>, DecimalWithPrecisionAndScale<19>,
-    DecimalWithPrecisionAndScale<22>, DecimalWithPrecisionAndScale<23>,
-    DecimalWithPrecisionAndScale<24>, DecimalWithPrecisionAndScale<27>,
-    DecimalWithPrecisionAndScale<29>, DecimalWithPrecisionAndScale<32>,
-    DecimalWithPrecisionAndScale<34>, DecimalWithPrecisionAndScale<38>>
-    TestTypes;
-
-TYPED_TEST_CASE(TestParquetIO, TestTypes);
-
-TYPED_TEST(TestParquetIO, SingleColumnRequiredWrite) {
-  std::shared_ptr<Array> values;
-  ASSERT_OK(NonNullArray<TypeParam>(SMALL_SIZE, &values));
-
-  std::shared_ptr<GroupNode> schema =
-      MakeSimpleSchema(*values->type(), Repetition::REQUIRED);
-  ASSERT_NO_FATAL_FAILURE(this->WriteColumn(schema, values));
-
-  ASSERT_NO_FATAL_FAILURE(this->ReadAndCheckSingleColumnFile(*values));
-}
-
-TYPED_TEST(TestParquetIO, SingleColumnTableRequiredWrite) {
-  std::shared_ptr<Array> values;
-  ASSERT_OK(NonNullArray<TypeParam>(SMALL_SIZE, &values));
-  std::shared_ptr<Table> table = MakeSimpleTable(values, false);
-  this->sink_ = std::make_shared<InMemoryOutputStream>();
-  ASSERT_OK_NO_THROW(WriteTable(*table, ::arrow::default_memory_pool(), this->sink_,
-                                values->length(), default_writer_properties()));
-
-  std::shared_ptr<Table> out;
-  std::unique_ptr<FileReader> reader;
-  ASSERT_NO_FATAL_FAILURE(this->ReaderFromSink(&reader));
-  ASSERT_NO_FATAL_FAILURE(this->ReadTableFromFile(std::move(reader), &out));
-  ASSERT_EQ(1, out->num_columns());
-  ASSERT_EQ(100, out->num_rows());
-
-  std::shared_ptr<ChunkedArray> chunked_array = out->column(0)->data();
-  ASSERT_EQ(1, chunked_array->num_chunks());
-
-  internal::AssertArraysEqual(*values, *chunked_array->chunk(0));
-}
-
-TYPED_TEST(TestParquetIO, SingleColumnOptionalReadWrite) {
-  // This also tests max_definition_level = 1
-  std::shared_ptr<Array> values;
-
-  ASSERT_OK(NullableArray<TypeParam>(SMALL_SIZE, 10, kDefaultSeed, &values));
-
-  std::shared_ptr<GroupNode> schema =
-      MakeSimpleSchema(*values->type(), Repetition::OPTIONAL);
-  ASSERT_NO_FATAL_FAILURE(this->WriteColumn(schema, values));
-
-  ASSERT_NO_FATAL_FAILURE(this->ReadAndCheckSingleColumnFile(*values));
-}
-
-TYPED_TEST(TestParquetIO, SingleColumnOptionalDictionaryWrite) {
-  // Skip tests for BOOL as we don't create dictionaries for it.
-  if (TypeParam::type_id == ::arrow::Type::BOOL) {
-    return;
-  }
-
-  std::shared_ptr<Array> values;
-
-  ASSERT_OK(NullableArray<TypeParam>(SMALL_SIZE, 10, kDefaultSeed, &values));
-
-  Datum out;
-  FunctionContext ctx(default_memory_pool());
-  ASSERT_OK(DictionaryEncode(&ctx, Datum(values), &out));
-  std::shared_ptr<Array> dict_values = MakeArray(out.array());
-  std::shared_ptr<GroupNode> schema =
-      MakeSimpleSchema(*dict_values->type(), Repetition::OPTIONAL);
-  ASSERT_NO_FATAL_FAILURE(this->WriteColumn(schema, dict_values));
-
-  ASSERT_NO_FATAL_FAILURE(this->ReadAndCheckSingleColumnFile(*values));
-}
-
-TYPED_TEST(TestParquetIO, SingleColumnRequiredSliceWrite) {
-  std::shared_ptr<Array> values;
-  ASSERT_OK(NonNullArray<TypeParam>(2 * SMALL_SIZE, &values));
-  std::shared_ptr<GroupNode> schema =
-      MakeSimpleSchema(*values->type(), Repetition::REQUIRED);
-
-  std::shared_ptr<Array> sliced_values = values->Slice(SMALL_SIZE / 2, SMALL_SIZE);
-  ASSERT_NO_FATAL_FAILURE(this->WriteColumn(schema, sliced_values));
-  ASSERT_NO_FATAL_FAILURE(this->ReadAndCheckSingleColumnFile(*sliced_values));
-
-  // Slice offset 1 higher
-  sliced_values = values->Slice(SMALL_SIZE / 2 + 1, SMALL_SIZE);
-  ASSERT_NO_FATAL_FAILURE(this->WriteColumn(schema, sliced_values));
-  ASSERT_NO_FATAL_FAILURE(this->ReadAndCheckSingleColumnFile(*sliced_values));
-}
-
-TYPED_TEST(TestParquetIO, SingleColumnOptionalSliceWrite) {
-  std::shared_ptr<Array> values;
-  ASSERT_OK(NullableArray<TypeParam>(2 * SMALL_SIZE, SMALL_SIZE, kDefaultSeed, &values));
-  std::shared_ptr<GroupNode> schema =
-      MakeSimpleSchema(*values->type(), Repetition::OPTIONAL);
-
-  std::shared_ptr<Array> sliced_values = values->Slice(SMALL_SIZE / 2, SMALL_SIZE);
-  ASSERT_NO_FATAL_FAILURE(this->WriteColumn(schema, sliced_values));
-  ASSERT_NO_FATAL_FAILURE(this->ReadAndCheckSingleColumnFile(*sliced_values));
-
-  // Slice offset 1 higher, thus different null bitmap.
-  sliced_values = values->Slice(SMALL_SIZE / 2 + 1, SMALL_SIZE);
-  ASSERT_NO_FATAL_FAILURE(this->WriteColumn(schema, sliced_values));
-  ASSERT_NO_FATAL_FAILURE(this->ReadAndCheckSingleColumnFile(*sliced_values));
-}
-
-TYPED_TEST(TestParquetIO, SingleColumnTableOptionalReadWrite) {
-  // This also tests max_definition_level = 1
-  std::shared_ptr<Array> values;
-
-  ASSERT_OK(NullableArray<TypeParam>(SMALL_SIZE, 10, kDefaultSeed, &values));
-  std::shared_ptr<Table> table = MakeSimpleTable(values, true);
-  ASSERT_NO_FATAL_FAILURE(this->CheckRoundTrip(table));
-}
-
-TYPED_TEST(TestParquetIO, SingleEmptyListsColumnReadWrite) {
-  std::shared_ptr<Table> table;
-  ASSERT_NO_FATAL_FAILURE(this->PrepareEmptyListsTable(SMALL_SIZE, &table));
-  ASSERT_NO_FATAL_FAILURE(this->CheckRoundTrip(table));
-}
-
-TYPED_TEST(TestParquetIO, SingleNullableListNullableColumnReadWrite) {
-  std::shared_ptr<Table> table;
-  ASSERT_NO_FATAL_FAILURE(this->PrepareListTable(SMALL_SIZE, true, true, 10, &table));
-  ASSERT_NO_FATAL_FAILURE(this->CheckRoundTrip(table));
-}
-
-TYPED_TEST(TestParquetIO, SingleRequiredListNullableColumnReadWrite) {
-  std::shared_ptr<Table> table;
-  ASSERT_NO_FATAL_FAILURE(this->PrepareListTable(SMALL_SIZE, false, true, 10, &table));
-  ASSERT_NO_FATAL_FAILURE(this->CheckRoundTrip(table));
-}
-
-TYPED_TEST(TestParquetIO, SingleNullableListRequiredColumnReadWrite) {
-  std::shared_ptr<Table> table;
-  ASSERT_NO_FATAL_FAILURE(this->PrepareListTable(SMALL_SIZE, true, false, 10, &table));
-  ASSERT_NO_FATAL_FAILURE(this->CheckRoundTrip(table));
-}
-
-TYPED_TEST(TestParquetIO, SingleRequiredListRequiredColumnReadWrite) {
-  std::shared_ptr<Table> table;
-  ASSERT_NO_FATAL_FAILURE(this->PrepareListTable(SMALL_SIZE, false, false, 0, &table));
-  ASSERT_NO_FATAL_FAILURE(this->CheckRoundTrip(table));
-}
-
-TYPED_TEST(TestParquetIO, SingleNullableListRequiredListRequiredColumnReadWrite) {
-  std::shared_ptr<Table> table;
-  ASSERT_NO_FATAL_FAILURE(
-      this->PrepareListOfListTable(SMALL_SIZE, true, false, false, 0, &table));
-  ASSERT_NO_FATAL_FAILURE(this->CheckRoundTrip(table));
-}
-
-TYPED_TEST(TestParquetIO, SingleColumnRequiredChunkedWrite) {
-  std::shared_ptr<Array> values;
-  ASSERT_OK(NonNullArray<TypeParam>(SMALL_SIZE, &values));
-  int64_t chunk_size = values->length() / 4;
-
-  std::shared_ptr<GroupNode> schema =
-      MakeSimpleSchema(*values->type(), Repetition::REQUIRED);
-  FileWriter writer(default_memory_pool(), this->MakeWriter(schema));
-  for (int i = 0; i < 4; i++) {
-    ASSERT_OK_NO_THROW(writer.NewRowGroup(chunk_size));
-    std::shared_ptr<Array> sliced_array = values->Slice(i * chunk_size, chunk_size);
-    ASSERT_OK_NO_THROW(writer.WriteColumnChunk(*sliced_array));
-  }
-  ASSERT_OK_NO_THROW(writer.Close());
-
-  ASSERT_NO_FATAL_FAILURE(this->ReadAndCheckSingleColumnFile(*values));
-}
-
-TYPED_TEST(TestParquetIO, SingleColumnTableRequiredChunkedWrite) {
-  std::shared_ptr<Array> values;
-  ASSERT_OK(NonNullArray<TypeParam>(LARGE_SIZE, &values));
-  std::shared_ptr<Table> table = MakeSimpleTable(values, false);
-  this->sink_ = std::make_shared<InMemoryOutputStream>();
-  ASSERT_OK_NO_THROW(WriteTable(*table, default_memory_pool(), this->sink_, 512,
-                                default_writer_properties()));
-
-  ASSERT_NO_FATAL_FAILURE(this->ReadAndCheckSingleColumnTable(values));
-}
-
-TYPED_TEST(TestParquetIO, SingleColumnTableRequiredChunkedWriteArrowIO) {
-  std::shared_ptr<Array> values;
-  ASSERT_OK(NonNullArray<TypeParam>(LARGE_SIZE, &values));
-  std::shared_ptr<Table> table = MakeSimpleTable(values, false);
-  this->sink_ = std::make_shared<InMemoryOutputStream>();
-  auto buffer = AllocateBuffer();
-
-  {
-    // BufferOutputStream closed on gc
-    auto arrow_sink_ = std::make_shared<::arrow::io::BufferOutputStream>(buffer);
-    ASSERT_OK_NO_THROW(WriteTable(*table, default_memory_pool(), arrow_sink_, 512,
-                                  default_writer_properties()));
-
-    // XXX: Remove this after ARROW-455 completed
-    ASSERT_OK(arrow_sink_->Close());
-  }
-
-  auto pbuffer = std::make_shared<Buffer>(buffer->data(), buffer->size());
-
-  auto source = std::make_shared<BufferReader>(pbuffer);
-  std::shared_ptr<::arrow::Table> out;
-  std::unique_ptr<FileReader> reader;
-  ASSERT_OK_NO_THROW(OpenFile(source, ::arrow::default_memory_pool(), &reader));
-  ASSERT_NO_FATAL_FAILURE(this->ReadTableFromFile(std::move(reader), &out));
-  ASSERT_EQ(1, out->num_columns());
-  ASSERT_EQ(values->length(), out->num_rows());
-
-  std::shared_ptr<ChunkedArray> chunked_array = out->column(0)->data();
-  ASSERT_EQ(1, chunked_array->num_chunks());
-
-  internal::AssertArraysEqual(*values, *chunked_array->chunk(0));
-}
-
-TYPED_TEST(TestParquetIO, SingleColumnOptionalChunkedWrite) {
-  int64_t chunk_size = SMALL_SIZE / 4;
-  std::shared_ptr<Array> values;
-
-  ASSERT_OK(NullableArray<TypeParam>(SMALL_SIZE, 10, kDefaultSeed, &values));
-
-  std::shared_ptr<GroupNode> schema =
-      MakeSimpleSchema(*values->type(), Repetition::OPTIONAL);
-  FileWriter writer(::arrow::default_memory_pool(), this->MakeWriter(schema));
-  for (int i = 0; i < 4; i++) {
-    ASSERT_OK_NO_THROW(writer.NewRowGroup(chunk_size));
-    std::shared_ptr<Array> sliced_array = values->Slice(i * chunk_size, chunk_size);
-    ASSERT_OK_NO_THROW(writer.WriteColumnChunk(*sliced_array));
-  }
-  ASSERT_OK_NO_THROW(writer.Close());
-
-  ASSERT_NO_FATAL_FAILURE(this->ReadAndCheckSingleColumnFile(*values));
-}
-
-TYPED_TEST(TestParquetIO, SingleColumnTableOptionalChunkedWrite) {
-  // This also tests max_definition_level = 1
-  std::shared_ptr<Array> values;
-
-  ASSERT_OK(NullableArray<TypeParam>(LARGE_SIZE, 100, kDefaultSeed, &values));
-  std::shared_ptr<Table> table = MakeSimpleTable(values, true);
-  this->sink_ = std::make_shared<InMemoryOutputStream>();
-  ASSERT_OK_NO_THROW(WriteTable(*table, ::arrow::default_memory_pool(), this->sink_, 512,
-                                default_writer_properties()));
-
-  ASSERT_NO_FATAL_FAILURE(this->ReadAndCheckSingleColumnTable(values));
-}
-
-TYPED_TEST(TestParquetIO, FileMetaDataWrite) {
-  std::shared_ptr<Array> values;
-  ASSERT_OK(NonNullArray<TypeParam>(SMALL_SIZE, &values));
-  std::shared_ptr<Table> table = MakeSimpleTable(values, false);
-  this->sink_ = std::make_shared<InMemoryOutputStream>();
-  ASSERT_OK_NO_THROW(WriteTable(*table, ::arrow::default_memory_pool(), this->sink_,
-                                values->length(), default_writer_properties()));
-
-  std::unique_ptr<FileReader> reader;
-  ASSERT_NO_FATAL_FAILURE(this->ReaderFromSink(&reader));
-  auto metadata = reader->parquet_reader()->metadata();
-  ASSERT_EQ(1, metadata->num_columns());
-  ASSERT_EQ(100, metadata->num_rows());
-
-  this->sink_ = std::make_shared<InMemoryOutputStream>();
-
-  ASSERT_OK_NO_THROW(::parquet::arrow::WriteFileMetaData(*metadata, this->sink_.get()));
-
-  ASSERT_NO_FATAL_FAILURE(this->ReaderFromSink(&reader));
-  auto metadata_written = reader->parquet_reader()->metadata();
-  ASSERT_EQ(metadata->size(), metadata_written->size());
-  ASSERT_EQ(metadata->num_row_groups(), metadata_written->num_row_groups());
-  ASSERT_EQ(metadata->num_rows(), metadata_written->num_rows());
-  ASSERT_EQ(metadata->num_columns(), metadata_written->num_columns());
-  ASSERT_EQ(metadata->RowGroup(0)->num_rows(), metadata_written->RowGroup(0)->num_rows());
-}
-
-using TestInt96ParquetIO = TestParquetIO<::arrow::TimestampType>;
-
-TEST_F(TestInt96ParquetIO, ReadIntoTimestamp) {
-  // This test explicitly tests the conversion from an Impala-style timestamp
-  // to a nanoseconds-since-epoch one.
-
-  // 2nd January 1970, 11:35min 145738543ns
-  Int96 day;
-  day.value[2] = UINT32_C(2440589);
-  int64_t seconds = (11 * 60 + 35) * 60;
-  *(reinterpret_cast<int64_t*>(&(day.value))) =
-      seconds * INT64_C(1000) * INT64_C(1000) * INT64_C(1000) + 145738543;
-  // Compute the corresponding nanosecond timestamp
-  struct tm datetime;
-  memset(&datetime, 0, sizeof(struct tm));
-  datetime.tm_year = 70;
-  datetime.tm_mon = 0;
-  datetime.tm_mday = 2;
-  datetime.tm_hour = 11;
-  datetime.tm_min = 35;
-  struct tm epoch;
-  memset(&epoch, 0, sizeof(struct tm));
-
-  epoch.tm_year = 70;
-  epoch.tm_mday = 1;
-  // Nanoseconds since the epoch
-  int64_t val = lrint(difftime(mktime(&datetime), mktime(&epoch))) * INT64_C(1000000000);
-  val += 145738543;
-
-  std::vector<std::shared_ptr<schema::Node>> fields(
-      {schema::PrimitiveNode::Make("int96", Repetition::REQUIRED, ParquetType::INT96)});
-  std::shared_ptr<schema::GroupNode> schema = std::static_pointer_cast<GroupNode>(
-      schema::GroupNode::Make("schema", Repetition::REQUIRED, fields));
-
-  // We cannot write this column with Arrow, so we have to use the plain parquet-cpp API
-  // to write an Int96 file.
-  this->sink_ = std::make_shared<InMemoryOutputStream>();
-  auto writer = ParquetFileWriter::Open(this->sink_, schema);
-  RowGroupWriter* rg_writer = writer->AppendRowGroup();
-  ColumnWriter* c_writer = rg_writer->NextColumn();
-  auto typed_writer = dynamic_cast<TypedColumnWriter<Int96Type>*>(c_writer);
-  ASSERT_NE(typed_writer, nullptr);
-  typed_writer->WriteBatch(1, nullptr, nullptr, &day);
-  c_writer->Close();
-  rg_writer->Close();
-  writer->Close();
-
-  ::arrow::TimestampBuilder builder(::arrow::timestamp(TimeUnit::NANO),
-                                    ::arrow::default_memory_pool());
-  ASSERT_OK(builder.Append(val));
-  std::shared_ptr<Array> values;
-  ASSERT_OK(builder.Finish(&values));
-  ASSERT_NO_FATAL_FAILURE(this->ReadAndCheckSingleColumnFile(*values));
-}
-
-using TestUInt32ParquetIO = TestParquetIO<::arrow::UInt32Type>;
-
-TEST_F(TestUInt32ParquetIO, Parquet_2_0_Compability) {
-  // This also tests max_definition_level = 1
-  std::shared_ptr<Array> values;
-
-  ASSERT_OK(NullableArray<::arrow::UInt32Type>(LARGE_SIZE, 100, kDefaultSeed, &values));
-  std::shared_ptr<Table> table = MakeSimpleTable(values, true);
-
-  // Parquet 2.0 roundtrip should yield an uint32_t column again
-  this->sink_ = std::make_shared<InMemoryOutputStream>();
-  std::shared_ptr<::parquet::WriterProperties> properties =
-      ::parquet::WriterProperties::Builder()
-          .version(ParquetVersion::PARQUET_2_0)
-          ->build();
-  ASSERT_OK_NO_THROW(
-      WriteTable(*table, default_memory_pool(), this->sink_, 512, properties));
-  ASSERT_NO_FATAL_FAILURE(this->ReadAndCheckSingleColumnTable(values));
-}
-
-TEST_F(TestUInt32ParquetIO, Parquet_1_0_Compability) {
-  // This also tests max_definition_level = 1
-  std::shared_ptr<Array> arr;
-  ASSERT_OK(NullableArray<::arrow::UInt32Type>(LARGE_SIZE, 100, kDefaultSeed, &arr));
-
-  std::shared_ptr<::arrow::UInt32Array> values =
-      std::dynamic_pointer_cast<::arrow::UInt32Array>(arr);
-
-  std::shared_ptr<Table> table = MakeSimpleTable(values, true);
-
-  // Parquet 1.0 returns an int64_t column as there is no way to tell a Parquet 1.0
-  // reader that a column is unsigned.
-  this->sink_ = std::make_shared<InMemoryOutputStream>();
-  std::shared_ptr<::parquet::WriterProperties> properties =
-      ::parquet::WriterProperties::Builder()
-          .version(ParquetVersion::PARQUET_1_0)
-          ->build();
-  ASSERT_OK_NO_THROW(
-      WriteTable(*table, ::arrow::default_memory_pool(), this->sink_, 512, properties));
-
-  std::shared_ptr<ResizableBuffer> int64_data = AllocateBuffer();
-  {
-    ASSERT_OK(int64_data->Resize(sizeof(int64_t) * values->length()));
-    auto int64_data_ptr = reinterpret_cast<int64_t*>(int64_data->mutable_data());
-    auto uint32_data_ptr = reinterpret_cast<const uint32_t*>(values->values()->data());
-    const auto cast_uint32_to_int64 = [](uint32_t value) {
-      return static_cast<int64_t>(value);
-    };
-    std::transform(uint32_data_ptr, uint32_data_ptr + values->length(), int64_data_ptr,
-                   cast_uint32_to_int64);
-  }
-
-  std::vector<std::shared_ptr<Buffer>> buffers{values->null_bitmap(), int64_data};
-  auto arr_data = std::make_shared<::arrow::ArrayData>(::arrow::int64(), values->length(),
-                                                       buffers, values->null_count());
-  std::shared_ptr<Array> expected_values = MakeArray(arr_data);
-  ASSERT_NE(expected_values, NULLPTR);
-
-  const auto& expected = static_cast<const ::arrow::Int64Array&>(*expected_values);
-  ASSERT_GT(values->length(), 0);
-  ASSERT_EQ(values->length(), expected.length());
-
-  // TODO(phillipc): Is there a better way to compare these two arrays?
-  // AssertArraysEqual requires the same type, but we only care about values in this case
-  for (int i = 0; i < expected.length(); ++i) {
-    const bool value_is_valid = values->IsValid(i);
-    const bool expected_value_is_valid = expected.IsValid(i);
-
-    ASSERT_EQ(expected_value_is_valid, value_is_valid);
-
-    if (value_is_valid) {
-      uint32_t value = values->Value(i);
-      int64_t expected_value = expected.Value(i);
-      ASSERT_EQ(expected_value, static_cast<int64_t>(value));
-    }
-  }
-}
-
-using TestStringParquetIO = TestParquetIO<::arrow::StringType>;
-
-TEST_F(TestStringParquetIO, EmptyStringColumnRequiredWrite) {
-  std::shared_ptr<Array> values;
-  ::arrow::StringBuilder builder;
-  for (size_t i = 0; i < SMALL_SIZE; i++) {
-    ASSERT_OK(builder.Append(""));
-  }
-  ASSERT_OK(builder.Finish(&values));
-  std::shared_ptr<Table> table = MakeSimpleTable(values, false);
-  this->sink_ = std::make_shared<InMemoryOutputStream>();
-  ASSERT_OK_NO_THROW(WriteTable(*table, ::arrow::default_memory_pool(), this->sink_,
-                                values->length(), default_writer_properties()));
-
-  std::shared_ptr<Table> out;
-  std::unique_ptr<FileReader> reader;
-  ASSERT_NO_FATAL_FAILURE(this->ReaderFromSink(&reader));
-  ASSERT_NO_FATAL_FAILURE(this->ReadTableFromFile(std::move(reader), &out));
-  ASSERT_EQ(1, out->num_columns());
-  ASSERT_EQ(100, out->num_rows());
-
-  std::shared_ptr<ChunkedArray> chunked_array = out->column(0)->data();
-  ASSERT_EQ(1, chunked_array->num_chunks());
-
-  internal::AssertArraysEqual(*values, *chunked_array->chunk(0));
-}
-
-using TestNullParquetIO = TestParquetIO<::arrow::NullType>;
-
-TEST_F(TestNullParquetIO, NullColumn) {
-  for (int32_t num_rows : {0, SMALL_SIZE}) {
-    std::shared_ptr<Array> values = std::make_shared<::arrow::NullArray>(num_rows);
-    std::shared_ptr<Table> table = MakeSimpleTable(values, true /* nullable */);
-    this->sink_ = std::make_shared<InMemoryOutputStream>();
-
-    const int64_t chunk_size = std::max(static_cast<int64_t>(1), table->num_rows());
-    ASSERT_OK_NO_THROW(WriteTable(*table, ::arrow::default_memory_pool(), this->sink_,
-                                  chunk_size, default_writer_properties()));
-
-    std::shared_ptr<Table> out;
-    std::unique_ptr<FileReader> reader;
-    ASSERT_NO_FATAL_FAILURE(this->ReaderFromSink(&reader));
-    ASSERT_NO_FATAL_FAILURE(this->ReadTableFromFile(std::move(reader), &out));
-    ASSERT_EQ(1, out->num_columns());
-    ASSERT_EQ(num_rows, out->num_rows());
-
-    std::shared_ptr<ChunkedArray> chunked_array = out->column(0)->data();
-    ASSERT_EQ(1, chunked_array->num_chunks());
-    internal::AssertArraysEqual(*values, *chunked_array->chunk(0));
-  }
-}
-
-TEST_F(TestNullParquetIO, NullListColumn) {
-  std::vector<int32_t> offsets1 = {0};
-  std::vector<int32_t> offsets2 = {0, 2, 2, 3, 115};
-  for (std::vector<int32_t> offsets : {offsets1, offsets2}) {
-    std::shared_ptr<Array> offsets_array, values_array, list_array;
-    ::arrow::ArrayFromVector<::arrow::Int32Type, int32_t>(offsets, &offsets_array);
-    values_array = std::make_shared<::arrow::NullArray>(offsets.back());
-    ASSERT_OK(::arrow::ListArray::FromArrays(*offsets_array, *values_array,
-                                             default_memory_pool(), &list_array));
-
-    std::shared_ptr<Table> table = MakeSimpleTable(list_array, false /* nullable */);
-    this->sink_ = std::make_shared<InMemoryOutputStream>();
-
-    const int64_t chunk_size = std::max(static_cast<int64_t>(1), table->num_rows());
-    ASSERT_OK_NO_THROW(WriteTable(*table, ::arrow::default_memory_pool(), this->sink_,
-                                  chunk_size, default_writer_properties()));
-
-    std::shared_ptr<Table> out;
-    std::unique_ptr<FileReader> reader;
-    this->ReaderFromSink(&reader);
-    this->ReadTableFromFile(std::move(reader), &out);
-    ASSERT_EQ(1, out->num_columns());
-    ASSERT_EQ(offsets.size() - 1, out->num_rows());
-
-    std::shared_ptr<ChunkedArray> chunked_array = out->column(0)->data();
-    ASSERT_EQ(1, chunked_array->num_chunks());
-    internal::AssertArraysEqual(*list_array, *chunked_array->chunk(0));
-  }
-}
-
-TEST_F(TestNullParquetIO, NullDictionaryColumn) {
-  std::shared_ptr<Array> values = std::make_shared<::arrow::NullArray>(0);
-  std::shared_ptr<Array> indices =
-      std::make_shared<::arrow::Int8Array>(SMALL_SIZE, nullptr, nullptr, SMALL_SIZE);
-  std::shared_ptr<::arrow::DictionaryType> dict_type =
-      std::make_shared<::arrow::DictionaryType>(::arrow::int8(), values);
-  std::shared_ptr<Array> dict_values =
-      std::make_shared<::arrow::DictionaryArray>(dict_type, indices);
-  std::shared_ptr<Table> table = MakeSimpleTable(dict_values, true);
-  this->sink_ = std::make_shared<InMemoryOutputStream>();
-  ASSERT_OK_NO_THROW(WriteTable(*table, ::arrow::default_memory_pool(), this->sink_,
-                                dict_values->length(), default_writer_properties()));
-
-  std::shared_ptr<Table> out;
-  std::unique_ptr<FileReader> reader;
-  ASSERT_NO_FATAL_FAILURE(this->ReaderFromSink(&reader));
-  ASSERT_NO_FATAL_FAILURE(this->ReadTableFromFile(std::move(reader), &out));
-  ASSERT_EQ(1, out->num_columns());
-  ASSERT_EQ(100, out->num_rows());
-
-  std::shared_ptr<ChunkedArray> chunked_array = out->column(0)->data();
-  ASSERT_EQ(1, chunked_array->num_chunks());
-
-  std::shared_ptr<Array> expected_values =
-      std::make_shared<::arrow::NullArray>(SMALL_SIZE);
-  internal::AssertArraysEqual(*expected_values, *chunked_array->chunk(0));
-}
-
-template <typename T>
-using ParquetCDataType = typename ParquetDataType<T>::c_type;
-
-template <typename T>
-struct c_type_trait {
-  using ArrowCType = typename T::c_type;
-};
-
-template <>
-struct c_type_trait<::arrow::BooleanType> {
-  using ArrowCType = uint8_t;
-};
-
-template <typename TestType>
-class TestPrimitiveParquetIO : public TestParquetIO<TestType> {
- public:
-  typedef typename c_type_trait<TestType>::ArrowCType T;
-
-  void MakeTestFile(std::vector<T>& values, int num_chunks,
-                    std::unique_ptr<FileReader>* reader) {
-    TestType dummy;
-
-    std::shared_ptr<GroupNode> schema = MakeSimpleSchema(dummy, Repetition::REQUIRED);
-    std::unique_ptr<ParquetFileWriter> file_writer = this->MakeWriter(schema);
-    size_t chunk_size = values.size() / num_chunks;
-    // Convert to Parquet's expected physical type
-    std::vector<uint8_t> values_buffer(sizeof(ParquetCDataType<TestType>) *
-                                       values.size());
-    auto values_parquet =
-        reinterpret_cast<ParquetCDataType<TestType>*>(values_buffer.data());
-    std::copy(values.cbegin(), values.cend(), values_parquet);
-    for (int i = 0; i < num_chunks; i++) {
-      auto row_group_writer = file_writer->AppendRowGroup();
-      auto column_writer =
-          static_cast<ParquetWriter<TestType>*>(row_group_writer->NextColumn());
-      ParquetCDataType<TestType>* data = values_parquet + i * chunk_size;
-      column_writer->WriteBatch(chunk_size, nullptr, nullptr, data);
-      column_writer->Close();
-      row_group_writer->Close();
-    }
-    file_writer->Close();
-    this->ReaderFromSink(reader);
-  }
-
-  void CheckSingleColumnRequiredTableRead(int num_chunks) {
-    std::vector<T> values(SMALL_SIZE, test_traits<TestType>::value);
-    std::unique_ptr<FileReader> file_reader;
-    ASSERT_NO_FATAL_FAILURE(MakeTestFile(values, num_chunks, &file_reader));
-
-    std::shared_ptr<Table> out;
-    this->ReadTableFromFile(std::move(file_reader), &out);
-    ASSERT_EQ(1, out->num_columns());
-    ASSERT_EQ(SMALL_SIZE, out->num_rows());
-
-    std::shared_ptr<ChunkedArray> chunked_array = out->column(0)->data();
-    ASSERT_EQ(1, chunked_array->num_chunks());
-    ExpectArrayT<TestType>(values.data(), chunked_array->chunk(0).get());
-  }
-
-  void CheckSingleColumnRequiredRead(int num_chunks) {
-    std::vector<T> values(SMALL_SIZE, test_traits<TestType>::value);
-    std::unique_ptr<FileReader> file_reader;
-    ASSERT_NO_FATAL_FAILURE(MakeTestFile(values, num_chunks, &file_reader));
-
-    std::shared_ptr<Array> out;
-    this->ReadSingleColumnFile(std::move(file_reader), &out);
-
-    ExpectArrayT<TestType>(values.data(), out.get());
-  }
-};
-
-typedef ::testing::Types<::arrow::BooleanType, ::arrow::UInt8Type, ::arrow::Int8Type,
-                         ::arrow::UInt16Type, ::arrow::Int16Type, ::arrow::UInt32Type,
-                         ::arrow::Int32Type, ::arrow::UInt64Type, ::arrow::Int64Type,
-                         ::arrow::FloatType, ::arrow::DoubleType>
-    PrimitiveTestTypes;
-
-TYPED_TEST_CASE(TestPrimitiveParquetIO, PrimitiveTestTypes);
-
-TYPED_TEST(TestPrimitiveParquetIO, SingleColumnRequiredRead) {
-  ASSERT_NO_FATAL_FAILURE(this->CheckSingleColumnRequiredRead(1));
-}
-
-TYPED_TEST(TestPrimitiveParquetIO, SingleColumnRequiredTableRead) {
-  ASSERT_NO_FATAL_FAILURE(this->CheckSingleColumnRequiredTableRead(1));
-}
-
-TYPED_TEST(TestPrimitiveParquetIO, SingleColumnRequiredChunkedRead) {
-  ASSERT_NO_FATAL_FAILURE(this->CheckSingleColumnRequiredRead(4));
-}
-
-TYPED_TEST(TestPrimitiveParquetIO, SingleColumnRequiredChunkedTableRead) {
-  ASSERT_NO_FATAL_FAILURE(this->CheckSingleColumnRequiredTableRead(4));
-}
-
-void MakeDateTimeTypesTable(std::shared_ptr<Table>* out, bool nanos_as_micros = false) {
-  using ::arrow::ArrayFromVector;
-
-  std::vector<bool> is_valid = {true, true, true, false, true, true};
-
-  // These are only types that roundtrip without modification
-  auto f0 = field("f0", ::arrow::date32());
-  auto f1 = field("f1", ::arrow::timestamp(TimeUnit::MILLI));
-  auto f2 = field("f2", ::arrow::timestamp(TimeUnit::MICRO));
-  std::shared_ptr<::arrow::Field> f3;
-  if (nanos_as_micros) {
-    f3 = field("f3", ::arrow::timestamp(TimeUnit::MICRO));
-  } else {
-    f3 = field("f3", ::arrow::timestamp(TimeUnit::NANO));
-  }
-  auto f4 = field("f4", ::arrow::time32(TimeUnit::MILLI));
-  auto f5 = field("f5", ::arrow::time64(TimeUnit::MICRO));
-  std::shared_ptr<::arrow::Schema> schema(new ::arrow::Schema({f0, f1, f2, f3, f4, f5}));
-
-  std::vector<int32_t> t32_values = {1489269000, 1489270000, 1489271000,
-                                     1489272000, 1489272000, 1489273000};
-  std::vector<int64_t> t64_values = {1489269000000, 1489270000000, 1489271000000,
-                                     1489272000000, 1489272000000, 1489273000000};
-  std::vector<int64_t> t64_us_values = {1489269000, 1489270000, 1489271000,
-                                        1489272000, 1489272000, 1489273000};
-
-  std::shared_ptr<Array> a0, a1, a2, a3, a4, a5;
-  ArrayFromVector<::arrow::Date32Type, int32_t>(f0->type(), is_valid, t32_values, &a0);
-  ArrayFromVector<::arrow::TimestampType, int64_t>(f1->type(), is_valid, t64_values, &a1);
-  ArrayFromVector<::arrow::TimestampType, int64_t>(f2->type(), is_valid, t64_values, &a2);
-  if (nanos_as_micros) {
-    ArrayFromVector<::arrow::TimestampType, int64_t>(f3->type(), is_valid, t64_us_values,
-                                                     &a3);
-  } else {
-    ArrayFromVector<::arrow::TimestampType, int64_t>(f3->type(), is_valid, t64_values,
-                                                     &a3);
-  }
-  ArrayFromVector<::arrow::Time32Type, int32_t>(f4->type(), is_valid, t32_values, &a4);
-  ArrayFromVector<::arrow::Time64Type, int64_t>(f5->type(), is_valid, t64_values, &a5);
-
-  std::vector<std::shared_ptr<::arrow::Column>> columns = {
-      std::make_shared<Column>("f0", a0), std::make_shared<Column>("f1", a1),
-      std::make_shared<Column>("f2", a2), std::make_shared<Column>("f3", a3),
-      std::make_shared<Column>("f4", a4), std::make_shared<Column>("f5", a5)};
-  *out = Table::Make(schema, columns);
-}
-
-TEST(TestArrowReadWrite, DateTimeTypes) {
-  std::shared_ptr<Table> table;
-  MakeDateTimeTypesTable(&table);
-
-  // Use deprecated INT96 type
-  std::shared_ptr<Table> result;
-  ASSERT_NO_FATAL_FAILURE(DoSimpleRoundtrip(
-      table, false /* use_threads */, table->num_rows(), {}, &result,
-      ArrowWriterProperties::Builder().enable_deprecated_int96_timestamps()->build()));
-
-  ASSERT_NO_FATAL_FAILURE(::arrow::AssertTablesEqual(*table, *result));
-
-  // Cast nanaoseconds to microseconds and use INT64 physical type
-  ASSERT_NO_FATAL_FAILURE(
-      DoSimpleRoundtrip(table, false /* use_threads */, table->num_rows(), {}, &result));
-  std::shared_ptr<Table> expected;
-  MakeDateTimeTypesTable(&table, true);
-
-  ASSERT_NO_FATAL_FAILURE(::arrow::AssertTablesEqual(*table, *result));
-}
-
-TEST(TestArrowReadWrite, CoerceTimestamps) {
-  using ::arrow::ArrayFromVector;
-  using ::arrow::field;
-
-  // PARQUET-1078, coerce Arrow timestamps to either TIMESTAMP_MILLIS or TIMESTAMP_MICROS
-  std::vector<bool> is_valid = {true, true, true, false, true, true};
-
-  auto t_s = ::arrow::timestamp(TimeUnit::SECOND);
-  auto t_ms = ::arrow::timestamp(TimeUnit::MILLI);
-  auto t_us = ::arrow::timestamp(TimeUnit::MICRO);
-  auto t_ns = ::arrow::timestamp(TimeUnit::NANO);
-
-  std::vector<int64_t> s_values = {1489269, 1489270, 1489271, 1489272, 1489272, 1489273};
-  std::vector<int64_t> ms_values = {1489269000, 1489270000, 1489271000,
-                                    1489272001, 1489272000, 1489273000};
-  std::vector<int64_t> us_values = {1489269000000, 1489270000000, 1489271000000,
-                                    1489272000001, 1489272000000, 1489273000000};
-  std::vector<int64_t> ns_values = {1489269000000000LL, 1489270000000000LL,
-                                    1489271000000000LL, 1489272000000001LL,
-                                    1489272000000000LL, 1489273000000000LL};
-
-  std::shared_ptr<Array> a_s, a_ms, a_us, a_ns;
-  ArrayFromVector<::arrow::TimestampType, int64_t>(t_s, is_valid, s_values, &a_s);
-  ArrayFromVector<::arrow::TimestampType, int64_t>(t_ms, is_valid, ms_values, &a_ms);
-  ArrayFromVector<::arrow::TimestampType, int64_t>(t_us, is_valid, us_values, &a_us);
-  ArrayFromVector<::arrow::TimestampType, int64_t>(t_ns, is_valid, ns_values, &a_ns);
-
-  // Input table, all data as is
-  auto s1 = std::shared_ptr<::arrow::Schema>(
-      new ::arrow::Schema({field("f_s", t_s), field("f_ms", t_ms), field("f_us", t_us),
-                           field("f_ns", t_ns)}));
-  auto input = Table::Make(
-      s1,
-      {std::make_shared<Column>("f_s", a_s), std::make_shared<Column>("f_ms", a_ms),
-       std::make_shared<Column>("f_us", a_us), std::make_shared<Column>("f_ns", a_ns)});
-
-  // Result when coercing to milliseconds
-  auto s2 = std::shared_ptr<::arrow::Schema>(
-      new ::arrow::Schema({field("f_s", t_ms), field("f_ms", t_ms), field("f_us", t_ms),
-                           field("f_ns", t_ms)}));
-  auto ex_milli_result = Table::Make(
-      s2,
-      {std::make_shared<Column>("f_s", a_ms), std::make_shared<Column>("f_ms", a_ms),
-       std::make_shared<Column>("f_us", a_ms), std::make_shared<Column>("f_ns", a_ms)});
-
-  // Result when coercing to microseconds
-  auto s3 = std::shared_ptr<::arrow::Schema>(
-      new ::arrow::Schema({field("f_s", t_us), field("f_ms", t_us), field("f_us", t_us),
-                           field("f_ns", t_us)}));
-  auto ex_micro_result = Table::Make(
-      s3,
-      {std::make_shared<Column>("f_s", a_us), std::make_shared<Column>("f_ms", a_us),
-       std::make_shared<Column>("f_us", a_us), std::make_shared<Column>("f_ns", a_us)});
-
-  std::shared_ptr<Table> milli_result;
-  ASSERT_NO_FATAL_FAILURE(DoSimpleRoundtrip(
-      input, false /* use_threads */, input->num_rows(), {}, &milli_result,
-      ArrowWriterProperties::Builder().coerce_timestamps(TimeUnit::MILLI)->build()));
-
-  ASSERT_NO_FATAL_FAILURE(::arrow::AssertTablesEqual(*ex_milli_result, *milli_result));
-
-  std::shared_ptr<Table> micro_result;
-  ASSERT_NO_FATAL_FAILURE(DoSimpleRoundtrip(
-      input, false /* use_threads */, input->num_rows(), {}, &micro_result,
-      ArrowWriterProperties::Builder().coerce_timestamps(TimeUnit::MICRO)->build()));
-  ASSERT_NO_FATAL_FAILURE(::arrow::AssertTablesEqual(*ex_micro_result, *micro_result));
-}
-
-TEST(TestArrowReadWrite, CoerceTimestampsLosePrecision) {
-  using ::arrow::ArrayFromVector;
-  using ::arrow::field;
-
-  // PARQUET-1078, coerce Arrow timestamps to either TIMESTAMP_MILLIS or TIMESTAMP_MICROS
-  std::vector<bool> is_valid = {true, true, true, false, true, true};
-
-  auto t_s = ::arrow::timestamp(TimeUnit::SECOND);
-  auto t_ms = ::arrow::timestamp(TimeUnit::MILLI);
-  auto t_us = ::arrow::timestamp(TimeUnit::MICRO);
-  auto t_ns = ::arrow::timestamp(TimeUnit::NANO);
-
-  std::vector<int64_t> s_values = {1489269, 1489270, 1489271, 1489272, 1489272, 1489273};
-  std::vector<int64_t> ms_values = {1489269001, 1489270001, 1489271001,
-                                    1489272001, 1489272001, 1489273001};
-  std::vector<int64_t> us_values = {1489269000001, 1489270000001, 1489271000001,
-                                    1489272000001, 1489272000001, 1489273000001};
-  std::vector<int64_t> ns_values = {1489269000000001LL, 1489270000000001LL,
-                                    1489271000000001LL, 1489272000000001LL,
-                                    1489272000000001LL, 1489273000000001LL};
-
-  std::shared_ptr<Array> a_s, a_ms, a_us, a_ns;
-  ArrayFromVector<::arrow::TimestampType, int64_t>(t_s, is_valid, s_values, &a_s);
-  ArrayFromVector<::arrow::TimestampType, int64_t>(t_ms, is_valid, ms_values, &a_ms);
-  ArrayFromVector<::arrow::TimestampType, int64_t>(t_us, is_valid, us_values, &a_us);
-  ArrayFromVector<::arrow::TimestampType, int64_t>(t_ns, is_valid, ns_values, &a_ns);
-
-  auto s1 = std::shared_ptr<::arrow::Schema>(new ::arrow::Schema({field("f_s", t_s)}));
-  auto s2 = std::shared_ptr<::arrow::Schema>(new ::arrow::Schema({field("f_ms", t_ms)}));
-  auto s3 = std::shared_ptr<::arrow::Schema>(new ::arrow::Schema({field("f_us", t_us)}));
-  auto s4 = std::shared_ptr<::arrow::Schema>(new ::arrow::Schema({field("f_ns", t_ns)}));
-
-  auto c1 = std::make_shared<Column>("f_s", a_s);
-  auto c2 = std::make_shared<Column>("f_ms", a_ms);
-  auto c3 = std::make_shared<Column>("f_us", a_us);
-  auto c4 = std::make_shared<Column>("f_ns", a_ns);
-
-  auto t1 = Table::Make(s1, {c1});
-  auto t2 = Table::Make(s2, {c2});
-  auto t3 = Table::Make(s3, {c3});
-  auto t4 = Table::Make(s4, {c4});
-
-  auto sink = std::make_shared<InMemoryOutputStream>();
-
-  // OK to write to millis
-  auto coerce_millis =
-      (ArrowWriterProperties::Builder().coerce_timestamps(TimeUnit::MILLI)->build());
-  ASSERT_OK_NO_THROW(WriteTable(*t1, ::arrow::default_memory_pool(), sink, 10,
-                                default_writer_properties(), coerce_millis));
-  ASSERT_OK_NO_THROW(WriteTable(*t2, ::arrow::default_memory_pool(), sink, 10,
-                                default_writer_properties(), coerce_millis));
-
-  // Loss of precision
-  ASSERT_RAISES(Invalid, WriteTable(*t3, ::arrow::default_memory_pool(), sink, 10,
-                                    default_writer_properties(), coerce_millis));
-  ASSERT_RAISES(Invalid, WriteTable(*t4, ::arrow::default_memory_pool(), sink, 10,
-                                    default_writer_properties(), coerce_millis));
-
-  // OK to write micros to micros
-  auto coerce_micros =
-      (ArrowWriterProperties::Builder().coerce_timestamps(TimeUnit::MICRO)->build());
-  ASSERT_OK_NO_THROW(WriteTable(*t3, ::arrow::default_memory_pool(), sink, 10,
-                                default_writer_properties(), coerce_micros));
-
-  // Loss of precision
-  ASSERT_RAISES(Invalid, WriteTable(*t4, ::arrow::default_memory_pool(), sink, 10,
-                                    default_writer_properties(), coerce_micros));
-}
-
-TEST(TestArrowReadWrite, ConvertedDateTimeTypes) {
-  using ::arrow::ArrayFromVector;
-
-  std::vector<bool> is_valid = {true, true, true, false, true, true};
-
-  auto f0 = field("f0", ::arrow::date64());
-  auto f1 = field("f1", ::arrow::time32(TimeUnit::SECOND));
-  auto f2 = field("f2", ::arrow::date64());
-  auto f3 = field("f3", ::arrow::time32(TimeUnit::SECOND));
-
-  auto schema = ::arrow::schema({f0, f1, f2, f3});
-
-  std::vector<int64_t> a0_values = {1489190400000, 1489276800000, 1489363200000,
-                                    1489449600000, 1489536000000, 1489622400000};
-  std::vector<int32_t> a1_values = {0, 1, 2, 3, 4, 5};
-
-  std::shared_ptr<Array> a0, a1, a0_nonnull, a1_nonnull, x0, x1, x0_nonnull, x1_nonnull;
-
-  ArrayFromVector<::arrow::Date64Type, int64_t>(f0->type(), is_valid, a0_values, &a0);
-  ArrayFromVector<::arrow::Date64Type, int64_t>(f0->type(), a0_values, &a0_nonnull);
-
-  ArrayFromVector<::arrow::Time32Type, int32_t>(f1->type(), is_valid, a1_values, &a1);
-  ArrayFromVector<::arrow::Time32Type, int32_t>(f1->type(), a1_values, &a1_nonnull);
-
-  std::vector<std::shared_ptr<::arrow::Column>> columns = {
-      std::make_shared<Column>("f0", a0), std::make_shared<Column>("f1", a1),
-      std::make_shared<Column>("f2", a0_nonnull),
-      std::make_shared<Column>("f3", a1_nonnull)};
-  auto table = Table::Make(schema, columns);
-
-  // Expected schema and values
-  auto e0 = field("f0", ::arrow::date32());
-  auto e1 = field("f1", ::arrow::time32(TimeUnit::MILLI));
-  auto e2 = field("f2", ::arrow::date32());
-  auto e3 = field("f3", ::arrow::time32(TimeUnit::MILLI));
-  auto ex_schema = ::arrow::schema({e0, e1, e2, e3});
-
-  std::vector<int32_t> x0_values = {17236, 17237, 17238, 17239, 17240, 17241};
-  std::vector<int32_t> x1_values = {0, 1000, 2000, 3000, 4000, 5000};
-  ArrayFromVector<::arrow::Date32Type, int32_t>(e0->type(), is_valid, x0_values, &x0);
-  ArrayFromVector<::arrow::Date32Type, int32_t>(e0->type(), x0_values, &x0_nonnull);
-
-  ArrayFromVector<::arrow::Time32Type, int32_t>(e1->type(), is_valid, x1_values, &x1);
-  ArrayFromVector<::arrow::Time32Type, int32_t>(e1->type(), x1_values, &x1_nonnull);
-
-  std::vector<std::shared_ptr<::arrow::Column>> ex_columns = {
-      std::make_shared<Column>("f0", x0), std::make_shared<Column>("f1", x1),
-      std::make_shared<Column>("f2", x0_nonnull),
-      std::make_shared<Column>("f3", x1_nonnull)};
-  auto ex_table = Table::Make(ex_schema, ex_columns);
-
-  std::shared_ptr<Table> result;
-  ASSERT_NO_FATAL_FAILURE(
-      DoSimpleRoundtrip(table, false /* use_threads */, table->num_rows(), {}, &result));
-
-  ASSERT_NO_FATAL_FAILURE(::arrow::AssertTablesEqual(*ex_table, *result));
-}
-
-// Regression for ARROW-2802
-TEST(TestArrowReadWrite, CoerceTimestampsAndSupportDeprecatedInt96) {
-  using ::arrow::Column;
-  using ::arrow::default_memory_pool;
-  using ::arrow::Field;
-  using ::arrow::Schema;
-  using ::arrow::Table;
-  using ::arrow::TimestampBuilder;
-  using ::arrow::TimestampType;
-  using ::arrow::TimeUnit;
-
-  auto timestamp_type = std::make_shared<TimestampType>(TimeUnit::NANO);
-
-  TimestampBuilder builder(timestamp_type, default_memory_pool());
-  for (std::int64_t ii = 0; ii < 10; ++ii) {
-    ASSERT_OK(builder.Append(1000000000L * ii));
-  }
-  std::shared_ptr<Array> values;
-  ASSERT_OK(builder.Finish(&values));
-
-  std::vector<std::shared_ptr<Field>> fields;
-  auto field = std::make_shared<Field>("nanos", timestamp_type);
-  fields.emplace_back(field);
-
-  auto schema = std::make_shared<Schema>(fields);
-
-  std::vector<std::shared_ptr<Column>> columns;
-  auto column = std::make_shared<Column>("nanos", values);
-  columns.emplace_back(column);
-
-  auto table = Table::Make(schema, columns);
-
-  auto arrow_writer_properties = ArrowWriterProperties::Builder()
-                                     .coerce_timestamps(TimeUnit::MICRO)
-                                     ->enable_deprecated_int96_timestamps()
-                                     ->build();
-
-  std::shared_ptr<Table> result;
-  DoSimpleRoundtrip(table, false /* use_threads */, table->num_rows(), {}, &result,
-                    arrow_writer_properties);
-
-  ASSERT_EQ(table->num_columns(), result->num_columns());
-  ASSERT_EQ(table->num_rows(), result->num_rows());
-
-  auto actual_column = result->column(0);
-  auto data = actual_column->data();
-  auto expected_values =
-      static_cast<::arrow::NumericArray<TimestampType>*>(values.get())->raw_values();
-  for (int ii = 0; ii < data->num_chunks(); ++ii) {
-    auto chunk =
-        static_cast<::arrow::NumericArray<TimestampType>*>(data->chunk(ii).get());
-    auto values = chunk->raw_values();
-    for (int64_t jj = 0; jj < chunk->length(); ++jj, ++expected_values) {
-      // Check that the nanos have been converted to micros
-      ASSERT_EQ(*expected_values / 1000, values[jj]);
-    }
-  }
-}
-
-void MakeDoubleTable(int num_columns, int num_rows, int nchunks,
-                     std::shared_ptr<Table>* out) {
-  std::shared_ptr<::arrow::Column> column;
-  std::vector<std::shared_ptr<::arrow::Column>> columns(num_columns);
-  std::vector<std::shared_ptr<::arrow::Field>> fields(num_columns);
-
-  for (int i = 0; i < num_columns; ++i) {
-    std::vector<std::shared_ptr<Array>> arrays;
-    std::shared_ptr<Array> values;
-    ASSERT_OK(NullableArray<::arrow::DoubleType>(num_rows, num_rows / 10,
-                                                 static_cast<uint32_t>(i), &values));
-    std::stringstream ss;
-    ss << "col" << i;
-
-    for (int j = 0; j < nchunks; ++j) {
-      arrays.push_back(values);
-    }
-    column = MakeColumn(ss.str(), arrays, true);
-
-    columns[i] = column;
-    fields[i] = column->field();
-  }
-  auto schema = std::make_shared<::arrow::Schema>(fields);
-  *out = Table::Make(schema, columns);
-}
-
-void MakeListArray(int num_rows, int max_value_length,
-                   std::shared_ptr<::DataType>* out_type,
-                   std::shared_ptr<Array>* out_array) {
-  std::vector<int32_t> length_draws;
-  randint(num_rows, 0, max_value_length, &length_draws);
-
-  std::vector<int32_t> offset_values;
-
-  // Make sure some of them are length 0
-  int32_t total_elements = 0;
-  for (size_t i = 0; i < length_draws.size(); ++i) {
-    if (length_draws[i] < max_value_length / 10) {
-      length_draws[i] = 0;
-    }
-    offset_values.push_back(total_elements);
-    total_elements += length_draws[i];
-  }
-  offset_values.push_back(total_elements);
-
-  std::vector<int8_t> value_draws;
-  randint(total_elements, 0, 100, &value_draws);
-
-  std::vector<bool> is_valid;
-  random_is_valid(total_elements, 0.1, &is_valid);
-
-  std::shared_ptr<Array> values, offsets;
-  ::arrow::ArrayFromVector<::arrow::Int8Type, int8_t>(::arrow::int8(), is_valid,
-                                                      value_draws, &values);
-  ::arrow::ArrayFromVector<::arrow::Int32Type, int32_t>(offset_values, &offsets);
-
-  ASSERT_OK(::arrow::ListArray::FromArrays(*offsets, *values, default_memory_pool(),
-                                           out_array));
-
-  *out_type = ::arrow::list(::arrow::int8());
-}
-
-TEST(TestArrowReadWrite, MultithreadedRead) {
-  const int num_columns = 20;
-  const int num_rows = 1000;
-  const bool use_threads = true;
-
-  std::shared_ptr<Table> table;
-  ASSERT_NO_FATAL_FAILURE(MakeDoubleTable(num_columns, num_rows, 1, &table));
-
-  std::shared_ptr<Table> result;
-  ASSERT_NO_FATAL_FAILURE(
-      DoSimpleRoundtrip(table, use_threads, table->num_rows(), {}, &result));
-
-  ASSERT_NO_FATAL_FAILURE(::arrow::AssertTablesEqual(*table, *result));
-}
-
-TEST(TestArrowReadWrite, ReadSingleRowGroup) {
-  const int num_columns = 20;
-  const int num_rows = 1000;
-
-  std::shared_ptr<Table> table;
-  ASSERT_NO_FATAL_FAILURE(MakeDoubleTable(num_columns, num_rows, 1, &table));
-
-  std::shared_ptr<Buffer> buffer;
-  ASSERT_NO_FATAL_FAILURE(WriteTableToBuffer(table, num_rows / 2,
-                                             default_arrow_writer_properties(), &buffer));
-
-  std::unique_ptr<FileReader> reader;
-  ASSERT_OK_NO_THROW(OpenFile(std::make_shared<BufferReader>(buffer),
-                              ::arrow::default_memory_pool(),
-                              ::parquet::default_reader_properties(), nullptr, &reader));
-
-  ASSERT_EQ(2, reader->num_row_groups());
-
-  std::shared_ptr<Table> r1, r2, r3, r4;
-  // Read everything
-  ASSERT_OK_NO_THROW(reader->ReadRowGroup(0, &r1));
-  ASSERT_OK_NO_THROW(reader->RowGroup(1)->ReadTable(&r2));
-  ASSERT_OK_NO_THROW(reader->ReadRowGroups({0, 1}, &r3));
-  ASSERT_OK_NO_THROW(reader->ReadRowGroups({1}, &r4));
-
-  std::shared_ptr<Table> concatenated;
-
-  ASSERT_OK(ConcatenateTables({r1, r2}, &concatenated));
-  ASSERT_TRUE(table->Equals(*concatenated));
-
-  ASSERT_TRUE(table->Equals(*r3));
-  ASSERT_TRUE(r2->Equals(*r4));
-  ASSERT_OK(ConcatenateTables({r1, r4}, &concatenated));
-  ASSERT_TRUE(table->Equals(*concatenated));
-}
-
-TEST(TestArrowReadWrite, GetRecordBatchReader) {
-  const int num_columns = 20;
-  const int num_rows = 1000;
-
-  std::shared_ptr<Table> table;
-  ASSERT_NO_FATAL_FAILURE(MakeDoubleTable(num_columns, num_rows, 1, &table));
-
-  std::shared_ptr<Buffer> buffer;
-  ASSERT_NO_FATAL_FAILURE(WriteTableToBuffer(table, num_rows / 2,
-                                             default_arrow_writer_properties(), &buffer));
-
-  std::unique_ptr<FileReader> reader;
-  ASSERT_OK_NO_THROW(OpenFile(std::make_shared<BufferReader>(buffer),
-                              ::arrow::default_memory_pool(),
-                              ::parquet::default_reader_properties(), nullptr, &reader));
-
-  std::shared_ptr<::arrow::RecordBatchReader> rb_reader;
-  ASSERT_OK_NO_THROW(reader->GetRecordBatchReader({0, 1}, &rb_reader));
-
-  std::shared_ptr<::arrow::RecordBatch> batch;
-
-  ASSERT_OK(rb_reader->ReadNext(&batch));
-  ASSERT_EQ(500, batch->num_rows());
-  ASSERT_EQ(20, batch->num_columns());
-
-  ASSERT_OK(rb_reader->ReadNext(&batch));
-  ASSERT_EQ(500, batch->num_rows());
-  ASSERT_EQ(20, batch->num_columns());
-
-  ASSERT_OK(rb_reader->ReadNext(&batch));
-  ASSERT_EQ(nullptr, batch);
-}
-
-TEST(TestArrowReadWrite, ScanContents) {
-  const int num_columns = 20;
-  const int num_rows = 1000;
-
-  std::shared_ptr<Table> table;
-  ASSERT_NO_FATAL_FAILURE(MakeDoubleTable(num_columns, num_rows, 1, &table));
-
-  std::shared_ptr<Buffer> buffer;
-  ASSERT_NO_FATAL_FAILURE(WriteTableToBuffer(table, num_rows / 2,
-                                             default_arrow_writer_properties(), &buffer));
-
-  std::unique_ptr<FileReader> reader;
-  ASSERT_OK_NO_THROW(OpenFile(std::make_shared<BufferReader>(buffer),
-                              ::arrow::default_memory_pool(),
-                              ::parquet::default_reader_properties(), nullptr, &reader));
-
-  int64_t num_rows_returned = 0;
-  ASSERT_OK_NO_THROW(reader->ScanContents({}, 256, &num_rows_returned));
-  ASSERT_EQ(num_rows, num_rows_returned);
-
-  ASSERT_OK_NO_THROW(reader->ScanContents({0, 1, 2}, 256, &num_rows_returned));
-  ASSERT_EQ(num_rows, num_rows_returned);
-}
-
-TEST(TestArrowReadWrite, ReadColumnSubset) {
-  const int num_columns = 20;
-  const int num_rows = 1000;
-  const bool use_threads = true;
-
-  std::shared_ptr<Table> table;
-  ASSERT_NO_FATAL_FAILURE(MakeDoubleTable(num_columns, num_rows, 1, &table));
-
-  std::shared_ptr<Table> result;
-  std::vector<int> column_subset = {0, 4, 8, 10};
-  ASSERT_NO_FATAL_FAILURE(
-      DoSimpleRoundtrip(table, use_threads, table->num_rows(), column_subset, &result));
-
-  std::vector<std::shared_ptr<::arrow::Column>> ex_columns;
-  std::vector<std::shared_ptr<::arrow::Field>> ex_fields;
-  for (int i : column_subset) {
-    ex_columns.push_back(table->column(i));
-    ex_fields.push_back(table->column(i)->field());
-  }
-
-  auto ex_schema = ::arrow::schema(ex_fields);
-  auto expected = Table::Make(ex_schema, ex_columns);
-  ASSERT_NO_FATAL_FAILURE(::arrow::AssertTablesEqual(*expected, *result));
-}
-
-TEST(TestArrowReadWrite, ListLargeRecords) {
-  // PARQUET-1308: This test passed on Linux when num_rows was smaller
-  const int num_rows = 2000;
-
-  std::shared_ptr<Array> list_array;
-  std::shared_ptr<::DataType> list_type;
-
-  MakeListArray(num_rows, 20, &list_type, &list_array);
-
-  auto schema = ::arrow::schema({::arrow::field("a", list_type)});
-
-  std::shared_ptr<Table> table = Table::Make(schema, {list_array});
-
-  std::shared_ptr<Buffer> buffer;
-  ASSERT_NO_FATAL_FAILURE(
-      WriteTableToBuffer(table, 100, default_arrow_writer_properties(), &buffer));
-
-  std::unique_ptr<FileReader> reader;
-  ASSERT_OK_NO_THROW(OpenFile(std::make_shared<BufferReader>(buffer),
-                              ::arrow::default_memory_pool(),
-                              ::parquet::default_reader_properties(), nullptr, &reader));
-
-  // Read everything
-  std::shared_ptr<Table> result;
-  ASSERT_OK_NO_THROW(reader->ReadTable(&result));
-  ASSERT_NO_FATAL_FAILURE(::arrow::AssertTablesEqual(*table, *result));
-
-  // Read chunked
-  ASSERT_OK_NO_THROW(OpenFile(std::make_shared<BufferReader>(buffer),
-                              ::arrow::default_memory_pool(),
-                              ::parquet::default_reader_properties(), nullptr, &reader));
-
-  std::unique_ptr<ColumnReader> col_reader;
-  ASSERT_OK(reader->GetColumn(0, &col_reader));
-
-  std::vector<std::shared_ptr<Array>> pieces;
-  for (int i = 0; i < num_rows; ++i) {
-    std::shared_ptr<Array> piece;
-    ASSERT_OK(col_reader->NextBatch(1, &piece));
-    ASSERT_EQ(1, piece->length());
-    pieces.push_back(piece);
-  }
-  auto chunked = std::make_shared<::arrow::ChunkedArray>(pieces);
-
-  auto chunked_col =
-      std::make_shared<::arrow::Column>(table->schema()->field(0), chunked);
-  std::vector<std::shared_ptr<::arrow::Column>> columns = {chunked_col};
-  auto chunked_table = Table::Make(table->schema(), columns);
-
-  ASSERT_TRUE(table->Equals(*chunked_table));
-}
-
-typedef std::function<void(int, std::shared_ptr<::DataType>*, std::shared_ptr<Array>*)>
-    ArrayFactory;
-
-template <typename ArrowType>
-struct GenerateArrayFunctor {
-  explicit GenerateArrayFunctor(double pct_null = 0.1) : pct_null(pct_null) {}
-
-  void operator()(int length, std::shared_ptr<::DataType>* type,
-                  std::shared_ptr<Array>* array) {
-    using T = typename ArrowType::c_type;
-
-    // TODO(wesm): generate things other than integers
-    std::vector<T> draws;
-    randint(length, 0, 100, &draws);
-
-    std::vector<bool> is_valid;
-    random_is_valid(length, this->pct_null, &is_valid);
-
-    *type = ::arrow::TypeTraits<ArrowType>::type_singleton();
-    ::arrow::ArrayFromVector<ArrowType, T>(*type, is_valid, draws, array);
-  }
-
-  double pct_null;
-};
-
-typedef std::function<void(int, std::shared_ptr<::DataType>*, std::shared_ptr<Array>*)>
-    ArrayFactory;
-
-auto GenerateInt32 = [](int length, std::shared_ptr<::DataType>* type,
-                        std::shared_ptr<Array>* array) {
-  GenerateArrayFunctor<::arrow::Int32Type> func;
-  func(length, type, array);
-};
-
-auto GenerateList = [](int length, std::shared_ptr<::DataType>* type,
-                       std::shared_ptr<Array>* array) {
-  MakeListArray(length, 100, type, array);
-};
-
-TEST(TestArrowReadWrite, TableWithChunkedColumns) {
-  std::vector<ArrayFactory> functions = {GenerateInt32, GenerateList};
-
-  std::vector<int> chunk_sizes = {2, 4, 10, 2};
-  const int64_t total_length = 18;
-
-  for (const auto& datagen_func : functions) {
-    ::arrow::ArrayVector arrays;
-    std::shared_ptr<Array> arr;
-    std::shared_ptr<::DataType> type;
-    datagen_func(total_length, &type, &arr);
-
-    int64_t offset = 0;
-    for (int chunk_size : chunk_sizes) {
-      arrays.push_back(arr->Slice(offset, chunk_size));
-      offset += chunk_size;
-    }
-
-    auto field = ::arrow::field("fname", type);
-    auto schema = ::arrow::schema({field});
-    auto col = std::make_shared<::arrow::Column>(field, arrays);
-    auto table = Table::Make(schema, {col});
-
-    ASSERT_NO_FATAL_FAILURE(CheckSimpleRoundtrip(table, 2));
-    ASSERT_NO_FATAL_FAILURE(CheckSimpleRoundtrip(table, 3));
-    ASSERT_NO_FATAL_FAILURE(CheckSimpleRoundtrip(table, 10));
-  }
-}
-
-TEST(TestArrowReadWrite, TableWithDuplicateColumns) {
-  // See ARROW-1974
-  using ::arrow::ArrayFromVector;
-
-  auto f0 = field("duplicate", ::arrow::int8());
-  auto f1 = field("duplicate", ::arrow::int16());
-  auto schema = ::arrow::schema({f0, f1});
-
-  std::vector<int8_t> a0_values = {1, 2, 3};
-  std::vector<int16_t> a1_values = {14, 15, 16};
-
-  std::shared_ptr<Array> a0, a1;
-
-  ArrayFromVector<::arrow::Int8Type, int8_t>(a0_values, &a0);
-  ArrayFromVector<::arrow::Int16Type, int16_t>(a1_values, &a1);
-
-  auto table = Table::Make(schema, {std::make_shared<Column>(f0->name(), a0),
-                                    std::make_shared<Column>(f1->name(), a1)});
-  ASSERT_NO_FATAL_FAILURE(CheckSimpleRoundtrip(table, table->num_rows()));
-}
-
-TEST(TestArrowReadWrite, DictionaryColumnChunkedWrite) {
-  // This is a regression test for this:
-  //
-  // https://issues.apache.org/jira/browse/ARROW-1938
-  //
-  // As of the writing of this test, columns of type
-  // dictionary are written as their raw/expanded values.
-  // The regression was that the whole column was being
-  // written for each chunk.
-  using ::arrow::ArrayFromVector;
-
-  std::vector<std::string> values = {"first", "second", "third"};
-  auto type = ::arrow::utf8();
-  std::shared_ptr<Array> dict_values;
-  ArrayFromVector<::arrow::StringType, std::string>(values, &dict_values);
-
-  auto dict_type = ::arrow::dictionary(::arrow::int32(), dict_values);
-  auto f0 = field("dictionary", dict_type);
-  std::vector<std::shared_ptr<::arrow::Field>> fields;
-  fields.emplace_back(f0);
-  auto schema = ::arrow::schema(fields);
-
-  std::shared_ptr<Array> f0_values, f1_values;
-  ArrayFromVector<::arrow::Int32Type, int32_t>({0, 1, 0, 2, 1}, &f0_values);
-  ArrayFromVector<::arrow::Int32Type, int32_t>({2, 0, 1, 0, 2}, &f1_values);
-  ::arrow::ArrayVector dict_arrays = {
-      std::make_shared<::arrow::DictionaryArray>(dict_type, f0_values),
-      std::make_shared<::arrow::DictionaryArray>(dict_type, f1_values)};
-
-  std::vector<std::shared_ptr<::arrow::Column>> columns;
-  auto column = MakeColumn("column", dict_arrays, false);
-  columns.emplace_back(column);
-
-  auto table = Table::Make(schema, columns);
-
-  std::shared_ptr<Table> result;
-  DoSimpleRoundtrip(table, 1,
-                    // Just need to make sure that we make
-                    // a chunk size that is smaller than the
-                    // total number of values
-                    2, {}, &result);
-
-  std::vector<std::string> expected_values = {"first",  "second", "first", "third",
-                                              "second", "third",  "first", "second",
-                                              "first",  "third"};
-  columns.clear();
-
-  std::shared_ptr<Array> expected_array;
-  ArrayFromVector<::arrow::StringType, std::string>(expected_values, &expected_array);
-
-  // The column name gets changed on output to the name of the
-  // field, and it also turns into a nullable column
-  columns.emplace_back(MakeColumn("dictionary", expected_array, true));
-
-  fields.clear();
-  fields.emplace_back(::arrow::field("dictionary", ::arrow::utf8()));
-  schema = ::arrow::schema(fields);
-
-  auto expected_table = Table::Make(schema, columns);
-
-  ::arrow::AssertTablesEqual(*expected_table, *result, false);
-}
-
-TEST(TestArrowWrite, CheckChunkSize) {
-  const int num_columns = 2;
-  const int num_rows = 128;
-  const int64_t chunk_size = 0;  // note the chunk_size is 0
-  std::shared_ptr<Table> table;
-  ASSERT_NO_FATAL_FAILURE(MakeDoubleTable(num_columns, num_rows, 1, &table));
-
-  auto sink = std::make_shared<InMemoryOutputStream>();
-
-  ASSERT_RAISES(Invalid,
-                WriteTable(*table, ::arrow::default_memory_pool(), sink, chunk_size));
-}
-
-class TestNestedSchemaRead : public ::testing::TestWithParam<Repetition::type> {
- protected:
-  // make it *3 to make it easily divisible by 3
-  const int NUM_SIMPLE_TEST_ROWS = SMALL_SIZE * 3;
-  std::shared_ptr<::arrow::Int32Array> values_array_ = nullptr;
-
-  void InitReader() {
-    std::shared_ptr<Buffer> buffer = nested_parquet_->GetBuffer();
-    ASSERT_OK_NO_THROW(
-        OpenFile(std::make_shared<BufferReader>(buffer), ::arrow::default_memory_pool(),
-                 ::parquet::default_reader_properties(), nullptr, &reader_));
-  }
-
-  void InitNewParquetFile(const std::shared_ptr<GroupNode>& schema, int num_rows) {
-    nested_parquet_ = std::make_shared<InMemoryOutputStream>();
-
-    writer_ = parquet::ParquetFileWriter::Open(nested_parquet_, schema,
-                                               default_writer_properties());
-    row_group_writer_ = writer_->AppendRowGroup();
-  }
-
-  void FinalizeParquetFile() {
-    row_group_writer_->Close();
-    writer_->Close();
-  }
-
-  void MakeValues(int num_rows) {
-    std::shared_ptr<Array> arr;
-    ASSERT_OK(NullableArray<::arrow::Int32Type>(num_rows, 0, kDefaultSeed, &arr));
-    values_array_ = std::dynamic_pointer_cast<::arrow::Int32Array>(arr);
-  }
-
-  void WriteColumnData(size_t num_rows, int16_t* def_levels, int16_t* rep_levels,
-                       int32_t* values) {
-    auto typed_writer =
-        static_cast<TypedColumnWriter<Int32Type>*>(row_group_writer_->NextColumn());
-    typed_writer->WriteBatch(num_rows, def_levels, rep_levels, values);
-  }
-
-  void ValidateArray(const Array& array, size_t expected_nulls) {
-    ASSERT_EQ(array.length(), values_array_->length());
-    ASSERT_EQ(array.null_count(), expected_nulls);
-    // Also independently count the nulls
-    auto local_null_count = 0;
-    for (int i = 0; i < array.length(); i++) {
-      if (array.IsNull(i)) {
-        local_null_count++;
-      }
-    }
-    ASSERT_EQ(local_null_count, expected_nulls);
-  }
-
-  void ValidateColumnArray(const ::arrow::Int32Array& array, size_t expected_nulls) {
-    ValidateArray(array, expected_nulls);
-    int j = 0;
-    for (int i = 0; i < values_array_->length(); i++) {
-      if (array.IsNull(i)) {
-        continue;
-      }
-      ASSERT_EQ(array.Value(i), values_array_->Value(j));
-      j++;
-    }
-  }
-
-  void ValidateTableArrayTypes(const Table& table) {
-    for (int i = 0; i < table.num_columns(); i++) {
-      const std::shared_ptr<::arrow::Field> schema_field = table.schema()->field(i);
-      const std::shared_ptr<Column> column = table.column(i);
-      // Compare with the column field
-      ASSERT_TRUE(schema_field->Equals(column->field()));
-      // Compare with the array type
-      ASSERT_TRUE(schema_field->type()->Equals(column->data()->chunk(0)->type()));
-    }
-  }
-
-  // A parquet with a simple nested schema
-  void CreateSimpleNestedParquet(Repetition::type struct_repetition) {
-    std::vector<NodePtr> parquet_fields;
-    // TODO(itaiin): We are using parquet low-level file api to create the nested parquet
-    // this needs to change when a nested writes are implemented
-
-    // create the schema:
-    // <struct_repetition> group group1 {
-    //   required int32 leaf1;
-    //   optional int32 leaf2;
-    // }
-    // required int32 leaf3;
-
-    parquet_fields.push_back(GroupNode::Make(
-        "group1", struct_repetition,
-        {PrimitiveNode::Make("leaf1", Repetition::REQUIRED, ParquetType::INT32),
-         PrimitiveNode::Make("leaf2", Repetition::OPTIONAL, ParquetType::INT32)}));
-    parquet_fields.push_back(
-        PrimitiveNode::Make("leaf3", Repetition::REQUIRED, ParquetType::INT32));
-
-    auto schema_node = GroupNode::Make("schema", Repetition::REQUIRED, parquet_fields);
-
-    // Create definition levels for the different columns that contain interleaved
-    // nulls and values at all nesting levels
-
-    //  definition levels for optional fields
-    std::vector<int16_t> leaf1_def_levels(NUM_SIMPLE_TEST_ROWS);
-    std::vector<int16_t> leaf2_def_levels(NUM_SIMPLE_TEST_ROWS);
-    std::vector<int16_t> leaf3_def_levels(NUM_SIMPLE_TEST_ROWS);
-    for (int i = 0; i < NUM_SIMPLE_TEST_ROWS; i++) {
-      // leaf1 is required within the optional group1, so it is only null
-      // when the group is null
-      leaf1_def_levels[i] = (i % 3 == 0) ? 0 : 1;
-      // leaf2 is optional, can be null in the primitive (def-level 1) or
-      // struct level (def-level 0)
-      leaf2_def_levels[i] = static_cast<int16_t>(i % 3);
-      // leaf3 is required
-      leaf3_def_levels[i] = 0;
-    }
-
-    std::vector<int16_t> rep_levels(NUM_SIMPLE_TEST_ROWS, 0);
-
-    // Produce values for the columns
-    MakeValues(NUM_SIMPLE_TEST_ROWS);
-    int32_t* values = reinterpret_cast<int32_t*>(values_array_->values()->mutable_data());
-
-    // Create the actual parquet file
-    InitNewParquetFile(std::static_pointer_cast<GroupNode>(schema_node),
-                       NUM_SIMPLE_TEST_ROWS);
-
-    // leaf1 column
-    WriteColumnData(NUM_SIMPLE_TEST_ROWS, leaf1_def_levels.data(), rep_levels.data(),
-                    values);
-    // leaf2 column
-    WriteColumnData(NUM_SIMPLE_TEST_ROWS, leaf2_def_levels.data(), rep_levels.data(),
-                    values);
-    // leaf3 column
-    WriteColumnData(NUM_SIMPLE_TEST_ROWS, leaf3_def_levels.data(), rep_levels.data(),
-                    values);
-
-    FinalizeParquetFile();
-    InitReader();
-  }
-
-  NodePtr CreateSingleTypedNestedGroup(int index, int depth, int num_children,
-                                       Repetition::type node_repetition,
-                                       ParquetType::type leaf_type) {
-    std::vector<NodePtr> children;
-
-    for (int i = 0; i < num_children; i++) {
-      if (depth <= 1) {
-        children.push_back(PrimitiveNode::Make("leaf", node_repetition, leaf_type));
-      } else {
-        children.push_back(CreateSingleTypedNestedGroup(i, depth - 1, num_children,
-                                                        node_repetition, leaf_type));
-      }
-    }
-
-    std::stringstream ss;
-    ss << "group-" << depth << "-" << index;
-    return NodePtr(GroupNode::Make(ss.str(), node_repetition, children));
-  }
-
-  // A deeply nested schema
-  void CreateMultiLevelNestedParquet(int num_trees, int tree_depth, int num_children,
-                                     int num_rows, Repetition::type node_repetition) {
-    // Create the schema
-    std::vector<NodePtr> parquet_fields;
-    for (int i = 0; i < num_trees; i++) {
-      parquet_fields.push_back(CreateSingleTypedNestedGroup(
-          i, tree_depth, num_children, node_repetition, ParquetType::INT32));
-    }
-    auto schema_node = GroupNode::Make("schema", Repetition::REQUIRED, parquet_fields);
-
-    int num_columns = num_trees * static_cast<int>((std::pow(num_children, tree_depth)));
-
-    std::vector<int16_t> def_levels;
-    std::vector<int16_t> rep_levels;
-
-    int num_levels = 0;
-    while (num_levels < num_rows) {
-      if (node_repetition == Repetition::REQUIRED) {
-        def_levels.push_back(0);  // all are required
-      } else {
-        int16_t level = static_cast<int16_t>(num_levels % (tree_depth + 2));
-        def_levels.push_back(level);  // all are optional
-      }
-      rep_levels.push_back(0);  // none is repeated
-      ++num_levels;
-    }
-
-    // Produce values for the columns
-    MakeValues(num_rows);
-    int32_t* values = reinterpret_cast<int32_t*>(values_array_->values()->mutable_data());
-
-    // Create the actual parquet file
-    InitNewParquetFile(std::static_pointer_cast<GroupNode>(schema_node), num_rows);
-
-    for (int i = 0; i < num_columns; i++) {
-      WriteColumnData(num_rows, def_levels.data(), rep_levels.data(), values);
-    }
-    FinalizeParquetFile();
-    InitReader();
-  }
-
-  class DeepParquetTestVisitor : public ArrayVisitor {
-   public:
-    DeepParquetTestVisitor(Repetition::type node_repetition,
-                           std::shared_ptr<::arrow::Int32Array> expected)
-        : node_repetition_(node_repetition), expected_(expected) {}
-
-    Status Validate(std::shared_ptr<Array> tree) { return tree->Accept(this); }
-
-    virtual Status Visit(const ::arrow::Int32Array& array) {
-      if (node_repetition_ == Repetition::REQUIRED) {
-        if (!array.Equals(expected_)) {
-          return Status::Invalid("leaf array data mismatch");
-        }
-      } else if (node_repetition_ == Repetition::OPTIONAL) {
-        if (array.length() != expected_->length()) {
-          return Status::Invalid("Bad leaf array length");
-        }
-        // expect only 1 value every `depth` row
-        if (array.null_count() != SMALL_SIZE) {
-          return Status::Invalid("Unexpected null count");
-        }
-      } else {
-        return Status::NotImplemented("Unsupported repetition");
-      }
-      return Status::OK();
-    }
-
-    virtual Status Visit(const ::arrow::StructArray& array) {
-      for (int32_t i = 0; i < array.num_fields(); ++i) {
-        auto child = array.field(i);
-        if (node_repetition_ == Repetition::REQUIRED) {
-          RETURN_NOT_OK(child->Accept(this));
-        } else if (node_repetition_ == Repetition::OPTIONAL) {
-          // Null count Must be a multiple of SMALL_SIZE
-          if (array.null_count() % SMALL_SIZE != 0) {
-            return Status::Invalid("Unexpected struct null count");
-          }
-        } else {
-          return Status::NotImplemented("Unsupported repetition");
-        }
-      }
-      return Status::OK();
-    }
-
-   private:
-    Repetition::type node_repetition_;
-    std::shared_ptr<::arrow::Int32Array> expected_;
-  };
-
-  std::shared_ptr<InMemoryOutputStream> nested_parquet_;
-  std::unique_ptr<FileReader> reader_;
-  std::unique_ptr<ParquetFileWriter> writer_;
-  RowGroupWriter* row_group_writer_;
-};
-
-TEST_F(TestNestedSchemaRead, ReadIntoTableFull) {
-  ASSERT_NO_FATAL_FAILURE(CreateSimpleNestedParquet(Repetition::OPTIONAL));
-
-  std::shared_ptr<Table> table;
-  ASSERT_OK_NO_THROW(reader_->ReadTable(&table));
-  ASSERT_EQ(table->num_rows(), NUM_SIMPLE_TEST_ROWS);
-  ASSERT_EQ(table->num_columns(), 2);
-  ASSERT_EQ(table->schema()->field(0)->type()->num_children(), 2);
-  ASSERT_NO_FATAL_FAILURE(ValidateTableArrayTypes(*table));
-
-  auto struct_field_array =
-      std::static_pointer_cast<::arrow::StructArray>(table->column(0)->data()->chunk(0));
-  auto leaf1_array =
-      std::static_pointer_cast<::arrow::Int32Array>(struct_field_array->field(0));
-  auto leaf2_array =
-      std::static_pointer_cast<::arrow::Int32Array>(struct_field_array->field(1));
-  auto leaf3_array =
-      std::static_pointer_cast<::arrow::Int32Array>(table->column(1)->data()->chunk(0));
-
-  // validate struct and leaf arrays
-
-  // validate struct array
-  ASSERT_NO_FATAL_FAILURE(ValidateArray(*struct_field_array, NUM_SIMPLE_TEST_ROWS / 3));
-  // validate leaf1
-  ASSERT_NO_FATAL_FAILURE(ValidateColumnArray(*leaf1_array, NUM_SIMPLE_TEST_ROWS / 3));
-  // validate leaf2
-  ASSERT_NO_FATAL_FAILURE(
-      ValidateColumnArray(*leaf2_array, NUM_SIMPLE_TEST_ROWS * 2 / 3));
-  // validate leaf3
-  ASSERT_NO_FATAL_FAILURE(ValidateColumnArray(*leaf3_array, 0));
-}
-
-TEST_F(TestNestedSchemaRead, ReadTablePartial) {
-  ASSERT_NO_FATAL_FAILURE(CreateSimpleNestedParquet(Repetition::OPTIONAL));
-  std::shared_ptr<Table> table;
-
-  // columns: {group1.leaf1, leaf3}
-  ASSERT_OK_NO_THROW(reader_->ReadTable({0, 2}, &table));
-  ASSERT_EQ(table->num_rows(), NUM_SIMPLE_TEST_ROWS);
-  ASSERT_EQ(table->num_columns(), 2);
-  ASSERT_EQ(table->schema()->field(0)->name(), "group1");
-  ASSERT_EQ(table->schema()->field(1)->name(), "leaf3");
-  ASSERT_EQ(table->schema()->field(0)->type()->num_children(), 1);
-  ASSERT_NO_FATAL_FAILURE(ValidateTableArrayTypes(*table));
-
-  // columns: {group1.leaf1, group1.leaf2}
-  ASSERT_OK_NO_THROW(reader_->ReadTable({0, 1}, &table));
-  ASSERT_EQ(table->num_rows(), NUM_SIMPLE_TEST_ROWS);
-  ASSERT_EQ(table->num_columns(), 1);
-  ASSERT_EQ(table->schema()->field(0)->name(), "group1");
-  ASSERT_EQ(table->schema()->field(0)->type()->num_children(), 2);
-  ASSERT_NO_FATAL_FAILURE(ValidateTableArrayTypes(*table));
-
-  // columns: {leaf3}
-  ASSERT_OK_NO_THROW(reader_->ReadTable({2}, &table));
-  ASSERT_EQ(table->num_rows(), NUM_SIMPLE_TEST_ROWS);
-  ASSERT_EQ(table->num_columns(), 1);
-  ASSERT_EQ(table->schema()->field(0)->name(), "leaf3");
-  ASSERT_EQ(table->schema()->field(0)->type()->num_children(), 0);
-  ASSERT_NO_FATAL_FAILURE(ValidateTableArrayTypes(*table));
-
-  // Test with different ordering
-  ASSERT_OK_NO_THROW(reader_->ReadTable({2, 0}, &table));
-  ASSERT_EQ(table->num_rows(), NUM_SIMPLE_TEST_ROWS);
-  ASSERT_EQ(table->num_columns(), 2);
-  ASSERT_EQ(table->schema()->field(0)->name(), "leaf3");
-  ASSERT_EQ(table->schema()->field(1)->name(), "group1");
-  ASSERT_EQ(table->schema()->field(1)->type()->num_children(), 1);
-  ASSERT_NO_FATAL_FAILURE(ValidateTableArrayTypes(*table));
-}
-
-TEST_F(TestNestedSchemaRead, StructAndListTogetherUnsupported) {
-  ASSERT_NO_FATAL_FAILURE(CreateSimpleNestedParquet(Repetition::REPEATED));
-  std::shared_ptr<Table> table;
-  ASSERT_RAISES(NotImplemented, reader_->ReadTable(&table));
-}
-
-TEST_P(TestNestedSchemaRead, DeepNestedSchemaRead) {
-#ifdef PARQUET_VALGRIND
-  const int num_trees = 3;
-  const int depth = 3;
-#else
-  const int num_trees = 10;
-  const int depth = 5;
-#endif
-  const int num_children = 3;
-  int num_rows = SMALL_SIZE * (depth + 2);
-  ASSERT_NO_FATAL_FAILURE(CreateMultiLevelNestedParquet(num_trees, depth, num_children,
-                                                        num_rows, GetParam()));
-  std::shared_ptr<Table> table;
-  ASSERT_OK_NO_THROW(reader_->ReadTable(&table));
-  ASSERT_EQ(table->num_columns(), num_trees);
-  ASSERT_EQ(table->num_rows(), num_rows);
-
-  DeepParquetTestVisitor visitor(GetParam(), values_array_);
-  for (int i = 0; i < table->num_columns(); i++) {
-    auto tree = table->column(i)->data()->chunk(0);
-    ASSERT_OK_NO_THROW(visitor.Validate(tree));
-  }
-}
-
-INSTANTIATE_TEST_CASE_P(Repetition_type, TestNestedSchemaRead,
-                        ::testing::Values(Repetition::REQUIRED, Repetition::OPTIONAL));
-
-TEST(TestImpalaConversion, NanosecondToImpala) {
-  // June 20, 2017 16:32:56 and 123456789 nanoseconds
-  int64_t nanoseconds = INT64_C(1497976376123456789);
-  Int96 expected = {{UINT32_C(632093973), UINT32_C(13871), UINT32_C(2457925)}};
-  Int96 calculated;
-  internal::NanosecondsToImpalaTimestamp(nanoseconds, &calculated);
-  ASSERT_EQ(expected, calculated);
-}
-
-TEST(TestArrowReaderAdHoc, Int96BadMemoryAccess) {
-  // PARQUET-995
-  std::string dir_string(test::get_data_dir());
-  std::stringstream ss;
-  ss << dir_string << "/"
-     << "alltypes_plain.parquet";
-  auto path = ss.str();
-
-  auto pool = ::arrow::default_memory_pool();
-
-  std::unique_ptr<FileReader> arrow_reader;
-  ASSERT_NO_THROW(
-      arrow_reader.reset(new FileReader(pool, ParquetFileReader::OpenFile(path, false))));
-  std::shared_ptr<::arrow::Table> table;
-  ASSERT_OK_NO_THROW(arrow_reader->ReadTable(&table));
-}
-
-class TestArrowReaderAdHocSpark
-    : public ::testing::TestWithParam<
-          std::tuple<std::string, std::shared_ptr<::DataType>>> {};
-
-TEST_P(TestArrowReaderAdHocSpark, ReadDecimals) {
-  std::string path(test::get_data_dir());
-
-  std::string filename;
-  std::shared_ptr<::DataType> decimal_type;
-  std::tie(filename, decimal_type) = GetParam();
-
-  path += "/" + filename;
-  ASSERT_GT(path.size(), 0);
-
-  auto pool = ::arrow::default_memory_pool();
-
-  std::unique_ptr<FileReader> arrow_reader;
-  ASSERT_NO_THROW(
-      arrow_reader.reset(new FileReader(pool, ParquetFileReader::OpenFile(path, false))));
-  std::shared_ptr<::arrow::Table> table;
-  ASSERT_OK_NO_THROW(arrow_reader->ReadTable(&table));
-
-  ASSERT_EQ(1, table->num_columns());
-
-  constexpr int32_t expected_length = 24;
-
-  auto value_column = table->column(0);
-  ASSERT_EQ(expected_length, value_column->length());
-
-  auto raw_array = value_column->data();
-  ASSERT_EQ(1, raw_array->num_chunks());
-
-  auto chunk = raw_array->chunk(0);
-
-  std::shared_ptr<Array> expected_array;
-
-  ::arrow::Decimal128Builder builder(decimal_type, pool);
-
-  for (int32_t i = 0; i < expected_length; ++i) {
-    ::arrow::Decimal128 value((i + 1) * 100);
-    ASSERT_OK(builder.Append(value));
-  }
-  ASSERT_OK(builder.Finish(&expected_array));
-
-  internal::AssertArraysEqual(*expected_array, *chunk);
-}
-
-INSTANTIATE_TEST_CASE_P(
-    ReadDecimals, TestArrowReaderAdHocSpark,
-    ::testing::Values(
-        std::make_tuple("int32_decimal.parquet", ::arrow::decimal(4, 2)),
-        std::make_tuple("int64_decimal.parquet", ::arrow::decimal(10, 2)),
-        std::make_tuple("fixed_length_decimal.parquet", ::arrow::decimal(25, 2)),
-        std::make_tuple("fixed_length_decimal_legacy.parquet", ::arrow::decimal(13, 2))));
-
-}  // namespace arrow
-
-}  // namespace parquet
diff --git a/src/parquet/arrow/arrow-schema-test.cc b/src/parquet/arrow/arrow-schema-test.cc
deleted file mode 100644
index cb2b850..0000000
--- a/src/parquet/arrow/arrow-schema-test.cc
+++ /dev/null
@@ -1,852 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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.
-
-#include <memory>
-#include <vector>
-
-#include "gtest/gtest.h"
-
-#include "parquet/arrow/schema.h"
-
-#include "arrow/api.h"
-#include "arrow/test-util.h"
-
-using arrow::ArrayFromVector;
-using arrow::Field;
-using arrow::TimeUnit;
-
-using ParquetType = parquet::Type;
-using parquet::LogicalType;
-using parquet::Repetition;
-using parquet::schema::GroupNode;
-using parquet::schema::NodePtr;
-using parquet::schema::PrimitiveNode;
-
-namespace parquet {
-
-namespace arrow {
-
-const auto BOOL = ::arrow::boolean();
-const auto UINT8 = ::arrow::uint8();
-const auto INT32 = ::arrow::int32();
-const auto INT64 = ::arrow::int64();
-const auto FLOAT = ::arrow::float32();
-const auto DOUBLE = ::arrow::float64();
-const auto UTF8 = ::arrow::utf8();
-const auto TIMESTAMP_MS = ::arrow::timestamp(TimeUnit::MILLI);
-const auto TIMESTAMP_US = ::arrow::timestamp(TimeUnit::MICRO);
-const auto TIMESTAMP_NS = ::arrow::timestamp(TimeUnit::NANO);
-const auto BINARY = ::arrow::binary();
-const auto DECIMAL_8_4 = std::make_shared<::arrow::Decimal128Type>(8, 4);
-
-class TestConvertParquetSchema : public ::testing::Test {
- public:
-  virtual void SetUp() {}
-
-  void CheckFlatSchema(const std::shared_ptr<::arrow::Schema>& expected_schema) {
-    ASSERT_EQ(expected_schema->num_fields(), result_schema_->num_fields());
-    for (int i = 0; i < expected_schema->num_fields(); ++i) {
-      auto lhs = result_schema_->field(i);
-      auto rhs = expected_schema->field(i);
-      EXPECT_TRUE(lhs->Equals(rhs))
-          << i << " " << lhs->ToString() << " != " << rhs->ToString();
-    }
-  }
-
-  ::arrow::Status ConvertSchema(const std::vector<NodePtr>& nodes) {
-    NodePtr schema = GroupNode::Make("schema", Repetition::REPEATED, nodes);
-    descr_.Init(schema);
-    return FromParquetSchema(&descr_, &result_schema_);
-  }
-
-  ::arrow::Status ConvertSchema(const std::vector<NodePtr>& nodes,
-                                const std::vector<int>& column_indices) {
-    NodePtr schema = GroupNode::Make("schema", Repetition::REPEATED, nodes);
-    descr_.Init(schema);
-    return FromParquetSchema(&descr_, column_indices, &result_schema_);
-  }
-
-  ::arrow::Status ConvertSchema(
-      const std::vector<NodePtr>& nodes,
-      const std::shared_ptr<const KeyValueMetadata>& key_value_metadata) {
-    NodePtr schema = GroupNode::Make("schema", Repetition::REPEATED, nodes);
-    descr_.Init(schema);
-    return FromParquetSchema(&descr_, {}, key_value_metadata, &result_schema_);
-  }
-
- protected:
-  SchemaDescriptor descr_;
-  std::shared_ptr<::arrow::Schema> result_schema_;
-};
-
-TEST_F(TestConvertParquetSchema, ParquetFlatPrimitives) {
-  std::vector<NodePtr> parquet_fields;
-  std::vector<std::shared_ptr<Field>> arrow_fields;
-
-  parquet_fields.push_back(
-      PrimitiveNode::Make("boolean", Repetition::REQUIRED, ParquetType::BOOLEAN));
-  arrow_fields.push_back(std::make_shared<Field>("boolean", BOOL, false));
-
-  parquet_fields.push_back(
-      PrimitiveNode::Make("int32", Repetition::REQUIRED, ParquetType::INT32));
-  arrow_fields.push_back(std::make_shared<Field>("int32", INT32, false));
-
-  parquet_fields.push_back(
-      PrimitiveNode::Make("int64", Repetition::REQUIRED, ParquetType::INT64));
-  arrow_fields.push_back(std::make_shared<Field>("int64", INT64, false));
-
-  parquet_fields.push_back(PrimitiveNode::Make("timestamp", Repetition::REQUIRED,
-                                               ParquetType::INT64,
-                                               LogicalType::TIMESTAMP_MILLIS));
-  arrow_fields.push_back(std::make_shared<Field>("timestamp", TIMESTAMP_MS, false));
-
-  parquet_fields.push_back(PrimitiveNode::Make("timestamp[us]", Repetition::REQUIRED,
-                                               ParquetType::INT64,
-                                               LogicalType::TIMESTAMP_MICROS));
-  arrow_fields.push_back(std::make_shared<Field>("timestamp[us]", TIMESTAMP_US, false));
-
-  parquet_fields.push_back(PrimitiveNode::Make("date", Repetition::REQUIRED,
-                                               ParquetType::INT32, LogicalType::DATE));
-  arrow_fields.push_back(std::make_shared<Field>("date", ::arrow::date32(), false));
-
-  parquet_fields.push_back(PrimitiveNode::Make(
-      "time32", Repetition::REQUIRED, ParquetType::INT32, LogicalType::TIME_MILLIS));
-  arrow_fields.push_back(
-      std::make_shared<Field>("time32", ::arrow::time32(TimeUnit::MILLI), false));
-
-  parquet_fields.push_back(PrimitiveNode::Make(
-      "time64", Repetition::REQUIRED, ParquetType::INT64, LogicalType::TIME_MICROS));
-  arrow_fields.push_back(
-      std::make_shared<Field>("time64", ::arrow::time64(TimeUnit::MICRO), false));
-
-  parquet_fields.push_back(
-      PrimitiveNode::Make("timestamp96", Repetition::REQUIRED, ParquetType::INT96));
-  arrow_fields.push_back(std::make_shared<Field>("timestamp96", TIMESTAMP_NS, false));
-
-  parquet_fields.push_back(
-      PrimitiveNode::Make("float", Repetition::OPTIONAL, ParquetType::FLOAT));
-  arrow_fields.push_back(std::make_shared<Field>("float", FLOAT));
-
-  parquet_fields.push_back(
-      PrimitiveNode::Make("double", Repetition::OPTIONAL, ParquetType::DOUBLE));
-  arrow_fields.push_back(std::make_shared<Field>("double", DOUBLE));
-
-  parquet_fields.push_back(
-      PrimitiveNode::Make("binary", Repetition::OPTIONAL, ParquetType::BYTE_ARRAY));
-  arrow_fields.push_back(std::make_shared<Field>("binary", BINARY));
-
-  parquet_fields.push_back(PrimitiveNode::Make(
-      "string", Repetition::OPTIONAL, ParquetType::BYTE_ARRAY, LogicalType::UTF8));
-  arrow_fields.push_back(std::make_shared<Field>("string", UTF8));
-
-  parquet_fields.push_back(PrimitiveNode::Make("flba-binary", Repetition::OPTIONAL,
-                                               ParquetType::FIXED_LEN_BYTE_ARRAY,
-                                               LogicalType::NONE, 12));
-  arrow_fields.push_back(
-      std::make_shared<Field>("flba-binary", ::arrow::fixed_size_binary(12)));
-
-  auto arrow_schema = std::make_shared<::arrow::Schema>(arrow_fields);
-  ASSERT_OK(ConvertSchema(parquet_fields));
-
-  ASSERT_NO_FATAL_FAILURE(CheckFlatSchema(arrow_schema));
-}
-
-TEST_F(TestConvertParquetSchema, DuplicateFieldNames) {
-  std::vector<NodePtr> parquet_fields;
-  std::vector<std::shared_ptr<Field>> arrow_fields;
-
-  parquet_fields.push_back(
-      PrimitiveNode::Make("xxx", Repetition::REQUIRED, ParquetType::BOOLEAN));
-  auto arrow_field1 = std::make_shared<Field>("xxx", BOOL, false);
-
-  parquet_fields.push_back(
-      PrimitiveNode::Make("xxx", Repetition::REQUIRED, ParquetType::INT32));
-  auto arrow_field2 = std::make_shared<Field>("xxx", INT32, false);
-
-  ASSERT_OK(ConvertSchema(parquet_fields));
-  arrow_fields = {arrow_field1, arrow_field2};
-  ASSERT_NO_FATAL_FAILURE(
-      CheckFlatSchema(std::make_shared<::arrow::Schema>(arrow_fields)));
-
-  ASSERT_OK(ConvertSchema(parquet_fields, std::vector<int>({0, 1})));
-  arrow_fields = {arrow_field1, arrow_field2};
-  ASSERT_NO_FATAL_FAILURE(
-      CheckFlatSchema(std::make_shared<::arrow::Schema>(arrow_fields)));
-
-  ASSERT_OK(ConvertSchema(parquet_fields, std::vector<int>({1, 0})));
-  arrow_fields = {arrow_field2, arrow_field1};
-  ASSERT_NO_FATAL_FAILURE(
-      CheckFlatSchema(std::make_shared<::arrow::Schema>(arrow_fields)));
-}
-
-TEST_F(TestConvertParquetSchema, ParquetKeyValueMetadata) {
-  std::vector<NodePtr> parquet_fields;
-  std::vector<std::shared_ptr<Field>> arrow_fields;
-
-  parquet_fields.push_back(
-      PrimitiveNode::Make("boolean", Repetition::REQUIRED, ParquetType::BOOLEAN));
-  arrow_fields.push_back(std::make_shared<Field>("boolean", BOOL, false));
-
-  parquet_fields.push_back(
-      PrimitiveNode::Make("int32", Repetition::REQUIRED, ParquetType::INT32));
-  arrow_fields.push_back(std::make_shared<Field>("int32", INT32, false));
-
-  auto key_value_metadata = std::make_shared<KeyValueMetadata>();
-  key_value_metadata->Append("foo", "bar");
-  key_value_metadata->Append("biz", "baz");
-  ASSERT_OK(ConvertSchema(parquet_fields, key_value_metadata));
-
-  auto arrow_metadata = result_schema_->metadata();
-  ASSERT_EQ("foo", arrow_metadata->key(0));
-  ASSERT_EQ("bar", arrow_metadata->value(0));
-  ASSERT_EQ("biz", arrow_metadata->key(1));
-  ASSERT_EQ("baz", arrow_metadata->value(1));
-}
-
-TEST_F(TestConvertParquetSchema, ParquetEmptyKeyValueMetadata) {
-  std::vector<NodePtr> parquet_fields;
-  std::vector<std::shared_ptr<Field>> arrow_fields;
-
-  parquet_fields.push_back(
-      PrimitiveNode::Make("int32", Repetition::REQUIRED, ParquetType::INT32));
-  arrow_fields.push_back(std::make_shared<Field>("int32", INT32, false));
-
-  std::shared_ptr<KeyValueMetadata> key_value_metadata = nullptr;
-  ASSERT_OK(ConvertSchema(parquet_fields, key_value_metadata));
-
-  auto arrow_metadata = result_schema_->metadata();
-  ASSERT_EQ(arrow_metadata, nullptr);
-}
-
-TEST_F(TestConvertParquetSchema, ParquetFlatDecimals) {
-  std::vector<NodePtr> parquet_fields;
-  std::vector<std::shared_ptr<Field>> arrow_fields;
-
-  parquet_fields.push_back(PrimitiveNode::Make("flba-decimal", Repetition::OPTIONAL,
-                                               ParquetType::FIXED_LEN_BYTE_ARRAY,
-                                               LogicalType::DECIMAL, 4, 8, 4));
-  arrow_fields.push_back(std::make_shared<Field>("flba-decimal", DECIMAL_8_4));
-
-  parquet_fields.push_back(PrimitiveNode::Make("binary-decimal", Repetition::OPTIONAL,
-                                               ParquetType::BYTE_ARRAY,
-                                               LogicalType::DECIMAL, -1, 8, 4));
-  arrow_fields.push_back(std::make_shared<Field>("binary-decimal", DECIMAL_8_4));
-
-  parquet_fields.push_back(PrimitiveNode::Make("int32-decimal", Repetition::OPTIONAL,
-                                               ParquetType::INT32, LogicalType::DECIMAL,
-                                               -1, 8, 4));
-  arrow_fields.push_back(std::make_shared<Field>("int32-decimal", DECIMAL_8_4));
-
-  parquet_fields.push_back(PrimitiveNode::Make("int64-decimal", Repetition::OPTIONAL,
-                                               ParquetType::INT64, LogicalType::DECIMAL,
-                                               -1, 8, 4));
-  arrow_fields.push_back(std::make_shared<Field>("int64-decimal", DECIMAL_8_4));
-
-  auto arrow_schema = std::make_shared<::arrow::Schema>(arrow_fields);
-  ASSERT_OK(ConvertSchema(parquet_fields));
-
-  ASSERT_NO_FATAL_FAILURE(CheckFlatSchema(arrow_schema));
-}
-
-TEST_F(TestConvertParquetSchema, ParquetLists) {
-  std::vector<NodePtr> parquet_fields;
-  std::vector<std::shared_ptr<Field>> arrow_fields;
-
-  // LIST encoding example taken from parquet-format/LogicalTypes.md
-
-  // // List<String> (list non-null, elements nullable)
-  // required group my_list (LIST) {
-  //   repeated group list {
-  //     optional binary element (UTF8);
-  //   }
-  // }
-  {
-    auto element = PrimitiveNode::Make("string", Repetition::OPTIONAL,
-                                       ParquetType::BYTE_ARRAY, LogicalType::UTF8);
-    auto list = GroupNode::Make("list", Repetition::REPEATED, {element});
-    parquet_fields.push_back(
-        GroupNode::Make("my_list", Repetition::REQUIRED, {list}, LogicalType::LIST));
-    auto arrow_element = std::make_shared<Field>("string", UTF8, true);
-    auto arrow_list = std::make_shared<::arrow::ListType>(arrow_element);
-    arrow_fields.push_back(std::make_shared<Field>("my_list", arrow_list, false));
-  }
-
-  // // List<String> (list nullable, elements non-null)
-  // optional group my_list (LIST) {
-  //   repeated group list {
-  //     required binary element (UTF8);
-  //   }
-  // }
-  {
-    auto element = PrimitiveNode::Make("string", Repetition::REQUIRED,
-                                       ParquetType::BYTE_ARRAY, LogicalType::UTF8);
-    auto list = GroupNode::Make("list", Repetition::REPEATED, {element});
-    parquet_fields.push_back(
-        GroupNode::Make("my_list", Repetition::OPTIONAL, {list}, LogicalType::LIST));
-    auto arrow_element = std::make_shared<Field>("string", UTF8, false);
-    auto arrow_list = std::make_shared<::arrow::ListType>(arrow_element);
-    arrow_fields.push_back(std::make_shared<Field>("my_list", arrow_list, true));
-  }
-
-  // Element types can be nested structures. For example, a list of lists:
-  //
-  // // List<List<Integer>>
-  // optional group array_of_arrays (LIST) {
-  //   repeated group list {
-  //     required group element (LIST) {
-  //       repeated group list {
-  //         required int32 element;
-  //       }
-  //     }
-  //   }
-  // }
-  {
-    auto inner_element =
-        PrimitiveNode::Make("int32", Repetition::REQUIRED, ParquetType::INT32);
-    auto inner_list = GroupNode::Make("list", Repetition::REPEATED, {inner_element});
-    auto element =
-        GroupNode::Make("element", Repetition::REQUIRED, {inner_list}, LogicalType::LIST);
-    auto list = GroupNode::Make("list", Repetition::REPEATED, {element});
-    parquet_fields.push_back(GroupNode::Make("array_of_arrays", Repetition::OPTIONAL,
-                                             {list}, LogicalType::LIST));
-    auto arrow_inner_element = std::make_shared<Field>("int32", INT32, false);
-    auto arrow_inner_list = std::make_shared<::arrow::ListType>(arrow_inner_element);
-    auto arrow_element = std::make_shared<Field>("element", arrow_inner_list, false);
-    auto arrow_list = std::make_shared<::arrow::ListType>(arrow_element);
-    arrow_fields.push_back(std::make_shared<Field>("array_of_arrays", arrow_list, true));
-  }
-
-  // // List<String> (list nullable, elements non-null)
-  // optional group my_list (LIST) {
-  //   repeated group element {
-  //     required binary str (UTF8);
-  //   };
-  // }
-  {
-    auto element = PrimitiveNode::Make("str", Repetition::REQUIRED,
-                                       ParquetType::BYTE_ARRAY, LogicalType::UTF8);
-    auto list = GroupNode::Make("element", Repetition::REPEATED, {element});
-    parquet_fields.push_back(
-        GroupNode::Make("my_list", Repetition::OPTIONAL, {list}, LogicalType::LIST));
-    auto arrow_element = std::make_shared<Field>("str", UTF8, false);
-    auto arrow_list = std::make_shared<::arrow::ListType>(arrow_element);
-    arrow_fields.push_back(std::make_shared<Field>("my_list", arrow_list, true));
-  }
-
-  // // List<Integer> (nullable list, non-null elements)
-  // optional group my_list (LIST) {
-  //   repeated int32 element;
-  // }
-  {
-    auto element =
-        PrimitiveNode::Make("element", Repetition::REPEATED, ParquetType::INT32);
-    parquet_fields.push_back(
-        GroupNode::Make("my_list", Repetition::OPTIONAL, {element}, LogicalType::LIST));
-    auto arrow_element = std::make_shared<Field>("element", INT32, false);
-    auto arrow_list = std::make_shared<::arrow::ListType>(arrow_element);
-    arrow_fields.push_back(std::make_shared<Field>("my_list", arrow_list, true));
-  }
-
-  // // List<Tuple<String, Integer>> (nullable list, non-null elements)
-  // optional group my_list (LIST) {
-  //   repeated group element {
-  //     required binary str (UTF8);
-  //     required int32 num;
-  //   };
-  // }
-  {
-    auto str_element = PrimitiveNode::Make("str", Repetition::REQUIRED,
-                                           ParquetType::BYTE_ARRAY, LogicalType::UTF8);
-    auto num_element =
-        PrimitiveNode::Make("num", Repetition::REQUIRED, ParquetType::INT32);
-    auto element =
-        GroupNode::Make("element", Repetition::REPEATED, {str_element, num_element});
-    parquet_fields.push_back(
-        GroupNode::Make("my_list", Repetition::OPTIONAL, {element}, LogicalType::LIST));
-    auto arrow_str = std::make_shared<Field>("str", UTF8, false);
-    auto arrow_num = std::make_shared<Field>("num", INT32, false);
-    std::vector<std::shared_ptr<Field>> fields({arrow_str, arrow_num});
-    auto arrow_struct = std::make_shared<::arrow::StructType>(fields);
-    auto arrow_element = std::make_shared<Field>("element", arrow_struct, false);
-    auto arrow_list = std::make_shared<::arrow::ListType>(arrow_element);
-    arrow_fields.push_back(std::make_shared<Field>("my_list", arrow_list, true));
-  }
-
-  // // List<OneTuple<String>> (nullable list, non-null elements)
-  // optional group my_list (LIST) {
-  //   repeated group array {
-  //     required binary str (UTF8);
-  //   };
-  // }
-  // Special case: group is named array
-  {
-    auto element = PrimitiveNode::Make("str", Repetition::REQUIRED,
-                                       ParquetType::BYTE_ARRAY, LogicalType::UTF8);
-    auto array = GroupNode::Make("array", Repetition::REPEATED, {element});
-    parquet_fields.push_back(
-        GroupNode::Make("my_list", Repetition::OPTIONAL, {array}, LogicalType::LIST));
-    auto arrow_str = std::make_shared<Field>("str", UTF8, false);
-    std::vector<std::shared_ptr<Field>> fields({arrow_str});
-    auto arrow_struct = std::make_shared<::arrow::StructType>(fields);
-    auto arrow_element = std::make_shared<Field>("array", arrow_struct, false);
-    auto arrow_list = std::make_shared<::arrow::ListType>(arrow_element);
-    arrow_fields.push_back(std::make_shared<Field>("my_list", arrow_list, true));
-  }
-
-  // // List<OneTuple<String>> (nullable list, non-null elements)
-  // optional group my_list (LIST) {
-  //   repeated group my_list_tuple {
-  //     required binary str (UTF8);
-  //   };
-  // }
-  // Special case: group named ends in _tuple
-  {
-    auto element = PrimitiveNode::Make("str", Repetition::REQUIRED,
-                                       ParquetType::BYTE_ARRAY, LogicalType::UTF8);
-    auto array = GroupNode::Make("my_list_tuple", Repetition::REPEATED, {element});
-    parquet_fields.push_back(
-        GroupNode::Make("my_list", Repetition::OPTIONAL, {array}, LogicalType::LIST));
-    auto arrow_str = std::make_shared<Field>("str", UTF8, false);
-    std::vector<std::shared_ptr<Field>> fields({arrow_str});
-    auto arrow_struct = std::make_shared<::arrow::StructType>(fields);
-    auto arrow_element = std::make_shared<Field>("my_list_tuple", arrow_struct, false);
-    auto arrow_list = std::make_shared<::arrow::ListType>(arrow_element);
-    arrow_fields.push_back(std::make_shared<Field>("my_list", arrow_list, true));
-  }
-
-  // One-level encoding: Only allows required lists with required cells
-  //   repeated value_type name
-  {
-    parquet_fields.push_back(
-        PrimitiveNode::Make("name", Repetition::REPEATED, ParquetType::INT32));
-    auto arrow_element = std::make_shared<Field>("name", INT32, false);
-    auto arrow_list = std::make_shared<::arrow::ListType>(arrow_element);
-    arrow_fields.push_back(std::make_shared<Field>("name", arrow_list, false));
-  }
-
-  auto arrow_schema = std::make_shared<::arrow::Schema>(arrow_fields);
-  ASSERT_OK(ConvertSchema(parquet_fields));
-
-  ASSERT_NO_FATAL_FAILURE(CheckFlatSchema(arrow_schema));
-}
-
-TEST_F(TestConvertParquetSchema, UnsupportedThings) {
-  std::vector<NodePtr> unsupported_nodes;
-
-  for (const NodePtr& node : unsupported_nodes) {
-    ASSERT_RAISES(NotImplemented, ConvertSchema({node}));
-  }
-}
-
-TEST_F(TestConvertParquetSchema, ParquetNestedSchema) {
-  std::vector<NodePtr> parquet_fields;
-  std::vector<std::shared_ptr<Field>> arrow_fields;
-
-  // required group group1 {
-  //   required bool leaf1;
-  //   required int32 leaf2;
-  // }
-  // required int64 leaf3;
-  {
-    parquet_fields.push_back(GroupNode::Make(
-        "group1", Repetition::REQUIRED,
-        {PrimitiveNode::Make("leaf1", Repetition::REQUIRED, ParquetType::BOOLEAN),
-         PrimitiveNode::Make("leaf2", Repetition::REQUIRED, ParquetType::INT32)}));
-    parquet_fields.push_back(
-        PrimitiveNode::Make("leaf3", Repetition::REQUIRED, ParquetType::INT64));
-
-    auto group1_fields = {std::make_shared<Field>("leaf1", BOOL, false),
-                          std::make_shared<Field>("leaf2", INT32, false)};
-    auto arrow_group1_type = std::make_shared<::arrow::StructType>(group1_fields);
-    arrow_fields.push_back(std::make_shared<Field>("group1", arrow_group1_type, false));
-    arrow_fields.push_back(std::make_shared<Field>("leaf3", INT64, false));
-  }
-
-  auto arrow_schema = std::make_shared<::arrow::Schema>(arrow_fields);
-  ASSERT_OK(ConvertSchema(parquet_fields));
-
-  ASSERT_NO_FATAL_FAILURE(CheckFlatSchema(arrow_schema));
-}
-
-TEST_F(TestConvertParquetSchema, ParquetNestedSchemaPartial) {
-  std::vector<NodePtr> parquet_fields;
-  std::vector<std::shared_ptr<Field>> arrow_fields;
-
-  // Full Parquet Schema:
-  // required group group1 {
-  //   required int64 leaf1;
-  //   required int64 leaf2;
-  // }
-  // required group group2 {
-  //   required int64 leaf3;
-  //   required int64 leaf4;
-  // }
-  // required int64 leaf5;
-  //
-  // Expected partial arrow schema (columns 0, 3, 4):
-  // required group group1 {
-  //   required int64 leaf1;
-  // }
-  // required group group2 {
-  //   required int64 leaf4;
-  // }
-  // required int64 leaf5;
-  {
-    parquet_fields.push_back(GroupNode::Make(
-        "group1", Repetition::REQUIRED,
-        {PrimitiveNode::Make("leaf1", Repetition::REQUIRED, ParquetType::INT64),
-         PrimitiveNode::Make("leaf2", Repetition::REQUIRED, ParquetType::INT64)}));
-    parquet_fields.push_back(GroupNode::Make(
-        "group2", Repetition::REQUIRED,
-        {PrimitiveNode::Make("leaf3", Repetition::REQUIRED, ParquetType::INT64),
-         PrimitiveNode::Make("leaf4", Repetition::REQUIRED, ParquetType::INT64)}));
-    parquet_fields.push_back(
-        PrimitiveNode::Make("leaf5", Repetition::REQUIRED, ParquetType::INT64));
-
-    auto group1_fields = {std::make_shared<Field>("leaf1", INT64, false)};
-    auto arrow_group1_type = std::make_shared<::arrow::StructType>(group1_fields);
-    auto group2_fields = {std::make_shared<Field>("leaf4", INT64, false)};
-    auto arrow_group2_type = std::make_shared<::arrow::StructType>(group2_fields);
-
-    arrow_fields.push_back(std::make_shared<Field>("group1", arrow_group1_type, false));
-    arrow_fields.push_back(std::make_shared<Field>("group2", arrow_group2_type, false));
-    arrow_fields.push_back(std::make_shared<Field>("leaf5", INT64, false));
-  }
-
-  auto arrow_schema = std::make_shared<::arrow::Schema>(arrow_fields);
-  ASSERT_OK(ConvertSchema(parquet_fields, std::vector<int>{0, 3, 4}));
-
-  ASSERT_NO_FATAL_FAILURE(CheckFlatSchema(arrow_schema));
-}
-
-TEST_F(TestConvertParquetSchema, ParquetNestedSchemaPartialOrdering) {
-  std::vector<NodePtr> parquet_fields;
-  std::vector<std::shared_ptr<Field>> arrow_fields;
-
-  // Full Parquet Schema:
-  // required group group1 {
-  //   required int64 leaf1;
-  //   required int64 leaf2;
-  // }
-  // required group group2 {
-  //   required int64 leaf3;
-  //   required int64 leaf4;
-  // }
-  // required int64 leaf5;
-  //
-  // Expected partial arrow schema (columns 3, 4, 0):
-  // required group group2 {
-  //   required int64 leaf4;
-  // }
-  // required int64 leaf5;
-  // required group group1 {
-  //   required int64 leaf1;
-  // }
-  {
-    parquet_fields.push_back(GroupNode::Make(
-        "group1", Repetition::REQUIRED,
-        {PrimitiveNode::Make("leaf1", Repetition::REQUIRED, ParquetType::INT64),
-         PrimitiveNode::Make("leaf2", Repetition::REQUIRED, ParquetType::INT64)}));
-    parquet_fields.push_back(GroupNode::Make(
-        "group2", Repetition::REQUIRED,
-        {PrimitiveNode::Make("leaf3", Repetition::REQUIRED, ParquetType::INT64),
-         PrimitiveNode::Make("leaf4", Repetition::REQUIRED, ParquetType::INT64)}));
-    parquet_fields.push_back(
-        PrimitiveNode::Make("leaf5", Repetition::REQUIRED, ParquetType::INT64));
-
-    auto group1_fields = {std::make_shared<Field>("leaf1", INT64, false)};
-    auto arrow_group1_type = std::make_shared<::arrow::StructType>(group1_fields);
-    auto group2_fields = {std::make_shared<Field>("leaf4", INT64, false)};
-    auto arrow_group2_type = std::make_shared<::arrow::StructType>(group2_fields);
-
-    arrow_fields.push_back(std::make_shared<Field>("group2", arrow_group2_type, false));
-    arrow_fields.push_back(std::make_shared<Field>("leaf5", INT64, false));
-    arrow_fields.push_back(std::make_shared<Field>("group1", arrow_group1_type, false));
-  }
-
-  auto arrow_schema = std::make_shared<::arrow::Schema>(arrow_fields);
-  ASSERT_OK(ConvertSchema(parquet_fields, std::vector<int>{3, 4, 0}));
-
-  ASSERT_NO_FATAL_FAILURE(CheckFlatSchema(arrow_schema));
-}
-TEST_F(TestConvertParquetSchema, ParquetRepeatedNestedSchema) {
-  std::vector<NodePtr> parquet_fields;
-  std::vector<std::shared_ptr<Field>> arrow_fields;
-  {
-    //   optional int32 leaf1;
-    //   repeated group outerGroup {
-    //     optional int32 leaf2;
-    //     repeated group innerGroup {
-    //       optional int32 leaf3;
-    //     }
-    //   }
-    parquet_fields.push_back(
-        PrimitiveNode::Make("leaf1", Repetition::OPTIONAL, ParquetType::INT32));
-    parquet_fields.push_back(GroupNode::Make(
-        "outerGroup", Repetition::REPEATED,
-        {PrimitiveNode::Make("leaf2", Repetition::OPTIONAL, ParquetType::INT32),
-         GroupNode::Make(
-             "innerGroup", Repetition::REPEATED,
-             {PrimitiveNode::Make("leaf3", Repetition::OPTIONAL, ParquetType::INT32)})}));
-
-    auto inner_group_fields = {std::make_shared<Field>("leaf3", INT32, true)};
-    auto inner_group_type = std::make_shared<::arrow::StructType>(inner_group_fields);
-    auto outer_group_fields = {
-        std::make_shared<Field>("leaf2", INT32, true),
-        std::make_shared<Field>(
-            "innerGroup",
-            ::arrow::list(std::make_shared<Field>("innerGroup", inner_group_type, false)),
-            false)};
-    auto outer_group_type = std::make_shared<::arrow::StructType>(outer_group_fields);
-
-    arrow_fields.push_back(std::make_shared<Field>("leaf1", INT32, true));
-    arrow_fields.push_back(std::make_shared<Field>(
-        "outerGroup",
-        ::arrow::list(std::make_shared<Field>("outerGroup", outer_group_type, false)),
-        false));
-  }
-  auto arrow_schema = std::make_shared<::arrow::Schema>(arrow_fields);
-  ASSERT_OK(ConvertSchema(parquet_fields));
-
-  ASSERT_NO_FATAL_FAILURE(CheckFlatSchema(arrow_schema));
-}
-
-class TestConvertArrowSchema : public ::testing::Test {
- public:
-  virtual void SetUp() {}
-
-  void CheckFlatSchema(const std::vector<NodePtr>& nodes) {
-    NodePtr schema_node = GroupNode::Make("schema", Repetition::REPEATED, nodes);
-    const GroupNode* expected_schema_node =
-        static_cast<const GroupNode*>(schema_node.get());
-    const GroupNode* result_schema_node = result_schema_->group_node();
-
-    ASSERT_EQ(expected_schema_node->field_count(), result_schema_node->field_count());
-
-    for (int i = 0; i < expected_schema_node->field_count(); i++) {
-      auto lhs = result_schema_node->field(i);
-      auto rhs = expected_schema_node->field(i);
-      EXPECT_TRUE(lhs->Equals(rhs.get()));
-    }
-  }
-
-  ::arrow::Status ConvertSchema(const std::vector<std::shared_ptr<Field>>& fields) {
-    arrow_schema_ = std::make_shared<::arrow::Schema>(fields);
-    std::shared_ptr<::parquet::WriterProperties> properties =
-        ::parquet::default_writer_properties();
-    return ToParquetSchema(arrow_schema_.get(), *properties.get(), &result_schema_);
-  }
-
- protected:
-  std::shared_ptr<::arrow::Schema> arrow_schema_;
-  std::shared_ptr<SchemaDescriptor> result_schema_;
-};
-
-TEST_F(TestConvertArrowSchema, ParquetFlatPrimitives) {
-  std::vector<NodePtr> parquet_fields;
-  std::vector<std::shared_ptr<Field>> arrow_fields;
-
-  parquet_fields.push_back(
-      PrimitiveNode::Make("boolean", Repetition::REQUIRED, ParquetType::BOOLEAN));
-  arrow_fields.push_back(std::make_shared<Field>("boolean", BOOL, false));
-
-  parquet_fields.push_back(
-      PrimitiveNode::Make("int32", Repetition::REQUIRED, ParquetType::INT32));
-  arrow_fields.push_back(std::make_shared<Field>("int32", INT32, false));
-
-  parquet_fields.push_back(
-      PrimitiveNode::Make("int64", Repetition::REQUIRED, ParquetType::INT64));
-  arrow_fields.push_back(std::make_shared<Field>("int64", INT64, false));
-
-  parquet_fields.push_back(PrimitiveNode::Make("date", Repetition::REQUIRED,
-                                               ParquetType::INT32, LogicalType::DATE));
-  arrow_fields.push_back(std::make_shared<Field>("date", ::arrow::date32(), false));
-
-  parquet_fields.push_back(PrimitiveNode::Make("date64", Repetition::REQUIRED,
-                                               ParquetType::INT32, LogicalType::DATE));
-  arrow_fields.push_back(std::make_shared<Field>("date64", ::arrow::date64(), false));
-
-  parquet_fields.push_back(PrimitiveNode::Make("timestamp", Repetition::REQUIRED,
-                                               ParquetType::INT64,
-                                               LogicalType::TIMESTAMP_MILLIS));
-  arrow_fields.push_back(std::make_shared<Field>("timestamp", TIMESTAMP_MS, false));
-
-  parquet_fields.push_back(PrimitiveNode::Make("timestamp[us]", Repetition::REQUIRED,
-                                               ParquetType::INT64,
-                                               LogicalType::TIMESTAMP_MICROS));
-  arrow_fields.push_back(std::make_shared<Field>("timestamp[us]", TIMESTAMP_US, false));
-
-  parquet_fields.push_back(
-      PrimitiveNode::Make("float", Repetition::OPTIONAL, ParquetType::FLOAT));
-  arrow_fields.push_back(std::make_shared<Field>("float", FLOAT));
-
-  parquet_fields.push_back(
-      PrimitiveNode::Make("double", Repetition::OPTIONAL, ParquetType::DOUBLE));
-  arrow_fields.push_back(std::make_shared<Field>("double", DOUBLE));
-
-  parquet_fields.push_back(PrimitiveNode::Make(
-      "string", Repetition::OPTIONAL, ParquetType::BYTE_ARRAY, LogicalType::UTF8));
-  arrow_fields.push_back(std::make_shared<Field>("string", UTF8));
-
-  parquet_fields.push_back(PrimitiveNode::Make(
-      "binary", Repetition::OPTIONAL, ParquetType::BYTE_ARRAY, LogicalType::NONE));
-  arrow_fields.push_back(std::make_shared<Field>("binary", BINARY));
-
-  ASSERT_OK(ConvertSchema(arrow_fields));
-
-  ASSERT_NO_FATAL_FAILURE(CheckFlatSchema(parquet_fields));
-}
-
-TEST_F(TestConvertArrowSchema, ParquetFlatPrimitivesAsDictionaries) {
-  std::vector<NodePtr> parquet_fields;
-  std::vector<std::shared_ptr<Field>> arrow_fields;
-  std::shared_ptr<::arrow::Array> dict;
-
-  parquet_fields.push_back(
-      PrimitiveNode::Make("int32", Repetition::REQUIRED, ParquetType::INT32));
-  ArrayFromVector<::arrow::Int32Type, int32_t>(std::vector<int32_t>(), &dict);
-  arrow_fields.push_back(
-      ::arrow::field("int32", ::arrow::dictionary(::arrow::int8(), dict), false));
-
-  parquet_fields.push_back(
-      PrimitiveNode::Make("int64", Repetition::REQUIRED, ParquetType::INT64));
-  ArrayFromVector<::arrow::Int64Type, int64_t>(std::vector<int64_t>(), &dict);
-  arrow_fields.push_back(std::make_shared<Field>(
-      "int64", ::arrow::dictionary(::arrow::int8(), dict), false));
-
-  parquet_fields.push_back(PrimitiveNode::Make("date", Repetition::REQUIRED,
-                                               ParquetType::INT32, LogicalType::DATE));
-  ArrayFromVector<::arrow::Date32Type, int32_t>(std::vector<int32_t>(), &dict);
-  arrow_fields.push_back(
-      std::make_shared<Field>("date", ::arrow::dictionary(::arrow::int8(), dict), false));
-
-  parquet_fields.push_back(PrimitiveNode::Make("date64", Repetition::REQUIRED,
-                                               ParquetType::INT32, LogicalType::DATE));
-  ArrayFromVector<::arrow::Date64Type, int64_t>(std::vector<int64_t>(), &dict);
-  arrow_fields.push_back(std::make_shared<Field>(
-      "date64", ::arrow::dictionary(::arrow::int8(), dict), false));
-
-  parquet_fields.push_back(
-      PrimitiveNode::Make("float", Repetition::OPTIONAL, ParquetType::FLOAT));
-  ArrayFromVector<::arrow::FloatType, float>(std::vector<float>(), &dict);
-  arrow_fields.push_back(
-      std::make_shared<Field>("float", ::arrow::dictionary(::arrow::int8(), dict)));
-
-  parquet_fields.push_back(
-      PrimitiveNode::Make("double", Repetition::OPTIONAL, ParquetType::DOUBLE));
-  ArrayFromVector<::arrow::DoubleType, double>(std::vector<double>(), &dict);
-  arrow_fields.push_back(
-      std::make_shared<Field>("double", ::arrow::dictionary(::arrow::int8(), dict)));
-
-  parquet_fields.push_back(PrimitiveNode::Make(
-      "string", Repetition::OPTIONAL, ParquetType::BYTE_ARRAY, LogicalType::UTF8));
-  ::arrow::StringBuilder string_builder(::arrow::default_memory_pool());
-  ASSERT_OK(string_builder.Finish(&dict));
-  arrow_fields.push_back(
-      std::make_shared<Field>("string", ::arrow::dictionary(::arrow::int8(), dict)));
-
-  parquet_fields.push_back(PrimitiveNode::Make(
-      "binary", Repetition::OPTIONAL, ParquetType::BYTE_ARRAY, LogicalType::NONE));
-  ::arrow::BinaryBuilder binary_builder(::arrow::default_memory_pool());
-  ASSERT_OK(binary_builder.Finish(&dict));
-  arrow_fields.push_back(
-      std::make_shared<Field>("binary", ::arrow::dictionary(::arrow::int8(), dict)));
-
-  ASSERT_OK(ConvertSchema(arrow_fields));
-
-  ASSERT_NO_FATAL_FAILURE(CheckFlatSchema(parquet_fields));
-}
-
-TEST_F(TestConvertArrowSchema, ParquetLists) {
-  std::vector<NodePtr> parquet_fields;
-  std::vector<std::shared_ptr<Field>> arrow_fields;
-
-  // parquet_arrow will always generate 3-level LIST encodings
-
-  // // List<String> (list non-null, elements nullable)
-  // required group my_list (LIST) {
-  //   repeated group list {
-  //     optional binary element (UTF8);
-  //   }
-  // }
-  {
-    auto element = PrimitiveNode::Make("string", Repetition::OPTIONAL,
-                                       ParquetType::BYTE_ARRAY, LogicalType::UTF8);
-    auto list = GroupNode::Make("list", Repetition::REPEATED, {element});
-    parquet_fields.push_back(
-        GroupNode::Make("my_list", Repetition::REQUIRED, {list}, LogicalType::LIST));
-    auto arrow_element = std::make_shared<Field>("string", UTF8, true);
-    auto arrow_list = std::make_shared<::arrow::ListType>(arrow_element);
-    arrow_fields.push_back(std::make_shared<Field>("my_list", arrow_list, false));
-  }
-
-  // // List<String> (list nullable, elements non-null)
-  // optional group my_list (LIST) {
-  //   repeated group list {
-  //     required binary element (UTF8);
-  //   }
-  // }
-  {
-    auto element = PrimitiveNode::Make("string", Repetition::REQUIRED,
-                                       ParquetType::BYTE_ARRAY, LogicalType::UTF8);
-    auto list = GroupNode::Make("list", Repetition::REPEATED, {element});
-    parquet_fields.push_back(
-        GroupNode::Make("my_list", Repetition::OPTIONAL, {list}, LogicalType::LIST));
-    auto arrow_element = std::make_shared<Field>("string", UTF8, false);
-    auto arrow_list = std::make_shared<::arrow::ListType>(arrow_element);
-    arrow_fields.push_back(std::make_shared<Field>("my_list", arrow_list, true));
-  }
-
-  ASSERT_OK(ConvertSchema(arrow_fields));
-
-  ASSERT_NO_FATAL_FAILURE(CheckFlatSchema(parquet_fields));
-}
-
-TEST_F(TestConvertArrowSchema, UnsupportedTypes) {
-  std::vector<std::shared_ptr<Field>> unsupported_fields = {
-      ::arrow::field("f0", ::arrow::time64(TimeUnit::NANO))};
-
-  for (const auto& field : unsupported_fields) {
-    ASSERT_RAISES(NotImplemented, ConvertSchema({field}));
-  }
-}
-
-TEST_F(TestConvertArrowSchema, ParquetFlatDecimals) {
-  std::vector<NodePtr> parquet_fields;
-  std::vector<std::shared_ptr<Field>> arrow_fields;
-
-  // TODO: Test Decimal Arrow -> Parquet conversion
-
-  ASSERT_OK(ConvertSchema(arrow_fields));
-
-  ASSERT_NO_FATAL_FAILURE(CheckFlatSchema(parquet_fields));
-}
-
-TEST(InvalidSchema, ParquetNegativeDecimalScale) {
-  const auto& type = ::arrow::decimal(23, -2);
-  const auto& field = ::arrow::field("f0", type);
-  const auto& arrow_schema = ::arrow::schema({field});
-  std::shared_ptr<::parquet::WriterProperties> properties =
-      ::parquet::default_writer_properties();
-  std::shared_ptr<SchemaDescriptor> result_schema;
-
-  ASSERT_RAISES(IOError,
-                ToParquetSchema(arrow_schema.get(), *properties.get(), &result_schema));
-}
-
-}  // namespace arrow
-}  // namespace parquet
diff --git a/src/parquet/arrow/reader.cc b/src/parquet/arrow/reader.cc
deleted file mode 100644
index 2e4dc81..0000000
--- a/src/parquet/arrow/reader.cc
+++ /dev/null
@@ -1,1558 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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.
-
-#include "parquet/arrow/reader.h"
-
-#include <algorithm>
-#include <atomic>
-#include <chrono>
-#include <mutex>
-#include <queue>
-#include <string>
-#include <thread>
-#include <type_traits>
-#include <vector>
-
-#include "arrow/api.h"
-#include "arrow/util/bit-util.h"
-#include "arrow/util/decimal.h"
-#include "arrow/util/logging.h"
-#include "arrow/util/thread-pool.h"
-
-#include "parquet/arrow/record_reader.h"
-#include "parquet/arrow/schema.h"
-#include "parquet/column_reader.h"
-#include "parquet/schema.h"
-#include "parquet/util/schema-util.h"
-
-using arrow::Array;
-using arrow::BooleanArray;
-using arrow::Column;
-using arrow::Field;
-using arrow::Int32Array;
-using arrow::ListArray;
-using arrow::MemoryPool;
-using arrow::ResizableBuffer;
-using arrow::Status;
-using arrow::StructArray;
-using arrow::Table;
-using arrow::TimestampArray;
-
-using parquet::schema::Node;
-
-// Help reduce verbosity
-using ParquetReader = parquet::ParquetFileReader;
-using arrow::RecordBatchReader;
-
-using parquet::internal::RecordReader;
-
-namespace parquet {
-namespace arrow {
-
-using ::arrow::BitUtil::BytesForBits;
-
-constexpr int64_t kJulianToUnixEpochDays = 2440588LL;
-constexpr int64_t kMillisecondsInADay = 86400000LL;
-constexpr int64_t kNanosecondsInADay = kMillisecondsInADay * 1000LL * 1000LL;
-
-static inline int64_t impala_timestamp_to_nanoseconds(const Int96& impala_timestamp) {
-  int64_t days_since_epoch = impala_timestamp.value[2] - kJulianToUnixEpochDays;
-  int64_t nanoseconds = *(reinterpret_cast<const int64_t*>(&(impala_timestamp.value)));
-  return days_since_epoch * kNanosecondsInADay + nanoseconds;
-}
-
-template <typename ArrowType>
-using ArrayType = typename ::arrow::TypeTraits<ArrowType>::ArrayType;
-
-// ----------------------------------------------------------------------
-// Iteration utilities
-
-// Abstraction to decouple row group iteration details from the ColumnReader,
-// so we can read only a single row group if we want
-class FileColumnIterator {
- public:
-  explicit FileColumnIterator(int column_index, ParquetFileReader* reader)
-      : column_index_(column_index),
-        reader_(reader),
-        schema_(reader->metadata()->schema()) {}
-
-  virtual ~FileColumnIterator() {}
-
-  virtual std::unique_ptr<::parquet::PageReader> NextChunk() = 0;
-
-  const SchemaDescriptor* schema() const { return schema_; }
-
-  const ColumnDescriptor* descr() const { return schema_->Column(column_index_); }
-
-  std::shared_ptr<FileMetaData> metadata() const { return reader_->metadata(); }
-
-  int column_index() const { return column_index_; }
-
- protected:
-  int column_index_;
-  ParquetFileReader* reader_;
-  const SchemaDescriptor* schema_;
-};
-
-class AllRowGroupsIterator : public FileColumnIterator {
- public:
-  explicit AllRowGroupsIterator(int column_index, ParquetFileReader* reader)
-      : FileColumnIterator(column_index, reader), next_row_group_(0) {}
-
-  std::unique_ptr<::parquet::PageReader> NextChunk() override {
-    std::unique_ptr<::parquet::PageReader> result;
-    if (next_row_group_ < reader_->metadata()->num_row_groups()) {
-      result = reader_->RowGroup(next_row_group_)->GetColumnPageReader(column_index_);
-      next_row_group_++;
-    } else {
-      result = nullptr;
-    }
-    return result;
-  }
-
- private:
-  int next_row_group_;
-};
-
-class SingleRowGroupIterator : public FileColumnIterator {
- public:
-  explicit SingleRowGroupIterator(int column_index, int row_group_number,
-                                  ParquetFileReader* reader)
-      : FileColumnIterator(column_index, reader),
-        row_group_number_(row_group_number),
-        done_(false) {}
-
-  std::unique_ptr<::parquet::PageReader> NextChunk() override {
-    if (done_) {
-      return nullptr;
-    }
-
-    auto result =
-        reader_->RowGroup(row_group_number_)->GetColumnPageReader(column_index_);
-    done_ = true;
-    return result;
-  }
-
- private:
-  int row_group_number_;
-  bool done_;
-};
-
-class RowGroupRecordBatchReader : public ::arrow::RecordBatchReader {
- public:
-  explicit RowGroupRecordBatchReader(const std::vector<int>& row_group_indices,
-                                     const std::vector<int>& column_indices,
-                                     std::shared_ptr<::arrow::Schema> schema,
-                                     FileReader* reader)
-      : row_group_indices_(row_group_indices),
-        column_indices_(column_indices),
-        schema_(schema),
-        file_reader_(reader),
-        next_row_group_(0) {}
-
-  ~RowGroupRecordBatchReader() override {}
-
-  std::shared_ptr<::arrow::Schema> schema() const override { return schema_; }
-
-  Status ReadNext(std::shared_ptr<::arrow::RecordBatch>* out) override {
-    if (table_ != nullptr) {  // one row group has been loaded
-      std::shared_ptr<::arrow::RecordBatch> tmp;
-      RETURN_NOT_OK(table_batch_reader_->ReadNext(&tmp));
-      if (tmp != nullptr) {  // some column chunks are left in table
-        *out = tmp;
-        return Status::OK();
-      } else {  // the entire table is consumed
-        table_batch_reader_.reset();
-        table_.reset();
-      }
-    }
-
-    // all row groups has been consumed
-    if (next_row_group_ == row_group_indices_.size()) {
-      *out = nullptr;
-      return Status::OK();
-    }
-
-    RETURN_NOT_OK(file_reader_->ReadRowGroup(row_group_indices_[next_row_group_],
-                                             column_indices_, &table_));
-
-    next_row_group_++;
-    table_batch_reader_.reset(new ::arrow::TableBatchReader(*table_.get()));
-    return table_batch_reader_->ReadNext(out);
-  }
-
- private:
-  std::vector<int> row_group_indices_;
-  std::vector<int> column_indices_;
-  std::shared_ptr<::arrow::Schema> schema_;
-  FileReader* file_reader_;
-  size_t next_row_group_;
-  std::shared_ptr<::arrow::Table> table_;
-  std::unique_ptr<::arrow::TableBatchReader> table_batch_reader_;
-};
-
-// ----------------------------------------------------------------------
-// File reader implementation
-
-class FileReader::Impl {
- public:
-  Impl(MemoryPool* pool, std::unique_ptr<ParquetFileReader> reader)
-      : pool_(pool), reader_(std::move(reader)), use_threads_(false) {}
-
-  virtual ~Impl() {}
-
-  Status GetColumn(int i, std::unique_ptr<ColumnReader>* out);
-  Status ReadSchemaField(int i, std::shared_ptr<Array>* out);
-  Status ReadSchemaField(int i, const std::vector<int>& indices,
-                         std::shared_ptr<Array>* out);
-  Status GetReaderForNode(int index, const Node* node, const std::vector<int>& indices,
-                          int16_t def_level,
-                          std::unique_ptr<ColumnReader::ColumnReaderImpl>* out);
-  Status ReadColumn(int i, std::shared_ptr<Array>* out);
-  Status ReadColumnChunk(int column_index, int row_group_index,
-                         std::shared_ptr<Array>* out);
-  Status GetSchema(std::shared_ptr<::arrow::Schema>* out);
-  Status GetSchema(const std::vector<int>& indices,
-                   std::shared_ptr<::arrow::Schema>* out);
-  Status ReadRowGroup(int row_group_index, std::shared_ptr<Table>* table);
-  Status ReadRowGroup(int row_group_index, const std::vector<int>& indices,
-                      std::shared_ptr<::arrow::Table>* out);
-  Status ReadTable(const std::vector<int>& indices, std::shared_ptr<Table>* table);
-  Status ReadTable(std::shared_ptr<Table>* table);
-  Status ReadRowGroups(const std::vector<int>& row_groups, std::shared_ptr<Table>* table);
-  Status ReadRowGroups(const std::vector<int>& row_groups,
-                       const std::vector<int>& indices,
-                       std::shared_ptr<::arrow::Table>* out);
-
-  bool CheckForFlatColumn(const ColumnDescriptor* descr);
-  bool CheckForFlatListColumn(const ColumnDescriptor* descr);
-
-  const ParquetFileReader* parquet_reader() const { return reader_.get(); }
-
-  int num_row_groups() const { return reader_->metadata()->num_row_groups(); }
-
-  int num_columns() const { return reader_->metadata()->num_columns(); }
-
-  void set_use_threads(bool use_threads) { use_threads_ = use_threads; }
-
-  ParquetFileReader* reader() { return reader_.get(); }
-
- private:
-  MemoryPool* pool_;
-  std::unique_ptr<ParquetFileReader> reader_;
-  bool use_threads_;
-};
-
-class ColumnReader::ColumnReaderImpl {
- public:
-  virtual ~ColumnReaderImpl() {}
-  virtual Status NextBatch(int64_t records_to_read, std::shared_ptr<Array>* out) = 0;
-  virtual Status GetDefLevels(const int16_t** data, size_t* length) = 0;
-  virtual Status GetRepLevels(const int16_t** data, size_t* length) = 0;
-  virtual const std::shared_ptr<Field> field() = 0;
-};
-
-// Reader implementation for primitive arrays
-class PARQUET_NO_EXPORT PrimitiveImpl : public ColumnReader::ColumnReaderImpl {
- public:
-  PrimitiveImpl(MemoryPool* pool, std::unique_ptr<FileColumnIterator> input)
-      : pool_(pool), input_(std::move(input)), descr_(input_->descr()) {
-    record_reader_ = RecordReader::Make(descr_, pool_);
-    DCHECK(NodeToField(*input_->descr()->schema_node(), &field_).ok());
-    NextRowGroup();
-  }
-
-  Status NextBatch(int64_t records_to_read, std::shared_ptr<Array>* out) override;
-
-  template <typename ParquetType>
-  Status WrapIntoListArray(std::shared_ptr<Array>* array);
-
-  Status GetDefLevels(const int16_t** data, size_t* length) override;
-  Status GetRepLevels(const int16_t** data, size_t* length) override;
-
-  const std::shared_ptr<Field> field() override { return field_; }
-
- private:
-  void NextRowGroup();
-
-  MemoryPool* pool_;
-  std::unique_ptr<FileColumnIterator> input_;
-  const ColumnDescriptor* descr_;
-
-  std::shared_ptr<RecordReader> record_reader_;
-
-  std::shared_ptr<Field> field_;
-};
-
-// Reader implementation for struct array
-class PARQUET_NO_EXPORT StructImpl : public ColumnReader::ColumnReaderImpl {
- public:
-  explicit StructImpl(const std::vector<std::shared_ptr<ColumnReaderImpl>>& children,
-                      int16_t struct_def_level, MemoryPool* pool, const Node* node)
-      : children_(children), struct_def_level_(struct_def_level), pool_(pool) {
-    InitField(node, children);
-  }
-
-  Status NextBatch(int64_t records_to_read, std::shared_ptr<Array>* out) override;
-  Status GetDefLevels(const int16_t** data, size_t* length) override;
-  Status GetRepLevels(const int16_t** data, size_t* length) override;
-  const std::shared_ptr<Field> field() override { return field_; }
-
- private:
-  std::vector<std::shared_ptr<ColumnReaderImpl>> children_;
-  int16_t struct_def_level_;
-  MemoryPool* pool_;
-  std::shared_ptr<Field> field_;
-  std::shared_ptr<ResizableBuffer> def_levels_buffer_;
-
-  Status DefLevelsToNullArray(std::shared_ptr<Buffer>* null_bitmap, int64_t* null_count);
-  void InitField(const Node* node,
-                 const std::vector<std::shared_ptr<ColumnReaderImpl>>& children);
-};
-
-FileReader::FileReader(MemoryPool* pool, std::unique_ptr<ParquetFileReader> reader)
-    : impl_(new FileReader::Impl(pool, std::move(reader))) {}
-
-FileReader::~FileReader() {}
-
-Status FileReader::Impl::GetColumn(int i, std::unique_ptr<ColumnReader>* out) {
-  std::unique_ptr<FileColumnIterator> input(new AllRowGroupsIterator(i, reader_.get()));
-
-  std::unique_ptr<ColumnReader::ColumnReaderImpl> impl(
-      new PrimitiveImpl(pool_, std::move(input)));
-  *out = std::unique_ptr<ColumnReader>(new ColumnReader(std::move(impl)));
-  return Status::OK();
-}
-
-Status FileReader::Impl::GetReaderForNode(
-    int index, const Node* node, const std::vector<int>& indices, int16_t def_level,
-    std::unique_ptr<ColumnReader::ColumnReaderImpl>* out) {
-  *out = nullptr;
-
-  if (IsSimpleStruct(node)) {
-    const schema::GroupNode* group = static_cast<const schema::GroupNode*>(node);
-    std::vector<std::shared_ptr<ColumnReader::ColumnReaderImpl>> children;
-    for (int i = 0; i < group->field_count(); i++) {
-      std::unique_ptr<ColumnReader::ColumnReaderImpl> child_reader;
-      // TODO(itaiin): Remove the -1 index hack when all types of nested reads
-      // are supported. This currently just signals the lower level reader resolution
-      // to abort
-      RETURN_NOT_OK(GetReaderForNode(index, group->field(i).get(), indices,
-                                     static_cast<int16_t>(def_level + 1), &child_reader));
-      if (child_reader != nullptr) {
-        children.push_back(std::move(child_reader));
-      }
-    }
-
-    if (children.size() > 0) {
-      *out = std::unique_ptr<ColumnReader::ColumnReaderImpl>(
-          new StructImpl(children, def_level, pool_, node));
-    }
-  } else {
-    // This should be a flat field case - translate the field index to
-    // the correct column index by walking down to the leaf node
-    const Node* walker = node;
-    while (!walker->is_primitive()) {
-      DCHECK(walker->is_group());
-      auto group = static_cast<const GroupNode*>(walker);
-      if (group->field_count() != 1) {
-        return Status::NotImplemented("lists with structs are not supported.");
-      }
-      walker = group->field(0).get();
-    }
-    auto column_index = reader_->metadata()->schema()->ColumnIndex(*walker);
-
-    // If the index of the column is found then a reader for the coliumn is needed.
-    // Otherwise *out keeps the nullptr value.
-    if (std::find(indices.begin(), indices.end(), column_index) != indices.end()) {
-      std::unique_ptr<ColumnReader> reader;
-      RETURN_NOT_OK(GetColumn(column_index, &reader));
-      *out = std::move(reader->impl_);
-    }
-  }
-
-  return Status::OK();
-}
-
-Status FileReader::Impl::ReadSchemaField(int i, std::shared_ptr<Array>* out) {
-  std::vector<int> indices(reader_->metadata()->num_columns());
-
-  for (size_t j = 0; j < indices.size(); ++j) {
-    indices[j] = static_cast<int>(j);
-  }
-
-  return ReadSchemaField(i, indices, out);
-}
-
-Status FileReader::Impl::ReadSchemaField(int i, const std::vector<int>& indices,
-                                         std::shared_ptr<Array>* out) {
-  auto parquet_schema = reader_->metadata()->schema();
-
-  auto node = parquet_schema->group_node()->field(i).get();
-  std::unique_ptr<ColumnReader::ColumnReaderImpl> reader_impl;
-
-  RETURN_NOT_OK(GetReaderForNode(i, node, indices, 1, &reader_impl));
-  if (reader_impl == nullptr) {
-    *out = nullptr;
-    return Status::OK();
-  }
-
-  std::unique_ptr<ColumnReader> reader(new ColumnReader(std::move(reader_impl)));
-
-  // TODO(wesm): This calculation doesn't make much sense when we have repeated
-  // schema nodes
-  int64_t records_to_read = 0;
-
-  const FileMetaData& metadata = *reader_->metadata();
-  for (int j = 0; j < metadata.num_row_groups(); j++) {
-    records_to_read += metadata.RowGroup(j)->ColumnChunk(i)->num_values();
-  }
-
-  return reader->NextBatch(records_to_read, out);
-}
-
-Status FileReader::Impl::ReadColumn(int i, std::shared_ptr<Array>* out) {
-  std::unique_ptr<ColumnReader> flat_column_reader;
-  RETURN_NOT_OK(GetColumn(i, &flat_column_reader));
-
-  int64_t records_to_read = 0;
-  for (int j = 0; j < reader_->metadata()->num_row_groups(); j++) {
-    records_to_read += reader_->metadata()->RowGroup(j)->ColumnChunk(i)->num_values();
-  }
-
-  return flat_column_reader->NextBatch(records_to_read, out);
-}
-
-Status FileReader::Impl::GetSchema(const std::vector<int>& indices,
-                                   std::shared_ptr<::arrow::Schema>* out) {
-  auto descr = reader_->metadata()->schema();
-  auto parquet_key_value_metadata = reader_->metadata()->key_value_metadata();
-  return FromParquetSchema(descr, indices, parquet_key_value_metadata, out);
-}
-
-Status FileReader::Impl::ReadColumnChunk(int column_index, int row_group_index,
-                                         std::shared_ptr<Array>* out) {
-  auto rg_metadata = reader_->metadata()->RowGroup(row_group_index);
-  int64_t records_to_read = rg_metadata->ColumnChunk(column_index)->num_values();
-
-  std::unique_ptr<FileColumnIterator> input(
-      new SingleRowGroupIterator(column_index, row_group_index, reader_.get()));
-
-  std::unique_ptr<ColumnReader::ColumnReaderImpl> impl(
-      new PrimitiveImpl(pool_, std::move(input)));
-  ColumnReader flat_column_reader(std::move(impl));
-
-  std::shared_ptr<Array> array;
-  RETURN_NOT_OK(flat_column_reader.NextBatch(records_to_read, &array));
-  *out = array;
-  return Status::OK();
-}
-
-Status FileReader::Impl::ReadRowGroup(int row_group_index,
-                                      const std::vector<int>& indices,
-                                      std::shared_ptr<Table>* out) {
-  std::shared_ptr<::arrow::Schema> schema;
-  RETURN_NOT_OK(GetSchema(indices, &schema));
-
-  auto rg_metadata = reader_->metadata()->RowGroup(row_group_index);
-
-  int num_columns = static_cast<int>(indices.size());
-  std::vector<std::shared_ptr<Column>> columns(num_columns);
-
-  // TODO(wesm): Refactor to share more code with ReadTable
-
-  auto ReadColumnFunc = [&indices, &row_group_index, &schema, &columns, this](int i) {
-    int column_index = indices[i];
-
-    std::shared_ptr<Array> array;
-    RETURN_NOT_OK(ReadColumnChunk(column_index, row_group_index, &array));
-    columns[i] = std::make_shared<Column>(schema->field(i), array);
-    return Status::OK();
-  };
-
-  if (use_threads_) {
-    std::vector<std::future<Status>> futures;
-    auto pool = ::arrow::internal::GetCpuThreadPool();
-    for (int i = 0; i < num_columns; i++) {
-      futures.push_back(pool->Submit(ReadColumnFunc, i));
-    }
-    Status final_status = Status::OK();
-    for (auto& fut : futures) {
-      Status st = fut.get();
-      if (!st.ok()) {
-        final_status = std::move(st);
-      }
-    }
-    RETURN_NOT_OK(final_status);
-  } else {
-    for (int i = 0; i < num_columns; i++) {
-      RETURN_NOT_OK(ReadColumnFunc(i));
-    }
-  }
-
-  *out = Table::Make(schema, columns);
-  return Status::OK();
-}
-
-Status FileReader::Impl::ReadTable(const std::vector<int>& indices,
-                                   std::shared_ptr<Table>* out) {
-  std::shared_ptr<::arrow::Schema> schema;
-  RETURN_NOT_OK(GetSchema(indices, &schema));
-
-  // We only need to read schema fields which have columns indicated
-  // in the indices vector
-  std::vector<int> field_indices;
-  if (!ColumnIndicesToFieldIndices(*reader_->metadata()->schema(), indices,
-                                   &field_indices)) {
-    return Status::Invalid("Invalid column index");
-  }
-
-  int num_fields = static_cast<int>(field_indices.size());
-  std::vector<std::shared_ptr<Column>> columns(num_fields);
-
-  auto ReadColumnFunc = [&indices, &field_indices, &schema, &columns, this](int i) {
-    std::shared_ptr<Array> array;
-    RETURN_NOT_OK(ReadSchemaField(field_indices[i], indices, &array));
-    columns[i] = std::make_shared<Column>(schema->field(i), array);
-    return Status::OK();
-  };
-
-  if (use_threads_) {
-    std::vector<std::future<Status>> futures;
-    auto pool = ::arrow::internal::GetCpuThreadPool();
-    for (int i = 0; i < num_fields; i++) {
-      futures.push_back(pool->Submit(ReadColumnFunc, i));
-    }
-    Status final_status = Status::OK();
-    for (auto& fut : futures) {
-      Status st = fut.get();
-      if (!st.ok()) {
-        final_status = std::move(st);
-      }
-    }
-    RETURN_NOT_OK(final_status);
-  } else {
-    for (int i = 0; i < num_fields; i++) {
-      RETURN_NOT_OK(ReadColumnFunc(i));
-    }
-  }
-
-  std::shared_ptr<Table> table = Table::Make(schema, columns);
-  RETURN_NOT_OK(table->Validate());
-  *out = table;
-  return Status::OK();
-}
-
-Status FileReader::Impl::ReadTable(std::shared_ptr<Table>* table) {
-  std::vector<int> indices(reader_->metadata()->num_columns());
-
-  for (size_t i = 0; i < indices.size(); ++i) {
-    indices[i] = static_cast<int>(i);
-  }
-  return ReadTable(indices, table);
-}
-
-Status FileReader::Impl::ReadRowGroups(const std::vector<int>& row_groups,
-                                       const std::vector<int>& indices,
-                                       std::shared_ptr<Table>* table) {
-  // TODO(PARQUET-1393): Modify the record readers to already read this into a single,
-  // continuous array.
-  std::vector<std::shared_ptr<Table>> tables(row_groups.size(), nullptr);
-
-  for (size_t i = 0; i < row_groups.size(); ++i) {
-    RETURN_NOT_OK(ReadRowGroup(row_groups[i], indices, &tables[i]));
-  }
-  return ConcatenateTables(tables, table);
-}
-
-Status FileReader::Impl::ReadRowGroups(const std::vector<int>& row_groups,
-                                       std::shared_ptr<Table>* table) {
-  std::vector<int> indices(reader_->metadata()->num_columns());
-
-  for (size_t i = 0; i < indices.size(); ++i) {
-    indices[i] = static_cast<int>(i);
-  }
-  return ReadRowGroups(row_groups, indices, table);
-}
-
-Status FileReader::Impl::ReadRowGroup(int i, std::shared_ptr<Table>* table) {
-  std::vector<int> indices(reader_->metadata()->num_columns());
-
-  for (size_t i = 0; i < indices.size(); ++i) {
-    indices[i] = static_cast<int>(i);
-  }
-  return ReadRowGroup(i, indices, table);
-}
-
-// Static ctor
-Status OpenFile(const std::shared_ptr<::arrow::io::ReadableFileInterface>& file,
-                MemoryPool* allocator, const ReaderProperties& props,
-                const std::shared_ptr<FileMetaData>& metadata,
-                std::unique_ptr<FileReader>* reader) {
-  std::unique_ptr<RandomAccessSource> io_wrapper(new ArrowInputFile(file));
-  std::unique_ptr<ParquetReader> pq_reader;
-  PARQUET_CATCH_NOT_OK(pq_reader =
-                           ParquetReader::Open(std::move(io_wrapper), props, metadata));
-  reader->reset(new FileReader(allocator, std::move(pq_reader)));
-  return Status::OK();
-}
-
-Status OpenFile(const std::shared_ptr<::arrow::io::ReadableFileInterface>& file,
-                MemoryPool* allocator, std::unique_ptr<FileReader>* reader) {
-  return OpenFile(file, allocator, ::parquet::default_reader_properties(), nullptr,
-                  reader);
-}
-
-Status FileReader::GetColumn(int i, std::unique_ptr<ColumnReader>* out) {
-  return impl_->GetColumn(i, out);
-}
-
-Status FileReader::GetSchema(const std::vector<int>& indices,
-                             std::shared_ptr<::arrow::Schema>* out) {
-  return impl_->GetSchema(indices, out);
-}
-
-Status FileReader::ReadColumn(int i, std::shared_ptr<Array>* out) {
-  try {
-    return impl_->ReadColumn(i, out);
-  } catch (const ::parquet::ParquetException& e) {
-    return ::arrow::Status::IOError(e.what());
-  }
-}
-
-Status FileReader::ReadSchemaField(int i, std::shared_ptr<Array>* out) {
-  try {
-    return impl_->ReadSchemaField(i, out);
-  } catch (const ::parquet::ParquetException& e) {
-    return ::arrow::Status::IOError(e.what());
-  }
-}
-
-Status FileReader::GetRecordBatchReader(const std::vector<int>& row_group_indices,
-                                        std::shared_ptr<RecordBatchReader>* out) {
-  std::vector<int> indices(impl_->num_columns());
-
-  for (size_t j = 0; j < indices.size(); ++j) {
-    indices[j] = static_cast<int>(j);
-  }
-
-  return GetRecordBatchReader(row_group_indices, indices, out);
-}
-
-Status FileReader::GetRecordBatchReader(const std::vector<int>& row_group_indices,
-                                        const std::vector<int>& column_indices,
-                                        std::shared_ptr<RecordBatchReader>* out) {
-  // column indicies check
-  std::shared_ptr<::arrow::Schema> schema;
-  RETURN_NOT_OK(GetSchema(column_indices, &schema));
-
-  // row group indices check
-  int max_num = num_row_groups();
-  for (auto row_group_index : row_group_indices) {
-    if (row_group_index < 0 || row_group_index >= max_num) {
-      std::ostringstream ss;
-      ss << "Some index in row_group_indices is " << row_group_index
-         << ", which is either < 0 or >= num_row_groups(" << max_num << ")";
-      return Status::Invalid(ss.str());
-    }
-  }
-
-  *out = std::make_shared<RowGroupRecordBatchReader>(row_group_indices, column_indices,
-                                                     schema, this);
-  return Status::OK();
-}
-
-Status FileReader::ReadTable(std::shared_ptr<Table>* out) {
-  try {
-    return impl_->ReadTable(out);
-  } catch (const ::parquet::ParquetException& e) {
-    return ::arrow::Status::IOError(e.what());
-  }
-}
-
-Status FileReader::ReadTable(const std::vector<int>& indices,
-                             std::shared_ptr<Table>* out) {
-  try {
-    return impl_->ReadTable(indices, out);
-  } catch (const ::parquet::ParquetException& e) {
-    return ::arrow::Status::IOError(e.what());
-  }
-}
-
-Status FileReader::ReadRowGroup(int i, std::shared_ptr<Table>* out) {
-  try {
-    return impl_->ReadRowGroup(i, out);
-  } catch (const ::parquet::ParquetException& e) {
-    return ::arrow::Status::IOError(e.what());
-  }
-}
-
-Status FileReader::ReadRowGroup(int i, const std::vector<int>& indices,
-                                std::shared_ptr<Table>* out) {
-  try {
-    return impl_->ReadRowGroup(i, indices, out);
-  } catch (const ::parquet::ParquetException& e) {
-    return ::arrow::Status::IOError(e.what());
-  }
-}
-
-Status FileReader::ReadRowGroups(const std::vector<int>& row_groups,
-                                 std::shared_ptr<Table>* out) {
-  try {
-    return impl_->ReadRowGroups(row_groups, out);
-  } catch (const ::parquet::ParquetException& e) {
-    return ::arrow::Status::IOError(e.what());
-  }
-}
-
-Status FileReader::ReadRowGroups(const std::vector<int>& row_groups,
-                                 const std::vector<int>& indices,
-                                 std::shared_ptr<Table>* out) {
-  try {
-    return impl_->ReadRowGroups(row_groups, indices, out);
-  } catch (const ::parquet::ParquetException& e) {
-    return ::arrow::Status::IOError(e.what());
-  }
-}
-
-std::shared_ptr<RowGroupReader> FileReader::RowGroup(int row_group_index) {
-  return std::shared_ptr<RowGroupReader>(
-      new RowGroupReader(impl_.get(), row_group_index));
-}
-
-int FileReader::num_row_groups() const { return impl_->num_row_groups(); }
-
-void FileReader::set_num_threads(int num_threads) {}
-
-void FileReader::set_use_threads(bool use_threads) {
-  impl_->set_use_threads(use_threads);
-}
-
-Status FileReader::ScanContents(std::vector<int> columns, const int32_t column_batch_size,
-                                int64_t* num_rows) {
-  try {
-    *num_rows = ScanFileContents(columns, column_batch_size, impl_->reader());
-    return Status::OK();
-  } catch (const ::parquet::ParquetException& e) {
-    return Status::IOError(e.what());
-  }
-}
-
-const ParquetFileReader* FileReader::parquet_reader() const {
-  return impl_->parquet_reader();
-}
-
-template <typename ParquetType>
-Status PrimitiveImpl::WrapIntoListArray(std::shared_ptr<Array>* array) {
-  const int16_t* def_levels = record_reader_->def_levels();
-  const int16_t* rep_levels = record_reader_->rep_levels();
-  const int64_t total_levels_read = record_reader_->levels_position();
-
-  std::shared_ptr<::arrow::Schema> arrow_schema;
-  RETURN_NOT_OK(FromParquetSchema(input_->schema(), {input_->column_index()},
-                                  input_->metadata()->key_value_metadata(),
-                                  &arrow_schema));
-  std::shared_ptr<Field> current_field = arrow_schema->field(0);
-
-  if (descr_->max_repetition_level() > 0) {
-    // Walk downwards to extract nullability
-    std::vector<bool> nullable;
-    std::vector<std::shared_ptr<::arrow::Int32Builder>> offset_builders;
-    std::vector<std::shared_ptr<::arrow::BooleanBuilder>> valid_bits_builders;
-    nullable.push_back(current_field->nullable());
-    while (current_field->type()->num_children() > 0) {
-      if (current_field->type()->num_children() > 1) {
-        return Status::NotImplemented(
-            "Fields with more than one child are not supported.");
-      } else {
-        if (current_field->type()->id() != ::arrow::Type::LIST) {
-          return Status::NotImplemented(
-              "Currently only nesting with Lists is supported.");
-        }
-        current_field = current_field->type()->child(0);
-      }
-      offset_builders.emplace_back(
-          std::make_shared<::arrow::Int32Builder>(::arrow::int32(), pool_));
-      valid_bits_builders.emplace_back(
-          std::make_shared<::arrow::BooleanBuilder>(::arrow::boolean(), pool_));
-      nullable.push_back(current_field->nullable());
-    }
-
-    int64_t list_depth = offset_builders.size();
-    // This describes the minimal definition that describes a level that
-    // reflects a value in the primitive values array.
-    int16_t values_def_level = descr_->max_definition_level();
-    if (nullable[nullable.size() - 1]) {
-      values_def_level--;
-    }
-
-    // The definition levels that are needed so that a list is declared
-    // as empty and not null.
-    std::vector<int16_t> empty_def_level(list_depth);
-    int def_level = 0;
-    for (int i = 0; i < list_depth; i++) {
-      if (nullable[i]) {
-        def_level++;
-      }
-      empty_def_level[i] = static_cast<int16_t>(def_level);
-      def_level++;
-    }
-
-    int32_t values_offset = 0;
-    std::vector<int64_t> null_counts(list_depth, 0);
-    for (int64_t i = 0; i < total_levels_read; i++) {
-      int16_t rep_level = rep_levels[i];
-      if (rep_level < descr_->max_repetition_level()) {
-        for (int64_t j = rep_level; j < list_depth; j++) {
-          if (j == (list_depth - 1)) {
-            RETURN_NOT_OK(offset_builders[j]->Append(values_offset));
-          } else {
-            RETURN_NOT_OK(offset_builders[j]->Append(
-                static_cast<int32_t>(offset_builders[j + 1]->length())));
-          }
-
-          if (((empty_def_level[j] - 1) == def_levels[i]) && (nullable[j])) {
-            RETURN_NOT_OK(valid_bits_builders[j]->Append(false));
-            null_counts[j]++;
-            break;
-          } else {
-            RETURN_NOT_OK(valid_bits_builders[j]->Append(true));
-            if (empty_def_level[j] == def_levels[i]) {
-              break;
-            }
-          }
-        }
-      }
-      if (def_levels[i] >= values_def_level) {
-        values_offset++;
-      }
-    }
-    // Add the final offset to all lists
-    for (int64_t j = 0; j < list_depth; j++) {
-      if (j == (list_depth - 1)) {
-        RETURN_NOT_OK(offset_builders[j]->Append(values_offset));
-      } else {
-        RETURN_NOT_OK(offset_builders[j]->Append(
-            static_cast<int32_t>(offset_builders[j + 1]->length())));
-      }
-    }
-
-    std::vector<std::shared_ptr<Buffer>> offsets;
-    std::vector<std::shared_ptr<Buffer>> valid_bits;
-    std::vector<int64_t> list_lengths;
-    for (int64_t j = 0; j < list_depth; j++) {
-      list_lengths.push_back(offset_builders[j]->length() - 1);
-      std::shared_ptr<Array> array;
-      RETURN_NOT_OK(offset_builders[j]->Finish(&array));
-      offsets.emplace_back(std::static_pointer_cast<Int32Array>(array)->values());
-      RETURN_NOT_OK(valid_bits_builders[j]->Finish(&array));
-      valid_bits.emplace_back(std::static_pointer_cast<BooleanArray>(array)->values());
-    }
-
-    std::shared_ptr<Array> output(*array);
-    for (int64_t j = list_depth - 1; j >= 0; j--) {
-      auto list_type =
-          ::arrow::list(::arrow::field("item", output->type(), nullable[j + 1]));
-      output = std::make_shared<::arrow::ListArray>(
-          list_type, list_lengths[j], offsets[j], output, valid_bits[j], null_counts[j]);
-    }
-    *array = output;
-  }
-  return Status::OK();
-}
-
-template <typename ArrowType, typename ParquetType>
-struct supports_fast_path_impl {
-  using ArrowCType = typename ArrowType::c_type;
-  using ParquetCType = typename ParquetType::c_type;
-  static constexpr bool value = std::is_same<ArrowCType, ParquetCType>::value;
-};
-
-template <typename ArrowType>
-struct supports_fast_path_impl<ArrowType, ByteArrayType> {
-  static constexpr bool value = false;
-};
-
-template <typename ArrowType>
-struct supports_fast_path_impl<ArrowType, FLBAType> {
-  static constexpr bool value = false;
-};
-
-template <typename ArrowType, typename ParquetType>
-using supports_fast_path =
-    typename std::enable_if<supports_fast_path_impl<ArrowType, ParquetType>::value>::type;
-
-template <typename ArrowType, typename ParquetType, typename Enable = void>
-struct TransferFunctor {
-  using ArrowCType = typename ArrowType::c_type;
-  using ParquetCType = typename ParquetType::c_type;
-
-  Status operator()(RecordReader* reader, MemoryPool* pool,
-                    const std::shared_ptr<::arrow::DataType>& type,
-                    std::shared_ptr<Array>* out) {
-    static_assert(!std::is_same<ArrowType, ::arrow::Int32Type>::value,
-                  "The fast path transfer functor should be used "
-                  "for primitive values");
-
-    int64_t length = reader->values_written();
-    std::shared_ptr<Buffer> data;
-    RETURN_NOT_OK(::arrow::AllocateBuffer(pool, length * sizeof(ArrowCType), &data));
-
-    auto values = reinterpret_cast<const ParquetCType*>(reader->values());
-    auto out_ptr = reinterpret_cast<ArrowCType*>(data->mutable_data());
-    std::copy(values, values + length, out_ptr);
-
-    if (reader->nullable_values()) {
-      std::shared_ptr<ResizableBuffer> is_valid = reader->ReleaseIsValid();
-      *out = std::make_shared<ArrayType<ArrowType>>(type, length, data, is_valid,
-                                                    reader->null_count());
-    } else {
-      *out = std::make_shared<ArrayType<ArrowType>>(type, length, data);
-    }
-    return Status::OK();
-  }
-};
-
-template <typename ArrowType, typename ParquetType>
-struct TransferFunctor<ArrowType, ParquetType,
-                       supports_fast_path<ArrowType, ParquetType>> {
-  Status operator()(RecordReader* reader, MemoryPool* pool,
-                    const std::shared_ptr<::arrow::DataType>& type,
-                    std::shared_ptr<Array>* out) {
-    int64_t length = reader->values_written();
-    std::shared_ptr<ResizableBuffer> values = reader->ReleaseValues();
-
-    if (reader->nullable_values()) {
-      std::shared_ptr<ResizableBuffer> is_valid = reader->ReleaseIsValid();
-      *out = std::make_shared<ArrayType<ArrowType>>(type, length, values, is_valid,
-                                                    reader->null_count());
-    } else {
-      *out = std::make_shared<ArrayType<ArrowType>>(type, length, values);
-    }
-    return Status::OK();
-  }
-};
-
-template <>
-struct TransferFunctor<::arrow::BooleanType, BooleanType> {
-  Status operator()(RecordReader* reader, MemoryPool* pool,
-                    const std::shared_ptr<::arrow::DataType>& type,
-                    std::shared_ptr<Array>* out) {
-    int64_t length = reader->values_written();
-    std::shared_ptr<Buffer> data;
-
-    const int64_t buffer_size = BytesForBits(length);
-    RETURN_NOT_OK(::arrow::AllocateBuffer(pool, buffer_size, &data));
-
-    // Transfer boolean values to packed bitmap
-    auto values = reinterpret_cast<const bool*>(reader->values());
-    uint8_t* data_ptr = data->mutable_data();
-    memset(data_ptr, 0, buffer_size);
-
-    for (int64_t i = 0; i < length; i++) {
-      if (values[i]) {
-        ::arrow::BitUtil::SetBit(data_ptr, i);
-      }
-    }
-
-    if (reader->nullable_values()) {
-      std::shared_ptr<ResizableBuffer> is_valid = reader->ReleaseIsValid();
-      RETURN_NOT_OK(is_valid->Resize(BytesForBits(length), false));
-      *out = std::make_shared<BooleanArray>(type, length, data, is_valid,
-                                            reader->null_count());
-    } else {
-      *out = std::make_shared<BooleanArray>(type, length, data);
-    }
-    return Status::OK();
-  }
-};
-
-template <>
-struct TransferFunctor<::arrow::TimestampType, Int96Type> {
-  Status operator()(RecordReader* reader, MemoryPool* pool,
-                    const std::shared_ptr<::arrow::DataType>& type,
-                    std::shared_ptr<Array>* out) {
-    int64_t length = reader->values_written();
-    auto values = reinterpret_cast<const Int96*>(reader->values());
-
-    std::shared_ptr<Buffer> data;
-    RETURN_NOT_OK(::arrow::AllocateBuffer(pool, length * sizeof(int64_t), &data));
-
-    auto data_ptr = reinterpret_cast<int64_t*>(data->mutable_data());
-    for (int64_t i = 0; i < length; i++) {
-      *data_ptr++ = impala_timestamp_to_nanoseconds(values[i]);
-    }
-
-    if (reader->nullable_values()) {
-      std::shared_ptr<ResizableBuffer> is_valid = reader->ReleaseIsValid();
-      *out = std::make_shared<TimestampArray>(type, length, data, is_valid,
-                                              reader->null_count());
-    } else {
-      *out = std::make_shared<TimestampArray>(type, length, data);
-    }
-
-    return Status::OK();
-  }
-};
-
-template <>
-struct TransferFunctor<::arrow::Date64Type, Int32Type> {
-  Status operator()(RecordReader* reader, MemoryPool* pool,
-                    const std::shared_ptr<::arrow::DataType>& type,
-                    std::shared_ptr<Array>* out) {
-    int64_t length = reader->values_written();
-    auto values = reinterpret_cast<const int32_t*>(reader->values());
-
-    std::shared_ptr<Buffer> data;
-    RETURN_NOT_OK(::arrow::AllocateBuffer(pool, length * sizeof(int64_t), &data));
-    auto out_ptr = reinterpret_cast<int64_t*>(data->mutable_data());
-
-    for (int64_t i = 0; i < length; i++) {
-      *out_ptr++ = static_cast<int64_t>(values[i]) * kMillisecondsInADay;
-    }
-
-    if (reader->nullable_values()) {
-      std::shared_ptr<ResizableBuffer> is_valid = reader->ReleaseIsValid();
-      *out = std::make_shared<::arrow::Date64Array>(type, length, data, is_valid,
-                                                    reader->null_count());
-    } else {
-      *out = std::make_shared<::arrow::Date64Array>(type, length, data);
-    }
-    return Status::OK();
-  }
-};
-
-template <typename ArrowType, typename ParquetType>
-struct TransferFunctor<
-    ArrowType, ParquetType,
-    typename std::enable_if<std::is_same<ParquetType, ByteArrayType>::value ||
-                            std::is_same<ParquetType, FLBAType>::value>::type> {
-  Status operator()(RecordReader* reader, MemoryPool* pool,
-                    const std::shared_ptr<::arrow::DataType>& type,
-                    std::shared_ptr<Array>* out) {
-    RETURN_NOT_OK(reader->builder()->Finish(out));
-
-    if (type->id() == ::arrow::Type::STRING) {
-      // Convert from BINARY type to STRING
-      auto new_data = (*out)->data()->Copy();
-      new_data->type = type;
-      *out = ::arrow::MakeArray(new_data);
-    }
-    return Status::OK();
-  }
-};
-
-static uint64_t BytesToInteger(const uint8_t* bytes, int32_t start, int32_t stop) {
-  using ::arrow::BitUtil::FromBigEndian;
-
-  const int32_t length = stop - start;
-
-  DCHECK_GE(length, 0);
-  DCHECK_LE(length, 8);
-
-  switch (length) {
-    case 0:
-      return 0;
-    case 1:
-      return bytes[start];
-    case 2:
-      return FromBigEndian(*reinterpret_cast<const uint16_t*>(bytes + start));
-    case 3: {
-      const uint64_t first_two_bytes =
-          FromBigEndian(*reinterpret_cast<const uint16_t*>(bytes + start));
-      const uint64_t last_byte = bytes[stop - 1];
-      return first_two_bytes << 8 | last_byte;
-    }
-    case 4:
-      return FromBigEndian(*reinterpret_cast<const uint32_t*>(bytes + start));
-    case 5: {
-      const uint64_t first_four_bytes =
-          FromBigEndian(*reinterpret_cast<const uint32_t*>(bytes + start));
-      const uint64_t last_byte = bytes[stop - 1];
-      return first_four_bytes << 8 | last_byte;
-    }
-    case 6: {
-      const uint64_t first_four_bytes =
-          FromBigEndian(*reinterpret_cast<const uint32_t*>(bytes + start));
-      const uint64_t last_two_bytes =
-          FromBigEndian(*reinterpret_cast<const uint16_t*>(bytes + start + 4));
-      return first_four_bytes << 16 | last_two_bytes;
-    }
-    case 7: {
-      const uint64_t first_four_bytes =
-          FromBigEndian(*reinterpret_cast<const uint32_t*>(bytes + start));
-      const uint64_t second_two_bytes =
-          FromBigEndian(*reinterpret_cast<const uint16_t*>(bytes + start + 4));
-      const uint64_t last_byte = bytes[stop - 1];
-      return first_four_bytes << 24 | second_two_bytes << 8 | last_byte;
-    }
-    case 8:
-      return FromBigEndian(*reinterpret_cast<const uint64_t*>(bytes + start));
-    default: {
-      DCHECK(false);
-      return UINT64_MAX;
-    }
-  }
-}
-
-static constexpr int32_t kMinDecimalBytes = 1;
-static constexpr int32_t kMaxDecimalBytes = 16;
-
-/// \brief Convert a sequence of big-endian bytes to one int64_t (high bits) and one
-/// uint64_t (low bits).
-static void BytesToIntegerPair(const uint8_t* bytes,
-                               const int32_t total_number_of_bytes_used, int64_t* high,
-                               uint64_t* low) {
-  DCHECK_GE(total_number_of_bytes_used, kMinDecimalBytes);
-  DCHECK_LE(total_number_of_bytes_used, kMaxDecimalBytes);
-
-  /// Bytes are coming in big-endian, so the first byte is the MSB and therefore holds the
-  /// sign bit.
-  const bool is_negative = static_cast<int8_t>(bytes[0]) < 0;
-
-  /// Sign extend the low bits if necessary
-  *low = UINT64_MAX * (is_negative && total_number_of_bytes_used < 8);
-  *high = -1 * (is_negative && total_number_of_bytes_used < kMaxDecimalBytes);
-
-  /// Stop byte of the high bytes
-  const int32_t high_bits_offset = std::max(0, total_number_of_bytes_used - 8);
-
-  /// Shift left enough bits to make room for the incoming int64_t
-  *high <<= high_bits_offset * CHAR_BIT;
-
-  /// Preserve the upper bits by inplace OR-ing the int64_t
-  *high |= BytesToInteger(bytes, 0, high_bits_offset);
-
-  /// Stop byte of the low bytes
-  const int32_t low_bits_offset = std::min(total_number_of_bytes_used, 8);
-
-  /// Shift left enough bits to make room for the incoming uint64_t
-  *low <<= low_bits_offset * CHAR_BIT;
-
-  /// Preserve the upper bits by inplace OR-ing the uint64_t
-  *low |= BytesToInteger(bytes, high_bits_offset, total_number_of_bytes_used);
-}
-
-static inline void RawBytesToDecimalBytes(const uint8_t* value, int32_t byte_width,
-                                          uint8_t* out_buf) {
-  // view the first 8 bytes as an unsigned 64-bit integer
-  auto low = reinterpret_cast<uint64_t*>(out_buf);
-
-  // view the second 8 bytes as a signed 64-bit integer
-  auto high = reinterpret_cast<int64_t*>(out_buf + sizeof(uint64_t));
-
-  // Convert the fixed size binary array bytes into a Decimal128 compatible layout
-  BytesToIntegerPair(value, byte_width, high, low);
-}
-
-/// \brief Convert an array of FixedLenByteArrays to an arrow::Decimal128Array
-/// We do this by:
-/// 1. Creating a arrow::FixedSizeBinaryArray from the RecordReader's builder
-/// 2. Allocating a buffer for the arrow::Decimal128Array
-/// 3. Converting the big-endian bytes in the FixedSizeBinaryArray to two integers
-///    representing the high and low bits of each decimal value.
-template <>
-struct TransferFunctor<::arrow::Decimal128Type, FLBAType> {
-  Status operator()(RecordReader* reader, MemoryPool* pool,
-                    const std::shared_ptr<::arrow::DataType>& type,
-                    std::shared_ptr<Array>* out) {
-    DCHECK_EQ(type->id(), ::arrow::Type::DECIMAL);
-
-    // Finish the built data into a temporary array
-    std::shared_ptr<Array> array;
-    RETURN_NOT_OK(reader->builder()->Finish(&array));
-    const auto& fixed_size_binary_array =
-        static_cast<const ::arrow::FixedSizeBinaryArray&>(*array);
-
-    // Get the byte width of the values in the FixedSizeBinaryArray. Most of the time
-    // this will be different from the decimal array width because we write the minimum
-    // number of bytes necessary to represent a given precision
-    const int32_t byte_width =
-        static_cast<const ::arrow::FixedSizeBinaryType&>(*fixed_size_binary_array.type())
-            .byte_width();
-
-    // The byte width of each decimal value
-    const int32_t type_length =
-        static_cast<const ::arrow::Decimal128Type&>(*type).byte_width();
-
-    // number of elements in the entire array
-    const int64_t length = fixed_size_binary_array.length();
-
-    // allocate memory for the decimal array
-    std::shared_ptr<Buffer> data;
-    RETURN_NOT_OK(::arrow::AllocateBuffer(pool, length * type_length, &data));
-
-    // raw bytes that we can write to
-    uint8_t* out_ptr = data->mutable_data();
-
-    // convert each FixedSizeBinary value to valid decimal bytes
-    const int64_t null_count = fixed_size_binary_array.null_count();
-    if (null_count > 0) {
-      for (int64_t i = 0; i < length; ++i, out_ptr += type_length) {
-        if (!fixed_size_binary_array.IsNull(i)) {
-          RawBytesToDecimalBytes(fixed_size_binary_array.GetValue(i), byte_width,
-                                 out_ptr);
-        }
-      }
-    } else {
-      for (int64_t i = 0; i < length; ++i, out_ptr += type_length) {
-        RawBytesToDecimalBytes(fixed_size_binary_array.GetValue(i), byte_width, out_ptr);
-      }
-    }
-
-    *out = std::make_shared<::arrow::Decimal128Array>(
-        type, length, data, fixed_size_binary_array.null_bitmap(), null_count);
-    return Status::OK();
-  }
-};
-
-/// \brief Convert an Int32 or Int64 array into a Decimal128Array
-/// The parquet spec allows systems to write decimals in int32, int64 if the values are
-/// small enough to fit in less 4 bytes or less than 8 bytes, respectively.
-/// This function implements the conversion from int32 and int64 arrays to decimal arrays.
-template <typename ParquetIntegerType,
-          typename = typename std::enable_if<
-              std::is_same<ParquetIntegerType, Int32Type>::value ||
-              std::is_same<ParquetIntegerType, Int64Type>::value>::type>
-static Status DecimalIntegerTransfer(RecordReader* reader, MemoryPool* pool,
-                                     const std::shared_ptr<::arrow::DataType>& type,
-                                     std::shared_ptr<Array>* out) {
-  DCHECK_EQ(type->id(), ::arrow::Type::DECIMAL);
-
-  const int64_t length = reader->values_written();
-
-  using ElementType = typename ParquetIntegerType::c_type;
-  static_assert(std::is_same<ElementType, int32_t>::value ||
-                    std::is_same<ElementType, int64_t>::value,
-                "ElementType must be int32_t or int64_t");
-
-  const auto values = reinterpret_cast<const ElementType*>(reader->values());
-
-  const auto& decimal_type = static_cast<const ::arrow::Decimal128Type&>(*type);
-  const int64_t type_length = decimal_type.byte_width();
-
-  std::shared_ptr<Buffer> data;
-  RETURN_NOT_OK(::arrow::AllocateBuffer(pool, length * type_length, &data));
-  uint8_t* out_ptr = data->mutable_data();
-
-  using ::arrow::BitUtil::FromLittleEndian;
-
-  for (int64_t i = 0; i < length; ++i, out_ptr += type_length) {
-    // sign/zero extend int32_t values, otherwise a no-op
-    const auto value = static_cast<int64_t>(values[i]);
-
-    auto out_ptr_view = reinterpret_cast<uint64_t*>(out_ptr);
-
-    // No-op on little endian machines, byteswap on big endian
-    out_ptr_view[0] = FromLittleEndian(static_cast<uint64_t>(value));
-
-    // no need to byteswap here because we're sign/zero extending exactly 8 bytes
-    out_ptr_view[1] = static_cast<uint64_t>(value < 0 ? -1 : 0);
-  }
-
-  if (reader->nullable_values()) {
-    std::shared_ptr<ResizableBuffer> is_valid = reader->ReleaseIsValid();
-    *out = std::make_shared<::arrow::Decimal128Array>(type, length, data, is_valid,
-                                                      reader->null_count());
-  } else {
-    *out = std::make_shared<::arrow::Decimal128Array>(type, length, data);
-  }
-  return Status::OK();
-}
-
-template <>
-struct TransferFunctor<::arrow::Decimal128Type, Int32Type> {
-  Status operator()(RecordReader* reader, MemoryPool* pool,
-                    const std::shared_ptr<::arrow::DataType>& type,
-                    std::shared_ptr<Array>* out) {
-    return DecimalIntegerTransfer<Int32Type>(reader, pool, type, out);
-  }
-};
-
-template <>
-struct TransferFunctor<::arrow::Decimal128Type, Int64Type> {
-  Status operator()(RecordReader* reader, MemoryPool* pool,
-                    const std::shared_ptr<::arrow::DataType>& type,
-                    std::shared_ptr<Array>* out) {
-    return DecimalIntegerTransfer<Int64Type>(reader, pool, type, out);
-  }
-};
-
-#define TRANSFER_DATA(ArrowType, ParquetType)                            \
-  TransferFunctor<ArrowType, ParquetType> func;                          \
-  RETURN_NOT_OK(func(record_reader_.get(), pool_, field_->type(), out)); \
-  RETURN_NOT_OK(WrapIntoListArray<ParquetType>(out))
-
-#define TRANSFER_CASE(ENUM, ArrowType, ParquetType) \
-  case ::arrow::Type::ENUM: {                       \
-    TRANSFER_DATA(ArrowType, ParquetType);          \
-  } break;
-
-Status PrimitiveImpl::NextBatch(int64_t records_to_read, std::shared_ptr<Array>* out) {
-  try {
-    // Pre-allocation gives much better performance for flat columns
-    record_reader_->Reserve(records_to_read);
-
-    record_reader_->Reset();
-    while (records_to_read > 0) {
-      if (!record_reader_->HasMoreData()) {
-        break;
-      }
-      int64_t records_read = record_reader_->ReadRecords(records_to_read);
-      records_to_read -= records_read;
-      if (records_read == 0) {
-        NextRowGroup();
-      }
-    }
-  } catch (const ::parquet::ParquetException& e) {
-    return ::arrow::Status::IOError(e.what());
-  }
-
-  switch (field_->type()->id()) {
-    TRANSFER_CASE(BOOL, ::arrow::BooleanType, BooleanType)
-    TRANSFER_CASE(UINT8, ::arrow::UInt8Type, Int32Type)
-    TRANSFER_CASE(INT8, ::arrow::Int8Type, Int32Type)
-    TRANSFER_CASE(UINT16, ::arrow::UInt16Type, Int32Type)
-    TRANSFER_CASE(INT16, ::arrow::Int16Type, Int32Type)
-    TRANSFER_CASE(UINT32, ::arrow::UInt32Type, Int32Type)
-    TRANSFER_CASE(INT32, ::arrow::Int32Type, Int32Type)
-    TRANSFER_CASE(UINT64, ::arrow::UInt64Type, Int64Type)
-    TRANSFER_CASE(INT64, ::arrow::Int64Type, Int64Type)
-    TRANSFER_CASE(FLOAT, ::arrow::FloatType, FloatType)
-    TRANSFER_CASE(DOUBLE, ::arrow::DoubleType, DoubleType)
-    TRANSFER_CASE(STRING, ::arrow::StringType, ByteArrayType)
-    TRANSFER_CASE(BINARY, ::arrow::BinaryType, ByteArrayType)
-    TRANSFER_CASE(DATE32, ::arrow::Date32Type, Int32Type)
-    TRANSFER_CASE(DATE64, ::arrow::Date64Type, Int32Type)
-    TRANSFER_CASE(FIXED_SIZE_BINARY, ::arrow::FixedSizeBinaryType, FLBAType)
-    case ::arrow::Type::NA: {
-      *out = std::make_shared<::arrow::NullArray>(record_reader_->values_written());
-      RETURN_NOT_OK(WrapIntoListArray<Int32Type>(out));
-      break;
-    }
-    case ::arrow::Type::DECIMAL: {
-      switch (descr_->physical_type()) {
-        case ::parquet::Type::INT32: {
-          TRANSFER_DATA(::arrow::Decimal128Type, Int32Type);
-        } break;
-        case ::parquet::Type::INT64: {
-          TRANSFER_DATA(::arrow::Decimal128Type, Int64Type);
-        } break;
-        case ::parquet::Type::FIXED_LEN_BYTE_ARRAY: {
-          TRANSFER_DATA(::arrow::Decimal128Type, FLBAType);
-        } break;
-        default:
-          return Status::Invalid(
-              "Physical type for decimal must be int32, int64, or fixed length binary");
-      }
-    } break;
-    case ::arrow::Type::TIMESTAMP: {
-      ::arrow::TimestampType* timestamp_type =
-          static_cast<::arrow::TimestampType*>(field_->type().get());
-      switch (timestamp_type->unit()) {
-        case ::arrow::TimeUnit::MILLI:
-        case ::arrow::TimeUnit::MICRO: {
-          TRANSFER_DATA(::arrow::TimestampType, Int64Type);
-        } break;
-        case ::arrow::TimeUnit::NANO: {
-          TRANSFER_DATA(::arrow::TimestampType, Int96Type);
-        } break;
-        default:
-          return Status::NotImplemented("TimeUnit not supported");
-      }
-    } break;
-      TRANSFER_CASE(TIME32, ::arrow::Time32Type, Int32Type)
-      TRANSFER_CASE(TIME64, ::arrow::Time64Type, Int64Type)
-    default:
-      std::stringstream ss;
-      ss << "No support for reading columns of type " << field_->type()->ToString();
-      return Status::NotImplemented(ss.str());
-  }
-
-  return Status::OK();
-}
-
-void PrimitiveImpl::NextRowGroup() {
-  std::unique_ptr<PageReader> page_reader = input_->NextChunk();
-  record_reader_->SetPageReader(std::move(page_reader));
-}
-
-Status PrimitiveImpl::GetDefLevels(const int16_t** data, size_t* length) {
-  *data = record_reader_->def_levels();
-  *length = record_reader_->levels_written();
-  return Status::OK();
-}
-
-Status PrimitiveImpl::GetRepLevels(const int16_t** data, size_t* length) {
-  *data = record_reader_->rep_levels();
-  *length = record_reader_->levels_written();
-  return Status::OK();
-}
-
-ColumnReader::ColumnReader(std::unique_ptr<ColumnReaderImpl> impl)
-    : impl_(std::move(impl)) {}
-
-ColumnReader::~ColumnReader() {}
-
-Status ColumnReader::NextBatch(int64_t records_to_read, std::shared_ptr<Array>* out) {
-  return impl_->NextBatch(records_to_read, out);
-}
-
-// StructImpl methods
-
-Status StructImpl::DefLevelsToNullArray(std::shared_ptr<Buffer>* null_bitmap_out,
-                                        int64_t* null_count_out) {
-  std::shared_ptr<Buffer> null_bitmap;
-  auto null_count = 0;
-  const int16_t* def_levels_data;
-  size_t def_levels_length;
-  RETURN_NOT_OK(GetDefLevels(&def_levels_data, &def_levels_length));
-  RETURN_NOT_OK(AllocateEmptyBitmap(pool_, def_levels_length, &null_bitmap));
-  uint8_t* null_bitmap_ptr = null_bitmap->mutable_data();
-  for (size_t i = 0; i < def_levels_length; i++) {
-    if (def_levels_data[i] < struct_def_level_) {
-      // Mark null
-      null_count += 1;
-    } else {
-      DCHECK_EQ(def_levels_data[i], struct_def_level_);
-      ::arrow::BitUtil::SetBit(null_bitmap_ptr, i);
-    }
-  }
-
-  *null_count_out = null_count;
-  *null_bitmap_out = (null_count == 0) ? nullptr : null_bitmap;
-  return Status::OK();
-}
-
-// TODO(itaiin): Consider caching the results of this calculation -
-//   note that this is only used once for each read for now
-Status StructImpl::GetDefLevels(const int16_t** data, size_t* length) {
-  *data = nullptr;
-  if (children_.size() == 0) {
-    // Empty struct
-    *length = 0;
-    return Status::OK();
-  }
-
-  // We have at least one child
-  const int16_t* child_def_levels;
-  size_t child_length;
-  RETURN_NOT_OK(children_[0]->GetDefLevels(&child_def_levels, &child_length));
-  auto size = child_length * sizeof(int16_t);
-  RETURN_NOT_OK(AllocateResizableBuffer(pool_, size, &def_levels_buffer_));
-  // Initialize with the minimal def level
-  std::memset(def_levels_buffer_->mutable_data(), -1, size);
-  auto result_levels = reinterpret_cast<int16_t*>(def_levels_buffer_->mutable_data());
-
-  // When a struct is defined, all of its children def levels are at least at
-  // nesting level, and def level equals nesting level.
-  // When a struct is not defined, all of its children def levels are less than
-  // the nesting level, and the def level equals max(children def levels)
-  // All other possibilities are malformed definition data.
-  for (auto& child : children_) {
-    size_t current_child_length;
-    RETURN_NOT_OK(child->GetDefLevels(&child_def_levels, &current_child_length));
-    DCHECK_EQ(child_length, current_child_length);
-    for (size_t i = 0; i < child_length; i++) {
-      // Check that value is either uninitialized, or current
-      // and previous children def levels agree on the struct level
-      DCHECK((result_levels[i] == -1) || ((result_levels[i] >= struct_def_level_) ==
-                                          (child_def_levels[i] >= struct_def_level_)));
-      result_levels[i] =
-          std::max(result_levels[i], std::min(child_def_levels[i], struct_def_level_));
-    }
-  }
-  *data = reinterpret_cast<const int16_t*>(def_levels_buffer_->data());
-  *length = child_length;
-  return Status::OK();
-}
-
-void StructImpl::InitField(
-    const Node* node, const std::vector<std::shared_ptr<ColumnReaderImpl>>& children) {
-  // Make a shallow node to field conversion from the children fields
-  std::vector<std::shared_ptr<::arrow::Field>> fields(children.size());
-  for (size_t i = 0; i < children.size(); i++) {
-    fields[i] = children[i]->field();
-  }
-  auto type = ::arrow::struct_(fields);
-  field_ = ::arrow::field(node->name(), type);
-}
-
-Status StructImpl::GetRepLevels(const int16_t** data, size_t* length) {
-  return Status::NotImplemented("GetRepLevels is not implemented for struct");
-}
-
-Status StructImpl::NextBatch(int64_t records_to_read, std::shared_ptr<Array>* out) {
-  std::vector<std::shared_ptr<Array>> children_arrays;
-  std::shared_ptr<Buffer> null_bitmap;
-  int64_t null_count;
-
-  // Gather children arrays and def levels
-  for (auto& child : children_) {
-    std::shared_ptr<Array> child_array;
-
-    RETURN_NOT_OK(child->NextBatch(records_to_read, &child_array));
-    children_arrays.push_back(child_array);
-  }
-
-  RETURN_NOT_OK(DefLevelsToNullArray(&null_bitmap, &null_count));
-
-  int64_t struct_length = children_arrays[0]->length();
-  for (size_t i = 1; i < children_arrays.size(); ++i) {
-    if (children_arrays[i]->length() != struct_length) {
-      // TODO(wesm): This should really only occur if the Parquet file is
-      // malformed. Should this be a DCHECK?
-      return Status::Invalid("Struct children had different lengths");
-    }
-  }
-
-  *out = std::make_shared<StructArray>(field()->type(), struct_length, children_arrays,
-                                       null_bitmap, null_count);
-  return Status::OK();
-}
-
-std::shared_ptr<ColumnChunkReader> RowGroupReader::Column(int column_index) {
-  return std::shared_ptr<ColumnChunkReader>(
-      new ColumnChunkReader(impl_, row_group_index_, column_index));
-}
-
-Status RowGroupReader::ReadTable(const std::vector<int>& column_indices,
-                                 std::shared_ptr<::arrow::Table>* out) {
-  return impl_->ReadRowGroup(row_group_index_, column_indices, out);
-}
-
-Status RowGroupReader::ReadTable(std::shared_ptr<::arrow::Table>* out) {
-  return impl_->ReadRowGroup(row_group_index_, out);
-}
-
-RowGroupReader::~RowGroupReader() {}
-
-RowGroupReader::RowGroupReader(FileReader::Impl* impl, int row_group_index)
-    : impl_(impl), row_group_index_(row_group_index) {}
-
-Status ColumnChunkReader::Read(std::shared_ptr<::arrow::Array>* out) {
-  return impl_->ReadColumnChunk(column_index_, row_group_index_, out);
-}
-
-ColumnChunkReader::~ColumnChunkReader() {}
-
-ColumnChunkReader::ColumnChunkReader(FileReader::Impl* impl, int row_group_index,
-                                     int column_index)
-    : impl_(impl), column_index_(column_index), row_group_index_(row_group_index) {}
-
-}  // namespace arrow
-}  // namespace parquet
diff --git a/src/parquet/arrow/reader.h b/src/parquet/arrow/reader.h
deleted file mode 100644
index db135da..0000000
--- a/src/parquet/arrow/reader.h
+++ /dev/null
@@ -1,306 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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.
-
-#ifndef PARQUET_ARROW_READER_H
-#define PARQUET_ARROW_READER_H
-
-#include <memory>
-#include <vector>
-
-#include "parquet/api/reader.h"
-#include "parquet/api/schema.h"
-
-#include "arrow/io/interfaces.h"
-
-namespace arrow {
-
-class Array;
-class MemoryPool;
-class RecordBatchReader;
-class Status;
-class Table;
-}  // namespace arrow
-
-namespace parquet {
-
-namespace arrow {
-
-class ColumnChunkReader;
-class ColumnReader;
-class RowGroupReader;
-
-// Arrow read adapter class for deserializing Parquet files as Arrow row
-// batches.
-//
-// This interfaces caters for different use cases and thus provides different
-// interfaces. In its most simplistic form, we cater for a user that wants to
-// read the whole Parquet at once with the FileReader::ReadTable method.
-//
-// More advanced users that also want to implement parallelism on top of each
-// single Parquet files should do this on the RowGroup level. For this, they can
-// call FileReader::RowGroup(i)->ReadTable to receive only the specified
-// RowGroup as a table.
-//
-// In the most advanced situation, where a consumer wants to independently read
-// RowGroups in parallel and consume each column individually, they can call
-// FileReader::RowGroup(i)->Column(j)->Read and receive an arrow::Column
-// instance.
-//
-// TODO(wesm): nested data does not always make sense with this user
-// interface unless you are only reading a single leaf node from a branch of
-// a table. For example:
-//
-// repeated group data {
-//   optional group record {
-//     optional int32 val1;
-//     optional byte_array val2;
-//     optional bool val3;
-//   }
-//   optional int32 val4;
-// }
-//
-// In the Parquet file, there are 3 leaf nodes:
-//
-// * data.record.val1
-// * data.record.val2
-// * data.record.val3
-// * data.val4
-//
-// When materializing this data in an Arrow array, we would have:
-//
-// data: list<struct<
-//   record: struct<
-//    val1: int32,
-//    val2: string (= list<uint8>),
-//    val3: bool,
-//   >,
-//   val4: int32
-// >>
-//
-// However, in the Parquet format, each leaf node has its own repetition and
-// definition levels describing the structure of the intermediate nodes in
-// this array structure. Thus, we will need to scan the leaf data for a group
-// of leaf nodes part of the same type tree to create a single result Arrow
-// nested array structure.
-//
-// This is additionally complicated "chunky" repeated fields or very large byte
-// arrays
-class PARQUET_EXPORT FileReader {
- public:
-  FileReader(::arrow::MemoryPool* pool, std::unique_ptr<ParquetFileReader> reader);
-
-  // Since the distribution of columns amongst a Parquet file's row groups may
-  // be uneven (the number of values in each column chunk can be different), we
-  // provide a column-oriented read interface. The ColumnReader hides the
-  // details of paging through the file's row groups and yielding
-  // fully-materialized arrow::Array instances
-  //
-  // Returns error status if the column of interest is not flat.
-  ::arrow::Status GetColumn(int i, std::unique_ptr<ColumnReader>* out);
-
-  /// \brief Return arrow schema by apply selection of column indices.
-  /// \returns error status if passed wrong indices.
-  ::arrow::Status GetSchema(const std::vector<int>& indices,
-                            std::shared_ptr<::arrow::Schema>* out);
-
-  // Read column as a whole into an Array.
-  ::arrow::Status ReadColumn(int i, std::shared_ptr<::arrow::Array>* out);
-
-  // NOTE: Experimental API
-  // Reads a specific top level schema field into an Array
-  // The index i refers the index of the top level schema field, which may
-  // be nested or flat - e.g.
-  //
-  // 0 foo.bar
-  //   foo.bar.baz
-  //   foo.qux
-  // 1 foo2
-  // 2 foo3
-  //
-  // i=0 will read the entire foo struct, i=1 the foo2 primitive column etc
-  ::arrow::Status ReadSchemaField(int i, std::shared_ptr<::arrow::Array>* out);
-
-  // NOTE: Experimental API
-  // Reads a specific top level schema field into an Array, while keeping only chosen
-  // leaf columns.
-  // The index i refers the index of the top level schema field, which may
-  // be nested or flat, and indices vector refers to the leaf column indices - e.g.
-  //
-  // i  indices
-  // 0  0        foo.bar
-  // 0  1        foo.bar.baz
-  // 0  2        foo.qux
-  // 1  3        foo2
-  // 2  4        foo3
-  //
-  // i=0 indices={0,2} will read a partial struct with foo.bar and foo.quox columns
-  // i=1 indices={3} will read foo2 column
-  // i=1 indices={2} will result in out=nullptr
-  // leaf indices which are unrelated to the schema field are ignored
-  ::arrow::Status ReadSchemaField(int i, const std::vector<int>& indices,
-                                  std::shared_ptr<::arrow::Array>* out);
-
-  /// \brief Return a RecordBatchReader of row groups selected from row_group_indices, the
-  ///    ordering in row_group_indices matters.
-  /// \returns error Status if row_group_indices contains invalid index
-  ::arrow::Status GetRecordBatchReader(const std::vector<int>& row_group_indices,
-                                       std::shared_ptr<::arrow::RecordBatchReader>* out);
-
-  /// \brief Return a RecordBatchReader of row groups selected from row_group_indices,
-  ///     whose columns are selected by column_indices. The ordering in row_group_indices
-  ///     and column_indices matter.
-  /// \returns error Status if either row_group_indices or column_indices contains invalid
-  ///    index
-  ::arrow::Status GetRecordBatchReader(const std::vector<int>& row_group_indices,
-                                       const std::vector<int>& column_indices,
-                                       std::shared_ptr<::arrow::RecordBatchReader>* out);
-
-  // Read a table of columns into a Table
-  ::arrow::Status ReadTable(std::shared_ptr<::arrow::Table>* out);
-
-  // Read a table of columns into a Table. Read only the indicated column
-  // indices (relative to the schema)
-  ::arrow::Status ReadTable(const std::vector<int>& column_indices,
-                            std::shared_ptr<::arrow::Table>* out);
-
-  ::arrow::Status ReadRowGroup(int i, const std::vector<int>& column_indices,
-                               std::shared_ptr<::arrow::Table>* out);
-
-  ::arrow::Status ReadRowGroup(int i, std::shared_ptr<::arrow::Table>* out);
-
-  ::arrow::Status ReadRowGroups(const std::vector<int>& row_groups,
-                                const std::vector<int>& column_indices,
-                                std::shared_ptr<::arrow::Table>* out);
-
-  ::arrow::Status ReadRowGroups(const std::vector<int>& row_groups,
-                                std::shared_ptr<::arrow::Table>* out);
-
-  /// \brief Scan file contents with one thread, return number of rows
-  ::arrow::Status ScanContents(std::vector<int> columns, const int32_t column_batch_size,
-                               int64_t* num_rows);
-
-  /// \brief Return a reader for the RowGroup, this object must not outlive the
-  ///   FileReader.
-  std::shared_ptr<RowGroupReader> RowGroup(int row_group_index);
-
-  int num_row_groups() const;
-
-  const ParquetFileReader* parquet_reader() const;
-
-  /// Set the number of threads to use during reads of multiple columns. By
-  /// default only 1 thread is used
-  /// \deprecated Use set_use_threads instead.
-  void set_num_threads(int num_threads);
-
-  /// Set whether to use multiple threads during reads of multiple columns.
-  /// By default only one thread is used.
-  void set_use_threads(bool use_threads);
-
-  virtual ~FileReader();
-
- private:
-  friend ColumnChunkReader;
-  friend RowGroupReader;
-
-  class PARQUET_NO_EXPORT Impl;
-  std::unique_ptr<Impl> impl_;
-};
-
-class PARQUET_EXPORT RowGroupReader {
- public:
-  std::shared_ptr<ColumnChunkReader> Column(int column_index);
-
-  ::arrow::Status ReadTable(const std::vector<int>& column_indices,
-                            std::shared_ptr<::arrow::Table>* out);
-  ::arrow::Status ReadTable(std::shared_ptr<::arrow::Table>* out);
-
-  virtual ~RowGroupReader();
-
- private:
-  friend FileReader;
-  RowGroupReader(FileReader::Impl* reader, int row_group_index);
-
-  FileReader::Impl* impl_;
-  int row_group_index_;
-};
-
-class PARQUET_EXPORT ColumnChunkReader {
- public:
-  ::arrow::Status Read(std::shared_ptr<::arrow::Array>* out);
-
-  virtual ~ColumnChunkReader();
-
- private:
-  friend RowGroupReader;
-  ColumnChunkReader(FileReader::Impl* impl, int row_group_index, int column_index);
-
-  FileReader::Impl* impl_;
-  int column_index_;
-  int row_group_index_;
-};
-
-// At this point, the column reader is a stream iterator. It only knows how to
-// read the next batch of values for a particular column from the file until it
-// runs out.
-//
-// We also do not expose any internal Parquet details, such as row groups. This
-// might change in the future.
-class PARQUET_EXPORT ColumnReader {
- public:
-  class PARQUET_NO_EXPORT ColumnReaderImpl;
-  virtual ~ColumnReader();
-
-  // Scan the next array of the indicated size. The actual size of the
-  // returned array may be less than the passed size depending how much data is
-  // available in the file.
-  //
-  // When all the data in the file has been exhausted, the result is set to
-  // nullptr.
-  //
-  // Returns Status::OK on a successful read, including if you have exhausted
-  // the data available in the file.
-  ::arrow::Status NextBatch(int64_t batch_size, std::shared_ptr<::arrow::Array>* out);
-
- private:
-  std::unique_ptr<ColumnReaderImpl> impl_;
-  explicit ColumnReader(std::unique_ptr<ColumnReaderImpl> impl);
-
-  friend class FileReader;
-  friend class PrimitiveImpl;
-  friend class StructImpl;
-};
-
-// Helper function to create a file reader from an implementation of an Arrow
-// readable file
-//
-// metadata : separately-computed file metadata, can be nullptr
-PARQUET_EXPORT
-::arrow::Status OpenFile(const std::shared_ptr<::arrow::io::ReadableFileInterface>& file,
-                         ::arrow::MemoryPool* allocator,
-                         const ReaderProperties& properties,
-                         const std::shared_ptr<FileMetaData>& metadata,
-                         std::unique_ptr<FileReader>* reader);
-
-PARQUET_EXPORT
-::arrow::Status OpenFile(const std::shared_ptr<::arrow::io::ReadableFileInterface>& file,
-                         ::arrow::MemoryPool* allocator,
-                         std::unique_ptr<FileReader>* reader);
-
-}  // namespace arrow
-}  // namespace parquet
-
-#endif  // PARQUET_ARROW_READER_H
diff --git a/src/parquet/arrow/record_reader.cc b/src/parquet/arrow/record_reader.cc
deleted file mode 100644
index 781e1ba..0000000
--- a/src/parquet/arrow/record_reader.cc
+++ /dev/null
@@ -1,817 +0,0 @@
-// licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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.
-
-#include "parquet/arrow/record_reader.h"
-
-#include <algorithm>
-#include <cstdint>
-#include <memory>
-#include <sstream>
-
-#include <arrow/buffer.h>
-#include <arrow/memory_pool.h>
-#include <arrow/status.h>
-#include <arrow/util/bit-util.h>
-#include <arrow/util/rle-encoding.h>
-
-#include "parquet/column_page.h"
-#include "parquet/column_reader.h"
-#include "parquet/encoding-internal.h"
-#include "parquet/exception.h"
-#include "parquet/properties.h"
-
-using arrow::MemoryPool;
-
-namespace parquet {
-namespace internal {
-
-namespace BitUtil = ::arrow::BitUtil;
-
-template <typename DType>
-class TypedRecordReader;
-
-// PLAIN_DICTIONARY is deprecated but used to be used as a dictionary index
-// encoding.
-static bool IsDictionaryIndexEncoding(const Encoding::type& e) {
-  return e == Encoding::RLE_DICTIONARY || e == Encoding::PLAIN_DICTIONARY;
-}
-
-class RecordReader::RecordReaderImpl {
- public:
-  RecordReaderImpl(const ColumnDescriptor* descr, MemoryPool* pool)
-      : descr_(descr),
-        pool_(pool),
-        num_buffered_values_(0),
-        num_decoded_values_(0),
-        max_def_level_(descr->max_definition_level()),
-        max_rep_level_(descr->max_repetition_level()),
-        at_record_start_(true),
-        records_read_(0),
-        values_written_(0),
-        values_capacity_(0),
-        null_count_(0),
-        levels_written_(0),
-        levels_position_(0),
-        levels_capacity_(0) {
-    nullable_values_ = internal::HasSpacedValues(descr);
-    values_ = AllocateBuffer(pool);
-    valid_bits_ = AllocateBuffer(pool);
-    def_levels_ = AllocateBuffer(pool);
-    rep_levels_ = AllocateBuffer(pool);
-
-    if (descr->physical_type() == Type::BYTE_ARRAY) {
-      builder_.reset(new ::arrow::BinaryBuilder(pool));
-    } else if (descr->physical_type() == Type::FIXED_LEN_BYTE_ARRAY) {
-      int byte_width = descr->type_length();
-      std::shared_ptr<::arrow::DataType> type = ::arrow::fixed_size_binary(byte_width);
-      builder_.reset(new ::arrow::FixedSizeBinaryBuilder(type, pool));
-    }
-    Reset();
-  }
-
-  virtual ~RecordReaderImpl() = default;
-
-  virtual int64_t ReadRecords(int64_t num_records) = 0;
-
-  // Dictionary decoders must be reset when advancing row groups
-  virtual void ResetDecoders() = 0;
-
-  void SetPageReader(std::unique_ptr<PageReader> reader) {
-    at_record_start_ = true;
-    pager_ = std::move(reader);
-    ResetDecoders();
-  }
-
-  bool HasMoreData() const { return pager_ != nullptr; }
-
-  int16_t* def_levels() const {
-    return reinterpret_cast<int16_t*>(def_levels_->mutable_data());
-  }
-
-  int16_t* rep_levels() {
-    return reinterpret_cast<int16_t*>(rep_levels_->mutable_data());
-  }
-
-  uint8_t* values() const { return values_->mutable_data(); }
-
-  /// \brief Number of values written including nulls (if any)
-  int64_t values_written() const { return values_written_; }
-
-  int64_t levels_position() const { return levels_position_; }
-  int64_t levels_written() const { return levels_written_; }
-
-  // We may outwardly have the appearance of having exhausted a column chunk
-  // when in fact we are in the middle of processing the last batch
-  bool has_values_to_process() const { return levels_position_ < levels_written_; }
-
-  int64_t null_count() const { return null_count_; }
-
-  bool nullable_values() const { return nullable_values_; }
-
-  std::shared_ptr<ResizableBuffer> ReleaseValues() {
-    auto result = values_;
-    values_ = AllocateBuffer(pool_);
-    return result;
-  }
-
-  std::shared_ptr<ResizableBuffer> ReleaseIsValid() {
-    auto result = valid_bits_;
-    valid_bits_ = AllocateBuffer(pool_);
-    return result;
-  }
-
-  ::arrow::ArrayBuilder* builder() { return builder_.get(); }
-
-  // Process written repetition/definition levels to reach the end of
-  // records. Process no more levels than necessary to delimit the indicated
-  // number of logical records. Updates internal state of RecordReader
-  //
-  // \return Number of records delimited
-  int64_t DelimitRecords(int64_t num_records, int64_t* values_seen) {
-    int64_t values_to_read = 0;
-    int64_t records_read = 0;
-
-    const int16_t* def_levels = this->def_levels() + levels_position_;
-    const int16_t* rep_levels = this->rep_levels() + levels_position_;
-
-    DCHECK_GT(max_rep_level_, 0);
-
-    // Count logical records and number of values to read
-    while (levels_position_ < levels_written_) {
-      if (*rep_levels++ == 0) {
-        // If at_record_start_ is true, we are seeing the start of a record
-        // for the second time, such as after repeated calls to
-        // DelimitRecords. In this case we must continue until we find
-        // another record start or exhausting the ColumnChunk
-        if (!at_record_start_) {
-          // We've reached the end of a record; increment the record count.
-          ++records_read;
-          if (records_read == num_records) {
-            // We've found the number of records we were looking for. Set
-            // at_record_start_ to true and break
-            at_record_start_ = true;
-            break;
-          }
-        }
-      }
-
-      // We have decided to consume the level at this position; therefore we
-      // must advance until we find another record boundary
-      at_record_start_ = false;
-
-      if (*def_levels++ == max_def_level_) {
-        ++values_to_read;
-      }
-      ++levels_position_;
-    }
-    *values_seen = values_to_read;
-    return records_read;
-  }
-
-  // Read multiple definition levels into preallocated memory
-  //
-  // Returns the number of decoded definition levels
-  int64_t ReadDefinitionLevels(int64_t batch_size, int16_t* levels) {
-    if (descr_->max_definition_level() == 0) {
-      return 0;
-    }
-    return definition_level_decoder_.Decode(static_cast<int>(batch_size), levels);
-  }
-
-  int64_t ReadRepetitionLevels(int64_t batch_size, int16_t* levels) {
-    if (descr_->max_repetition_level() == 0) {
-      return 0;
-    }
-    return repetition_level_decoder_.Decode(static_cast<int>(batch_size), levels);
-  }
-
-  int64_t available_values_current_page() const {
-    return num_buffered_values_ - num_decoded_values_;
-  }
-
-  void ConsumeBufferedValues(int64_t num_values) { num_decoded_values_ += num_values; }
-
-  Type::type type() const { return descr_->physical_type(); }
-
-  const ColumnDescriptor* descr() const { return descr_; }
-
-  void Reserve(int64_t capacity) {
-    ReserveLevels(capacity);
-    ReserveValues(capacity);
-  }
-
-  void ReserveLevels(int64_t capacity) {
-    if (descr_->max_definition_level() > 0 &&
-        (levels_written_ + capacity > levels_capacity_)) {
-      int64_t new_levels_capacity = BitUtil::NextPower2(levels_capacity_ + 1);
-      while (levels_written_ + capacity > new_levels_capacity) {
-        new_levels_capacity = BitUtil::NextPower2(new_levels_capacity + 1);
-      }
-      PARQUET_THROW_NOT_OK(
-          def_levels_->Resize(new_levels_capacity * sizeof(int16_t), false));
-      if (descr_->max_repetition_level() > 0) {
-        PARQUET_THROW_NOT_OK(
-            rep_levels_->Resize(new_levels_capacity * sizeof(int16_t), false));
-      }
-      levels_capacity_ = new_levels_capacity;
-    }
-  }
-
-  void ReserveValues(int64_t capacity) {
-    if (values_written_ + capacity > values_capacity_) {
-      int64_t new_values_capacity = BitUtil::NextPower2(values_capacity_ + 1);
-      while (values_written_ + capacity > new_values_capacity) {
-        new_values_capacity = BitUtil::NextPower2(new_values_capacity + 1);
-      }
-
-      int type_size = GetTypeByteSize(descr_->physical_type());
-      PARQUET_THROW_NOT_OK(values_->Resize(new_values_capacity * type_size, false));
-      values_capacity_ = new_values_capacity;
-    }
-    if (nullable_values_) {
-      int64_t valid_bytes_new = BitUtil::BytesForBits(values_capacity_);
-      if (valid_bits_->size() < valid_bytes_new) {
-        int64_t valid_bytes_old = BitUtil::BytesForBits(values_written_);
-        PARQUET_THROW_NOT_OK(valid_bits_->Resize(valid_bytes_new, false));
-
-        // Avoid valgrind warnings
-        memset(valid_bits_->mutable_data() + valid_bytes_old, 0,
-               valid_bytes_new - valid_bytes_old);
-      }
-    }
-  }
-
-  void Reset() {
-    ResetValues();
-
-    if (levels_written_ > 0) {
-      const int64_t levels_remaining = levels_written_ - levels_position_;
-      // Shift remaining levels to beginning of buffer and trim to only the number
-      // of decoded levels remaining
-      int16_t* def_data = def_levels();
-      int16_t* rep_data = rep_levels();
-
-      std::copy(def_data + levels_position_, def_data + levels_written_, def_data);
-      std::copy(rep_data + levels_position_, rep_data + levels_written_, rep_data);
-
-      PARQUET_THROW_NOT_OK(
-          def_levels_->Resize(levels_remaining * sizeof(int16_t), false));
-      PARQUET_THROW_NOT_OK(
-          rep_levels_->Resize(levels_remaining * sizeof(int16_t), false));
-
-      levels_written_ -= levels_position_;
-      levels_position_ = 0;
-      levels_capacity_ = levels_remaining;
-    }
-
-    records_read_ = 0;
-
-    // Calling Finish on the builders also resets them
-  }
-
-  void ResetValues() {
-    if (values_written_ > 0) {
-      // Resize to 0, but do not shrink to fit
-      PARQUET_THROW_NOT_OK(values_->Resize(0, false));
-      PARQUET_THROW_NOT_OK(valid_bits_->Resize(0, false));
-      values_written_ = 0;
-      values_capacity_ = 0;
-      null_count_ = 0;
-    }
-  }
-
- protected:
-  const ColumnDescriptor* descr_;
-  ::arrow::MemoryPool* pool_;
-
-  std::unique_ptr<PageReader> pager_;
-  std::shared_ptr<Page> current_page_;
-
-  // Not set if full schema for this field has no optional or repeated elements
-  LevelDecoder definition_level_decoder_;
-
-  // Not set for flat schemas.
-  LevelDecoder repetition_level_decoder_;
-
-  // The total number of values stored in the data page. This is the maximum of
-  // the number of encoded definition levels or encoded values. For
-  // non-repeated, required columns, this is equal to the number of encoded
-  // values. For repeated or optional values, there may be fewer data values
-  // than levels, and this tells you how many encoded levels there are in that
-  // case.
-  int64_t num_buffered_values_;
-
-  // The number of values from the current data page that have been decoded
-  // into memory
-  int64_t num_decoded_values_;
-
-  const int16_t max_def_level_;
-  const int16_t max_rep_level_;
-
-  bool nullable_values_;
-
-  bool at_record_start_;
-  int64_t records_read_;
-
-  int64_t values_written_;
-  int64_t values_capacity_;
-  int64_t null_count_;
-
-  int64_t levels_written_;
-  int64_t levels_position_;
-  int64_t levels_capacity_;
-
-  // TODO(wesm): ByteArray / FixedLenByteArray types
-  std::unique_ptr<::arrow::ArrayBuilder> builder_;
-
-  std::shared_ptr<::arrow::ResizableBuffer> values_;
-
-  template <typename T>
-  T* ValuesHead() {
-    return reinterpret_cast<T*>(values_->mutable_data()) + values_written_;
-  }
-
-  std::shared_ptr<::arrow::ResizableBuffer> valid_bits_;
-  std::shared_ptr<::arrow::ResizableBuffer> def_levels_;
-  std::shared_ptr<::arrow::ResizableBuffer> rep_levels_;
-};
-
-// The minimum number of repetition/definition levels to decode at a time, for
-// better vectorized performance when doing many smaller record reads
-constexpr int64_t kMinLevelBatchSize = 1024;
-
-template <typename DType>
-class TypedRecordReader : public RecordReader::RecordReaderImpl {
- public:
-  typedef typename DType::c_type T;
-
-  TypedRecordReader(const ColumnDescriptor* schema, ::arrow::MemoryPool* pool)
-      : RecordReader::RecordReaderImpl(schema, pool), current_decoder_(nullptr) {}
-
-  void ResetDecoders() override { decoders_.clear(); }
-
-  inline void ReadValuesSpaced(int64_t values_with_nulls, int64_t null_count) {
-    uint8_t* valid_bits = valid_bits_->mutable_data();
-    const int64_t valid_bits_offset = values_written_;
-
-    int64_t num_decoded = current_decoder_->DecodeSpaced(
-        ValuesHead<T>(), static_cast<int>(values_with_nulls),
-        static_cast<int>(null_count), valid_bits, valid_bits_offset);
-    DCHECK_EQ(num_decoded, values_with_nulls);
-  }
-
-  inline void ReadValuesDense(int64_t values_to_read) {
-    int64_t num_decoded =
-        current_decoder_->Decode(ValuesHead<T>(), static_cast<int>(values_to_read));
-    DCHECK_EQ(num_decoded, values_to_read);
-  }
-
-  // Return number of logical records read
-  int64_t ReadRecordData(const int64_t num_records) {
-    // Conservative upper bound
-    const int64_t possible_num_values =
-        std::max(num_records, levels_written_ - levels_position_);
-    ReserveValues(possible_num_values);
-
-    const int64_t start_levels_position = levels_position_;
-
-    int64_t values_to_read = 0;
-    int64_t records_read = 0;
-    if (max_rep_level_ > 0) {
-      records_read = DelimitRecords(num_records, &values_to_read);
-    } else if (max_def_level_ > 0) {
-      // No repetition levels, skip delimiting logic. Each level represents a
-      // null or not null entry
-      records_read = std::min(levels_written_ - levels_position_, num_records);
-
-      // This is advanced by DelimitRecords, which we skipped
-      levels_position_ += records_read;
-    } else {
-      records_read = values_to_read = num_records;
-    }
-
-    int64_t null_count = 0;
-    if (nullable_values_) {
-      int64_t values_with_nulls = 0;
-      internal::DefinitionLevelsToBitmap(
-          def_levels() + start_levels_position, levels_position_ - start_levels_position,
-          max_def_level_, max_rep_level_, &values_with_nulls, &null_count,
-          valid_bits_->mutable_data(), values_written_);
-      values_to_read = values_with_nulls - null_count;
-      ReadValuesSpaced(values_with_nulls, null_count);
-      ConsumeBufferedValues(levels_position_ - start_levels_position);
-    } else {
-      ReadValuesDense(values_to_read);
-      ConsumeBufferedValues(values_to_read);
-    }
-    // Total values, including null spaces, if any
-    values_written_ += values_to_read + null_count;
-    null_count_ += null_count;
-
-    return records_read;
-  }
-
-  // Returns true if there are still values in this column.
-  bool HasNext() {
-    // Either there is no data page available yet, or the data page has been
-    // exhausted
-    if (num_buffered_values_ == 0 || num_decoded_values_ == num_buffered_values_) {
-      if (!ReadNewPage() || num_buffered_values_ == 0) {
-        return false;
-      }
-    }
-    return true;
-  }
-
-  int64_t ReadRecords(int64_t num_records) override {
-    // Delimit records, then read values at the end
-    int64_t records_read = 0;
-
-    if (levels_position_ < levels_written_) {
-      records_read += ReadRecordData(num_records);
-    }
-
-    int64_t level_batch_size = std::max(kMinLevelBatchSize, num_records);
-
-    // If we are in the middle of a record, we continue until reaching the
-    // desired number of records or the end of the current record if we've found
-    // enough records
-    while (!at_record_start_ || records_read < num_records) {
-      // Is there more data to read in this row group?
-      if (!HasNext()) {
-        if (!at_record_start_) {
-          // We ended the row group while inside a record that we haven't seen
-          // the end of yet. So increment the record count for the last record in
-          // the row group
-          ++records_read;
-          at_record_start_ = true;
-        }
-        break;
-      }
-
-      /// We perform multiple batch reads until we either exhaust the row group
-      /// or observe the desired number of records
-      int64_t batch_size = std::min(level_batch_size, available_values_current_page());
-
-      // No more data in column
-      if (batch_size == 0) {
-        break;
-      }
-
-      if (max_def_level_ > 0) {
-        ReserveLevels(batch_size);
-
-        int16_t* def_levels = this->def_levels() + levels_written_;
-        int16_t* rep_levels = this->rep_levels() + levels_written_;
-
-        // Not present for non-repeated fields
-        int64_t levels_read = 0;
-        if (max_rep_level_ > 0) {
-          levels_read = ReadDefinitionLevels(batch_size, def_levels);
-          if (ReadRepetitionLevels(batch_size, rep_levels) != levels_read) {
-            throw ParquetException("Number of decoded rep / def levels did not match");
-          }
-        } else if (max_def_level_ > 0) {
-          levels_read = ReadDefinitionLevels(batch_size, def_levels);
-        }
-
-        // Exhausted column chunk
-        if (levels_read == 0) {
-          break;
-        }
-
-        levels_written_ += levels_read;
-        records_read += ReadRecordData(num_records - records_read);
-      } else {
-        // No repetition or definition levels
-        batch_size = std::min(num_records - records_read, batch_size);
-        records_read += ReadRecordData(batch_size);
-      }
-    }
-
-    return records_read;
-  }
-
- private:
-  typedef Decoder<DType> DecoderType;
-
-  // Map of encoding type to the respective decoder object. For example, a
-  // column chunk's data pages may include both dictionary-encoded and
-  // plain-encoded data.
-  std::unordered_map<int, std::shared_ptr<DecoderType>> decoders_;
-
-  DecoderType* current_decoder_;
-
-  // Advance to the next data page
-  bool ReadNewPage();
-
-  void ConfigureDictionary(const DictionaryPage* page);
-};
-
-template <>
-inline void TypedRecordReader<ByteArrayType>::ReadValuesDense(int64_t values_to_read) {
-  auto values = ValuesHead<ByteArray>();
-  int64_t num_decoded =
-      current_decoder_->Decode(values, static_cast<int>(values_to_read));
-  DCHECK_EQ(num_decoded, values_to_read);
-
-  auto builder = static_cast<::arrow::BinaryBuilder*>(builder_.get());
-  for (int64_t i = 0; i < num_decoded; i++) {
-    PARQUET_THROW_NOT_OK(
-        builder->Append(values[i].ptr, static_cast<int64_t>(values[i].len)));
-  }
-  ResetValues();
-}
-
-template <>
-inline void TypedRecordReader<FLBAType>::ReadValuesDense(int64_t values_to_read) {
-  auto values = ValuesHead<FLBA>();
-  int64_t num_decoded =
-      current_decoder_->Decode(values, static_cast<int>(values_to_read));
-  DCHECK_EQ(num_decoded, values_to_read);
-
-  auto builder = static_cast<::arrow::FixedSizeBinaryBuilder*>(builder_.get());
-  for (int64_t i = 0; i < num_decoded; i++) {
-    PARQUET_THROW_NOT_OK(builder->Append(values[i].ptr));
-  }
-  ResetValues();
-}
-
-template <>
-inline void TypedRecordReader<ByteArrayType>::ReadValuesSpaced(int64_t values_to_read,
-                                                               int64_t null_count) {
-  uint8_t* valid_bits = valid_bits_->mutable_data();
-  const int64_t valid_bits_offset = values_written_;
-  auto values = ValuesHead<ByteArray>();
-
-  int64_t num_decoded = current_decoder_->DecodeSpaced(
-      values, static_cast<int>(values_to_read), static_cast<int>(null_count), valid_bits,
-      valid_bits_offset);
-  DCHECK_EQ(num_decoded, values_to_read);
-
-  auto builder = static_cast<::arrow::BinaryBuilder*>(builder_.get());
-
-  for (int64_t i = 0; i < num_decoded; i++) {
-    if (::arrow::BitUtil::GetBit(valid_bits, valid_bits_offset + i)) {
-      PARQUET_THROW_NOT_OK(
-          builder->Append(values[i].ptr, static_cast<int64_t>(values[i].len)));
-    } else {
-      PARQUET_THROW_NOT_OK(builder->AppendNull());
-    }
-  }
-  ResetValues();
-}
-
-template <>
-inline void TypedRecordReader<FLBAType>::ReadValuesSpaced(int64_t values_to_read,
-                                                          int64_t null_count) {
-  uint8_t* valid_bits = valid_bits_->mutable_data();
-  const int64_t valid_bits_offset = values_written_;
-  auto values = ValuesHead<FLBA>();
-
-  int64_t num_decoded = current_decoder_->DecodeSpaced(
-      values, static_cast<int>(values_to_read), static_cast<int>(null_count), valid_bits,
-      valid_bits_offset);
-  DCHECK_EQ(num_decoded, values_to_read);
-
-  auto builder = static_cast<::arrow::FixedSizeBinaryBuilder*>(builder_.get());
-  for (int64_t i = 0; i < num_decoded; i++) {
-    if (::arrow::BitUtil::GetBit(valid_bits, valid_bits_offset + i)) {
-      PARQUET_THROW_NOT_OK(builder->Append(values[i].ptr));
-    } else {
-      PARQUET_THROW_NOT_OK(builder->AppendNull());
-    }
-  }
-  ResetValues();
-}
-
-template <typename DType>
-inline void TypedRecordReader<DType>::ConfigureDictionary(const DictionaryPage* page) {
-  int encoding = static_cast<int>(page->encoding());
-  if (page->encoding() == Encoding::PLAIN_DICTIONARY ||
-      page->encoding() == Encoding::PLAIN) {
-    encoding = static_cast<int>(Encoding::RLE_DICTIONARY);
-  }
-
-  auto it = decoders_.find(encoding);
-  if (it != decoders_.end()) {
-    throw ParquetException("Column cannot have more than one dictionary.");
-  }
-
-  if (page->encoding() == Encoding::PLAIN_DICTIONARY ||
-      page->encoding() == Encoding::PLAIN) {
-    PlainDecoder<DType> dictionary(descr_);
-    dictionary.SetData(page->num_values(), page->data(), page->size());
-
-    // The dictionary is fully decoded during DictionaryDecoder::Init, so the
-    // DictionaryPage buffer is no longer required after this step
-    //
-    // TODO(wesm): investigate whether this all-or-nothing decoding of the
-    // dictionary makes sense and whether performance can be improved
-
-    auto decoder = std::make_shared<DictionaryDecoder<DType>>(descr_, pool_);
-    decoder->SetDict(&dictionary);
-    decoders_[encoding] = decoder;
-  } else {
-    ParquetException::NYI("only plain dictionary encoding has been implemented");
-  }
-
-  current_decoder_ = decoders_[encoding].get();
-}
-
-template <typename DType>
-bool TypedRecordReader<DType>::ReadNewPage() {
-  // Loop until we find the next data page.
-  const uint8_t* buffer;
-
-  while (true) {
-    current_page_ = pager_->NextPage();
-    if (!current_page_) {
-      // EOS
-      return false;
-    }
-
-    if (current_page_->type() == PageType::DICTIONARY_PAGE) {
-      ConfigureDictionary(static_cast<const DictionaryPage*>(current_page_.get()));
-      continue;
-    } else if (current_page_->type() == PageType::DATA_PAGE) {
-      const DataPage* page = static_cast<const DataPage*>(current_page_.get());
-
-      // Read a data page.
-      num_buffered_values_ = page->num_values();
-
-      // Have not decoded any values from the data page yet
-      num_decoded_values_ = 0;
-
-      buffer = page->data();
-
-      // If the data page includes repetition and definition levels, we
-      // initialize the level decoder and subtract the encoded level bytes from
-      // the page size to determine the number of bytes in the encoded data.
-      int64_t data_size = page->size();
-
-      // Data page Layout: Repetition Levels - Definition Levels - encoded values.
-      // Levels are encoded as rle or bit-packed.
-      // Init repetition levels
-      if (descr_->max_repetition_level() > 0) {
-        int64_t rep_levels_bytes = repetition_level_decoder_.SetData(
-            page->repetition_level_encoding(), descr_->max_repetition_level(),
-            static_cast<int>(num_buffered_values_), buffer);
-        buffer += rep_levels_bytes;
-        data_size -= rep_levels_bytes;
-      }
-      // TODO figure a way to set max_definition_level_ to 0
-      // if the initial value is invalid
-
-      // Init definition levels
-      if (descr_->max_definition_level() > 0) {
-        int64_t def_levels_bytes = definition_level_decoder_.SetData(
-            page->definition_level_encoding(), descr_->max_definition_level(),
-            static_cast<int>(num_buffered_values_), buffer);
-        buffer += def_levels_bytes;
-        data_size -= def_levels_bytes;
-      }
-
-      // Get a decoder object for this page or create a new decoder if this is the
-      // first page with this encoding.
-      Encoding::type encoding = page->encoding();
-
-      if (IsDictionaryIndexEncoding(encoding)) {
-        encoding = Encoding::RLE_DICTIONARY;
-      }
-
-      auto it = decoders_.find(static_cast<int>(encoding));
-      if (it != decoders_.end()) {
-        if (encoding == Encoding::RLE_DICTIONARY) {
-          DCHECK(current_decoder_->encoding() == Encoding::RLE_DICTIONARY);
-        }
-        current_decoder_ = it->second.get();
-      } else {
-        switch (encoding) {
-          case Encoding::PLAIN: {
-            std::shared_ptr<DecoderType> decoder(new PlainDecoder<DType>(descr_));
-            decoders_[static_cast<int>(encoding)] = decoder;
-            current_decoder_ = decoder.get();
-            break;
-          }
-          case Encoding::RLE_DICTIONARY:
-            throw ParquetException("Dictionary page must be before data page.");
-
-          case Encoding::DELTA_BINARY_PACKED:
-          case Encoding::DELTA_LENGTH_BYTE_ARRAY:
-          case Encoding::DELTA_BYTE_ARRAY:
-            ParquetException::NYI("Unsupported encoding");
-
-          default:
-            throw ParquetException("Unknown encoding type.");
-        }
-      }
-      current_decoder_->SetData(static_cast<int>(num_buffered_values_), buffer,
-                                static_cast<int>(data_size));
-      return true;
-    } else {
-      // We don't know what this page type is. We're allowed to skip non-data
-      // pages.
-      continue;
-    }
-  }
-  return true;
-}
-
-std::shared_ptr<RecordReader> RecordReader::Make(const ColumnDescriptor* descr,
-                                                 MemoryPool* pool) {
-  switch (descr->physical_type()) {
-    case Type::BOOLEAN:
-      return std::shared_ptr<RecordReader>(
-          new RecordReader(new TypedRecordReader<BooleanType>(descr, pool)));
-    case Type::INT32:
-      return std::shared_ptr<RecordReader>(
-          new RecordReader(new TypedRecordReader<Int32Type>(descr, pool)));
-    case Type::INT64:
-      return std::shared_ptr<RecordReader>(
-          new RecordReader(new TypedRecordReader<Int64Type>(descr, pool)));
-    case Type::INT96:
-      return std::shared_ptr<RecordReader>(
-          new RecordReader(new TypedRecordReader<Int96Type>(descr, pool)));
-    case Type::FLOAT:
-      return std::shared_ptr<RecordReader>(
-          new RecordReader(new TypedRecordReader<FloatType>(descr, pool)));
-    case Type::DOUBLE:
-      return std::shared_ptr<RecordReader>(
-          new RecordReader(new TypedRecordReader<DoubleType>(descr, pool)));
-    case Type::BYTE_ARRAY:
-      return std::shared_ptr<RecordReader>(
-          new RecordReader(new TypedRecordReader<ByteArrayType>(descr, pool)));
-    case Type::FIXED_LEN_BYTE_ARRAY:
-      return std::shared_ptr<RecordReader>(
-          new RecordReader(new TypedRecordReader<FLBAType>(descr, pool)));
-    default:
-      DCHECK(false);
-  }
-  // Unreachable code, but supress compiler warning
-  return nullptr;
-}
-
-// ----------------------------------------------------------------------
-// Implement public API
-
-RecordReader::RecordReader(RecordReaderImpl* impl) { impl_.reset(impl); }
-
-RecordReader::~RecordReader() {}
-
-int64_t RecordReader::ReadRecords(int64_t num_records) {
-  return impl_->ReadRecords(num_records);
-}
-
-void RecordReader::Reset() { return impl_->Reset(); }
-
-void RecordReader::Reserve(int64_t num_values) { impl_->Reserve(num_values); }
-
-const int16_t* RecordReader::def_levels() const { return impl_->def_levels(); }
-
-const int16_t* RecordReader::rep_levels() const { return impl_->rep_levels(); }
-
-const uint8_t* RecordReader::values() const { return impl_->values(); }
-
-std::shared_ptr<ResizableBuffer> RecordReader::ReleaseValues() {
-  return impl_->ReleaseValues();
-}
-
-std::shared_ptr<ResizableBuffer> RecordReader::ReleaseIsValid() {
-  return impl_->ReleaseIsValid();
-}
-
-::arrow::ArrayBuilder* RecordReader::builder() { return impl_->builder(); }
-
-int64_t RecordReader::values_written() const { return impl_->values_written(); }
-
-int64_t RecordReader::levels_position() const { return impl_->levels_position(); }
-
-int64_t RecordReader::levels_written() const { return impl_->levels_written(); }
-
-int64_t RecordReader::null_count() const { return impl_->null_count(); }
-
-bool RecordReader::nullable_values() const { return impl_->nullable_values(); }
-
-bool RecordReader::HasMoreData() const { return impl_->HasMoreData(); }
-
-void RecordReader::SetPageReader(std::unique_ptr<PageReader> reader) {
-  impl_->SetPageReader(std::move(reader));
-}
-
-}  // namespace internal
-}  // namespace parquet
diff --git a/src/parquet/arrow/record_reader.h b/src/parquet/arrow/record_reader.h
deleted file mode 100644
index f02bf05..0000000
--- a/src/parquet/arrow/record_reader.h
+++ /dev/null
@@ -1,113 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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.
-
-#ifndef PARQUET_RECORD_READER_H
-#define PARQUET_RECORD_READER_H
-
-#include <cstdint>
-#include <cstring>
-#include <iostream>
-#include <memory>
-#include <unordered_map>
-#include <vector>
-
-#include <arrow/buffer.h>
-#include <arrow/builder.h>
-#include <arrow/memory_pool.h>
-#include <arrow/util/bit-util.h>
-
-#include "parquet/column_reader.h"
-#include "parquet/schema.h"
-#include "parquet/util/visibility.h"
-
-namespace parquet {
-namespace internal {
-
-/// \brief Stateful column reader that delimits semantic records for both flat
-/// and nested columns
-///
-/// \note API EXPERIMENTAL
-/// \since 1.3.0
-class RecordReader {
- public:
-  // So that we can create subclasses
-  class RecordReaderImpl;
-
-  static std::shared_ptr<RecordReader> Make(
-      const ColumnDescriptor* descr,
-      ::arrow::MemoryPool* pool = ::arrow::default_memory_pool());
-
-  virtual ~RecordReader();
-
-  /// \brief Decoded definition levels
-  const int16_t* def_levels() const;
-
-  /// \brief Decoded repetition levels
-  const int16_t* rep_levels() const;
-
-  /// \brief Decoded values, including nulls, if any
-  const uint8_t* values() const;
-
-  /// \brief Attempt to read indicated number of records from column chunk
-  /// \return number of records read
-  int64_t ReadRecords(int64_t num_records);
-
-  /// \brief Pre-allocate space for data. Results in better flat read performance
-  void Reserve(int64_t num_values);
-
-  /// \brief Clear consumed values and repetition/definition levels as the
-  /// result of calling ReadRecords
-  void Reset();
-
-  std::shared_ptr<ResizableBuffer> ReleaseValues();
-  std::shared_ptr<ResizableBuffer> ReleaseIsValid();
-  ::arrow::ArrayBuilder* builder();
-
-  /// \brief Number of values written including nulls (if any)
-  int64_t values_written() const;
-
-  /// \brief Number of definition / repetition levels (from those that have
-  /// been decoded) that have been consumed inside the reader.
-  int64_t levels_position() const;
-
-  /// \brief Number of definition / repetition levels that have been written
-  /// internally in the reader
-  int64_t levels_written() const;
-
-  /// \brief Number of nulls in the leaf
-  int64_t null_count() const;
-
-  /// \brief True if the leaf values are nullable
-  bool nullable_values() const;
-
-  /// \brief Return true if the record reader has more internal data yet to
-  /// process
-  bool HasMoreData() const;
-
-  /// \brief Advance record reader to the next row group
-  /// \param[in] reader obtained from RowGroupReader::GetColumnPageReader
-  void SetPageReader(std::unique_ptr<PageReader> reader);
-
- private:
-  std::unique_ptr<RecordReaderImpl> impl_;
-  explicit RecordReader(RecordReaderImpl* impl);
-};
-
-}  // namespace internal
-}  // namespace parquet
-
-#endif  // PARQUET_RECORD_READER_H
diff --git a/src/parquet/arrow/schema.cc b/src/parquet/arrow/schema.cc
deleted file mode 100644
index 48b1181..0000000
--- a/src/parquet/arrow/schema.cc
+++ /dev/null
@@ -1,704 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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.
-
-#include "parquet/arrow/schema.h"
-
-#include <string>
-#include <unordered_set>
-#include <vector>
-
-#include "parquet/api/schema.h"
-#include "parquet/util/schema-util.h"
-
-#include "arrow/api.h"
-#include "arrow/util/logging.h"
-
-using arrow::Field;
-using arrow::Status;
-using arrow::TypePtr;
-
-using ArrowType = arrow::Type;
-
-using parquet::Repetition;
-using parquet::schema::GroupNode;
-using parquet::schema::Node;
-using parquet::schema::NodePtr;
-using parquet::schema::PrimitiveNode;
-
-using ParquetType = parquet::Type;
-using parquet::LogicalType;
-
-namespace parquet {
-
-namespace arrow {
-
-const auto TIMESTAMP_MS = ::arrow::timestamp(::arrow::TimeUnit::MILLI);
-const auto TIMESTAMP_US = ::arrow::timestamp(::arrow::TimeUnit::MICRO);
-const auto TIMESTAMP_NS = ::arrow::timestamp(::arrow::TimeUnit::NANO);
-
-TypePtr MakeDecimal128Type(const PrimitiveNode& node) {
-  const auto& metadata = node.decimal_metadata();
-  return ::arrow::decimal(metadata.precision, metadata.scale);
-}
-
-static Status FromByteArray(const PrimitiveNode& node, TypePtr* out) {
-  switch (node.logical_type()) {
-    case LogicalType::UTF8:
-      *out = ::arrow::utf8();
-      break;
-    case LogicalType::DECIMAL:
-      *out = MakeDecimal128Type(node);
-      break;
-    default:
-      // BINARY
-      *out = ::arrow::binary();
-      break;
-  }
-  return Status::OK();
-}
-
-static Status FromFLBA(const PrimitiveNode& node, TypePtr* out) {
-  switch (node.logical_type()) {
-    case LogicalType::NONE:
-      *out = ::arrow::fixed_size_binary(node.type_length());
-      break;
-    case LogicalType::DECIMAL:
-      *out = MakeDecimal128Type(node);
-      break;
-    default:
-      std::stringstream ss;
-      ss << "Unhandled logical type " << LogicalTypeToString(node.logical_type())
-         << " for fixed-length binary array";
-      return Status::NotImplemented(ss.str());
-  }
-
-  return Status::OK();
-}
-
-static Status FromInt32(const PrimitiveNode& node, TypePtr* out) {
-  switch (node.logical_type()) {
-    case LogicalType::NONE:
-      *out = ::arrow::int32();
-      break;
-    case LogicalType::UINT_8:
-      *out = ::arrow::uint8();
-      break;
-    case LogicalType::INT_8:
-      *out = ::arrow::int8();
-      break;
-    case LogicalType::UINT_16:
-      *out = ::arrow::uint16();
-      break;
-    case LogicalType::INT_16:
-      *out = ::arrow::int16();
-      break;
-    case LogicalType::INT_32:
-      *out = ::arrow::int32();
-      break;
-    case LogicalType::UINT_32:
-      *out = ::arrow::uint32();
-      break;
-    case LogicalType::DATE:
-      *out = ::arrow::date32();
-      break;
-    case LogicalType::TIME_MILLIS:
-      *out = ::arrow::time32(::arrow::TimeUnit::MILLI);
-      break;
-    case LogicalType::DECIMAL:
-      *out = MakeDecimal128Type(node);
-      break;
-    default:
-      std::stringstream ss;
-      ss << "Unhandled logical type " << LogicalTypeToString(node.logical_type())
-         << " for INT32";
-      return Status::NotImplemented(ss.str());
-  }
-  return Status::OK();
-}
-
-static Status FromInt64(const PrimitiveNode& node, TypePtr* out) {
-  switch (node.logical_type()) {
-    case LogicalType::NONE:
-      *out = ::arrow::int64();
-      break;
-    case LogicalType::INT_64:
-      *out = ::arrow::int64();
-      break;
-    case LogicalType::UINT_64:
-      *out = ::arrow::uint64();
-      break;
-    case LogicalType::DECIMAL:
-      *out = MakeDecimal128Type(node);
-      break;
-    case LogicalType::TIMESTAMP_MILLIS:
-      *out = TIMESTAMP_MS;
-      break;
-    case LogicalType::TIMESTAMP_MICROS:
-      *out = TIMESTAMP_US;
-      break;
-    case LogicalType::TIME_MICROS:
-      *out = ::arrow::time64(::arrow::TimeUnit::MICRO);
-      break;
-    default:
-      std::stringstream ss;
-      ss << "Unhandled logical type " << LogicalTypeToString(node.logical_type())
-         << " for INT64";
-      return Status::NotImplemented(ss.str());
-  }
-  return Status::OK();
-}
-
-Status FromPrimitive(const PrimitiveNode& primitive, TypePtr* out) {
-  if (primitive.logical_type() == LogicalType::NA) {
-    *out = ::arrow::null();
-    return Status::OK();
-  }
-
-  switch (primitive.physical_type()) {
-    case ParquetType::BOOLEAN:
-      *out = ::arrow::boolean();
-      break;
-    case ParquetType::INT32:
-      RETURN_NOT_OK(FromInt32(primitive, out));
-      break;
-    case ParquetType::INT64:
-      RETURN_NOT_OK(FromInt64(primitive, out));
-      break;
-    case ParquetType::INT96:
-      *out = TIMESTAMP_NS;
-      break;
-    case ParquetType::FLOAT:
-      *out = ::arrow::float32();
-      break;
-    case ParquetType::DOUBLE:
-      *out = ::arrow::float64();
-      break;
-    case ParquetType::BYTE_ARRAY:
-      RETURN_NOT_OK(FromByteArray(primitive, out));
-      break;
-    case ParquetType::FIXED_LEN_BYTE_ARRAY:
-      RETURN_NOT_OK(FromFLBA(primitive, out));
-      break;
-  }
-  return Status::OK();
-}
-
-// Forward declaration
-Status NodeToFieldInternal(const Node& node,
-                           const std::unordered_set<const Node*>* included_leaf_nodes,
-                           std::shared_ptr<Field>* out);
-
-/*
- * Auxilary function to test if a parquet schema node is a leaf node
- * that should be included in a resulting arrow schema
- */
-inline bool IsIncludedLeaf(const Node& node,
-                           const std::unordered_set<const Node*>* included_leaf_nodes) {
-  if (included_leaf_nodes == nullptr) {
-    return true;
-  }
-  auto search = included_leaf_nodes->find(&node);
-  return (search != included_leaf_nodes->end());
-}
-
-Status StructFromGroup(const GroupNode& group,
-                       const std::unordered_set<const Node*>* included_leaf_nodes,
-                       TypePtr* out) {
-  std::vector<std::shared_ptr<Field>> fields;
-  std::shared_ptr<Field> field;
-
-  *out = nullptr;
-
-  for (int i = 0; i < group.field_count(); i++) {
-    RETURN_NOT_OK(NodeToFieldInternal(*group.field(i), included_leaf_nodes, &field));
-    if (field != nullptr) {
-      fields.push_back(field);
-    }
-  }
-  if (fields.size() > 0) {
-    *out = std::make_shared<::arrow::StructType>(fields);
-  }
-  return Status::OK();
-}
-
-Status NodeToList(const GroupNode& group,
-                  const std::unordered_set<const Node*>* included_leaf_nodes,
-                  TypePtr* out) {
-  *out = nullptr;
-  if (group.field_count() == 1) {
-    // This attempts to resolve the preferred 3-level list encoding.
-    const Node& list_node = *group.field(0);
-    if (list_node.is_group() && list_node.is_repeated()) {
-      const auto& list_group = static_cast<const GroupNode&>(list_node);
-      // Special case mentioned in the format spec:
-      //   If the name is array or ends in _tuple, this should be a list of struct
-      //   even for single child elements.
-      if (list_group.field_count() == 1 && !HasStructListName(list_group)) {
-        // List of primitive type
-        std::shared_ptr<Field> item_field;
-        RETURN_NOT_OK(
-            NodeToFieldInternal(*list_group.field(0), included_leaf_nodes, &item_field));
-
-        if (item_field != nullptr) {
-          *out = ::arrow::list(item_field);
-        }
-      } else {
-        // List of struct
-        std::shared_ptr<::arrow::DataType> inner_type;
-        RETURN_NOT_OK(StructFromGroup(list_group, included_leaf_nodes, &inner_type));
-        if (inner_type != nullptr) {
-          auto item_field = std::make_shared<Field>(list_node.name(), inner_type, false);
-          *out = ::arrow::list(item_field);
-        }
-      }
-    } else if (list_node.is_repeated()) {
-      // repeated primitive node
-      std::shared_ptr<::arrow::DataType> inner_type;
-      if (IsIncludedLeaf(static_cast<const Node&>(list_node), included_leaf_nodes)) {
-        RETURN_NOT_OK(
-            FromPrimitive(static_cast<const PrimitiveNode&>(list_node), &inner_type));
-        auto item_field = std::make_shared<Field>(list_node.name(), inner_type, false);
-        *out = ::arrow::list(item_field);
-      }
-    } else {
-      return Status::NotImplemented(
-          "Non-repeated groups in a LIST-annotated group are not supported.");
-    }
-  } else {
-    return Status::NotImplemented(
-        "Only LIST-annotated groups with a single child can be handled.");
-  }
-  return Status::OK();
-}
-
-Status NodeToField(const Node& node, std::shared_ptr<Field>* out) {
-  return NodeToFieldInternal(node, nullptr, out);
-}
-
-Status NodeToFieldInternal(const Node& node,
-                           const std::unordered_set<const Node*>* included_leaf_nodes,
-                           std::shared_ptr<Field>* out) {
-  std::shared_ptr<::arrow::DataType> type = nullptr;
-  bool nullable = !node.is_required();
-
-  *out = nullptr;
-
-  if (node.is_repeated()) {
-    // 1-level LIST encoding fields are required
-    std::shared_ptr<::arrow::DataType> inner_type;
-    if (node.is_group()) {
-      RETURN_NOT_OK(StructFromGroup(static_cast<const GroupNode&>(node),
-                                    included_leaf_nodes, &inner_type));
-    } else if (IsIncludedLeaf(node, included_leaf_nodes)) {
-      RETURN_NOT_OK(FromPrimitive(static_cast<const PrimitiveNode&>(node), &inner_type));
-    }
-    if (inner_type != nullptr) {
-      auto item_field = std::make_shared<Field>(node.name(), inner_type, false);
-      type = ::arrow::list(item_field);
-      nullable = false;
-    }
-  } else if (node.is_group()) {
-    const auto& group = static_cast<const GroupNode&>(node);
-    if (node.logical_type() == LogicalType::LIST) {
-      RETURN_NOT_OK(NodeToList(group, included_leaf_nodes, &type));
-    } else {
-      RETURN_NOT_OK(StructFromGroup(group, included_leaf_nodes, &type));
-    }
-  } else {
-    // Primitive (leaf) node
-    if (IsIncludedLeaf(node, included_leaf_nodes)) {
-      RETURN_NOT_OK(FromPrimitive(static_cast<const PrimitiveNode&>(node), &type));
-    }
-  }
-  if (type != nullptr) {
-    *out = std::make_shared<Field>(node.name(), type, nullable);
-  }
-  return Status::OK();
-}
-
-Status FromParquetSchema(
-    const SchemaDescriptor* parquet_schema,
-    const std::shared_ptr<const KeyValueMetadata>& key_value_metadata,
-    std::shared_ptr<::arrow::Schema>* out) {
-  const GroupNode& schema_node = *parquet_schema->group_node();
-
-  int num_fields = static_cast<int>(schema_node.field_count());
-  std::vector<std::shared_ptr<Field>> fields(num_fields);
-  for (int i = 0; i < num_fields; i++) {
-    RETURN_NOT_OK(NodeToField(*schema_node.field(i), &fields[i]));
-  }
-
-  *out = std::make_shared<::arrow::Schema>(fields, key_value_metadata);
-  return Status::OK();
-}
-
-Status FromParquetSchema(
-    const SchemaDescriptor* parquet_schema, const std::vector<int>& column_indices,
-    const std::shared_ptr<const KeyValueMetadata>& key_value_metadata,
-    std::shared_ptr<::arrow::Schema>* out) {
-  // TODO(wesm): Consider adding an arrow::Schema name attribute, which comes
-  // from the root Parquet node
-
-  // Put the right leaf nodes in an unordered set
-  // Index in column_indices should be unique, duplicate indices are merged into one and
-  // ordering by its first appearing.
-  int num_columns = static_cast<int>(column_indices.size());
-  std::unordered_set<const Node*> top_nodes;  // to deduplicate the top nodes
-  std::vector<const Node*> base_nodes;        // to keep the ordering
-  std::unordered_set<const Node*> included_leaf_nodes(num_columns);
-  for (int i = 0; i < num_columns; i++) {
-    const ColumnDescriptor* column_desc = parquet_schema->Column(column_indices[i]);
-    included_leaf_nodes.insert(column_desc->schema_node().get());
-    const Node* column_root = parquet_schema->GetColumnRoot(column_indices[i]);
-    auto insertion = top_nodes.insert(column_root);
-    if (insertion.second) {
-      base_nodes.push_back(column_root);
-    }
-  }
-
-  std::vector<std::shared_ptr<Field>> fields;
-  std::shared_ptr<Field> field;
-  for (auto node : base_nodes) {
-    RETURN_NOT_OK(NodeToFieldInternal(*node, &included_leaf_nodes, &field));
-    if (field != nullptr) {
-      fields.push_back(field);
-    }
-  }
-
-  *out = std::make_shared<::arrow::Schema>(fields, key_value_metadata);
-  return Status::OK();
-}
-
-Status FromParquetSchema(const SchemaDescriptor* parquet_schema,
-                         const std::vector<int>& column_indices,
-                         std::shared_ptr<::arrow::Schema>* out) {
-  return FromParquetSchema(parquet_schema, column_indices, nullptr, out);
-}
-
-Status FromParquetSchema(const SchemaDescriptor* parquet_schema,
-                         std::shared_ptr<::arrow::Schema>* out) {
-  return FromParquetSchema(parquet_schema, nullptr, out);
-}
-
-Status ListToNode(const std::shared_ptr<::arrow::ListType>& type, const std::string& name,
-                  bool nullable, const WriterProperties& properties,
-                  const ArrowWriterProperties& arrow_properties, NodePtr* out) {
-  Repetition::type repetition = nullable ? Repetition::OPTIONAL : Repetition::REQUIRED;
-
-  NodePtr element;
-  RETURN_NOT_OK(FieldToNode(type->value_field(), properties, arrow_properties, &element));
-
-  NodePtr list = GroupNode::Make("list", Repetition::REPEATED, {element});
-  *out = GroupNode::Make(name, repetition, {list}, LogicalType::LIST);
-  return Status::OK();
-}
-
-Status StructToNode(const std::shared_ptr<::arrow::StructType>& type,
-                    const std::string& name, bool nullable,
-                    const WriterProperties& properties,
-                    const ArrowWriterProperties& arrow_properties, NodePtr* out) {
-  Repetition::type repetition = nullable ? Repetition::OPTIONAL : Repetition::REQUIRED;
-
-  std::vector<NodePtr> children(type->num_children());
-  for (int i = 0; i < type->num_children(); i++) {
-    RETURN_NOT_OK(
-        FieldToNode(type->child(i), properties, arrow_properties, &children[i]));
-  }
-
-  *out = GroupNode::Make(name, repetition, children);
-  return Status::OK();
-}
-
-static Status GetTimestampMetadata(const ::arrow::TimestampType& type,
-                                   const ArrowWriterProperties& properties,
-                                   ParquetType::type* physical_type,
-                                   LogicalType::type* logical_type) {
-  auto unit = type.unit();
-  *physical_type = ParquetType::INT64;
-
-  if (properties.coerce_timestamps_enabled()) {
-    auto coerce_unit = properties.coerce_timestamps_unit();
-    if (coerce_unit == ::arrow::TimeUnit::MILLI) {
-      *logical_type = LogicalType::TIMESTAMP_MILLIS;
-    } else if (coerce_unit == ::arrow::TimeUnit::MICRO) {
-      *logical_type = LogicalType::TIMESTAMP_MICROS;
-    } else {
-      return Status::NotImplemented(
-          "Can only coerce Arrow timestamps to milliseconds"
-          " or microseconds");
-    }
-    return Status::OK();
-  }
-
-  if (unit == ::arrow::TimeUnit::MILLI) {
-    *logical_type = LogicalType::TIMESTAMP_MILLIS;
-  } else if (unit == ::arrow::TimeUnit::MICRO) {
-    *logical_type = LogicalType::TIMESTAMP_MICROS;
-  } else if (unit == ::arrow::TimeUnit::NANO) {
-    if (properties.support_deprecated_int96_timestamps()) {
-      *physical_type = ParquetType::INT96;
-      // No corresponding logical type
-    } else {
-      *logical_type = LogicalType::TIMESTAMP_MICROS;
-    }
-  } else {
-    return Status::NotImplemented(
-        "Only MILLI, MICRO, and NANOS units supported for Arrow timestamps with "
-        "Parquet.");
-  }
-  return Status::OK();
-}
-
-Status FieldToNode(const std::shared_ptr<Field>& field,
-                   const WriterProperties& properties,
-                   const ArrowWriterProperties& arrow_properties, NodePtr* out) {
-  LogicalType::type logical_type = LogicalType::NONE;
-  ParquetType::type type;
-  Repetition::type repetition =
-      field->nullable() ? Repetition::OPTIONAL : Repetition::REQUIRED;
-
-  int length = -1;
-  int precision = -1;
-  int scale = -1;
-
-  switch (field->type()->id()) {
-    case ArrowType::NA:
-      type = ParquetType::INT32;
-      logical_type = LogicalType::NA;
-      break;
-    case ArrowType::BOOL:
-      type = ParquetType::BOOLEAN;
-      break;
-    case ArrowType::UINT8:
-      type = ParquetType::INT32;
-      logical_type = LogicalType::UINT_8;
-      break;
-    case ArrowType::INT8:
-      type = ParquetType::INT32;
-      logical_type = LogicalType::INT_8;
-      break;
-    case ArrowType::UINT16:
-      type = ParquetType::INT32;
-      logical_type = LogicalType::UINT_16;
-      break;
-    case ArrowType::INT16:
-      type = ParquetType::INT32;
-      logical_type = LogicalType::INT_16;
-      break;
-    case ArrowType::UINT32:
-      if (properties.version() == ::parquet::ParquetVersion::PARQUET_1_0) {
-        type = ParquetType::INT64;
-      } else {
-        type = ParquetType::INT32;
-        logical_type = LogicalType::UINT_32;
-      }
-      break;
-    case ArrowType::INT32:
-      type = ParquetType::INT32;
-      break;
-    case ArrowType::UINT64:
-      type = ParquetType::INT64;
-      logical_type = LogicalType::UINT_64;
-      break;
-    case ArrowType::INT64:
-      type = ParquetType::INT64;
-      break;
-    case ArrowType::FLOAT:
-      type = ParquetType::FLOAT;
-      break;
-    case ArrowType::DOUBLE:
-      type = ParquetType::DOUBLE;
-      break;
-    case ArrowType::STRING:
-      type = ParquetType::BYTE_ARRAY;
-      logical_type = LogicalType::UTF8;
-      break;
-    case ArrowType::BINARY:
-      type = ParquetType::BYTE_ARRAY;
-      break;
-    case ArrowType::FIXED_SIZE_BINARY: {
-      type = ParquetType::FIXED_LEN_BYTE_ARRAY;
-      const auto& fixed_size_binary_type =
-          static_cast<const ::arrow::FixedSizeBinaryType&>(*field->type());
-      length = fixed_size_binary_type.byte_width();
-    } break;
-    case ArrowType::DECIMAL: {
-      type = ParquetType::FIXED_LEN_BYTE_ARRAY;
-      logical_type = LogicalType::DECIMAL;
-      const auto& decimal_type =
-          static_cast<const ::arrow::Decimal128Type&>(*field->type());
-      precision = decimal_type.precision();
-      scale = decimal_type.scale();
-      length = DecimalSize(precision);
-    } break;
-    case ArrowType::DATE32:
-      type = ParquetType::INT32;
-      logical_type = LogicalType::DATE;
-      break;
-    case ArrowType::DATE64:
-      type = ParquetType::INT32;
-      logical_type = LogicalType::DATE;
-      break;
-    case ArrowType::TIMESTAMP:
-      RETURN_NOT_OK(
-          GetTimestampMetadata(static_cast<::arrow::TimestampType&>(*field->type()),
-                               arrow_properties, &type, &logical_type));
-      break;
-    case ArrowType::TIME32:
-      type = ParquetType::INT32;
-      logical_type = LogicalType::TIME_MILLIS;
-      break;
-    case ArrowType::TIME64: {
-      auto time_type = static_cast<::arrow::Time64Type*>(field->type().get());
-      if (time_type->unit() == ::arrow::TimeUnit::NANO) {
-        return Status::NotImplemented("Nanosecond time not supported in Parquet.");
-      }
-      type = ParquetType::INT64;
-      logical_type = LogicalType::TIME_MICROS;
-    } break;
-    case ArrowType::STRUCT: {
-      auto struct_type = std::static_pointer_cast<::arrow::StructType>(field->type());
-      return StructToNode(struct_type, field->name(), field->nullable(), properties,
-                          arrow_properties, out);
-    }
-    case ArrowType::LIST: {
-      auto list_type = std::static_pointer_cast<::arrow::ListType>(field->type());
-      return ListToNode(list_type, field->name(), field->nullable(), properties,
-                        arrow_properties, out);
-    }
-    case ArrowType::DICTIONARY: {
-      // Parquet has no Dictionary type, dictionary-encoded is handled on
-      // the encoding, not the schema level.
-      const ::arrow::DictionaryType& dict_type =
-          static_cast<const ::arrow::DictionaryType&>(*field->type());
-      std::shared_ptr<::arrow::Field> unpacked_field =
-          ::arrow::field(field->name(), dict_type.dictionary()->type(), field->nullable(),
-                         field->metadata());
-      return FieldToNode(unpacked_field, properties, arrow_properties, out);
-    }
-    default: {
-      // TODO: DENSE_UNION, SPARE_UNION, JSON_SCALAR, DECIMAL_TEXT, VARCHAR
-      std::stringstream ss;
-      ss << "Unhandled type for Arrow to Parquet schema conversion: ";
-      ss << field->type()->ToString();
-      return Status::NotImplemented(ss.str());
-    }
-  }
-  PARQUET_CATCH_NOT_OK(*out =
-                           PrimitiveNode::Make(field->name(), repetition, type,
-                                               logical_type, length, precision, scale));
-  return Status::OK();
-}
-
-Status ToParquetSchema(const ::arrow::Schema* arrow_schema,
-                       const WriterProperties& properties,
-                       const ArrowWriterProperties& arrow_properties,
-                       std::shared_ptr<SchemaDescriptor>* out) {
-  std::vector<NodePtr> nodes(arrow_schema->num_fields());
-  for (int i = 0; i < arrow_schema->num_fields(); i++) {
-    RETURN_NOT_OK(
-        FieldToNode(arrow_schema->field(i), properties, arrow_properties, &nodes[i]));
-  }
-
-  NodePtr schema = GroupNode::Make("schema", Repetition::REQUIRED, nodes);
-  *out = std::make_shared<::parquet::SchemaDescriptor>();
-  PARQUET_CATCH_NOT_OK((*out)->Init(schema));
-
-  return Status::OK();
-}
-
-Status ToParquetSchema(const ::arrow::Schema* arrow_schema,
-                       const WriterProperties& properties,
-                       std::shared_ptr<SchemaDescriptor>* out) {
-  return ToParquetSchema(arrow_schema, properties, *default_arrow_writer_properties(),
-                         out);
-}
-
-/// \brief Compute the number of bytes required to represent a decimal of a
-/// given precision. Taken from the Apache Impala codebase. The comments next
-/// to the return values are the maximum value that can be represented in 2's
-/// complement with the returned number of bytes.
-int32_t DecimalSize(int32_t precision) {
-  DCHECK_GE(precision, 1) << "decimal precision must be greater than or equal to 1, got "
-                          << precision;
-  DCHECK_LE(precision, 38) << "decimal precision must be less than or equal to 38, got "
-                           << precision;
-
-  switch (precision) {
-    case 1:
-    case 2:
-      return 1;  // 127
-    case 3:
-    case 4:
-      return 2;  // 32,767
-    case 5:
-    case 6:
-      return 3;  // 8,388,607
-    case 7:
-    case 8:
-    case 9:
-      return 4;  // 2,147,483,427
-    case 10:
-    case 11:
-      return 5;  // 549,755,813,887
-    case 12:
-    case 13:
-    case 14:
-      return 6;  // 140,737,488,355,327
-    case 15:
-    case 16:
-      return 7;  // 36,028,797,018,963,967
-    case 17:
-    case 18:
-      return 8;  // 9,223,372,036,854,775,807
-    case 19:
-    case 20:
-    case 21:
-      return 9;  // 2,361,183,241,434,822,606,847
-    case 22:
-    case 23:
-      return 10;  // 604,462,909,807,314,587,353,087
-    case 24:
-    case 25:
-    case 26:
-      return 11;  // 154,742,504,910,672,534,362,390,527
-    case 27:
-    case 28:
-      return 12;  // 39,614,081,257,132,168,796,771,975,167
-    case 29:
-    case 30:
-    case 31:
-      return 13;  // 10,141,204,801,825,835,211,973,625,643,007
-    case 32:
-    case 33:
-      return 14;  // 2,596,148,429,267,413,814,265,248,164,610,047
-    case 34:
-    case 35:
-      return 15;  // 664,613,997,892,457,936,451,903,530,140,172,287
-    case 36:
-    case 37:
-    case 38:
-      return 16;  // 170,141,183,460,469,231,731,687,303,715,884,105,727
-    default:
-      break;
-  }
-  DCHECK(false);
-  return -1;
-}
-
-}  // namespace arrow
-}  // namespace parquet
diff --git a/src/parquet/arrow/schema.h b/src/parquet/arrow/schema.h
deleted file mode 100644
index 3b212da..0000000
--- a/src/parquet/arrow/schema.h
+++ /dev/null
@@ -1,94 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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.
-
-#ifndef PARQUET_ARROW_SCHEMA_H
-#define PARQUET_ARROW_SCHEMA_H
-
-#include <memory>
-#include <vector>
-
-#include "arrow/api.h"
-
-#include "parquet/api/schema.h"
-#include "parquet/api/writer.h"
-#include "parquet/arrow/writer.h"
-
-namespace arrow {
-
-class Status;
-
-}  // namespace arrow
-
-namespace parquet {
-
-namespace arrow {
-
-PARQUET_EXPORT
-::arrow::Status NodeToField(const schema::Node& node,
-                            std::shared_ptr<::arrow::Field>* out);
-
-/// Convert parquet schema to arrow schema with selected indices
-/// \param parquet_schema to be converted
-/// \param column_indices indices of leaf nodes in parquet schema tree. Appearing ordering
-///                       matters for the converted schema. Repeated indices are ignored
-///                       except for the first one
-/// \param key_value_metadata optional metadata, can be nullptr
-/// \param out the corresponding arrow schema
-/// \return Status::OK() on a successful conversion.
-PARQUET_EXPORT
-::arrow::Status FromParquetSchema(
-    const SchemaDescriptor* parquet_schema, const std::vector<int>& column_indices,
-    const std::shared_ptr<const KeyValueMetadata>& key_value_metadata,
-    std::shared_ptr<::arrow::Schema>* out);
-
-// Without indices
-PARQUET_EXPORT
-::arrow::Status FromParquetSchema(
-    const SchemaDescriptor* parquet_schema,
-    const std::shared_ptr<const KeyValueMetadata>& key_value_metadata,
-    std::shared_ptr<::arrow::Schema>* out);
-
-// Without metadata
-::arrow::Status PARQUET_EXPORT FromParquetSchema(const SchemaDescriptor* parquet_schema,
-                                                 const std::vector<int>& column_indices,
-                                                 std::shared_ptr<::arrow::Schema>* out);
-
-// Without metadata or indices
-::arrow::Status PARQUET_EXPORT FromParquetSchema(const SchemaDescriptor* parquet_schema,
-                                                 std::shared_ptr<::arrow::Schema>* out);
-
-::arrow::Status PARQUET_EXPORT FieldToNode(const std::shared_ptr<::arrow::Field>& field,
-                                           const WriterProperties& properties,
-                                           const ArrowWriterProperties& arrow_properties,
-                                           schema::NodePtr* out);
-
-::arrow::Status PARQUET_EXPORT
-ToParquetSchema(const ::arrow::Schema* arrow_schema, const WriterProperties& properties,
-                const ArrowWriterProperties& arrow_properties,
-                std::shared_ptr<SchemaDescriptor>* out);
-
-::arrow::Status PARQUET_EXPORT ToParquetSchema(const ::arrow::Schema* arrow_schema,
-                                               const WriterProperties& properties,
-                                               std::shared_ptr<SchemaDescriptor>* out);
-
-int32_t DecimalSize(int32_t precision);
-
-}  // namespace arrow
-
-}  // namespace parquet
-
-#endif  // PARQUET_ARROW_SCHEMA_H
diff --git a/src/parquet/arrow/test-util.h b/src/parquet/arrow/test-util.h
deleted file mode 100644
index 631bb71..0000000
--- a/src/parquet/arrow/test-util.h
+++ /dev/null
@@ -1,525 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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.
-
-#include <limits>
-#include <string>
-#include <vector>
-
-#include "arrow/api.h"
-#include "arrow/test-util.h"
-#include "arrow/type_traits.h"
-#include "arrow/util/decimal.h"
-
-#include "parquet/arrow/record_reader.h"
-
-namespace arrow {
-// PARQUET-1382: backwards-compatible shim for arrow::test namespace
-namespace test {}
-
-using namespace ::arrow::test;  // NOLINT
-
-}  // namespace arrow
-
-namespace parquet {
-
-using internal::RecordReader;
-
-namespace arrow {
-
-using ::arrow::Array;
-using ::arrow::Status;
-
-template <int32_t PRECISION>
-struct DecimalWithPrecisionAndScale {
-  static_assert(PRECISION >= 1 && PRECISION <= 38, "Invalid precision value");
-
-  using type = ::arrow::Decimal128Type;
-  static constexpr ::arrow::Type::type type_id = ::arrow::Decimal128Type::type_id;
-  static constexpr int32_t precision = PRECISION;
-  static constexpr int32_t scale = PRECISION - 1;
-};
-
-template <typename ArrowType>
-using is_arrow_float = std::is_floating_point<typename ArrowType::c_type>;
-
-template <typename ArrowType>
-using is_arrow_int = std::is_integral<typename ArrowType::c_type>;
-
-template <typename ArrowType>
-using is_arrow_date = std::is_same<ArrowType, ::arrow::Date64Type>;
-
-template <typename ArrowType>
-using is_arrow_string = std::is_same<ArrowType, ::arrow::StringType>;
-
-template <typename ArrowType>
-using is_arrow_binary = std::is_same<ArrowType, ::arrow::BinaryType>;
-
-template <typename ArrowType>
-using is_arrow_fixed_size_binary = std::is_same<ArrowType, ::arrow::FixedSizeBinaryType>;
-
-template <typename ArrowType>
-using is_arrow_bool = std::is_same<ArrowType, ::arrow::BooleanType>;
-
-template <class ArrowType>
-typename std::enable_if<is_arrow_float<ArrowType>::value, Status>::type NonNullArray(
-    size_t size, std::shared_ptr<Array>* out) {
-  using c_type = typename ArrowType::c_type;
-  std::vector<c_type> values;
-  ::arrow::random_real(size, 0, static_cast<c_type>(0), static_cast<c_type>(1), &values);
-  ::arrow::NumericBuilder<ArrowType> builder;
-  RETURN_NOT_OK(builder.AppendValues(values.data(), values.size()));
-  return builder.Finish(out);
-}
-
-template <class ArrowType>
-typename std::enable_if<
-    is_arrow_int<ArrowType>::value && !is_arrow_date<ArrowType>::value, Status>::type
-NonNullArray(size_t size, std::shared_ptr<Array>* out) {
-  std::vector<typename ArrowType::c_type> values;
-  ::arrow::randint(size, 0, 64, &values);
-
-  // Passing data type so this will work with TimestampType too
-  ::arrow::NumericBuilder<ArrowType> builder(std::make_shared<ArrowType>(),
-                                             ::arrow::default_memory_pool());
-  RETURN_NOT_OK(builder.AppendValues(values.data(), values.size()));
-  return builder.Finish(out);
-}
-
-template <class ArrowType>
-typename std::enable_if<is_arrow_date<ArrowType>::value, Status>::type NonNullArray(
-    size_t size, std::shared_ptr<Array>* out) {
-  std::vector<typename ArrowType::c_type> values;
-  ::arrow::randint(size, 0, 64, &values);
-  for (size_t i = 0; i < size; i++) {
-    values[i] *= 86400000;
-  }
-
-  // Passing data type so this will work with TimestampType too
-  ::arrow::NumericBuilder<ArrowType> builder(std::make_shared<ArrowType>(),
-                                             ::arrow::default_memory_pool());
-  builder.AppendValues(values.data(), values.size());
-  return builder.Finish(out);
-}
-
-template <class ArrowType>
-typename std::enable_if<
-    is_arrow_string<ArrowType>::value || is_arrow_binary<ArrowType>::value, Status>::type
-NonNullArray(size_t size, std::shared_ptr<Array>* out) {
-  using BuilderType = typename ::arrow::TypeTraits<ArrowType>::BuilderType;
-  BuilderType builder;
-  for (size_t i = 0; i < size; i++) {
-    RETURN_NOT_OK(builder.Append("test-string"));
-  }
-  return builder.Finish(out);
-}
-
-template <typename ArrowType>
-typename std::enable_if<is_arrow_fixed_size_binary<ArrowType>::value, Status>::type
-NonNullArray(size_t size, std::shared_ptr<Array>* out) {
-  using BuilderType = typename ::arrow::TypeTraits<ArrowType>::BuilderType;
-  // set byte_width to the length of "fixed": 5
-  // todo: find a way to generate test data with more diversity.
-  BuilderType builder(::arrow::fixed_size_binary(5));
-  for (size_t i = 0; i < size; i++) {
-    RETURN_NOT_OK(builder.Append("fixed"));
-  }
-  return builder.Finish(out);
-}
-
-static inline void random_decimals(int64_t n, uint32_t seed, int32_t precision,
-                                   uint8_t* out) {
-  std::mt19937 gen(seed);
-  std::uniform_int_distribution<uint32_t> d(0, std::numeric_limits<uint8_t>::max());
-  const int32_t required_bytes = DecimalSize(precision);
-  constexpr int32_t byte_width = 16;
-  std::fill(out, out + byte_width * n, '\0');
-
-  for (int64_t i = 0; i < n; ++i, out += byte_width) {
-    std::generate(out, out + required_bytes,
-                  [&d, &gen] { return static_cast<uint8_t>(d(gen)); });
-
-    // sign extend if the sign bit is set for the last byte generated
-    // 0b10000000 == 0x80 == 128
-    if ((out[required_bytes - 1] & '\x80') != 0) {
-      std::fill(out + required_bytes, out + byte_width, '\xFF');
-    }
-  }
-}
-
-template <typename ArrowType, int32_t precision = ArrowType::precision>
-typename std::enable_if<
-    std::is_same<ArrowType, DecimalWithPrecisionAndScale<precision>>::value, Status>::type
-NonNullArray(size_t size, std::shared_ptr<Array>* out) {
-  constexpr int32_t kDecimalPrecision = precision;
-  constexpr int32_t kDecimalScale = DecimalWithPrecisionAndScale<precision>::scale;
-
-  const auto type = ::arrow::decimal(kDecimalPrecision, kDecimalScale);
-  ::arrow::Decimal128Builder builder(type);
-  const int32_t byte_width =
-      static_cast<const ::arrow::Decimal128Type&>(*type).byte_width();
-
-  constexpr int32_t seed = 0;
-
-  std::shared_ptr<Buffer> out_buf;
-  RETURN_NOT_OK(::arrow::AllocateBuffer(::arrow::default_memory_pool(), size * byte_width,
-                                        &out_buf));
-  random_decimals(size, seed, kDecimalPrecision, out_buf->mutable_data());
-
-  RETURN_NOT_OK(builder.AppendValues(out_buf->data(), size));
-  return builder.Finish(out);
-}
-
-template <class ArrowType>
-typename std::enable_if<is_arrow_bool<ArrowType>::value, Status>::type NonNullArray(
-    size_t size, std::shared_ptr<Array>* out) {
-  std::vector<uint8_t> values;
-  ::arrow::randint(size, 0, 1, &values);
-  ::arrow::BooleanBuilder builder;
-  RETURN_NOT_OK(builder.AppendValues(values.data(), values.size()));
-  return builder.Finish(out);
-}
-
-// This helper function only supports (size/2) nulls.
-template <typename ArrowType>
-typename std::enable_if<is_arrow_float<ArrowType>::value, Status>::type NullableArray(
-    size_t size, size_t num_nulls, uint32_t seed, std::shared_ptr<Array>* out) {
-  using c_type = typename ArrowType::c_type;
-  std::vector<c_type> values;
-  ::arrow::random_real(size, seed, static_cast<c_type>(-1e10), static_cast<c_type>(1e10),
-                       &values);
-  std::vector<uint8_t> valid_bytes(size, 1);
-
-  for (size_t i = 0; i < num_nulls; i++) {
-    valid_bytes[i * 2] = 0;
-  }
-
-  ::arrow::NumericBuilder<ArrowType> builder;
-  RETURN_NOT_OK(builder.AppendValues(values.data(), values.size(), valid_bytes.data()));
-  return builder.Finish(out);
-}
-
-// This helper function only supports (size/2) nulls.
-template <typename ArrowType>
-typename std::enable_if<
-    is_arrow_int<ArrowType>::value && !is_arrow_date<ArrowType>::value, Status>::type
-NullableArray(size_t size, size_t num_nulls, uint32_t seed, std::shared_ptr<Array>* out) {
-  std::vector<typename ArrowType::c_type> values;
-
-  // Seed is random in Arrow right now
-  (void)seed;
-  ::arrow::randint(size, 0, 64, &values);
-  std::vector<uint8_t> valid_bytes(size, 1);
-
-  for (size_t i = 0; i < num_nulls; i++) {
-    valid_bytes[i * 2] = 0;
-  }
-
-  // Passing data type so this will work with TimestampType too
-  ::arrow::NumericBuilder<ArrowType> builder(std::make_shared<ArrowType>(),
-                                             ::arrow::default_memory_pool());
-  RETURN_NOT_OK(builder.AppendValues(values.data(), values.size(), valid_bytes.data()));
-  return builder.Finish(out);
-}
-
-template <typename ArrowType>
-typename std::enable_if<is_arrow_date<ArrowType>::value, Status>::type NullableArray(
-    size_t size, size_t num_nulls, uint32_t seed, std::shared_ptr<Array>* out) {
-  std::vector<typename ArrowType::c_type> values;
-
-  // Seed is random in Arrow right now
-  (void)seed;
-  ::arrow::randint(size, 0, 64, &values);
-  for (size_t i = 0; i < size; i++) {
-    values[i] *= 86400000;
-  }
-  std::vector<uint8_t> valid_bytes(size, 1);
-
-  for (size_t i = 0; i < num_nulls; i++) {
-    valid_bytes[i * 2] = 0;
-  }
-
-  // Passing data type so this will work with TimestampType too
-  ::arrow::NumericBuilder<ArrowType> builder(std::make_shared<ArrowType>(),
-                                             ::arrow::default_memory_pool());
-  builder.AppendValues(values.data(), values.size(), valid_bytes.data());
-  return builder.Finish(out);
-}
-
-// This helper function only supports (size/2) nulls yet.
-template <typename ArrowType>
-typename std::enable_if<
-    is_arrow_string<ArrowType>::value || is_arrow_binary<ArrowType>::value, Status>::type
-NullableArray(size_t size, size_t num_nulls, uint32_t seed,
-              std::shared_ptr<::arrow::Array>* out) {
-  std::vector<uint8_t> valid_bytes(size, 1);
-
-  for (size_t i = 0; i < num_nulls; i++) {
-    valid_bytes[i * 2] = 0;
-  }
-
-  using BuilderType = typename ::arrow::TypeTraits<ArrowType>::BuilderType;
-  BuilderType builder;
-
-  const int kBufferSize = 10;
-  uint8_t buffer[kBufferSize];
-  for (size_t i = 0; i < size; i++) {
-    if (!valid_bytes[i]) {
-      RETURN_NOT_OK(builder.AppendNull());
-    } else {
-      ::arrow::random_bytes(kBufferSize, seed + static_cast<uint32_t>(i), buffer);
-      RETURN_NOT_OK(builder.Append(buffer, kBufferSize));
-    }
-  }
-  return builder.Finish(out);
-}
-
-// This helper function only supports (size/2) nulls yet,
-// same as NullableArray<String|Binary>(..)
-template <typename ArrowType>
-typename std::enable_if<is_arrow_fixed_size_binary<ArrowType>::value, Status>::type
-NullableArray(size_t size, size_t num_nulls, uint32_t seed,
-              std::shared_ptr<::arrow::Array>* out) {
-  std::vector<uint8_t> valid_bytes(size, 1);
-
-  for (size_t i = 0; i < num_nulls; i++) {
-    valid_bytes[i * 2] = 0;
-  }
-
-  using BuilderType = typename ::arrow::TypeTraits<ArrowType>::BuilderType;
-  const int byte_width = 10;
-  BuilderType builder(::arrow::fixed_size_binary(byte_width));
-
-  const int kBufferSize = byte_width;
-  uint8_t buffer[kBufferSize];
-  for (size_t i = 0; i < size; i++) {
-    if (!valid_bytes[i]) {
-      RETURN_NOT_OK(builder.AppendNull());
-    } else {
-      ::arrow::random_bytes(kBufferSize, seed + static_cast<uint32_t>(i), buffer);
-      RETURN_NOT_OK(builder.Append(buffer));
-    }
-  }
-  return builder.Finish(out);
-}
-
-template <typename ArrowType, int32_t precision = ArrowType::precision>
-typename std::enable_if<
-    std::is_same<ArrowType, DecimalWithPrecisionAndScale<precision>>::value, Status>::type
-NullableArray(size_t size, size_t num_nulls, uint32_t seed,
-              std::shared_ptr<::arrow::Array>* out) {
-  std::vector<uint8_t> valid_bytes(size, '\1');
-
-  for (size_t i = 0; i < num_nulls; ++i) {
-    valid_bytes[i * 2] = '\0';
-  }
-
-  constexpr int32_t kDecimalPrecision = precision;
-  constexpr int32_t kDecimalScale = DecimalWithPrecisionAndScale<precision>::scale;
-  const auto type = ::arrow::decimal(kDecimalPrecision, kDecimalScale);
-  const int32_t byte_width =
-      static_cast<const ::arrow::Decimal128Type&>(*type).byte_width();
-
-  std::shared_ptr<::arrow::Buffer> out_buf;
-  RETURN_NOT_OK(::arrow::AllocateBuffer(::arrow::default_memory_pool(), size * byte_width,
-                                        &out_buf));
-
-  random_decimals(size, seed, precision, out_buf->mutable_data());
-
-  ::arrow::Decimal128Builder builder(type);
-  RETURN_NOT_OK(builder.AppendValues(out_buf->data(), size, valid_bytes.data()));
-  return builder.Finish(out);
-}
-
-// This helper function only supports (size/2) nulls yet.
-template <class ArrowType>
-typename std::enable_if<is_arrow_bool<ArrowType>::value, Status>::type NullableArray(
-    size_t size, size_t num_nulls, uint32_t seed, std::shared_ptr<Array>* out) {
-  std::vector<uint8_t> values;
-
-  // Seed is random in Arrow right now
-  (void)seed;
-
-  ::arrow::randint(size, 0, 1, &values);
-  std::vector<uint8_t> valid_bytes(size, 1);
-
-  for (size_t i = 0; i < num_nulls; i++) {
-    valid_bytes[i * 2] = 0;
-  }
-
-  ::arrow::BooleanBuilder builder;
-  RETURN_NOT_OK(builder.AppendValues(values.data(), values.size(), valid_bytes.data()));
-  return builder.Finish(out);
-}
-
-/// Wrap an Array into a ListArray by splitting it up into size lists.
-///
-/// This helper function only supports (size/2) nulls.
-Status MakeListArray(const std::shared_ptr<Array>& values, int64_t size,
-                     int64_t null_count, bool nullable_values,
-                     std::shared_ptr<::arrow::ListArray>* out) {
-  // We always include an empty list
-  int64_t non_null_entries = size - null_count - 1;
-  int64_t length_per_entry = values->length() / non_null_entries;
-
-  auto offsets = AllocateBuffer();
-  RETURN_NOT_OK(offsets->Resize((size + 1) * sizeof(int32_t)));
-  int32_t* offsets_ptr = reinterpret_cast<int32_t*>(offsets->mutable_data());
-
-  auto null_bitmap = AllocateBuffer();
-  int64_t bitmap_size = ::arrow::BitUtil::BytesForBits(size);
-  RETURN_NOT_OK(null_bitmap->Resize(bitmap_size));
-  uint8_t* null_bitmap_ptr = null_bitmap->mutable_data();
-  memset(null_bitmap_ptr, 0, bitmap_size);
-
-  int32_t current_offset = 0;
-  for (int64_t i = 0; i < size; i++) {
-    offsets_ptr[i] = current_offset;
-    if (!(((i % 2) == 0) && ((i / 2) < null_count))) {
-      // Non-null list (list with index 1 is always empty).
-      ::arrow::BitUtil::SetBit(null_bitmap_ptr, i);
-      if (i != 1) {
-        current_offset += static_cast<int32_t>(length_per_entry);
-      }
-    }
-  }
-  offsets_ptr[size] = static_cast<int32_t>(values->length());
-
-  auto value_field = ::arrow::field("item", values->type(), nullable_values);
-  *out = std::make_shared<::arrow::ListArray>(::arrow::list(value_field), size, offsets,
-                                              values, null_bitmap, null_count);
-
-  return Status::OK();
-}
-
-// Make an array containing only empty lists, with a null values array
-Status MakeEmptyListsArray(int64_t size, std::shared_ptr<Array>* out_array) {
-  // Allocate an offsets buffer containing only zeroes
-  std::shared_ptr<Buffer> offsets_buffer;
-  const int64_t offsets_nbytes = (size + 1) * sizeof(int32_t);
-  RETURN_NOT_OK(::arrow::AllocateBuffer(::arrow::default_memory_pool(), offsets_nbytes,
-                                        &offsets_buffer));
-  memset(offsets_buffer->mutable_data(), 0, offsets_nbytes);
-
-  auto value_field =
-      ::arrow::field("item", ::arrow::float64(), false /* nullable_values */);
-  auto list_type = ::arrow::list(value_field);
-
-  std::vector<std::shared_ptr<Buffer>> child_buffers = {nullptr /* null bitmap */,
-                                                        nullptr /* values */};
-  auto child_data =
-      ::arrow::ArrayData::Make(value_field->type(), 0, std::move(child_buffers));
-
-  std::vector<std::shared_ptr<Buffer>> buffers = {nullptr /* bitmap */, offsets_buffer};
-  auto array_data = ::arrow::ArrayData::Make(list_type, size, std::move(buffers));
-  array_data->child_data.push_back(child_data);
-
-  *out_array = ::arrow::MakeArray(array_data);
-  return Status::OK();
-}
-
-static std::shared_ptr<::arrow::Column> MakeColumn(const std::string& name,
-                                                   const std::shared_ptr<Array>& array,
-                                                   bool nullable) {
-  auto field = ::arrow::field(name, array->type(), nullable);
-  return std::make_shared<::arrow::Column>(field, array);
-}
-
-static std::shared_ptr<::arrow::Column> MakeColumn(
-    const std::string& name, const std::vector<std::shared_ptr<Array>>& arrays,
-    bool nullable) {
-  auto field = ::arrow::field(name, arrays[0]->type(), nullable);
-  return std::make_shared<::arrow::Column>(field, arrays);
-}
-
-std::shared_ptr<::arrow::Table> MakeSimpleTable(const std::shared_ptr<Array>& values,
-                                                bool nullable) {
-  std::shared_ptr<::arrow::Column> column = MakeColumn("col", values, nullable);
-  std::vector<std::shared_ptr<::arrow::Column>> columns({column});
-  std::vector<std::shared_ptr<::arrow::Field>> fields({column->field()});
-  auto schema = std::make_shared<::arrow::Schema>(fields);
-  return ::arrow::Table::Make(schema, columns);
-}
-
-template <typename T>
-void ExpectArray(T* expected, Array* result) {
-  auto p_array = static_cast<::arrow::PrimitiveArray*>(result);
-  for (int i = 0; i < result->length(); i++) {
-    EXPECT_EQ(expected[i], reinterpret_cast<const T*>(p_array->values()->data())[i]);
-  }
-}
-
-template <typename ArrowType>
-void ExpectArrayT(void* expected, Array* result) {
-  ::arrow::PrimitiveArray* p_array = static_cast<::arrow::PrimitiveArray*>(result);
-  for (int64_t i = 0; i < result->length(); i++) {
-    EXPECT_EQ(reinterpret_cast<typename ArrowType::c_type*>(expected)[i],
-              reinterpret_cast<const typename ArrowType::c_type*>(
-                  p_array->values()->data())[i]);
-  }
-}
-
-template <>
-void ExpectArrayT<::arrow::BooleanType>(void* expected, Array* result) {
-  ::arrow::BooleanBuilder builder;
-  EXPECT_OK(builder.AppendValues(reinterpret_cast<uint8_t*>(expected), result->length()));
-
-  std::shared_ptr<Array> expected_array;
-  EXPECT_OK(builder.Finish(&expected_array));
-  EXPECT_TRUE(result->Equals(*expected_array));
-}
-
-template <typename ParquetType>
-void PrintBufferedLevels(const RecordReader& reader) {
-  using T = typename ::parquet::type_traits<ParquetType::type_num>::value_type;
-
-  const int16_t* def_levels = reader.def_levels();
-  const int16_t* rep_levels = reader.rep_levels();
-  const int64_t total_levels_read = reader.levels_position();
-
-  const T* values = reinterpret_cast<const T*>(reader.values());
-
-  std::cout << "def levels: ";
-  for (int64_t i = 0; i < total_levels_read; ++i) {
-    std::cout << def_levels[i] << " ";
-  }
-  std::cout << std::endl;
-
-  std::cout << "rep levels: ";
-  for (int64_t i = 0; i < total_levels_read; ++i) {
-    std::cout << rep_levels[i] << " ";
-  }
-  std::cout << std::endl;
-
-  std::cout << "values: ";
-  for (int64_t i = 0; i < reader.values_written(); ++i) {
-    std::cout << values[i] << " ";
-  }
-  std::cout << std::endl;
-}
-
-template <>
-void PrintBufferedLevels<ByteArrayType>(const RecordReader& reader) {}
-
-template <>
-void PrintBufferedLevels<FLBAType>(const RecordReader& reader) {}
-
-template <>
-void PrintBufferedLevels<Int96Type>(const RecordReader& reader) {}
-
-}  // namespace arrow
-
-}  // namespace parquet
diff --git a/src/parquet/arrow/writer.cc b/src/parquet/arrow/writer.cc
deleted file mode 100644
index b7d139e..0000000
--- a/src/parquet/arrow/writer.cc
+++ /dev/null
@@ -1,1151 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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.
-
-#include "parquet/arrow/writer.h"
-
-#include <algorithm>
-#include <string>
-#include <vector>
-
-#include "arrow/api.h"
-#include "arrow/compute/api.h"
-#include "arrow/util/bit-util.h"
-#include "arrow/visitor_inline.h"
-
-#include "parquet/arrow/schema.h"
-#include "parquet/util/logging.h"
-
-using arrow::Array;
-using arrow::BinaryArray;
-using arrow::BooleanArray;
-using arrow::ChunkedArray;
-using arrow::Decimal128Array;
-using arrow::Field;
-using arrow::FixedSizeBinaryArray;
-using arrow::Int16Array;
-using arrow::Int16Builder;
-using arrow::ListArray;
-using arrow::MemoryPool;
-using arrow::NumericArray;
-using arrow::PrimitiveArray;
-using arrow::ResizableBuffer;
-using arrow::Status;
-using arrow::Table;
-using arrow::TimeUnit;
-
-using arrow::compute::Cast;
-using arrow::compute::CastOptions;
-using arrow::compute::FunctionContext;
-
-using parquet::ParquetFileWriter;
-using parquet::ParquetVersion;
-using parquet::schema::GroupNode;
-
-namespace parquet {
-namespace arrow {
-
-namespace BitUtil = ::arrow::BitUtil;
-
-std::shared_ptr<ArrowWriterProperties> default_arrow_writer_properties() {
-  static std::shared_ptr<ArrowWriterProperties> default_writer_properties =
-      ArrowWriterProperties::Builder().build();
-  return default_writer_properties;
-}
-
-namespace {
-
-class LevelBuilder {
- public:
-  explicit LevelBuilder(MemoryPool* pool)
-      : def_levels_(::arrow::int16(), pool), rep_levels_(::arrow::int16(), pool) {}
-
-  Status VisitInline(const Array& array);
-
-  template <typename T>
-  typename std::enable_if<std::is_base_of<::arrow::FlatArray, T>::value, Status>::type
-  Visit(const T& array) {
-    array_offsets_.push_back(static_cast<int32_t>(array.offset()));
-    valid_bitmaps_.push_back(array.null_bitmap_data());
-    null_counts_.push_back(array.null_count());
-    values_array_ = std::make_shared<T>(array.data());
-    return Status::OK();
-  }
-
-  Status Visit(const ListArray& array) {
-    array_offsets_.push_back(static_cast<int32_t>(array.offset()));
-    valid_bitmaps_.push_back(array.null_bitmap_data());
-    null_counts_.push_back(array.null_count());
-    offsets_.push_back(array.raw_value_offsets());
-
-    min_offset_idx_ = array.value_offset(min_offset_idx_);
-    max_offset_idx_ = array.value_offset(max_offset_idx_);
-
-    return VisitInline(*array.values());
-  }
-
-#define NOT_IMPLEMENTED_VISIT(ArrowTypePrefix)                             \
-  Status Visit(const ::arrow::ArrowTypePrefix##Array& array) {             \
-    return Status::NotImplemented("Level generation for " #ArrowTypePrefix \
-                                  " not supported yet");                   \
-  }
-
-  NOT_IMPLEMENTED_VISIT(Struct)
-  NOT_IMPLEMENTED_VISIT(Union)
-  NOT_IMPLEMENTED_VISIT(Dictionary)
-
-  Status GenerateLevels(const Array& array, const std::shared_ptr<Field>& field,
-                        int64_t* values_offset, int64_t* num_values, int64_t* num_levels,
-                        const std::shared_ptr<ResizableBuffer>& def_levels_scratch,
-                        std::shared_ptr<Buffer>* def_levels_out,
-                        std::shared_ptr<Buffer>* rep_levels_out,
-                        std::shared_ptr<Array>* values_array) {
-    // Work downwards to extract bitmaps and offsets
-    min_offset_idx_ = 0;
-    max_offset_idx_ = array.length();
-    RETURN_NOT_OK(VisitInline(array));
-    *num_values = max_offset_idx_ - min_offset_idx_;
-    *values_offset = min_offset_idx_;
-    *values_array = values_array_;
-
-    // Walk downwards to extract nullability
-    std::shared_ptr<Field> current_field = field;
-    nullable_.push_back(current_field->nullable());
-    while (current_field->type()->num_children() > 0) {
-      if (current_field->type()->num_children() > 1) {
-        return Status::NotImplemented(
-            "Fields with more than one child are not supported.");
-      } else {
-        current_field = current_field->type()->child(0);
-      }
-      nullable_.push_back(current_field->nullable());
-    }
-
-    // Generate the levels.
-    if (nullable_.size() == 1) {
-      // We have a PrimitiveArray
-      *rep_levels_out = nullptr;
-      if (nullable_[0]) {
-        RETURN_NOT_OK(
-            def_levels_scratch->Resize(array.length() * sizeof(int16_t), false));
-        auto def_levels_ptr =
-            reinterpret_cast<int16_t*>(def_levels_scratch->mutable_data());
-        if (array.null_count() == 0) {
-          std::fill(def_levels_ptr, def_levels_ptr + array.length(), 1);
-        } else if (array.null_count() == array.length()) {
-          std::fill(def_levels_ptr, def_levels_ptr + array.length(), 0);
-        } else {
-          ::arrow::internal::BitmapReader valid_bits_reader(
-              array.null_bitmap_data(), array.offset(), array.length());
-          for (int i = 0; i < array.length(); i++) {
-            def_levels_ptr[i] = valid_bits_reader.IsSet() ? 1 : 0;
-            valid_bits_reader.Next();
-          }
-        }
-
-        *def_levels_out = def_levels_scratch;
-      } else {
-        *def_levels_out = nullptr;
-      }
-      *num_levels = array.length();
-    } else {
-      RETURN_NOT_OK(rep_levels_.Append(0));
-      RETURN_NOT_OK(HandleListEntries(0, 0, 0, array.length()));
-
-      std::shared_ptr<Array> def_levels_array;
-      std::shared_ptr<Array> rep_levels_array;
-
-      RETURN_NOT_OK(def_levels_.Finish(&def_levels_array));
-      RETURN_NOT_OK(rep_levels_.Finish(&rep_levels_array));
-
-      *def_levels_out = static_cast<PrimitiveArray*>(def_levels_array.get())->values();
-      *rep_levels_out = static_cast<PrimitiveArray*>(rep_levels_array.get())->values();
-      *num_levels = rep_levels_array->length();
-    }
-
-    return Status::OK();
-  }
-
-  Status HandleList(int16_t def_level, int16_t rep_level, int64_t index) {
-    if (nullable_[rep_level]) {
-      if (null_counts_[rep_level] == 0 ||
-          BitUtil::GetBit(valid_bitmaps_[rep_level], index + array_offsets_[rep_level])) {
-        return HandleNonNullList(static_cast<int16_t>(def_level + 1), rep_level, index);
-      } else {
-        return def_levels_.Append(def_level);
-      }
-    } else {
-      return HandleNonNullList(def_level, rep_level, index);
-    }
-  }
-
-  Status HandleNonNullList(int16_t def_level, int16_t rep_level, int64_t index) {
-    const int32_t inner_offset = offsets_[rep_level][index];
-    const int32_t inner_length = offsets_[rep_level][index + 1] - inner_offset;
-    const int64_t recursion_level = rep_level + 1;
-    if (inner_length == 0) {
-      return def_levels_.Append(def_level);
-    }
-    if (recursion_level < static_cast<int64_t>(offsets_.size())) {
-      return HandleListEntries(static_cast<int16_t>(def_level + 1),
-                               static_cast<int16_t>(rep_level + 1), inner_offset,
-                               inner_length);
-    } else {
-      // We have reached the leaf: primitive list, handle remaining nullables
-      const bool nullable_level = nullable_[recursion_level];
-      const int64_t level_null_count = null_counts_[recursion_level];
-      const uint8_t* level_valid_bitmap = valid_bitmaps_[recursion_level];
-
-      for (int64_t i = 0; i < inner_length; i++) {
-        if (i > 0) {
-          RETURN_NOT_OK(rep_levels_.Append(static_cast<int16_t>(rep_level + 1)));
-        }
-        if (level_null_count && level_valid_bitmap == nullptr) {
-          // Special case: this is a null array (all elements are null)
-          RETURN_NOT_OK(def_levels_.Append(static_cast<int16_t>(def_level + 1)));
-        } else if (nullable_level &&
-                   ((level_null_count == 0) ||
-                    BitUtil::GetBit(
-                        level_valid_bitmap,
-                        inner_offset + i + array_offsets_[recursion_level]))) {
-          // Non-null element in a null level
-          RETURN_NOT_OK(def_levels_.Append(static_cast<int16_t>(def_level + 2)));
-        } else {
-          // This can be produced in two case:
-          //  * elements are nullable and this one is null (i.e. max_def_level = def_level
-          //  + 2)
-          //  * elements are non-nullable (i.e. max_def_level = def_level + 1)
-          RETURN_NOT_OK(def_levels_.Append(static_cast<int16_t>(def_level + 1)));
-        }
-      }
-      return Status::OK();
-    }
-  }
-
-  Status HandleListEntries(int16_t def_level, int16_t rep_level, int64_t offset,
-                           int64_t length) {
-    for (int64_t i = 0; i < length; i++) {
-      if (i > 0) {
-        RETURN_NOT_OK(rep_levels_.Append(rep_level));
-      }
-      RETURN_NOT_OK(HandleList(def_level, rep_level, offset + i));
-    }
-    return Status::OK();
-  }
-
- private:
-  Int16Builder def_levels_;
-  Int16Builder rep_levels_;
-
-  std::vector<int64_t> null_counts_;
-  std::vector<const uint8_t*> valid_bitmaps_;
-  std::vector<const int32_t*> offsets_;
-  std::vector<int32_t> array_offsets_;
-  std::vector<bool> nullable_;
-
-  int64_t min_offset_idx_;
-  int64_t max_offset_idx_;
-  std::shared_ptr<Array> values_array_;
-};
-
-Status LevelBuilder::VisitInline(const Array& array) {
-  return VisitArrayInline(array, this);
-}
-
-struct ColumnWriterContext {
-  ColumnWriterContext(MemoryPool* memory_pool, ArrowWriterProperties* properties)
-      : memory_pool(memory_pool), properties(properties) {
-    this->data_buffer = AllocateBuffer(memory_pool);
-    this->def_levels_buffer = AllocateBuffer(memory_pool);
-  }
-
-  template <typename T>
-  Status GetScratchData(const int64_t num_values, T** out) {
-    RETURN_NOT_OK(this->data_buffer->Resize(num_values * sizeof(T), false));
-    *out = reinterpret_cast<T*>(this->data_buffer->mutable_data());
-    return Status::OK();
-  }
-
-  MemoryPool* memory_pool;
-  ArrowWriterProperties* properties;
-
-  // Buffer used for storing the data of an array converted to the physical type
-  // as expected by parquet-cpp.
-  std::shared_ptr<ResizableBuffer> data_buffer;
-
-  // We use the shared ownership of this buffer
-  std::shared_ptr<ResizableBuffer> def_levels_buffer;
-};
-
-Status GetLeafType(const ::arrow::DataType& type, ::arrow::Type::type* leaf_type) {
-  if (type.id() == ::arrow::Type::LIST || type.id() == ::arrow::Type::STRUCT) {
-    if (type.num_children() != 1) {
-      return Status::Invalid("Nested column branch had multiple children");
-    }
-    return GetLeafType(*type.child(0)->type(), leaf_type);
-  } else {
-    *leaf_type = type.id();
-    return Status::OK();
-  }
-}
-
-class ArrowColumnWriter {
- public:
-  ArrowColumnWriter(ColumnWriterContext* ctx, ColumnWriter* column_writer,
-                    const std::shared_ptr<Field>& field)
-      : ctx_(ctx), writer_(column_writer), field_(field) {}
-
-  Status Write(const Array& data);
-
-  Status Write(const ChunkedArray& data, int64_t offset, const int64_t size) {
-    int64_t absolute_position = 0;
-    int chunk_index = 0;
-    int64_t chunk_offset = 0;
-    while (chunk_index < data.num_chunks() && absolute_position < offset) {
-      const int64_t chunk_length = data.chunk(chunk_index)->length();
-      if (absolute_position + chunk_length > offset) {
-        // Relative offset into the chunk to reach the desired start offset for
-        // writing
-        chunk_offset = offset - absolute_position;
-        break;
-      } else {
-        ++chunk_index;
-        absolute_position += chunk_length;
-      }
-    }
-
-    if (absolute_position >= data.length()) {
-      return Status::Invalid("Cannot write data at offset past end of chunked array");
-    }
-
-    int64_t values_written = 0;
-    while (values_written < size) {
-      const Array& chunk = *data.chunk(chunk_index);
-      const int64_t available_values = chunk.length() - chunk_offset;
-      const int64_t chunk_write_size = std::min(size - values_written, available_values);
-
-      // The chunk offset here will be 0 except for possibly the first chunk
-      // because of the advancing logic above
-      std::shared_ptr<Array> array_to_write = chunk.Slice(chunk_offset, chunk_write_size);
-      RETURN_NOT_OK(Write(*array_to_write));
-
-      if (chunk_write_size == available_values) {
-        chunk_offset = 0;
-        ++chunk_index;
-      }
-      values_written += chunk_write_size;
-    }
-
-    return Status::OK();
-  }
-
-  Status Close() {
-    PARQUET_CATCH_NOT_OK(writer_->Close());
-    return Status::OK();
-  }
-
- private:
-  template <typename ParquetType, typename ArrowType>
-  Status TypedWriteBatch(const Array& data, int64_t num_levels, const int16_t* def_levels,
-                         const int16_t* rep_levels);
-
-  Status WriteTimestamps(const Array& data, int64_t num_levels, const int16_t* def_levels,
-                         const int16_t* rep_levels);
-
-  Status WriteTimestampsCoerce(const Array& data, int64_t num_levels,
-                               const int16_t* def_levels, const int16_t* rep_levels);
-
-  template <typename ParquetType, typename ArrowType>
-  Status WriteNonNullableBatch(const ArrowType& type, int64_t num_values,
-                               int64_t num_levels, const int16_t* def_levels,
-                               const int16_t* rep_levels,
-                               const typename ArrowType::c_type* values);
-
-  template <typename ParquetType, typename ArrowType>
-  Status WriteNullableBatch(const ArrowType& type, int64_t num_values, int64_t num_levels,
-                            const int16_t* def_levels, const int16_t* rep_levels,
-                            const uint8_t* valid_bits, int64_t valid_bits_offset,
-                            const typename ArrowType::c_type* values);
-
-  template <typename ParquetType>
-  Status WriteBatch(int64_t num_levels, const int16_t* def_levels,
-                    const int16_t* rep_levels,
-                    const typename ParquetType::c_type* values) {
-    auto typed_writer = static_cast<TypedColumnWriter<ParquetType>*>(writer_);
-    PARQUET_CATCH_NOT_OK(
-        typed_writer->WriteBatch(num_levels, def_levels, rep_levels, values));
-    return Status::OK();
-  }
-
-  template <typename ParquetType>
-  Status WriteBatchSpaced(int64_t num_levels, const int16_t* def_levels,
-                          const int16_t* rep_levels, const uint8_t* valid_bits,
-                          int64_t valid_bits_offset,
-                          const typename ParquetType::c_type* values) {
-    auto typed_writer = static_cast<TypedColumnWriter<ParquetType>*>(writer_);
-    PARQUET_CATCH_NOT_OK(typed_writer->WriteBatchSpaced(
-        num_levels, def_levels, rep_levels, valid_bits, valid_bits_offset, values));
-    return Status::OK();
-  }
-
-  ColumnWriterContext* ctx_;
-  ColumnWriter* writer_;
-  std::shared_ptr<Field> field_;
-};
-
-template <typename ParquetType, typename ArrowType>
-Status ArrowColumnWriter::TypedWriteBatch(const Array& array, int64_t num_levels,
-                                          const int16_t* def_levels,
-                                          const int16_t* rep_levels) {
-  using ArrowCType = typename ArrowType::c_type;
-
-  const auto& data = static_cast<const PrimitiveArray&>(array);
-  const ArrowCType* values = nullptr;
-  // The values buffer may be null if the array is empty (ARROW-2744)
-  if (data.values() != nullptr) {
-    values = reinterpret_cast<const ArrowCType*>(data.values()->data()) + data.offset();
-  } else {
-    DCHECK_EQ(data.length(), 0);
-  }
-
-  if (writer_->descr()->schema_node()->is_required() || (data.null_count() == 0)) {
-    // no nulls, just dump the data
-    RETURN_NOT_OK((WriteNonNullableBatch<ParquetType, ArrowType>(
-        static_cast<const ArrowType&>(*array.type()), array.length(), num_levels,
-        def_levels, rep_levels, values)));
-  } else {
-    const uint8_t* valid_bits = data.null_bitmap_data();
-    RETURN_NOT_OK((WriteNullableBatch<ParquetType, ArrowType>(
-        static_cast<const ArrowType&>(*array.type()), data.length(), num_levels,
-        def_levels, rep_levels, valid_bits, data.offset(), values)));
-  }
-  return Status::OK();
-}
-
-template <typename ParquetType, typename ArrowType>
-Status ArrowColumnWriter::WriteNonNullableBatch(
-    const ArrowType& type, int64_t num_values, int64_t num_levels,
-    const int16_t* def_levels, const int16_t* rep_levels,
-    const typename ArrowType::c_type* values) {
-  using ParquetCType = typename ParquetType::c_type;
-  ParquetCType* buffer;
-  RETURN_NOT_OK(ctx_->GetScratchData<ParquetCType>(num_values, &buffer));
-
-  std::copy(values, values + num_values, buffer);
-
-  return WriteBatch<ParquetType>(num_levels, def_levels, rep_levels, buffer);
-}
-
-template <>
-Status ArrowColumnWriter::WriteNonNullableBatch<Int32Type, ::arrow::Date64Type>(
-    const ::arrow::Date64Type& type, int64_t num_values, int64_t num_levels,
-    const int16_t* def_levels, const int16_t* rep_levels, const int64_t* values) {
-  int32_t* buffer;
-  RETURN_NOT_OK(ctx_->GetScratchData<int32_t>(num_levels, &buffer));
-
-  for (int i = 0; i < num_values; i++) {
-    buffer[i] = static_cast<int32_t>(values[i] / 86400000);
-  }
-
-  return WriteBatch<Int32Type>(num_levels, def_levels, rep_levels, buffer);
-}
-
-template <>
-Status ArrowColumnWriter::WriteNonNullableBatch<Int32Type, ::arrow::Time32Type>(
-    const ::arrow::Time32Type& type, int64_t num_values, int64_t num_levels,
-    const int16_t* def_levels, const int16_t* rep_levels, const int32_t* values) {
-  int32_t* buffer;
-  RETURN_NOT_OK(ctx_->GetScratchData<int32_t>(num_levels, &buffer));
-  if (type.unit() == TimeUnit::SECOND) {
-    for (int i = 0; i < num_values; i++) {
-      buffer[i] = values[i] * 1000;
-    }
-  } else {
-    std::copy(values, values + num_values, buffer);
-  }
-  return WriteBatch<Int32Type>(num_levels, def_levels, rep_levels, buffer);
-}
-
-#define NONNULLABLE_BATCH_FAST_PATH(ParquetType, ArrowType, CType)                 \
-  template <>                                                                      \
-  Status ArrowColumnWriter::WriteNonNullableBatch<ParquetType, ArrowType>(         \
-      const ArrowType& type, int64_t num_values, int64_t num_levels,               \
-      const int16_t* def_levels, const int16_t* rep_levels, const CType* buffer) { \
-    return WriteBatch<ParquetType>(num_levels, def_levels, rep_levels, buffer);    \
-  }
-
-NONNULLABLE_BATCH_FAST_PATH(Int32Type, ::arrow::Int32Type, int32_t)
-NONNULLABLE_BATCH_FAST_PATH(Int32Type, ::arrow::Date32Type, int32_t)
-NONNULLABLE_BATCH_FAST_PATH(Int64Type, ::arrow::Int64Type, int64_t)
-NONNULLABLE_BATCH_FAST_PATH(Int64Type, ::arrow::Time64Type, int64_t)
-NONNULLABLE_BATCH_FAST_PATH(FloatType, ::arrow::FloatType, float)
-NONNULLABLE_BATCH_FAST_PATH(DoubleType, ::arrow::DoubleType, double)
-
-template <typename ParquetType, typename ArrowType>
-Status ArrowColumnWriter::WriteNullableBatch(
-    const ArrowType& type, int64_t num_values, int64_t num_levels,
-    const int16_t* def_levels, const int16_t* rep_levels, const uint8_t* valid_bits,
-    int64_t valid_bits_offset, const typename ArrowType::c_type* values) {
-  using ParquetCType = typename ParquetType::c_type;
-
-  ParquetCType* buffer;
-  RETURN_NOT_OK(ctx_->GetScratchData<ParquetCType>(num_levels, &buffer));
-  for (int i = 0; i < num_values; i++) {
-    buffer[i] = static_cast<ParquetCType>(values[i]);
-  }
-
-  return WriteBatchSpaced<ParquetType>(num_levels, def_levels, rep_levels, valid_bits,
-                                       valid_bits_offset, buffer);
-}
-
-template <>
-Status ArrowColumnWriter::WriteNullableBatch<Int32Type, ::arrow::Date64Type>(
-    const ::arrow::Date64Type& type, int64_t num_values, int64_t num_levels,
-    const int16_t* def_levels, const int16_t* rep_levels, const uint8_t* valid_bits,
-    int64_t valid_bits_offset, const int64_t* values) {
-  int32_t* buffer;
-  RETURN_NOT_OK(ctx_->GetScratchData<int32_t>(num_values, &buffer));
-
-  for (int i = 0; i < num_values; i++) {
-    // Convert from milliseconds into days since the epoch
-    buffer[i] = static_cast<int32_t>(values[i] / 86400000);
-  }
-
-  return WriteBatchSpaced<Int32Type>(num_levels, def_levels, rep_levels, valid_bits,
-                                     valid_bits_offset, buffer);
-}
-
-template <>
-Status ArrowColumnWriter::WriteNullableBatch<Int32Type, ::arrow::Time32Type>(
-    const ::arrow::Time32Type& type, int64_t num_values, int64_t num_levels,
-    const int16_t* def_levels, const int16_t* rep_levels, const uint8_t* valid_bits,
-    int64_t valid_bits_offset, const int32_t* values) {
-  int32_t* buffer;
-  RETURN_NOT_OK(ctx_->GetScratchData<int32_t>(num_values, &buffer));
-
-  if (type.unit() == TimeUnit::SECOND) {
-    for (int i = 0; i < num_values; i++) {
-      buffer[i] = values[i] * 1000;
-    }
-  } else {
-    for (int i = 0; i < num_values; i++) {
-      buffer[i] = values[i];
-    }
-  }
-  return WriteBatchSpaced<Int32Type>(num_levels, def_levels, rep_levels, valid_bits,
-                                     valid_bits_offset, buffer);
-}
-
-#define NULLABLE_BATCH_FAST_PATH(ParquetType, ArrowType, CType)                          \
-  template <>                                                                            \
-  Status ArrowColumnWriter::WriteNullableBatch<ParquetType, ArrowType>(                  \
-      const ArrowType& type, int64_t num_values, int64_t num_levels,                     \
-      const int16_t* def_levels, const int16_t* rep_levels, const uint8_t* valid_bits,   \
-      int64_t valid_bits_offset, const CType* values) {                                  \
-    return WriteBatchSpaced<ParquetType>(num_levels, def_levels, rep_levels, valid_bits, \
-                                         valid_bits_offset, values);                     \
-  }
-
-NULLABLE_BATCH_FAST_PATH(Int32Type, ::arrow::Int32Type, int32_t)
-NULLABLE_BATCH_FAST_PATH(Int32Type, ::arrow::Date32Type, int32_t)
-NULLABLE_BATCH_FAST_PATH(Int64Type, ::arrow::Int64Type, int64_t)
-NULLABLE_BATCH_FAST_PATH(Int64Type, ::arrow::Time64Type, int64_t)
-NULLABLE_BATCH_FAST_PATH(FloatType, ::arrow::FloatType, float)
-NULLABLE_BATCH_FAST_PATH(DoubleType, ::arrow::DoubleType, double)
-NULLABLE_BATCH_FAST_PATH(Int64Type, ::arrow::TimestampType, int64_t)
-NONNULLABLE_BATCH_FAST_PATH(Int64Type, ::arrow::TimestampType, int64_t)
-
-template <>
-Status ArrowColumnWriter::WriteNullableBatch<Int96Type, ::arrow::TimestampType>(
-    const ::arrow::TimestampType& type, int64_t num_values, int64_t num_levels,
-    const int16_t* def_levels, const int16_t* rep_levels, const uint8_t* valid_bits,
-    int64_t valid_bits_offset, const int64_t* values) {
-  Int96* buffer;
-  RETURN_NOT_OK(ctx_->GetScratchData<Int96>(num_values, &buffer));
-  if (type.unit() == TimeUnit::NANO) {
-    for (int i = 0; i < num_values; i++) {
-      internal::NanosecondsToImpalaTimestamp(values[i], &buffer[i]);
-    }
-  } else {
-    return Status::NotImplemented("Only NANO timestamps are supported for Int96 writing");
-  }
-  return WriteBatchSpaced<Int96Type>(num_levels, def_levels, rep_levels, valid_bits,
-                                     valid_bits_offset, buffer);
-}
-
-template <>
-Status ArrowColumnWriter::WriteNonNullableBatch<Int96Type, ::arrow::TimestampType>(
-    const ::arrow::TimestampType& type, int64_t num_values, int64_t num_levels,
-    const int16_t* def_levels, const int16_t* rep_levels, const int64_t* values) {
-  Int96* buffer;
-  RETURN_NOT_OK(ctx_->GetScratchData<Int96>(num_values, &buffer));
-  if (type.unit() == TimeUnit::NANO) {
-    for (int i = 0; i < num_values; i++) {
-      internal::NanosecondsToImpalaTimestamp(values[i], buffer + i);
-    }
-  } else {
-    return Status::NotImplemented("Only NANO timestamps are supported for Int96 writing");
-  }
-  return WriteBatch<Int96Type>(num_levels, def_levels, rep_levels, buffer);
-}
-
-Status ArrowColumnWriter::WriteTimestamps(const Array& values, int64_t num_levels,
-                                          const int16_t* def_levels,
-                                          const int16_t* rep_levels) {
-  const auto& type = static_cast<const ::arrow::TimestampType&>(*values.type());
-
-  const bool is_nanosecond = type.unit() == TimeUnit::NANO;
-
-  // In the case where support_deprecated_int96_timestamps was specified
-  // and coerce_timestamps_enabled was specified, a nanosecond column
-  // will have a physical type of int64. In that case, we fall through
-  // to the else if below.
-  //
-  // See https://issues.apache.org/jira/browse/ARROW-2082
-  if (is_nanosecond && ctx_->properties->support_deprecated_int96_timestamps() &&
-      !ctx_->properties->coerce_timestamps_enabled()) {
-    return TypedWriteBatch<Int96Type, ::arrow::TimestampType>(values, num_levels,
-                                                              def_levels, rep_levels);
-  } else if (is_nanosecond ||
-             (ctx_->properties->coerce_timestamps_enabled() &&
-              (type.unit() != ctx_->properties->coerce_timestamps_unit()))) {
-    // Casting is required. This covers several cases
-    // * Nanoseconds -> cast to microseconds
-    // * coerce_timestamps_enabled_, cast all timestamps to requested unit
-    return WriteTimestampsCoerce(values, num_levels, def_levels, rep_levels);
-  } else {
-    // No casting of timestamps is required, take the fast path
-    return TypedWriteBatch<Int64Type, ::arrow::TimestampType>(values, num_levels,
-                                                              def_levels, rep_levels);
-  }
-}
-
-Status ArrowColumnWriter::WriteTimestampsCoerce(const Array& array, int64_t num_levels,
-                                                const int16_t* def_levels,
-                                                const int16_t* rep_levels) {
-  int64_t* buffer;
-  RETURN_NOT_OK(ctx_->GetScratchData<int64_t>(num_levels, &buffer));
-
-  const auto& data = static_cast<const ::arrow::TimestampArray&>(array);
-
-  auto values = data.raw_values();
-  const auto& type = static_cast<const ::arrow::TimestampType&>(*array.type());
-
-  TimeUnit::type target_unit = ctx_->properties->coerce_timestamps_enabled()
-                                   ? ctx_->properties->coerce_timestamps_unit()
-                                   : TimeUnit::MICRO;
-  auto target_type = ::arrow::timestamp(target_unit);
-
-  auto DivideBy = [&](const int64_t factor) {
-    for (int64_t i = 0; i < array.length(); i++) {
-      if (!data.IsNull(i) && (values[i] % factor != 0)) {
-        std::stringstream ss;
-        ss << "Casting from " << type.ToString() << " to " << target_type->ToString()
-           << " would lose data: " << values[i];
-        return Status::Invalid(ss.str());
-      }
-      buffer[i] = values[i] / factor;
-    }
-    return Status::OK();
-  };
-
-  auto MultiplyBy = [&](const int64_t factor) {
-    for (int64_t i = 0; i < array.length(); i++) {
-      buffer[i] = values[i] * factor;
-    }
-    return Status::OK();
-  };
-
-  if (type.unit() == TimeUnit::NANO) {
-    if (target_unit == TimeUnit::MICRO) {
-      RETURN_NOT_OK(DivideBy(1000));
-    } else {
-      DCHECK_EQ(TimeUnit::MILLI, target_unit);
-      RETURN_NOT_OK(DivideBy(1000000));
-    }
-  } else if (type.unit() == TimeUnit::SECOND) {
-    RETURN_NOT_OK(MultiplyBy(target_unit == TimeUnit::MICRO ? 1000000 : 1000));
-  } else if (type.unit() == TimeUnit::MILLI) {
-    DCHECK_EQ(TimeUnit::MICRO, target_unit);
-    RETURN_NOT_OK(MultiplyBy(1000));
-  } else {
-    DCHECK_EQ(TimeUnit::MILLI, target_unit);
-    RETURN_NOT_OK(DivideBy(1000));
-  }
-
-  if (writer_->descr()->schema_node()->is_required() || (data.null_count() == 0)) {
-    // no nulls, just dump the data
-    RETURN_NOT_OK((WriteNonNullableBatch<Int64Type, ::arrow::TimestampType>(
-        static_cast<const ::arrow::TimestampType&>(*target_type), array.length(),
-        num_levels, def_levels, rep_levels, buffer)));
-  } else {
-    const uint8_t* valid_bits = data.null_bitmap_data();
-    RETURN_NOT_OK((WriteNullableBatch<Int64Type, ::arrow::TimestampType>(
-        static_cast<const ::arrow::TimestampType&>(*target_type), array.length(),
-        num_levels, def_levels, rep_levels, valid_bits, data.offset(), buffer)));
-  }
-  return Status::OK();
-}
-
-// This specialization seems quite similar but it significantly differs in two points:
-// * offset is added at the most latest time to the pointer as we have sub-byte access
-// * Arrow data is stored bitwise thus we cannot use std::copy to transform from
-//   ArrowType::c_type to ParquetType::c_type
-
-template <>
-Status ArrowColumnWriter::TypedWriteBatch<BooleanType, ::arrow::BooleanType>(
-    const Array& array, int64_t num_levels, const int16_t* def_levels,
-    const int16_t* rep_levels) {
-  bool* buffer;
-  RETURN_NOT_OK(ctx_->GetScratchData<bool>(array.length(), &buffer));
-
-  const auto& data = static_cast<const BooleanArray&>(array);
-  const uint8_t* values = nullptr;
-  // The values buffer may be null if the array is empty (ARROW-2744)
-  if (data.values() != nullptr) {
-    values = reinterpret_cast<const uint8_t*>(data.values()->data());
-  } else {
-    DCHECK_EQ(data.length(), 0);
-  }
-
-  int buffer_idx = 0;
-  int64_t offset = array.offset();
-  for (int i = 0; i < data.length(); i++) {
-    if (!data.IsNull(i)) {
-      buffer[buffer_idx++] = BitUtil::GetBit(values, offset + i);
-    }
-  }
-
-  return WriteBatch<BooleanType>(num_levels, def_levels, rep_levels, buffer);
-}
-
-template <>
-Status ArrowColumnWriter::TypedWriteBatch<Int32Type, ::arrow::NullType>(
-    const Array& array, int64_t num_levels, const int16_t* def_levels,
-    const int16_t* rep_levels) {
-  return WriteBatch<Int32Type>(num_levels, def_levels, rep_levels, nullptr);
-}
-
-template <>
-Status ArrowColumnWriter::TypedWriteBatch<ByteArrayType, ::arrow::BinaryType>(
-    const Array& array, int64_t num_levels, const int16_t* def_levels,
-    const int16_t* rep_levels) {
-  ByteArray* buffer;
-  RETURN_NOT_OK(ctx_->GetScratchData<ByteArray>(num_levels, &buffer));
-
-  const auto& data = static_cast<const BinaryArray&>(array);
-
-  // In the case of an array consisting of only empty strings or all null,
-  // data.data() points already to a nullptr, thus data.data()->data() will
-  // segfault.
-  const uint8_t* values = nullptr;
-  if (data.value_data()) {
-    values = reinterpret_cast<const uint8_t*>(data.value_data()->data());
-    DCHECK(values != nullptr);
-  }
-
-  // Slice offset is accounted for in raw_value_offsets
-  const int32_t* value_offset = data.raw_value_offsets();
-
-  if (writer_->descr()->schema_node()->is_required() || (data.null_count() == 0)) {
-    // no nulls, just dump the data
-    for (int64_t i = 0; i < data.length(); i++) {
-      buffer[i] =
-          ByteArray(value_offset[i + 1] - value_offset[i], values + value_offset[i]);
-    }
-  } else {
-    int buffer_idx = 0;
-    for (int64_t i = 0; i < data.length(); i++) {
-      if (!data.IsNull(i)) {
-        buffer[buffer_idx++] =
-            ByteArray(value_offset[i + 1] - value_offset[i], values + value_offset[i]);
-      }
-    }
-  }
-
-  return WriteBatch<ByteArrayType>(num_levels, def_levels, rep_levels, buffer);
-}
-
-template <>
-Status ArrowColumnWriter::TypedWriteBatch<FLBAType, ::arrow::FixedSizeBinaryType>(
-    const Array& array, int64_t num_levels, const int16_t* def_levels,
-    const int16_t* rep_levels) {
-  const auto& data = static_cast<const FixedSizeBinaryArray&>(array);
-  const int64_t length = data.length();
-
-  FLBA* buffer;
-  RETURN_NOT_OK(ctx_->GetScratchData<FLBA>(num_levels, &buffer));
-
-  if (writer_->descr()->schema_node()->is_required() || data.null_count() == 0) {
-    // no nulls, just dump the data
-    // todo(advancedxy): use a writeBatch to avoid this step
-    for (int64_t i = 0; i < length; i++) {
-      buffer[i] = FixedLenByteArray(data.GetValue(i));
-    }
-  } else {
-    int buffer_idx = 0;
-    for (int64_t i = 0; i < length; i++) {
-      if (!data.IsNull(i)) {
-        buffer[buffer_idx++] = FixedLenByteArray(data.GetValue(i));
-      }
-    }
-  }
-
-  return WriteBatch<FLBAType>(num_levels, def_levels, rep_levels, buffer);
-}
-
-template <>
-Status ArrowColumnWriter::TypedWriteBatch<FLBAType, ::arrow::Decimal128Type>(
-    const Array& array, int64_t num_levels, const int16_t* def_levels,
-    const int16_t* rep_levels) {
-  const auto& data = static_cast<const Decimal128Array&>(array);
-  const int64_t length = data.length();
-
-  FLBA* buffer;
-  RETURN_NOT_OK(ctx_->GetScratchData<FLBA>(num_levels, &buffer));
-
-  const auto& decimal_type = static_cast<const ::arrow::Decimal128Type&>(*data.type());
-  const int32_t offset =
-      decimal_type.byte_width() - DecimalSize(decimal_type.precision());
-
-  const bool does_not_have_nulls =
-      writer_->descr()->schema_node()->is_required() || data.null_count() == 0;
-
-  const auto valid_value_count = static_cast<size_t>(length - data.null_count()) * 2;
-  std::vector<uint64_t> big_endian_values(valid_value_count);
-
-  // TODO(phillipc): Look into whether our compilers will perform loop unswitching so we
-  // don't have to keep writing two loops to handle the case where we know there are no
-  // nulls
-  if (does_not_have_nulls) {
-    // no nulls, just dump the data
-    // todo(advancedxy): use a writeBatch to avoid this step
-    for (int64_t i = 0, j = 0; i < length; ++i, j += 2) {
-      auto unsigned_64_bit = reinterpret_cast<const uint64_t*>(data.GetValue(i));
-      big_endian_values[j] = ::arrow::BitUtil::ToBigEndian(unsigned_64_bit[1]);
-      big_endian_values[j + 1] = ::arrow::BitUtil::ToBigEndian(unsigned_64_bit[0]);
-      buffer[i] = FixedLenByteArray(
-          reinterpret_cast<const uint8_t*>(&big_endian_values[j]) + offset);
-    }
-  } else {
-    for (int64_t i = 0, buffer_idx = 0, j = 0; i < length; ++i) {
-      if (!data.IsNull(i)) {
-        auto unsigned_64_bit = reinterpret_cast<const uint64_t*>(data.GetValue(i));
-        big_endian_values[j] = ::arrow::BitUtil::ToBigEndian(unsigned_64_bit[1]);
-        big_endian_values[j + 1] = ::arrow::BitUtil::ToBigEndian(unsigned_64_bit[0]);
-        buffer[buffer_idx++] = FixedLenByteArray(
-            reinterpret_cast<const uint8_t*>(&big_endian_values[j]) + offset);
-        j += 2;
-      }
-    }
-  }
-
-  return WriteBatch<FLBAType>(num_levels, def_levels, rep_levels, buffer);
-}
-
-Status ArrowColumnWriter::Write(const Array& data) {
-  ::arrow::Type::type values_type;
-  RETURN_NOT_OK(GetLeafType(*data.type(), &values_type));
-
-  std::shared_ptr<Array> _values_array;
-  int64_t values_offset;
-  int64_t num_levels;
-  int64_t num_values;
-  LevelBuilder level_builder(ctx_->memory_pool);
-
-  std::shared_ptr<Buffer> def_levels_buffer, rep_levels_buffer;
-  RETURN_NOT_OK(level_builder.GenerateLevels(
-      data, field_, &values_offset, &num_values, &num_levels, ctx_->def_levels_buffer,
-      &def_levels_buffer, &rep_levels_buffer, &_values_array));
-  const int16_t* def_levels = nullptr;
-  if (def_levels_buffer) {
-    def_levels = reinterpret_cast<const int16_t*>(def_levels_buffer->data());
-  }
-  const int16_t* rep_levels = nullptr;
-  if (rep_levels_buffer) {
-    rep_levels = reinterpret_cast<const int16_t*>(rep_levels_buffer->data());
-  }
-  std::shared_ptr<Array> values_array = _values_array->Slice(values_offset, num_values);
-
-#define WRITE_BATCH_CASE(ArrowEnum, ArrowType, ParquetType)                            \
-  case ::arrow::Type::ArrowEnum:                                                       \
-    return TypedWriteBatch<ParquetType, ::arrow::ArrowType>(*values_array, num_levels, \
-                                                            def_levels, rep_levels);
-
-  switch (values_type) {
-    case ::arrow::Type::UINT32: {
-      if (writer_->properties()->version() == ParquetVersion::PARQUET_1_0) {
-        // Parquet 1.0 reader cannot read the UINT_32 logical type. Thus we need
-        // to use the larger Int64Type to store them lossless.
-        return TypedWriteBatch<Int64Type, ::arrow::UInt32Type>(*values_array, num_levels,
-                                                               def_levels, rep_levels);
-      } else {
-        return TypedWriteBatch<Int32Type, ::arrow::UInt32Type>(*values_array, num_levels,
-                                                               def_levels, rep_levels);
-      }
-    }
-      WRITE_BATCH_CASE(NA, NullType, Int32Type)
-    case ::arrow::Type::TIMESTAMP:
-      return WriteTimestamps(*values_array, num_levels, def_levels, rep_levels);
-      WRITE_BATCH_CASE(BOOL, BooleanType, BooleanType)
-      WRITE_BATCH_CASE(INT8, Int8Type, Int32Type)
-      WRITE_BATCH_CASE(UINT8, UInt8Type, Int32Type)
-      WRITE_BATCH_CASE(INT16, Int16Type, Int32Type)
-      WRITE_BATCH_CASE(UINT16, UInt16Type, Int32Type)
-      WRITE_BATCH_CASE(INT32, Int32Type, Int32Type)
-      WRITE_BATCH_CASE(INT64, Int64Type, Int64Type)
-      WRITE_BATCH_CASE(UINT64, UInt64Type, Int64Type)
-      WRITE_BATCH_CASE(FLOAT, FloatType, FloatType)
-      WRITE_BATCH_CASE(DOUBLE, DoubleType, DoubleType)
-      WRITE_BATCH_CASE(BINARY, BinaryType, ByteArrayType)
-      WRITE_BATCH_CASE(STRING, BinaryType, ByteArrayType)
-      WRITE_BATCH_CASE(FIXED_SIZE_BINARY, FixedSizeBinaryType, FLBAType)
-      WRITE_BATCH_CASE(DECIMAL, Decimal128Type, FLBAType)
-      WRITE_BATCH_CASE(DATE32, Date32Type, Int32Type)
-      WRITE_BATCH_CASE(DATE64, Date64Type, Int32Type)
-      WRITE_BATCH_CASE(TIME32, Time32Type, Int32Type)
-      WRITE_BATCH_CASE(TIME64, Time64Type, Int64Type)
-    default:
-      break;
-  }
-  std::stringstream ss;
-  ss << "Data type not supported as list value: " << values_array->type()->ToString();
-  return Status::NotImplemented(ss.str());
-}
-
-}  // namespace
-
-// ----------------------------------------------------------------------
-// FileWriter implementation
-
-class FileWriter::Impl {
- public:
-  Impl(MemoryPool* pool, std::unique_ptr<ParquetFileWriter> writer,
-       const std::shared_ptr<ArrowWriterProperties>& arrow_properties)
-      : writer_(std::move(writer)),
-        row_group_writer_(nullptr),
-        column_write_context_(pool, arrow_properties.get()),
-        arrow_properties_(arrow_properties),
-        closed_(false) {}
-
-  Status NewRowGroup(int64_t chunk_size) {
-    if (row_group_writer_ != nullptr) {
-      PARQUET_CATCH_NOT_OK(row_group_writer_->Close());
-    }
-    PARQUET_CATCH_NOT_OK(row_group_writer_ = writer_->AppendRowGroup());
-    return Status::OK();
-  }
-
-  Status Close() {
-    if (!closed_) {
-      // Make idempotent
-      closed_ = true;
-      if (row_group_writer_ != nullptr) {
-        PARQUET_CATCH_NOT_OK(row_group_writer_->Close());
-      }
-      PARQUET_CATCH_NOT_OK(writer_->Close());
-    }
-    return Status::OK();
-  }
-
-  Status WriteColumnChunk(const Array& data) {
-    // A bit awkward here since cannot instantiate ChunkedArray from const Array&
-    ::arrow::ArrayVector chunks = {::arrow::MakeArray(data.data())};
-    auto chunked_array = std::make_shared<::arrow::ChunkedArray>(chunks);
-    return WriteColumnChunk(chunked_array, 0, data.length());
-  }
-
-  Status WriteColumnChunk(const std::shared_ptr<ChunkedArray>& data, int64_t offset,
-                          const int64_t size) {
-    // DictionaryArrays are not yet handled with a fast path. To still support
-    // writing them as a workaround, we convert them back to their non-dictionary
-    // representation.
-    if (data->type()->id() == ::arrow::Type::DICTIONARY) {
-      const ::arrow::DictionaryType& dict_type =
-          static_cast<const ::arrow::DictionaryType&>(*data->type());
-
-      // TODO(ARROW-1648): Remove this special handling once we require an Arrow
-      // version that has this fixed.
-      if (dict_type.dictionary()->type()->id() == ::arrow::Type::NA) {
-        auto null_array = std::make_shared<::arrow::NullArray>(data->length());
-        return WriteColumnChunk(*null_array);
-      }
-
-      FunctionContext ctx(this->memory_pool());
-      ::arrow::compute::Datum cast_input(data);
-      ::arrow::compute::Datum cast_output;
-      RETURN_NOT_OK(Cast(&ctx, cast_input, dict_type.dictionary()->type(), CastOptions(),
-                         &cast_output));
-      return WriteColumnChunk(cast_output.chunked_array(), offset, size);
-    }
-
-    ColumnWriter* column_writer;
-    PARQUET_CATCH_NOT_OK(column_writer = row_group_writer_->NextColumn());
-
-    // TODO(wesm): This trick to construct a schema for one Parquet root node
-    // will not work for arbitrary nested data
-    int current_column_idx = row_group_writer_->current_column();
-    std::shared_ptr<::arrow::Schema> arrow_schema;
-    RETURN_NOT_OK(FromParquetSchema(writer_->schema(), {current_column_idx - 1},
-                                    writer_->key_value_metadata(), &arrow_schema));
-
-    ArrowColumnWriter arrow_writer(&column_write_context_, column_writer,
-                                   arrow_schema->field(0));
-
-    RETURN_NOT_OK(arrow_writer.Write(*data, offset, size));
-    return arrow_writer.Close();
-  }
-
-  const WriterProperties& properties() const { return *writer_->properties(); }
-
-  ::arrow::MemoryPool* memory_pool() const { return column_write_context_.memory_pool; }
-
-  virtual ~Impl() {}
-
- private:
-  friend class FileWriter;
-
-  std::unique_ptr<ParquetFileWriter> writer_;
-  RowGroupWriter* row_group_writer_;
-  ColumnWriterContext column_write_context_;
-  std::shared_ptr<ArrowWriterProperties> arrow_properties_;
-  bool closed_;
-};
-
-Status FileWriter::NewRowGroup(int64_t chunk_size) {
-  return impl_->NewRowGroup(chunk_size);
-}
-
-Status FileWriter::WriteColumnChunk(const ::arrow::Array& data) {
-  return impl_->WriteColumnChunk(data);
-}
-
-Status FileWriter::WriteColumnChunk(const std::shared_ptr<::arrow::ChunkedArray>& data,
-                                    const int64_t offset, const int64_t size) {
-  return impl_->WriteColumnChunk(data, offset, size);
-}
-
-Status FileWriter::WriteColumnChunk(const std::shared_ptr<::arrow::ChunkedArray>& data) {
-  return WriteColumnChunk(data, 0, data->length());
-}
-
-Status FileWriter::Close() { return impl_->Close(); }
-
-MemoryPool* FileWriter::memory_pool() const { return impl_->memory_pool(); }
-
-FileWriter::~FileWriter() {}
-
-FileWriter::FileWriter(MemoryPool* pool, std::unique_ptr<ParquetFileWriter> writer,
-                       const std::shared_ptr<ArrowWriterProperties>& arrow_properties)
-    : impl_(new FileWriter::Impl(pool, std::move(writer), arrow_properties)) {}
-
-Status FileWriter::Open(const ::arrow::Schema& schema, ::arrow::MemoryPool* pool,
-                        const std::shared_ptr<OutputStream>& sink,
-                        const std::shared_ptr<WriterProperties>& properties,
-                        std::unique_ptr<FileWriter>* writer) {
-  return Open(schema, pool, sink, properties, default_arrow_writer_properties(), writer);
-}
-
-Status FileWriter::Open(const ::arrow::Schema& schema, ::arrow::MemoryPool* pool,
-                        const std::shared_ptr<OutputStream>& sink,
-                        const std::shared_ptr<WriterProperties>& properties,
-                        const std::shared_ptr<ArrowWriterProperties>& arrow_properties,
-                        std::unique_ptr<FileWriter>* writer) {
-  std::shared_ptr<SchemaDescriptor> parquet_schema;
-  RETURN_NOT_OK(
-      ToParquetSchema(&schema, *properties, *arrow_properties, &parquet_schema));
-
-  auto schema_node = std::static_pointer_cast<GroupNode>(parquet_schema->schema_root());
-
-  std::unique_ptr<ParquetFileWriter> base_writer =
-      ParquetFileWriter::Open(sink, schema_node, properties, schema.metadata());
-
-  writer->reset(new FileWriter(pool, std::move(base_writer), arrow_properties));
-  return Status::OK();
-}
-
-Status FileWriter::Open(const ::arrow::Schema& schema, ::arrow::MemoryPool* pool,
-                        const std::shared_ptr<::arrow::io::OutputStream>& sink,
-                        const std::shared_ptr<WriterProperties>& properties,
-                        std::unique_ptr<FileWriter>* writer) {
-  auto wrapper = std::make_shared<ArrowOutputStream>(sink);
-  return Open(schema, pool, wrapper, properties, writer);
-}
-
-Status FileWriter::Open(const ::arrow::Schema& schema, ::arrow::MemoryPool* pool,
-                        const std::shared_ptr<::arrow::io::OutputStream>& sink,
-                        const std::shared_ptr<WriterProperties>& properties,
-                        const std::shared_ptr<ArrowWriterProperties>& arrow_properties,
-                        std::unique_ptr<FileWriter>* writer) {
-  auto wrapper = std::make_shared<ArrowOutputStream>(sink);
-  return Open(schema, pool, wrapper, properties, arrow_properties, writer);
-}
-
-Status WriteFileMetaData(const FileMetaData& file_metadata, OutputStream* sink) {
-  PARQUET_CATCH_NOT_OK(::parquet::WriteFileMetaData(file_metadata, sink));
-  return Status::OK();
-}
-
-Status WriteFileMetaData(const FileMetaData& file_metadata,
-                         const std::shared_ptr<::arrow::io::OutputStream>& sink) {
-  ArrowOutputStream wrapper(sink);
-  return ::parquet::arrow::WriteFileMetaData(file_metadata, &wrapper);
-}
-
-namespace {}  // namespace
-
-Status FileWriter::WriteTable(const Table& table, int64_t chunk_size) {
-  if (chunk_size <= 0) {
-    return Status::Invalid("chunk size per row_group must be greater than 0");
-  } else if (chunk_size > impl_->properties().max_row_group_length()) {
-    chunk_size = impl_->properties().max_row_group_length();
-  }
-
-  for (int chunk = 0; chunk * chunk_size < table.num_rows(); chunk++) {
-    int64_t offset = chunk * chunk_size;
-    int64_t size = std::min(chunk_size, table.num_rows() - offset);
-
-    RETURN_NOT_OK_ELSE(NewRowGroup(size), PARQUET_IGNORE_NOT_OK(Close()));
-    for (int i = 0; i < table.num_columns(); i++) {
-      auto chunked_data = table.column(i)->data();
-      RETURN_NOT_OK_ELSE(WriteColumnChunk(chunked_data, offset, size),
-                         PARQUET_IGNORE_NOT_OK(Close()));
-    }
-  }
-  return Status::OK();
-}
-
-Status WriteTable(const ::arrow::Table& table, ::arrow::MemoryPool* pool,
-                  const std::shared_ptr<OutputStream>& sink, int64_t chunk_size,
-                  const std::shared_ptr<WriterProperties>& properties,
-                  const std::shared_ptr<ArrowWriterProperties>& arrow_properties) {
-  std::unique_ptr<FileWriter> writer;
-  RETURN_NOT_OK(FileWriter::Open(*table.schema(), pool, sink, properties,
-                                 arrow_properties, &writer));
-  RETURN_NOT_OK(writer->WriteTable(table, chunk_size));
-  return writer->Close();
-}
-
-Status WriteTable(const ::arrow::Table& table, ::arrow::MemoryPool* pool,
-                  const std::shared_ptr<::arrow::io::OutputStream>& sink,
-                  int64_t chunk_size, const std::shared_ptr<WriterProperties>& properties,
-                  const std::shared_ptr<ArrowWriterProperties>& arrow_properties) {
-  auto wrapper = std::make_shared<ArrowOutputStream>(sink);
-  return WriteTable(table, pool, wrapper, chunk_size, properties, arrow_properties);
-}
-
-}  // namespace arrow
-}  // namespace parquet
diff --git a/src/parquet/arrow/writer.h b/src/parquet/arrow/writer.h
deleted file mode 100644
index ad6f1d5..0000000
--- a/src/parquet/arrow/writer.h
+++ /dev/null
@@ -1,210 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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.
-
-#ifndef PARQUET_ARROW_WRITER_H
-#define PARQUET_ARROW_WRITER_H
-
-#include <memory>
-
-#include "parquet/api/schema.h"
-#include "parquet/api/writer.h"
-
-#include "arrow/io/interfaces.h"
-#include "arrow/type.h"
-
-namespace arrow {
-
-class Array;
-class MemoryPool;
-class PrimitiveArray;
-class Schema;
-class Status;
-class StringArray;
-class Table;
-}  // namespace arrow
-
-namespace parquet {
-namespace arrow {
-
-class PARQUET_EXPORT ArrowWriterProperties {
- public:
-  class Builder {
-   public:
-    Builder() : write_nanos_as_int96_(false), coerce_timestamps_enabled_(false) {}
-    virtual ~Builder() {}
-
-    Builder* disable_deprecated_int96_timestamps() {
-      write_nanos_as_int96_ = false;
-      return this;
-    }
-
-    Builder* enable_deprecated_int96_timestamps() {
-      write_nanos_as_int96_ = true;
-      return this;
-    }
-
-    Builder* coerce_timestamps(::arrow::TimeUnit::type unit) {
-      coerce_timestamps_enabled_ = true;
-      coerce_timestamps_unit_ = unit;
-      return this;
-    }
-
-    std::shared_ptr<ArrowWriterProperties> build() {
-      return std::shared_ptr<ArrowWriterProperties>(new ArrowWriterProperties(
-          write_nanos_as_int96_, coerce_timestamps_enabled_, coerce_timestamps_unit_));
-    }
-
-   private:
-    bool write_nanos_as_int96_;
-
-    bool coerce_timestamps_enabled_;
-    ::arrow::TimeUnit::type coerce_timestamps_unit_;
-  };
-
-  bool support_deprecated_int96_timestamps() const { return write_nanos_as_int96_; }
-
-  bool coerce_timestamps_enabled() const { return coerce_timestamps_enabled_; }
-  ::arrow::TimeUnit::type coerce_timestamps_unit() const {
-    return coerce_timestamps_unit_;
-  }
-
- private:
-  explicit ArrowWriterProperties(bool write_nanos_as_int96,
-                                 bool coerce_timestamps_enabled,
-                                 ::arrow::TimeUnit::type coerce_timestamps_unit)
-      : write_nanos_as_int96_(write_nanos_as_int96),
-        coerce_timestamps_enabled_(coerce_timestamps_enabled),
-        coerce_timestamps_unit_(coerce_timestamps_unit) {}
-
-  const bool write_nanos_as_int96_;
-  const bool coerce_timestamps_enabled_;
-  const ::arrow::TimeUnit::type coerce_timestamps_unit_;
-};
-
-std::shared_ptr<ArrowWriterProperties> PARQUET_EXPORT default_arrow_writer_properties();
-
-/**
- * Iterative API:
- *  Start a new RowGroup/Chunk with NewRowGroup
- *  Write column-by-column the whole column chunk
- */
-class PARQUET_EXPORT FileWriter {
- public:
-  FileWriter(::arrow::MemoryPool* pool, std::unique_ptr<ParquetFileWriter> writer,
-             const std::shared_ptr<ArrowWriterProperties>& arrow_properties =
-                 default_arrow_writer_properties());
-
-  static ::arrow::Status Open(const ::arrow::Schema& schema, ::arrow::MemoryPool* pool,
-                              const std::shared_ptr<OutputStream>& sink,
-                              const std::shared_ptr<WriterProperties>& properties,
-                              std::unique_ptr<FileWriter>* writer);
-
-  static ::arrow::Status Open(
-      const ::arrow::Schema& schema, ::arrow::MemoryPool* pool,
-      const std::shared_ptr<OutputStream>& sink,
-      const std::shared_ptr<WriterProperties>& properties,
-      const std::shared_ptr<ArrowWriterProperties>& arrow_properties,
-      std::unique_ptr<FileWriter>* writer);
-
-  static ::arrow::Status Open(const ::arrow::Schema& schema, ::arrow::MemoryPool* pool,
-                              const std::shared_ptr<::arrow::io::OutputStream>& sink,
-                              const std::shared_ptr<WriterProperties>& properties,
-                              std::unique_ptr<FileWriter>* writer);
-
-  static ::arrow::Status Open(
-      const ::arrow::Schema& schema, ::arrow::MemoryPool* pool,
-      const std::shared_ptr<::arrow::io::OutputStream>& sink,
-      const std::shared_ptr<WriterProperties>& properties,
-      const std::shared_ptr<ArrowWriterProperties>& arrow_properties,
-      std::unique_ptr<FileWriter>* writer);
-
-  /// \brief Write a Table to Parquet.
-  ::arrow::Status WriteTable(const ::arrow::Table& table, int64_t chunk_size);
-
-  ::arrow::Status NewRowGroup(int64_t chunk_size);
-  ::arrow::Status WriteColumnChunk(const ::arrow::Array& data);
-
-  /// \brief Write ColumnChunk in row group using slice of a ChunkedArray
-  ::arrow::Status WriteColumnChunk(const std::shared_ptr<::arrow::ChunkedArray>& data,
-                                   const int64_t offset, const int64_t size);
-  ::arrow::Status WriteColumnChunk(const std::shared_ptr<::arrow::ChunkedArray>& data);
-  ::arrow::Status Close();
-
-  virtual ~FileWriter();
-
-  ::arrow::MemoryPool* memory_pool() const;
-
- private:
-  class PARQUET_NO_EXPORT Impl;
-  std::unique_ptr<Impl> impl_;
-};
-
-/// \brief Write Parquet file metadata only to indicated OutputStream
-PARQUET_EXPORT
-::arrow::Status WriteFileMetaData(const FileMetaData& file_metadata, OutputStream* sink);
-
-/// \brief Write Parquet file metadata only to indicated Arrow OutputStream
-PARQUET_EXPORT
-::arrow::Status WriteFileMetaData(const FileMetaData& file_metadata,
-                                  const std::shared_ptr<::arrow::io::OutputStream>& sink);
-
-/**
- * Write a Table to Parquet.
- *
- * The table shall only consist of columns of primitive type or of primitive lists.
- */
-::arrow::Status PARQUET_EXPORT WriteTable(
-    const ::arrow::Table& table, ::arrow::MemoryPool* pool,
-    const std::shared_ptr<OutputStream>& sink, int64_t chunk_size,
-    const std::shared_ptr<WriterProperties>& properties = default_writer_properties(),
-    const std::shared_ptr<ArrowWriterProperties>& arrow_properties =
-        default_arrow_writer_properties());
-
-::arrow::Status PARQUET_EXPORT WriteTable(
-    const ::arrow::Table& table, ::arrow::MemoryPool* pool,
-    const std::shared_ptr<::arrow::io::OutputStream>& sink, int64_t chunk_size,
-    const std::shared_ptr<WriterProperties>& properties = default_writer_properties(),
-    const std::shared_ptr<ArrowWriterProperties>& arrow_properties =
-        default_arrow_writer_properties());
-
-namespace internal {
-
-/**
- * Timestamp conversion constants
- */
-constexpr int64_t kJulianEpochOffsetDays = INT64_C(2440588);
-constexpr int64_t kNanosecondsPerDay = INT64_C(86400000000000);
-
-/**
- * Converts nanosecond timestamps to Impala (Int96) format
- */
-inline void NanosecondsToImpalaTimestamp(const int64_t nanoseconds,
-                                         Int96* impala_timestamp) {
-  int64_t julian_days = (nanoseconds / kNanosecondsPerDay) + kJulianEpochOffsetDays;
-  (*impala_timestamp).value[2] = (uint32_t)julian_days;
-
-  int64_t last_day_nanos = nanoseconds % kNanosecondsPerDay;
-  int64_t* impala_last_day_nanos = reinterpret_cast<int64_t*>(impala_timestamp);
-  *impala_last_day_nanos = last_day_nanos;
-}
-
-}  // namespace internal
-
-}  // namespace arrow
-}  // namespace parquet
-
-#endif  // PARQUET_ARROW_WRITER_H
diff --git a/src/parquet/bloom_filter-test.cc b/src/parquet/bloom_filter-test.cc
deleted file mode 100644
index 96d2e06..0000000
--- a/src/parquet/bloom_filter-test.cc
+++ /dev/null
@@ -1,244 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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.
-
-#include <gtest/gtest.h>
-
-#include <algorithm>
-#include <random>
-#include <string>
-
-#include "arrow/io/file.h"
-#include "parquet/bloom_filter.h"
-#include "parquet/murmur3.h"
-#include "parquet/util/memory.h"
-#include "parquet/util/test-common.h"
-
-namespace parquet {
-namespace test {
-TEST(Murmur3Test, TestBloomFilter) {
-  uint64_t result;
-  const uint8_t bitset[8] = {0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7};
-  ByteArray byteArray(8, bitset);
-  MurmurHash3 murmur3;
-  result = murmur3.Hash(&byteArray);
-  EXPECT_EQ(result, UINT64_C(913737700387071329));
-}
-
-TEST(ConstructorTest, TestBloomFilter) {
-  BlockSplitBloomFilter bloom_filter;
-  EXPECT_NO_THROW(bloom_filter.Init(1000));
-
-  // It throws because the length cannot be zero
-  std::unique_ptr<uint8_t[]> bitset1(new uint8_t[1024]());
-  EXPECT_THROW(bloom_filter.Init(bitset1.get(), 0), ParquetException);
-
-  // It throws because the number of bytes of Bloom filter bitset must be a power of 2.
-  std::unique_ptr<uint8_t[]> bitset2(new uint8_t[1024]());
-  EXPECT_THROW(bloom_filter.Init(bitset2.get(), 1023), ParquetException);
-}
-
-// The BasicTest is used to test basic operations including InsertHash, FindHash and
-// serializing and de-serializing.
-TEST(BasicTest, TestBloomFilter) {
-  BlockSplitBloomFilter bloom_filter;
-  bloom_filter.Init(1024);
-
-  for (int i = 0; i < 10; i++) {
-    bloom_filter.InsertHash(bloom_filter.Hash(i));
-  }
-
-  for (int i = 0; i < 10; i++) {
-    EXPECT_TRUE(bloom_filter.FindHash(bloom_filter.Hash(i)));
-  }
-
-  // Serialize Bloom filter to memory output stream
-  InMemoryOutputStream sink;
-  bloom_filter.WriteTo(&sink);
-
-  // Deserialize Bloom filter from memory
-  InMemoryInputStream source(sink.GetBuffer());
-
-  BlockSplitBloomFilter de_bloom = BlockSplitBloomFilter::Deserialize(&source);
-
-  for (int i = 0; i < 10; i++) {
-    EXPECT_TRUE(de_bloom.FindHash(de_bloom.Hash(i)));
-  }
-}
-
-// Helper function to generate random string.
-std::string GetRandomString(uint32_t length) {
-  // Character set used to generate random string
-  const std::string charset =
-      "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
-
-  // The uuid_seed was generated by "uuidgen -r"
-  const std::string uuid_seed = "8de406aa-fb59-4195-a81c-5152af26433f";
-  std::seed_seq seed(uuid_seed.begin(), uuid_seed.end());
-  std::mt19937 generator(seed);
-  std::uniform_int_distribution<uint32_t> dist(0, static_cast<int>(charset.size() - 1));
-  std::string ret = "";
-
-  for (uint32_t i = 0; i < length; i++) {
-    ret += charset[dist(generator)];
-  }
-
-  return ret;
-}
-
-TEST(FPPTest, TestBloomFilter) {
-  // It counts the number of times FindHash returns true.
-  int exist = 0;
-
-  // Total count of elements that will be used
-#ifdef PARQUET_VALGRIND
-  const int total_count = 5000;
-#else
-  const int total_count = 100000;
-#endif
-
-  // Bloom filter fpp parameter
-  const double fpp = 0.01;
-
-  std::vector<std::string> members;
-  BlockSplitBloomFilter bloom_filter;
-  bloom_filter.Init(BlockSplitBloomFilter::OptimalNumOfBits(total_count, fpp));
-
-  // Insert elements into the Bloom filter
-  for (int i = 0; i < total_count; i++) {
-    // Insert random string which length is 8
-    std::string tmp = GetRandomString(8);
-    const ByteArray byte_array(8, reinterpret_cast<const uint8_t*>(tmp.c_str()));
-    members.push_back(tmp);
-    bloom_filter.InsertHash(bloom_filter.Hash(&byte_array));
-  }
-
-  for (int i = 0; i < total_count; i++) {
-    const ByteArray byte_array1(8, reinterpret_cast<const uint8_t*>(members[i].c_str()));
-    ASSERT_TRUE(bloom_filter.FindHash(bloom_filter.Hash(&byte_array1)));
-    std::string tmp = GetRandomString(7);
-    const ByteArray byte_array2(7, reinterpret_cast<const uint8_t*>(tmp.c_str()));
-
-    if (bloom_filter.FindHash(bloom_filter.Hash(&byte_array2))) {
-      exist++;
-    }
-  }
-
-  // The exist should be probably less than 1000 according default FPP 0.01.
-  EXPECT_TRUE(exist < total_count * fpp);
-}
-
-// The CompatibilityTest is used to test cross compatibility with parquet-mr, it reads
-// the Bloom filter binary generated by the Bloom filter class in the parquet-mr project
-// and tests whether the values inserted before could be filtered or not.
-
-// The Bloom filter binary is generated by three steps in from Parquet-mr.
-// Step 1: Construct a Bloom filter with 1024 bytes bitset.
-// Step 2: Insert "hello", "parquet", "bloom", "filter" to Bloom filter.
-// Step 3: Call writeTo API to write to File.
-TEST(CompatibilityTest, TestBloomFilter) {
-  const std::string test_string[4] = {"hello", "parquet", "bloom", "filter"};
-  const std::string bloom_filter_test_binary =
-      std::string(test::get_data_dir()) + "/bloom_filter.bin";
-  std::shared_ptr<::arrow::io::ReadableFile> handle;
-
-  int64_t size;
-  PARQUET_THROW_NOT_OK(
-      ::arrow::io::ReadableFile::Open(bloom_filter_test_binary, &handle));
-  PARQUET_THROW_NOT_OK(handle->GetSize(&size));
-
-  // 1024 bytes (bitset) + 4 bytes (hash) + 4 bytes (algorithm) + 4 bytes (length)
-  EXPECT_EQ(size, 1036);
-
-  std::unique_ptr<uint8_t[]> bitset(new uint8_t[size]());
-  std::shared_ptr<Buffer> buffer(new Buffer(bitset.get(), size));
-  PARQUET_THROW_NOT_OK(handle->Read(size, &buffer));
-
-  InMemoryInputStream source(buffer);
-  BlockSplitBloomFilter bloom_filter1 = BlockSplitBloomFilter::Deserialize(&source);
-
-  for (int i = 0; i < 4; i++) {
-    const ByteArray tmp(static_cast<uint32_t>(test_string[i].length()),
-                        reinterpret_cast<const uint8_t*>(test_string[i].c_str()));
-    EXPECT_TRUE(bloom_filter1.FindHash(bloom_filter1.Hash(&tmp)));
-  }
-
-  // The following is used to check whether the new created Bloom filter in parquet-cpp is
-  // byte-for-byte identical to file at bloom_data_path which is created from parquet-mr
-  // with same inserted hashes.
-  BlockSplitBloomFilter bloom_filter2;
-  bloom_filter2.Init(bloom_filter1.GetBitsetSize());
-  for (int i = 0; i < 4; i++) {
-    const ByteArray byte_array(static_cast<uint32_t>(test_string[i].length()),
-                               reinterpret_cast<const uint8_t*>(test_string[i].c_str()));
-    bloom_filter2.InsertHash(bloom_filter2.Hash(&byte_array));
-  }
-
-  // Serialize Bloom filter to memory output stream
-  InMemoryOutputStream sink;
-  bloom_filter2.WriteTo(&sink);
-  std::shared_ptr<Buffer> buffer1 = sink.GetBuffer();
-
-  PARQUET_THROW_NOT_OK(handle->Seek(0));
-  PARQUET_THROW_NOT_OK(handle->GetSize(&size));
-  std::shared_ptr<Buffer> buffer2;
-  PARQUET_THROW_NOT_OK(handle->Read(size, &buffer2));
-
-  EXPECT_TRUE((*buffer1).Equals(*buffer2));
-}
-
-// OptmialValueTest is used to test whether OptimalNumOfBits returns expected
-// numbers according to formula:
-//     num_of_bits = -8.0 * ndv / log(1 - pow(fpp, 1.0 / 8.0))
-// where ndv is the number of distinct values and fpp is the false positive probability.
-// Also it is used to test whether OptimalNumOfBits returns value between
-// [MINIMUM_BLOOM_FILTER_SIZE, MAXIMUM_BLOOM_FILTER_SIZE].
-TEST(OptimalValueTest, TestBloomFilter) {
-  EXPECT_EQ(BlockSplitBloomFilter::OptimalNumOfBits(256, 0.01), UINT32_C(4096));
-  EXPECT_EQ(BlockSplitBloomFilter::OptimalNumOfBits(512, 0.01), UINT32_C(8192));
-  EXPECT_EQ(BlockSplitBloomFilter::OptimalNumOfBits(1024, 0.01), UINT32_C(16384));
-  EXPECT_EQ(BlockSplitBloomFilter::OptimalNumOfBits(2048, 0.01), UINT32_C(32768));
-
-  EXPECT_EQ(BlockSplitBloomFilter::OptimalNumOfBits(200, 0.01), UINT32_C(2048));
-  EXPECT_EQ(BlockSplitBloomFilter::OptimalNumOfBits(300, 0.01), UINT32_C(4096));
-  EXPECT_EQ(BlockSplitBloomFilter::OptimalNumOfBits(700, 0.01), UINT32_C(8192));
-  EXPECT_EQ(BlockSplitBloomFilter::OptimalNumOfBits(1500, 0.01), UINT32_C(16384));
-
-  EXPECT_EQ(BlockSplitBloomFilter::OptimalNumOfBits(200, 0.025), UINT32_C(2048));
-  EXPECT_EQ(BlockSplitBloomFilter::OptimalNumOfBits(300, 0.025), UINT32_C(4096));
-  EXPECT_EQ(BlockSplitBloomFilter::OptimalNumOfBits(700, 0.025), UINT32_C(8192));
-  EXPECT_EQ(BlockSplitBloomFilter::OptimalNumOfBits(1500, 0.025), UINT32_C(16384));
-
-  EXPECT_EQ(BlockSplitBloomFilter::OptimalNumOfBits(200, 0.05), UINT32_C(2048));
-  EXPECT_EQ(BlockSplitBloomFilter::OptimalNumOfBits(300, 0.05), UINT32_C(4096));
-  EXPECT_EQ(BlockSplitBloomFilter::OptimalNumOfBits(700, 0.05), UINT32_C(8192));
-  EXPECT_EQ(BlockSplitBloomFilter::OptimalNumOfBits(1500, 0.05), UINT32_C(16384));
-
-  // Boundary check
-  EXPECT_EQ(BlockSplitBloomFilter::OptimalNumOfBits(4, 0.01), UINT32_C(256));
-  EXPECT_EQ(BlockSplitBloomFilter::OptimalNumOfBits(4, 0.25), UINT32_C(256));
-
-  EXPECT_EQ(
-      BlockSplitBloomFilter::OptimalNumOfBits(std::numeric_limits<uint32_t>::max(), 0.01),
-      UINT32_C(1073741824));
-  EXPECT_EQ(
-      BlockSplitBloomFilter::OptimalNumOfBits(std::numeric_limits<uint32_t>::max(), 0.25),
-      UINT32_C(1073741824));
-}
-
-}  // namespace test
-
-}  // namespace parquet
diff --git a/src/parquet/bloom_filter.cc b/src/parquet/bloom_filter.cc
deleted file mode 100644
index faa344c..0000000
--- a/src/parquet/bloom_filter.cc
+++ /dev/null
@@ -1,166 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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.
-
-#include <algorithm>
-#include <cmath>
-#include <cstdint>
-
-#include "arrow/status.h"
-#include "arrow/util/bit-util.h"
-#include "parquet/bloom_filter.h"
-#include "parquet/exception.h"
-#include "parquet/murmur3.h"
-#include "parquet/types.h"
-#include "parquet/util/logging.h"
-
-namespace parquet {
-constexpr uint32_t BlockSplitBloomFilter::SALT[kBitsSetPerBlock];
-
-BlockSplitBloomFilter::BlockSplitBloomFilter()
-    : pool_(::arrow::default_memory_pool()),
-      hash_strategy_(HashStrategy::MURMUR3_X64_128),
-      algorithm_(Algorithm::BLOCK) {}
-
-void BlockSplitBloomFilter::Init(uint32_t num_bytes) {
-  if (num_bytes < kMinimumBloomFilterBytes) {
-    num_bytes = kMinimumBloomFilterBytes;
-  }
-
-  // Get next power of 2 if it is not power of 2.
-  if ((num_bytes & (num_bytes - 1)) != 0) {
-    num_bytes = static_cast<uint32_t>(::arrow::BitUtil::NextPower2(num_bytes));
-  }
-
-  if (num_bytes > kMaximumBloomFilterBytes) {
-    num_bytes = kMaximumBloomFilterBytes;
-  }
-
-  num_bytes_ = num_bytes;
-  PARQUET_THROW_NOT_OK(::arrow::AllocateBuffer(pool_, num_bytes_, &data_));
-  memset(data_->mutable_data(), 0, num_bytes_);
-
-  this->hasher_.reset(new MurmurHash3());
-}
-
-void BlockSplitBloomFilter::Init(const uint8_t* bitset, uint32_t num_bytes) {
-  DCHECK(bitset != nullptr);
-
-  if (num_bytes < kMinimumBloomFilterBytes || num_bytes > kMaximumBloomFilterBytes ||
-      (num_bytes & (num_bytes - 1)) != 0) {
-    throw ParquetException("Given length of bitset is illegal");
-  }
-
-  num_bytes_ = num_bytes;
-  PARQUET_THROW_NOT_OK(::arrow::AllocateBuffer(pool_, num_bytes_, &data_));
-  memcpy(data_->mutable_data(), bitset, num_bytes_);
-
-  this->hasher_.reset(new MurmurHash3());
-}
-
-BlockSplitBloomFilter BlockSplitBloomFilter::Deserialize(InputStream* input) {
-  int64_t bytes_available;
-
-  const uint8_t* read_buffer = NULL;
-  read_buffer = input->Read(sizeof(uint32_t), &bytes_available);
-  if (static_cast<uint32_t>(bytes_available) != sizeof(uint32_t) || !read_buffer) {
-    throw ParquetException("Failed to deserialize from input stream");
-  }
-  uint32_t len;
-  memcpy(&len, read_buffer, sizeof(uint32_t));
-
-  read_buffer = input->Read(sizeof(uint32_t), &bytes_available);
-  if (static_cast<uint32_t>(bytes_available) != sizeof(uint32_t) || !read_buffer) {
-    throw ParquetException("Failed to deserialize from input stream");
-  }
-  uint32_t hash;
-  memcpy(&hash, read_buffer, sizeof(uint32_t));
-  if (static_cast<HashStrategy>(hash) != HashStrategy::MURMUR3_X64_128) {
-    throw ParquetException("Unsupported hash strategy");
-  }
-
-  read_buffer = input->Read(sizeof(uint32_t), &bytes_available);
-  if (static_cast<uint32_t>(bytes_available) != sizeof(uint32_t) || !read_buffer) {
-    throw ParquetException("Failed to deserialize from input stream");
-  }
-  uint32_t algorithm;
-  memcpy(&algorithm, read_buffer, sizeof(uint32_t));
-  if (static_cast<Algorithm>(algorithm) != BloomFilter::Algorithm::BLOCK) {
-    throw ParquetException("Unsupported Bloom filter algorithm");
-  }
-
-  BlockSplitBloomFilter bloom_filter;
-  bloom_filter.Init(input->Read(len, &bytes_available), len);
-  return bloom_filter;
-}
-
-void BlockSplitBloomFilter::WriteTo(OutputStream* sink) const {
-  DCHECK(sink != nullptr);
-
-  sink->Write(reinterpret_cast<const uint8_t*>(&num_bytes_), sizeof(num_bytes_));
-  sink->Write(reinterpret_cast<const uint8_t*>(&hash_strategy_), sizeof(hash_strategy_));
-  sink->Write(reinterpret_cast<const uint8_t*>(&algorithm_), sizeof(algorithm_));
-  sink->Write(data_->mutable_data(), num_bytes_);
-}
-
-void BlockSplitBloomFilter::SetMask(uint32_t key, BlockMask& block_mask) const {
-  for (int i = 0; i < kBitsSetPerBlock; ++i) {
-    block_mask.item[i] = key * SALT[i];
-  }
-
-  for (int i = 0; i < kBitsSetPerBlock; ++i) {
-    block_mask.item[i] = block_mask.item[i] >> 27;
-  }
-
-  for (int i = 0; i < kBitsSetPerBlock; ++i) {
-    block_mask.item[i] = UINT32_C(0x1) << block_mask.item[i];
-  }
-}
-
-bool BlockSplitBloomFilter::FindHash(uint64_t hash) const {
-  const uint32_t bucket_index =
-      static_cast<uint32_t>((hash >> 32) & (num_bytes_ / kBytesPerFilterBlock - 1));
-  uint32_t key = static_cast<uint32_t>(hash);
-  uint32_t* bitset32 = reinterpret_cast<uint32_t*>(data_->mutable_data());
-
-  // Calculate mask for bucket.
-  BlockMask block_mask;
-  SetMask(key, block_mask);
-
-  for (int i = 0; i < kBitsSetPerBlock; ++i) {
-    if (0 == (bitset32[kBitsSetPerBlock * bucket_index + i] & block_mask.item[i])) {
-      return false;
-    }
-  }
-  return true;
-}
-
-void BlockSplitBloomFilter::InsertHash(uint64_t hash) {
-  const uint32_t bucket_index =
-      static_cast<uint32_t>(hash >> 32) & (num_bytes_ / kBytesPerFilterBlock - 1);
-  uint32_t key = static_cast<uint32_t>(hash);
-  uint32_t* bitset32 = reinterpret_cast<uint32_t*>(data_->mutable_data());
-
-  // Calculate mask for bucket.
-  BlockMask block_mask;
-  SetMask(key, block_mask);
-
-  for (int i = 0; i < kBitsSetPerBlock; i++) {
-    bitset32[bucket_index * kBitsSetPerBlock + i] |= block_mask.item[i];
-  }
-}
-
-}  // namespace parquet
diff --git a/src/parquet/bloom_filter.h b/src/parquet/bloom_filter.h
deleted file mode 100644
index e39370a..0000000
--- a/src/parquet/bloom_filter.h
+++ /dev/null
@@ -1,244 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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.
-
-#ifndef PARQUET_BLOOM_FILTER_H
-#define PARQUET_BLOOM_FILTER_H
-
-#include <cstdint>
-
-#include "parquet/exception.h"
-#include "parquet/hasher.h"
-#include "parquet/types.h"
-#include "parquet/util/logging.h"
-#include "parquet/util/memory.h"
-
-namespace parquet {
-class OutputStream;
-
-// A Bloom filter is a compact structure to indicate whether an item is not in a set or
-// probably in a set. The Bloom filter usually consists of a bit set that represents a
-// set of elements, a hash strategy and a Bloom filter algorithm.
-class BloomFilter {
- public:
-  // Maximum Bloom filter size, it sets to HDFS default block size 128MB
-  // This value will be reconsidered when implementing Bloom filter producer.
-  static constexpr uint32_t kMaximumBloomFilterBytes = 128 * 1024 * 1024;
-
-  /// Determine whether an element exist in set or not.
-  ///
-  /// @param hash the element to contain.
-  /// @return false if value is definitely not in set, and true means PROBABLY
-  /// in set.
-  virtual bool FindHash(uint64_t hash) const = 0;
-
-  /// Insert element to set represented by Bloom filter bitset.
-  /// @param hash the hash of value to insert into Bloom filter.
-  virtual void InsertHash(uint64_t hash) = 0;
-
-  /// Write this Bloom filter to an output stream. A Bloom filter structure should
-  /// include bitset length, hash strategy, algorithm, and bitset.
-  ///
-  /// @param sink the output stream to write
-  virtual void WriteTo(OutputStream* sink) const = 0;
-
-  /// Get the number of bytes of bitset
-  virtual uint32_t GetBitsetSize() const = 0;
-
-  /// Compute hash for 32 bits value by using its plain encoding result.
-  ///
-  /// @param value the value to hash.
-  /// @return hash result.
-  virtual uint64_t Hash(int32_t value) const = 0;
-
-  /// Compute hash for 64 bits value by using its plain encoding result.
-  ///
-  /// @param value the value to hash.
-  /// @return hash result.
-  virtual uint64_t Hash(int64_t value) const = 0;
-
-  /// Compute hash for float value by using its plain encoding result.
-  ///
-  /// @param value the value to hash.
-  /// @return hash result.
-  virtual uint64_t Hash(float value) const = 0;
-
-  /// Compute hash for double value by using its plain encoding result.
-  ///
-  /// @param value the value to hash.
-  /// @return hash result.
-  virtual uint64_t Hash(double value) const = 0;
-
-  /// Compute hash for Int96 value by using its plain encoding result.
-  ///
-  /// @param value the value to hash.
-  /// @return hash result.
-  virtual uint64_t Hash(const Int96* value) const = 0;
-
-  /// Compute hash for ByteArray value by using its plain encoding result.
-  ///
-  /// @param value the value to hash.
-  /// @return hash result.
-  virtual uint64_t Hash(const ByteArray* value) const = 0;
-
-  /// Compute hash for fixed byte array value by using its plain encoding result.
-  ///
-  /// @param value the value to hash.
-  /// @return hash result.
-  virtual uint64_t Hash(const FLBA* value, uint32_t len) const = 0;
-
-  virtual ~BloomFilter() {}
-
- protected:
-  // Hash strategy available for Bloom filter.
-  enum class HashStrategy : uint32_t { MURMUR3_X64_128 = 0 };
-
-  // Bloom filter algorithm.
-  enum class Algorithm : uint32_t { BLOCK = 0 };
-};
-
-// The BlockSplitBloomFilter is implemented using block-based Bloom filters from
-// Putze et al.'s "Cache-,Hash- and Space-Efficient Bloom filters". The basic idea is to
-// hash the item to a tiny Bloom filter which size fit a single cache line or smaller.
-//
-// This implementation sets 8 bits in each tiny Bloom filter. Each tiny Bloom
-// filter is 32 bytes to take advantage of 32-byte SIMD instructions.
-class BlockSplitBloomFilter : public BloomFilter {
- public:
-  /// The constructor of BlockSplitBloomFilter. It uses murmur3_x64_128 as hash function.
-  BlockSplitBloomFilter();
-
-  /// Initialize the BlockSplitBloomFilter. The range of num_bytes should be within
-  /// [kMinimumBloomFilterBytes, kMaximumBloomFilterBytes], it will be
-  /// rounded up/down to lower/upper bound if num_bytes is out of range and also
-  /// will be rounded up to a power of 2.
-  ///
-  /// @param num_bytes The number of bytes to store Bloom filter bitset.
-  void Init(uint32_t num_bytes);
-
-  /// Initialize the BlockSplitBloomFilter. It copies the bitset as underlying
-  /// bitset because the given bitset may not satisfy the 32-byte alignment requirement
-  /// which may lead to segfault when performing SIMD instructions. It is the caller's
-  /// responsibility to free the bitset passed in. This is used when reconstructing
-  /// a Bloom filter from a parquet file.
-  ///
-  /// @param bitset The given bitset to initialize the Bloom filter.
-  /// @param num_bytes  The number of bytes of given bitset.
-  void Init(const uint8_t* bitset, uint32_t num_bytes);
-
-  // Minimum Bloom filter size, it sets to 32 bytes to fit a tiny Bloom filter.
-  static constexpr uint32_t kMinimumBloomFilterBytes = 32;
-
-  /// Calculate optimal size according to the number of distinct values and false
-  /// positive probability.
-  ///
-  /// @param ndv The number of distinct values.
-  /// @param fpp The false positive probability.
-  /// @return it always return a value between kMinimumBloomFilterBytes and
-  /// kMaximumBloomFilterBytes, and the return value is always a power of 2
-  static uint32_t OptimalNumOfBits(uint32_t ndv, double fpp) {
-    DCHECK(fpp > 0.0 && fpp < 1.0);
-    const double m = -8.0 * ndv / log(1 - pow(fpp, 1.0 / 8));
-    uint32_t num_bits = static_cast<uint32_t>(m);
-
-    // Handle overflow.
-    if (m < 0 || m > kMaximumBloomFilterBytes << 3) {
-      num_bits = static_cast<uint32_t>(kMaximumBloomFilterBytes << 3);
-    }
-
-    // Round up to lower bound
-    if (num_bits < kMinimumBloomFilterBytes << 3) {
-      num_bits = kMinimumBloomFilterBytes << 3;
-    }
-
-    // Get next power of 2 if bits is not power of 2.
-    if ((num_bits & (num_bits - 1)) != 0) {
-      num_bits = static_cast<uint32_t>(::arrow::BitUtil::NextPower2(num_bits));
-    }
-
-    // Round down to upper bound
-    if (num_bits > kMaximumBloomFilterBytes << 3) {
-      num_bits = kMaximumBloomFilterBytes << 3;
-    }
-
-    return num_bits;
-  }
-
-  bool FindHash(uint64_t hash) const override;
-  void InsertHash(uint64_t hash) override;
-  void WriteTo(OutputStream* sink) const override;
-  uint32_t GetBitsetSize() const override { return num_bytes_; }
-  uint64_t Hash(int64_t value) const override { return hasher_->Hash(value); }
-  uint64_t Hash(float value) const override { return hasher_->Hash(value); }
-  uint64_t Hash(double value) const override { return hasher_->Hash(value); }
-  uint64_t Hash(const Int96* value) const override { return hasher_->Hash(value); }
-  uint64_t Hash(const ByteArray* value) const override { return hasher_->Hash(value); }
-  uint64_t Hash(int32_t value) const override { return hasher_->Hash(value); }
-  uint64_t Hash(const FLBA* value, uint32_t len) const override {
-    return hasher_->Hash(value, len);
-  }
-  /// Deserialize the Bloom filter from an input stream. It is used when reconstructing
-  /// a Bloom filter from a parquet filter.
-  ///
-  /// @param input_stream The input stream from which to construct the Bloom filter
-  /// @return The BlockSplitBloomFilter.
-  static BlockSplitBloomFilter Deserialize(InputStream* input_stream);
-
- private:
-  // Bytes in a tiny Bloom filter block.
-  static constexpr int kBytesPerFilterBlock = 32;
-
-  // The number of bits to be set in each tiny Bloom filter
-  static constexpr int kBitsSetPerBlock = 8;
-
-  // A mask structure used to set bits in each tiny Bloom filter.
-  struct BlockMask {
-    uint32_t item[kBitsSetPerBlock];
-  };
-
-  // The block-based algorithm needs eight odd SALT values to calculate eight indexes
-  // of bit to set, one bit in each 32-bit word.
-  static constexpr uint32_t SALT[kBitsSetPerBlock] = {
-      0x47b6137bU, 0x44974d91U, 0x8824ad5bU, 0xa2b7289dU,
-      0x705495c7U, 0x2df1424bU, 0x9efc4947U, 0x5c6bfb31U};
-
-  /// Set bits in mask array according to input key.
-  /// @param key the value to calculate mask values.
-  /// @param mask the mask array is used to set inside a block
-  void SetMask(uint32_t key, BlockMask& mask) const;
-
-  // Memory pool to allocate aligned buffer for bitset
-  ::arrow::MemoryPool* pool_;
-
-  // The underlying buffer of bitset.
-  std::shared_ptr<Buffer> data_;
-
-  // The number of bytes of Bloom filter bitset.
-  uint32_t num_bytes_;
-
-  // Hash strategy used in this Bloom filter.
-  HashStrategy hash_strategy_;
-
-  // Algorithm used in this Bloom filter.
-  Algorithm algorithm_;
-
-  // The hash pointer points to actual hash class used.
-  std::unique_ptr<Hasher> hasher_;
-};
-
-}  // namespace parquet
-
-#endif  // PARQUET_BLOOM_FILTER_H
diff --git a/src/parquet/column-io-benchmark.cc b/src/parquet/column-io-benchmark.cc
deleted file mode 100644
index a9a7530..0000000
--- a/src/parquet/column-io-benchmark.cc
+++ /dev/null
@@ -1,237 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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.
-
-#include "benchmark/benchmark.h"
-
-#include "parquet/column_reader.h"
-#include "parquet/column_writer.h"
-#include "parquet/file_reader.h"
-#include "parquet/parquet_types.h"
-#include "parquet/util/memory.h"
-
-namespace parquet {
-
-using schema::PrimitiveNode;
-
-namespace benchmark {
-
-std::unique_ptr<Int64Writer> BuildWriter(int64_t output_size, OutputStream* dst,
-                                         ColumnChunkMetaDataBuilder* metadata,
-                                         ColumnDescriptor* schema,
-                                         const WriterProperties* properties) {
-  std::unique_ptr<PageWriter> pager =
-      PageWriter::Open(dst, Compression::UNCOMPRESSED, metadata);
-  return std::unique_ptr<Int64Writer>(
-      new Int64Writer(metadata, std::move(pager), Encoding::PLAIN, properties));
-}
-
-std::shared_ptr<ColumnDescriptor> Int64Schema(Repetition::type repetition) {
-  auto node = PrimitiveNode::Make("int64", repetition, Type::INT64);
-  return std::make_shared<ColumnDescriptor>(node, repetition != Repetition::REQUIRED,
-                                            repetition == Repetition::REPEATED);
-}
-
-void SetBytesProcessed(::benchmark::State& state, Repetition::type repetition) {
-  int64_t bytes_processed = state.iterations() * state.range(0) * sizeof(int64_t);
-  if (repetition != Repetition::REQUIRED) {
-    bytes_processed += state.iterations() * state.range(0) * sizeof(int16_t);
-  }
-  if (repetition == Repetition::REPEATED) {
-    bytes_processed += state.iterations() * state.range(0) * sizeof(int16_t);
-  }
-  state.SetBytesProcessed(state.iterations() * state.range(0) * sizeof(int16_t));
-}
-
-template <Repetition::type repetition,
-          Compression::type codec = Compression::UNCOMPRESSED>
-static void BM_WriteInt64Column(::benchmark::State& state) {
-  format::ColumnChunk thrift_metadata;
-  std::vector<int64_t> values(state.range(0), 128);
-  std::vector<int16_t> definition_levels(state.range(0), 1);
-  std::vector<int16_t> repetition_levels(state.range(0), 0);
-  std::shared_ptr<ColumnDescriptor> schema = Int64Schema(repetition);
-  WriterProperties::Builder builder;
-  std::shared_ptr<WriterProperties> properties = builder.compression(codec)->build();
-  auto metadata = ColumnChunkMetaDataBuilder::Make(
-      properties, schema.get(), reinterpret_cast<uint8_t*>(&thrift_metadata));
-
-  while (state.KeepRunning()) {
-    InMemoryOutputStream stream;
-    std::unique_ptr<Int64Writer> writer = BuildWriter(
-        state.range(0), &stream, metadata.get(), schema.get(), properties.get());
-    writer->WriteBatch(values.size(), definition_levels.data(), repetition_levels.data(),
-                       values.data());
-    writer->Close();
-  }
-  SetBytesProcessed(state, repetition);
-}
-
-BENCHMARK_TEMPLATE(BM_WriteInt64Column, Repetition::REQUIRED)->Range(1024, 65536);
-
-BENCHMARK_TEMPLATE(BM_WriteInt64Column, Repetition::OPTIONAL)->Range(1024, 65536);
-
-BENCHMARK_TEMPLATE(BM_WriteInt64Column, Repetition::REPEATED)->Range(1024, 65536);
-
-BENCHMARK_TEMPLATE(BM_WriteInt64Column, Repetition::REQUIRED, Compression::SNAPPY)
-    ->Range(1024, 65536);
-BENCHMARK_TEMPLATE(BM_WriteInt64Column, Repetition::OPTIONAL, Compression::SNAPPY)
-    ->Range(1024, 65536);
-BENCHMARK_TEMPLATE(BM_WriteInt64Column, Repetition::REPEATED, Compression::SNAPPY)
-    ->Range(1024, 65536);
-
-BENCHMARK_TEMPLATE(BM_WriteInt64Column, Repetition::REQUIRED, Compression::LZ4)
-    ->Range(1024, 65536);
-BENCHMARK_TEMPLATE(BM_WriteInt64Column, Repetition::OPTIONAL, Compression::LZ4)
-    ->Range(1024, 65536);
-BENCHMARK_TEMPLATE(BM_WriteInt64Column, Repetition::REPEATED, Compression::LZ4)
-    ->Range(1024, 65536);
-
-BENCHMARK_TEMPLATE(BM_WriteInt64Column, Repetition::REQUIRED, Compression::ZSTD)
-    ->Range(1024, 65536);
-BENCHMARK_TEMPLATE(BM_WriteInt64Column, Repetition::OPTIONAL, Compression::ZSTD)
-    ->Range(1024, 65536);
-BENCHMARK_TEMPLATE(BM_WriteInt64Column, Repetition::REPEATED, Compression::ZSTD)
-    ->Range(1024, 65536);
-
-std::unique_ptr<Int64Reader> BuildReader(std::shared_ptr<Buffer>& buffer,
-                                         int64_t num_values, ColumnDescriptor* schema) {
-  std::unique_ptr<InMemoryInputStream> source(new InMemoryInputStream(buffer));
-  std::unique_ptr<PageReader> page_reader =
-      PageReader::Open(std::move(source), num_values, Compression::UNCOMPRESSED);
-  return std::unique_ptr<Int64Reader>(new Int64Reader(schema, std::move(page_reader)));
-}
-
-template <Repetition::type repetition,
-          Compression::type codec = Compression::UNCOMPRESSED>
-static void BM_ReadInt64Column(::benchmark::State& state) {
-  format::ColumnChunk thrift_metadata;
-  std::vector<int64_t> values(state.range(0), 128);
-  std::vector<int16_t> definition_levels(state.range(0), 1);
-  std::vector<int16_t> repetition_levels(state.range(0), 0);
-  std::shared_ptr<ColumnDescriptor> schema = Int64Schema(repetition);
-  WriterProperties::Builder builder;
-  std::shared_ptr<WriterProperties> properties = builder.compression(codec)->build();
-  auto metadata = ColumnChunkMetaDataBuilder::Make(
-      properties, schema.get(), reinterpret_cast<uint8_t*>(&thrift_metadata));
-
-  InMemoryOutputStream stream;
-  std::unique_ptr<Int64Writer> writer = BuildWriter(
-      state.range(0), &stream, metadata.get(), schema.get(), properties.get());
-  writer->WriteBatch(values.size(), definition_levels.data(), repetition_levels.data(),
-                     values.data());
-  writer->Close();
-
-  std::shared_ptr<Buffer> src = stream.GetBuffer();
-  std::vector<int64_t> values_out(state.range(1));
-  std::vector<int16_t> definition_levels_out(state.range(1));
-  std::vector<int16_t> repetition_levels_out(state.range(1));
-  while (state.KeepRunning()) {
-    std::unique_ptr<Int64Reader> reader = BuildReader(src, state.range(1), schema.get());
-    int64_t values_read = 0;
-    for (size_t i = 0; i < values.size(); i += values_read) {
-      reader->ReadBatch(values_out.size(), definition_levels_out.data(),
-                        repetition_levels_out.data(), values_out.data(), &values_read);
-    }
-  }
-  SetBytesProcessed(state, repetition);
-}
-
-BENCHMARK_TEMPLATE(BM_ReadInt64Column, Repetition::REQUIRED)
-    ->RangePair(1024, 65536, 1, 1024);
-
-BENCHMARK_TEMPLATE(BM_ReadInt64Column, Repetition::OPTIONAL)
-    ->RangePair(1024, 65536, 1, 1024);
-
-BENCHMARK_TEMPLATE(BM_ReadInt64Column, Repetition::REPEATED)
-    ->RangePair(1024, 65536, 1, 1024);
-
-BENCHMARK_TEMPLATE(BM_ReadInt64Column, Repetition::REQUIRED, Compression::SNAPPY)
-    ->RangePair(1024, 65536, 1, 1024);
-BENCHMARK_TEMPLATE(BM_ReadInt64Column, Repetition::OPTIONAL, Compression::SNAPPY)
-    ->RangePair(1024, 65536, 1, 1024);
-BENCHMARK_TEMPLATE(BM_ReadInt64Column, Repetition::REPEATED, Compression::SNAPPY)
-    ->RangePair(1024, 65536, 1, 1024);
-
-BENCHMARK_TEMPLATE(BM_ReadInt64Column, Repetition::REQUIRED, Compression::LZ4)
-    ->RangePair(1024, 65536, 1, 1024);
-BENCHMARK_TEMPLATE(BM_ReadInt64Column, Repetition::OPTIONAL, Compression::LZ4)
-    ->RangePair(1024, 65536, 1, 1024);
-BENCHMARK_TEMPLATE(BM_ReadInt64Column, Repetition::REPEATED, Compression::LZ4)
-    ->RangePair(1024, 65536, 1, 1024);
-
-BENCHMARK_TEMPLATE(BM_ReadInt64Column, Repetition::REQUIRED, Compression::ZSTD)
-    ->RangePair(1024, 65536, 1, 1024);
-BENCHMARK_TEMPLATE(BM_ReadInt64Column, Repetition::OPTIONAL, Compression::ZSTD)
-    ->RangePair(1024, 65536, 1, 1024);
-BENCHMARK_TEMPLATE(BM_ReadInt64Column, Repetition::REPEATED, Compression::ZSTD)
-    ->RangePair(1024, 65536, 1, 1024);
-
-static void BM_RleEncoding(::benchmark::State& state) {
-  std::vector<int16_t> levels(state.range(0), 0);
-  int64_t n = 0;
-  std::generate(levels.begin(), levels.end(),
-                [&state, &n] { return (n++ % state.range(1)) == 0; });
-  int16_t max_level = 1;
-  int64_t rle_size = LevelEncoder::MaxBufferSize(Encoding::RLE, max_level,
-                                                 static_cast<int>(levels.size()));
-  auto buffer_rle = AllocateBuffer();
-  PARQUET_THROW_NOT_OK(buffer_rle->Resize(rle_size));
-
-  while (state.KeepRunning()) {
-    LevelEncoder level_encoder;
-    level_encoder.Init(Encoding::RLE, max_level, static_cast<int>(levels.size()),
-                       buffer_rle->mutable_data(), static_cast<int>(buffer_rle->size()));
-    level_encoder.Encode(static_cast<int>(levels.size()), levels.data());
-  }
-  state.SetBytesProcessed(state.iterations() * state.range(0) * sizeof(int16_t));
-  state.SetItemsProcessed(state.iterations() * state.range(0));
-}
-
-BENCHMARK(BM_RleEncoding)->RangePair(1024, 65536, 1, 16);
-
-static void BM_RleDecoding(::benchmark::State& state) {
-  LevelEncoder level_encoder;
-  std::vector<int16_t> levels(state.range(0), 0);
-  int64_t n = 0;
-  std::generate(levels.begin(), levels.end(),
-                [&state, &n] { return (n++ % state.range(1)) == 0; });
-  int16_t max_level = 1;
-  int rle_size = LevelEncoder::MaxBufferSize(Encoding::RLE, max_level,
-                                             static_cast<int>(levels.size()));
-  auto buffer_rle = AllocateBuffer();
-  PARQUET_THROW_NOT_OK(buffer_rle->Resize(rle_size + sizeof(int32_t)));
-  level_encoder.Init(Encoding::RLE, max_level, static_cast<int>(levels.size()),
-                     buffer_rle->mutable_data() + sizeof(int32_t), rle_size);
-  level_encoder.Encode(static_cast<int>(levels.size()), levels.data());
-  reinterpret_cast<int32_t*>(buffer_rle->mutable_data())[0] = level_encoder.len();
-
-  while (state.KeepRunning()) {
-    LevelDecoder level_decoder;
-    level_decoder.SetData(Encoding::RLE, max_level, static_cast<int>(levels.size()),
-                          buffer_rle->data());
-    level_decoder.Decode(state.range(0), levels.data());
-  }
-
-  state.SetBytesProcessed(state.iterations() * state.range(0) * sizeof(int16_t));
-  state.SetItemsProcessed(state.iterations() * state.range(0));
-}
-
-BENCHMARK(BM_RleDecoding)->RangePair(1024, 65536, 1, 16);
-
-}  // namespace benchmark
-
-}  // namespace parquet
diff --git a/src/parquet/column_page.h b/src/parquet/column_page.h
deleted file mode 100644
index c34eee7..0000000
--- a/src/parquet/column_page.h
+++ /dev/null
@@ -1,173 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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.
-
-// This module defines an abstract interface for iterating through pages in a
-// Parquet column chunk within a row group. It could be extended in the future
-// to iterate through all data pages in all chunks in a file.
-
-#ifndef PARQUET_COLUMN_PAGE_H
-#define PARQUET_COLUMN_PAGE_H
-
-#include <cstdint>
-#include <memory>
-#include <string>
-
-#include "parquet/statistics.h"
-#include "parquet/types.h"
-#include "parquet/util/memory.h"
-
-namespace parquet {
-
-// TODO: Parallel processing is not yet safe because of memory-ownership
-// semantics (the PageReader may or may not own the memory referenced by a
-// page)
-//
-// TODO(wesm): In the future Parquet implementations may store the crc code
-// in format::PageHeader. parquet-mr currently does not, so we also skip it
-// here, both on the read and write path
-class Page {
- public:
-  Page(const std::shared_ptr<Buffer>& buffer, PageType::type type)
-      : buffer_(buffer), type_(type) {}
-
-  PageType::type type() const { return type_; }
-
-  std::shared_ptr<Buffer> buffer() const { return buffer_; }
-
-  // @returns: a pointer to the page's data
-  const uint8_t* data() const { return buffer_->data(); }
-
-  // @returns: the total size in bytes of the page's data buffer
-  int32_t size() const { return static_cast<int32_t>(buffer_->size()); }
-
- private:
-  std::shared_ptr<Buffer> buffer_;
-  PageType::type type_;
-};
-
-class DataPage : public Page {
- public:
-  DataPage(const std::shared_ptr<Buffer>& buffer, int32_t num_values,
-           Encoding::type encoding, Encoding::type definition_level_encoding,
-           Encoding::type repetition_level_encoding,
-           const EncodedStatistics& statistics = EncodedStatistics())
-      : Page(buffer, PageType::DATA_PAGE),
-        num_values_(num_values),
-        encoding_(encoding),
-        definition_level_encoding_(definition_level_encoding),
-        repetition_level_encoding_(repetition_level_encoding),
-        statistics_(statistics) {}
-
-  int32_t num_values() const { return num_values_; }
-
-  Encoding::type encoding() const { return encoding_; }
-
-  Encoding::type repetition_level_encoding() const { return repetition_level_encoding_; }
-
-  Encoding::type definition_level_encoding() const { return definition_level_encoding_; }
-
-  const EncodedStatistics& statistics() const { return statistics_; }
-
- private:
-  int32_t num_values_;
-  Encoding::type encoding_;
-  Encoding::type definition_level_encoding_;
-  Encoding::type repetition_level_encoding_;
-  EncodedStatistics statistics_;
-};
-
-class CompressedDataPage : public DataPage {
- public:
-  CompressedDataPage(const std::shared_ptr<Buffer>& buffer, int32_t num_values,
-                     Encoding::type encoding, Encoding::type definition_level_encoding,
-                     Encoding::type repetition_level_encoding, int64_t uncompressed_size,
-                     const EncodedStatistics& statistics = EncodedStatistics())
-      : DataPage(buffer, num_values, encoding, definition_level_encoding,
-                 repetition_level_encoding, statistics),
-        uncompressed_size_(uncompressed_size) {}
-
-  int64_t uncompressed_size() const { return uncompressed_size_; }
-
- private:
-  int64_t uncompressed_size_;
-};
-
-class DataPageV2 : public Page {
- public:
-  DataPageV2(const std::shared_ptr<Buffer>& buffer, int32_t num_values, int32_t num_nulls,
-             int32_t num_rows, Encoding::type encoding,
-             int32_t definition_levels_byte_length, int32_t repetition_levels_byte_length,
-             bool is_compressed = false)
-      : Page(buffer, PageType::DATA_PAGE_V2),
-        num_values_(num_values),
-        num_nulls_(num_nulls),
-        num_rows_(num_rows),
-        encoding_(encoding),
-        definition_levels_byte_length_(definition_levels_byte_length),
-        repetition_levels_byte_length_(repetition_levels_byte_length),
-        is_compressed_(is_compressed) {}
-
-  int32_t num_values() const { return num_values_; }
-
-  int32_t num_nulls() const { return num_nulls_; }
-
-  int32_t num_rows() const { return num_rows_; }
-
-  Encoding::type encoding() const { return encoding_; }
-
-  int32_t definition_levels_byte_length() const { return definition_levels_byte_length_; }
-
-  int32_t repetition_levels_byte_length() const { return repetition_levels_byte_length_; }
-
-  bool is_compressed() const { return is_compressed_; }
-
- private:
-  int32_t num_values_;
-  int32_t num_nulls_;
-  int32_t num_rows_;
-  Encoding::type encoding_;
-  int32_t definition_levels_byte_length_;
-  int32_t repetition_levels_byte_length_;
-  bool is_compressed_;
-
-  // TODO(wesm): format::DataPageHeaderV2.statistics
-};
-
-class DictionaryPage : public Page {
- public:
-  DictionaryPage(const std::shared_ptr<Buffer>& buffer, int32_t num_values,
-                 Encoding::type encoding, bool is_sorted = false)
-      : Page(buffer, PageType::DICTIONARY_PAGE),
-        num_values_(num_values),
-        encoding_(encoding),
-        is_sorted_(is_sorted) {}
-
-  int32_t num_values() const { return num_values_; }
-
-  Encoding::type encoding() const { return encoding_; }
-
-  bool is_sorted() const { return is_sorted_; }
-
- private:
-  int32_t num_values_;
-  Encoding::type encoding_;
-  bool is_sorted_;
-};
-
-}  // namespace parquet
-
-#endif  // PARQUET_COLUMN_PAGE_H
diff --git a/src/parquet/column_reader-test.cc b/src/parquet/column_reader-test.cc
deleted file mode 100644
index 273b302..0000000
--- a/src/parquet/column_reader-test.cc
+++ /dev/null
@@ -1,390 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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.
-
-#include <gtest/gtest.h>
-
-#include <algorithm>
-#include <cstdint>
-#include <cstdlib>
-#include <limits>
-#include <memory>
-#include <string>
-#include <vector>
-
-#include "parquet/column_page.h"
-#include "parquet/column_reader.h"
-#include "parquet/schema.h"
-#include "parquet/test-util.h"
-#include "parquet/types.h"
-#include "parquet/util/test-common.h"
-
-using std::shared_ptr;
-using std::string;
-using std::vector;
-
-namespace parquet {
-
-using schema::NodePtr;
-
-namespace test {
-
-template <typename T>
-static inline bool vector_equal_with_def_levels(const vector<T>& left,
-                                                const vector<int16_t>& def_levels,
-                                                int16_t max_def_levels,
-                                                int16_t max_rep_levels,
-                                                const vector<T>& right) {
-  size_t i_left = 0;
-  size_t i_right = 0;
-  for (size_t i = 0; i < def_levels.size(); i++) {
-    if (def_levels[i] == max_def_levels) {
-      // Compare
-      if (left[i_left] != right[i_right]) {
-        std::cerr << "index " << i << " left was " << left[i_left] << " right was "
-                  << right[i] << std::endl;
-        return false;
-      }
-      i_left++;
-      i_right++;
-    } else if (def_levels[i] == (max_def_levels - 1)) {
-      // Null entry on the lowest nested level
-      i_right++;
-    } else if (def_levels[i] < (max_def_levels - 1)) {
-      // Null entry on a higher nesting level, only supported for non-repeating data
-      if (max_rep_levels == 0) {
-        i_right++;
-      }
-    }
-  }
-
-  return true;
-}
-
-class TestPrimitiveReader : public ::testing::Test {
- public:
-  void InitReader(const ColumnDescriptor* d) {
-    std::unique_ptr<PageReader> pager_;
-    pager_.reset(new test::MockPageReader(pages_));
-    reader_ = ColumnReader::Make(d, std::move(pager_));
-  }
-
-  void CheckResults() {
-    vector<int32_t> vresult(num_values_, -1);
-    vector<int16_t> dresult(num_levels_, -1);
-    vector<int16_t> rresult(num_levels_, -1);
-    int64_t values_read = 0;
-    int total_values_read = 0;
-    int batch_actual = 0;
-
-    Int32Reader* reader = static_cast<Int32Reader*>(reader_.get());
-    int32_t batch_size = 8;
-    int batch = 0;
-    // This will cover both the cases
-    // 1) batch_size < page_size (multiple ReadBatch from a single page)
-    // 2) batch_size > page_size (BatchRead limits to a single page)
-    do {
-      batch = static_cast<int>(reader->ReadBatch(
-          batch_size, &dresult[0] + batch_actual, &rresult[0] + batch_actual,
-          &vresult[0] + total_values_read, &values_read));
-      total_values_read += static_cast<int>(values_read);
-      batch_actual += batch;
-      batch_size = std::max(batch_size * 2, 4096);
-    } while (batch > 0);
-
-    ASSERT_EQ(num_levels_, batch_actual);
-    ASSERT_EQ(num_values_, total_values_read);
-    ASSERT_TRUE(vector_equal(values_, vresult));
-    if (max_def_level_ > 0) {
-      ASSERT_TRUE(vector_equal(def_levels_, dresult));
-    }
-    if (max_rep_level_ > 0) {
-      ASSERT_TRUE(vector_equal(rep_levels_, rresult));
-    }
-    // catch improper writes at EOS
-    batch_actual =
-        static_cast<int>(reader->ReadBatch(5, nullptr, nullptr, nullptr, &values_read));
-    ASSERT_EQ(0, batch_actual);
-    ASSERT_EQ(0, values_read);
-  }
-
-  void CheckResultsSpaced() {
-    vector<int32_t> vresult(num_levels_, -1);
-    vector<int16_t> dresult(num_levels_, -1);
-    vector<int16_t> rresult(num_levels_, -1);
-    vector<uint8_t> valid_bits(num_levels_, 255);
-    int total_values_read = 0;
-    int batch_actual = 0;
-    int levels_actual = 0;
-    int64_t null_count = -1;
-    int64_t levels_read = 0;
-    int64_t values_read;
-
-    Int32Reader* reader = static_cast<Int32Reader*>(reader_.get());
-    int32_t batch_size = 8;
-    int batch = 0;
-    // This will cover both the cases
-    // 1) batch_size < page_size (multiple ReadBatch from a single page)
-    // 2) batch_size > page_size (BatchRead limits to a single page)
-    do {
-      batch = static_cast<int>(reader->ReadBatchSpaced(
-          batch_size, dresult.data() + levels_actual, rresult.data() + levels_actual,
-          vresult.data() + batch_actual, valid_bits.data() + batch_actual, 0,
-          &levels_read, &values_read, &null_count));
-      total_values_read += batch - static_cast<int>(null_count);
-      batch_actual += batch;
-      levels_actual += static_cast<int>(levels_read);
-      batch_size = std::max(batch_size * 2, 4096);
-    } while ((batch > 0) || (levels_read > 0));
-
-    ASSERT_EQ(num_levels_, levels_actual);
-    ASSERT_EQ(num_values_, total_values_read);
-    if (max_def_level_ > 0) {
-      ASSERT_TRUE(vector_equal(def_levels_, dresult));
-      ASSERT_TRUE(vector_equal_with_def_levels(values_, dresult, max_def_level_,
-                                               max_rep_level_, vresult));
-    } else {
-      ASSERT_TRUE(vector_equal(values_, vresult));
-    }
-    if (max_rep_level_ > 0) {
-      ASSERT_TRUE(vector_equal(rep_levels_, rresult));
-    }
-    // catch improper writes at EOS
-    batch_actual = static_cast<int>(
-        reader->ReadBatchSpaced(5, nullptr, nullptr, nullptr, valid_bits.data(), 0,
-                                &levels_read, &values_read, &null_count));
-    ASSERT_EQ(0, batch_actual);
-    ASSERT_EQ(0, null_count);
-  }
-
-  void Clear() {
-    values_.clear();
-    def_levels_.clear();
-    rep_levels_.clear();
-    pages_.clear();
-    reader_.reset();
-  }
-
-  void ExecutePlain(int num_pages, int levels_per_page, const ColumnDescriptor* d) {
-    num_values_ =
-        MakePages<Int32Type>(d, num_pages, levels_per_page, def_levels_, rep_levels_,
-                             values_, data_buffer_, pages_, Encoding::PLAIN);
-    num_levels_ = num_pages * levels_per_page;
-    InitReader(d);
-    CheckResults();
-    Clear();
-
-    num_values_ =
-        MakePages<Int32Type>(d, num_pages, levels_per_page, def_levels_, rep_levels_,
-                             values_, data_buffer_, pages_, Encoding::PLAIN);
-    num_levels_ = num_pages * levels_per_page;
-    InitReader(d);
-    CheckResultsSpaced();
-    Clear();
-  }
-
-  void ExecuteDict(int num_pages, int levels_per_page, const ColumnDescriptor* d) {
-    num_values_ =
-        MakePages<Int32Type>(d, num_pages, levels_per_page, def_levels_, rep_levels_,
-                             values_, data_buffer_, pages_, Encoding::RLE_DICTIONARY);
-    num_levels_ = num_pages * levels_per_page;
-    InitReader(d);
-    CheckResults();
-    Clear();
-
-    num_values_ =
-        MakePages<Int32Type>(d, num_pages, levels_per_page, def_levels_, rep_levels_,
-                             values_, data_buffer_, pages_, Encoding::RLE_DICTIONARY);
-    num_levels_ = num_pages * levels_per_page;
-    InitReader(d);
-    CheckResultsSpaced();
-    Clear();
-  }
-
- protected:
-  int num_levels_;
-  int num_values_;
-  int16_t max_def_level_;
-  int16_t max_rep_level_;
-  vector<shared_ptr<Page>> pages_;
-  std::shared_ptr<ColumnReader> reader_;
-  vector<int32_t> values_;
-  vector<int16_t> def_levels_;
-  vector<int16_t> rep_levels_;
-  vector<uint8_t> data_buffer_;  // For BA and FLBA
-};
-
-TEST_F(TestPrimitiveReader, TestInt32FlatRequired) {
-  int levels_per_page = 100;
-  int num_pages = 50;
-  max_def_level_ = 0;
-  max_rep_level_ = 0;
-  NodePtr type = schema::Int32("a", Repetition::REQUIRED);
-  const ColumnDescriptor descr(type, max_def_level_, max_rep_level_);
-  ASSERT_NO_FATAL_FAILURE(ExecutePlain(num_pages, levels_per_page, &descr));
-  ASSERT_NO_FATAL_FAILURE(ExecuteDict(num_pages, levels_per_page, &descr));
-}
-
-TEST_F(TestPrimitiveReader, TestInt32FlatOptional) {
-  int levels_per_page = 100;
-  int num_pages = 50;
-  max_def_level_ = 4;
-  max_rep_level_ = 0;
-  NodePtr type = schema::Int32("b", Repetition::OPTIONAL);
-  const ColumnDescriptor descr(type, max_def_level_, max_rep_level_);
-  ASSERT_NO_FATAL_FAILURE(ExecutePlain(num_pages, levels_per_page, &descr));
-  ASSERT_NO_FATAL_FAILURE(ExecuteDict(num_pages, levels_per_page, &descr));
-}
-
-TEST_F(TestPrimitiveReader, TestInt32FlatRepeated) {
-  int levels_per_page = 100;
-  int num_pages = 50;
-  max_def_level_ = 4;
-  max_rep_level_ = 2;
-  NodePtr type = schema::Int32("c", Repetition::REPEATED);
-  const ColumnDescriptor descr(type, max_def_level_, max_rep_level_);
-  ASSERT_NO_FATAL_FAILURE(ExecutePlain(num_pages, levels_per_page, &descr));
-  ASSERT_NO_FATAL_FAILURE(ExecuteDict(num_pages, levels_per_page, &descr));
-}
-
-TEST_F(TestPrimitiveReader, TestInt32FlatRequiredSkip) {
-  int levels_per_page = 100;
-  int num_pages = 5;
-  max_def_level_ = 0;
-  max_rep_level_ = 0;
-  NodePtr type = schema::Int32("b", Repetition::REQUIRED);
-  const ColumnDescriptor descr(type, max_def_level_, max_rep_level_);
-  MakePages<Int32Type>(&descr, num_pages, levels_per_page, def_levels_, rep_levels_,
-                       values_, data_buffer_, pages_, Encoding::PLAIN);
-  InitReader(&descr);
-  vector<int32_t> vresult(levels_per_page / 2, -1);
-  vector<int16_t> dresult(levels_per_page / 2, -1);
-  vector<int16_t> rresult(levels_per_page / 2, -1);
-
-  Int32Reader* reader = static_cast<Int32Reader*>(reader_.get());
-  int64_t values_read = 0;
-
-  // 1) skip_size > page_size (multiple pages skipped)
-  // Skip first 2 pages
-  int64_t levels_skipped = reader->Skip(2 * levels_per_page);
-  ASSERT_EQ(2 * levels_per_page, levels_skipped);
-  // Read half a page
-  reader->ReadBatch(levels_per_page / 2, dresult.data(), rresult.data(), vresult.data(),
-                    &values_read);
-  vector<int32_t> sub_values(
-      values_.begin() + 2 * levels_per_page,
-      values_.begin() + static_cast<int>(2.5 * static_cast<double>(levels_per_page)));
-  ASSERT_TRUE(vector_equal(sub_values, vresult));
-
-  // 2) skip_size == page_size (skip across two pages)
-  levels_skipped = reader->Skip(levels_per_page);
-  ASSERT_EQ(levels_per_page, levels_skipped);
-  // Read half a page
-  reader->ReadBatch(levels_per_page / 2, dresult.data(), rresult.data(), vresult.data(),
-                    &values_read);
-  sub_values.clear();
-  sub_values.insert(
-      sub_values.end(),
-      values_.begin() + static_cast<int>(3.5 * static_cast<double>(levels_per_page)),
-      values_.begin() + 4 * levels_per_page);
-  ASSERT_TRUE(vector_equal(sub_values, vresult));
-
-  // 3) skip_size < page_size (skip limited to a single page)
-  // Skip half a page
-  levels_skipped = reader->Skip(levels_per_page / 2);
-  ASSERT_EQ(0.5 * levels_per_page, levels_skipped);
-  // Read half a page
-  reader->ReadBatch(levels_per_page / 2, dresult.data(), rresult.data(), vresult.data(),
-                    &values_read);
-  sub_values.clear();
-  sub_values.insert(
-      sub_values.end(),
-      values_.begin() + static_cast<int>(4.5 * static_cast<double>(levels_per_page)),
-      values_.end());
-  ASSERT_TRUE(vector_equal(sub_values, vresult));
-
-  values_.clear();
-  def_levels_.clear();
-  rep_levels_.clear();
-  pages_.clear();
-  reader_.reset();
-}
-
-TEST_F(TestPrimitiveReader, TestDictionaryEncodedPages) {
-  max_def_level_ = 0;
-  max_rep_level_ = 0;
-  NodePtr type = schema::Int32("a", Repetition::REQUIRED);
-  const ColumnDescriptor descr(type, max_def_level_, max_rep_level_);
-  shared_ptr<ResizableBuffer> dummy = AllocateBuffer();
-
-  shared_ptr<DictionaryPage> dict_page =
-      std::make_shared<DictionaryPage>(dummy, 0, Encoding::PLAIN);
-  shared_ptr<DataPage> data_page = MakeDataPage<Int32Type>(
-      &descr, {}, 0, Encoding::RLE_DICTIONARY, {}, 0, {}, 0, {}, 0);
-  pages_.push_back(dict_page);
-  pages_.push_back(data_page);
-  InitReader(&descr);
-  // Tests Dict : PLAIN, Data : RLE_DICTIONARY
-  ASSERT_NO_THROW(reader_->HasNext());
-  pages_.clear();
-
-  dict_page = std::make_shared<DictionaryPage>(dummy, 0, Encoding::PLAIN_DICTIONARY);
-  data_page = MakeDataPage<Int32Type>(&descr, {}, 0, Encoding::PLAIN_DICTIONARY, {}, 0,
-                                      {}, 0, {}, 0);
-  pages_.push_back(dict_page);
-  pages_.push_back(data_page);
-  InitReader(&descr);
-  // Tests Dict : PLAIN_DICTIONARY, Data : PLAIN_DICTIONARY
-  ASSERT_NO_THROW(reader_->HasNext());
-  pages_.clear();
-
-  data_page = MakeDataPage<Int32Type>(&descr, {}, 0, Encoding::RLE_DICTIONARY, {}, 0, {},
-                                      0, {}, 0);
-  pages_.push_back(data_page);
-  InitReader(&descr);
-  // Tests dictionary page must occur before data page
-  ASSERT_THROW(reader_->HasNext(), ParquetException);
-  pages_.clear();
-
-  dict_page = std::make_shared<DictionaryPage>(dummy, 0, Encoding::DELTA_BYTE_ARRAY);
-  pages_.push_back(dict_page);
-  InitReader(&descr);
-  // Tests only RLE_DICTIONARY is supported
-  ASSERT_THROW(reader_->HasNext(), ParquetException);
-  pages_.clear();
-
-  shared_ptr<DictionaryPage> dict_page1 =
-      std::make_shared<DictionaryPage>(dummy, 0, Encoding::PLAIN_DICTIONARY);
-  shared_ptr<DictionaryPage> dict_page2 =
-      std::make_shared<DictionaryPage>(dummy, 0, Encoding::PLAIN);
-  pages_.push_back(dict_page1);
-  pages_.push_back(dict_page2);
-  InitReader(&descr);
-  // Column cannot have more than one dictionary
-  ASSERT_THROW(reader_->HasNext(), ParquetException);
-  pages_.clear();
-
-  data_page = MakeDataPage<Int32Type>(&descr, {}, 0, Encoding::DELTA_BYTE_ARRAY, {}, 0,
-                                      {}, 0, {}, 0);
-  pages_.push_back(data_page);
-  InitReader(&descr);
-  // unsupported encoding
-  ASSERT_THROW(reader_->HasNext(), ParquetException);
-  pages_.clear();
-}
-
-}  // namespace test
-}  // namespace parquet
diff --git a/src/parquet/column_reader.cc b/src/parquet/column_reader.cc
deleted file mode 100644
index 28d0dcb..0000000
--- a/src/parquet/column_reader.cc
+++ /dev/null
@@ -1,475 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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.
-
-#include "parquet/column_reader.h"
-
-#include <algorithm>
-#include <cstdint>
-#include <memory>
-
-#include <arrow/buffer.h>
-#include <arrow/memory_pool.h>
-#include <arrow/util/bit-util.h>
-#include <arrow/util/compression.h>
-#include <arrow/util/rle-encoding.h>
-
-#include "parquet/column_page.h"
-#include "parquet/encoding-internal.h"
-#include "parquet/parquet_types.h"
-#include "parquet/properties.h"
-#include "parquet/thrift.h"
-
-using arrow::MemoryPool;
-
-namespace parquet {
-
-LevelDecoder::LevelDecoder() : num_values_remaining_(0) {}
-
-LevelDecoder::~LevelDecoder() {}
-
-int LevelDecoder::SetData(Encoding::type encoding, int16_t max_level,
-                          int num_buffered_values, const uint8_t* data) {
-  int32_t num_bytes = 0;
-  encoding_ = encoding;
-  num_values_remaining_ = num_buffered_values;
-  bit_width_ = BitUtil::Log2(max_level + 1);
-  switch (encoding) {
-    case Encoding::RLE: {
-      num_bytes = *reinterpret_cast<const int32_t*>(data);
-      const uint8_t* decoder_data = data + sizeof(int32_t);
-      if (!rle_decoder_) {
-        rle_decoder_.reset(new ::arrow::RleDecoder(decoder_data, num_bytes, bit_width_));
-      } else {
-        rle_decoder_->Reset(decoder_data, num_bytes, bit_width_);
-      }
-      return static_cast<int>(sizeof(int32_t)) + num_bytes;
-    }
-    case Encoding::BIT_PACKED: {
-      num_bytes =
-          static_cast<int32_t>(BitUtil::BytesForBits(num_buffered_values * bit_width_));
-      if (!bit_packed_decoder_) {
-        bit_packed_decoder_.reset(new ::arrow::BitReader(data, num_bytes));
-      } else {
-        bit_packed_decoder_->Reset(data, num_bytes);
-      }
-      return num_bytes;
-    }
-    default:
-      throw ParquetException("Unknown encoding type for levels.");
-  }
-  return -1;
-}
-
-int LevelDecoder::Decode(int batch_size, int16_t* levels) {
-  int num_decoded = 0;
-
-  int num_values = std::min(num_values_remaining_, batch_size);
-  if (encoding_ == Encoding::RLE) {
-    num_decoded = rle_decoder_->GetBatch(levels, num_values);
-  } else {
-    num_decoded = bit_packed_decoder_->GetBatch(bit_width_, levels, num_values);
-  }
-  num_values_remaining_ -= num_decoded;
-  return num_decoded;
-}
-
-ReaderProperties default_reader_properties() {
-  static ReaderProperties default_reader_properties;
-  return default_reader_properties;
-}
-
-// ----------------------------------------------------------------------
-// SerializedPageReader deserializes Thrift metadata and pages that have been
-// assembled in a serialized stream for storing in a Parquet files
-
-// This subclass delimits pages appearing in a serialized stream, each preceded
-// by a serialized Thrift format::PageHeader indicating the type of each page
-// and the page metadata.
-class SerializedPageReader : public PageReader {
- public:
-  SerializedPageReader(std::unique_ptr<InputStream> stream, int64_t total_num_rows,
-                       Compression::type codec, ::arrow::MemoryPool* pool)
-      : stream_(std::move(stream)),
-        decompression_buffer_(AllocateBuffer(pool, 0)),
-        seen_num_rows_(0),
-        total_num_rows_(total_num_rows) {
-    max_page_header_size_ = kDefaultMaxPageHeaderSize;
-    decompressor_ = GetCodecFromArrow(codec);
-  }
-
-  // Implement the PageReader interface
-  std::shared_ptr<Page> NextPage() override;
-
-  void set_max_page_header_size(uint32_t size) override { max_page_header_size_ = size; }
-
- private:
-  std::unique_ptr<InputStream> stream_;
-
-  format::PageHeader current_page_header_;
-  std::shared_ptr<Page> current_page_;
-
-  // Compression codec to use.
-  std::unique_ptr<::arrow::Codec> decompressor_;
-  std::shared_ptr<ResizableBuffer> decompression_buffer_;
-
-  // Maximum allowed page size
-  uint32_t max_page_header_size_;
-
-  // Number of rows read in data pages so far
-  int64_t seen_num_rows_;
-
-  // Number of rows in all the data pages
-  int64_t total_num_rows_;
-};
-
-std::shared_ptr<Page> SerializedPageReader::NextPage() {
-  // Loop here because there may be unhandled page types that we skip until
-  // finding a page that we do know what to do with
-  while (seen_num_rows_ < total_num_rows_) {
-    int64_t bytes_read = 0;
-    int64_t bytes_available = 0;
-    uint32_t header_size = 0;
-    const uint8_t* buffer;
-    uint32_t allowed_page_size = kDefaultPageHeaderSize;
-
-    // Page headers can be very large because of page statistics
-    // We try to deserialize a larger buffer progressively
-    // until a maximum allowed header limit
-    while (true) {
-      buffer = stream_->Peek(allowed_page_size, &bytes_available);
-      if (bytes_available == 0) {
-        return std::shared_ptr<Page>(nullptr);
-      }
-
-      // This gets used, then set by DeserializeThriftMsg
-      header_size = static_cast<uint32_t>(bytes_available);
-      try {
-        DeserializeThriftMsg(buffer, &header_size, &current_page_header_);
-        break;
-      } catch (std::exception& e) {
-        // Failed to deserialize. Double the allowed page header size and try again
-        std::stringstream ss;
-        ss << e.what();
-        allowed_page_size *= 2;
-        if (allowed_page_size > max_page_header_size_) {
-          ss << "Deserializing page header failed.\n";
-          throw ParquetException(ss.str());
-        }
-      }
-    }
-    // Advance the stream offset
-    stream_->Advance(header_size);
-
-    int compressed_len = current_page_header_.compressed_page_size;
-    int uncompressed_len = current_page_header_.uncompressed_page_size;
-
-    // Read the compressed data page.
-    buffer = stream_->Read(compressed_len, &bytes_read);
-    if (bytes_read != compressed_len) {
-      std::stringstream ss;
-      ss << "Page was smaller (" << bytes_read << ") than expected (" << compressed_len
-         << ")";
-      ParquetException::EofException(ss.str());
-    }
-
-    // Uncompress it if we need to
-    if (decompressor_ != nullptr) {
-      // Grow the uncompressed buffer if we need to.
-      if (uncompressed_len > static_cast<int>(decompression_buffer_->size())) {
-        PARQUET_THROW_NOT_OK(decompression_buffer_->Resize(uncompressed_len, false));
-      }
-      PARQUET_THROW_NOT_OK(
-          decompressor_->Decompress(compressed_len, buffer, uncompressed_len,
-                                    decompression_buffer_->mutable_data()));
-      buffer = decompression_buffer_->data();
-    }
-
-    auto page_buffer = std::make_shared<Buffer>(buffer, uncompressed_len);
-
-    if (current_page_header_.type == format::PageType::DICTIONARY_PAGE) {
-      const format::DictionaryPageHeader& dict_header =
-          current_page_header_.dictionary_page_header;
-
-      bool is_sorted = dict_header.__isset.is_sorted ? dict_header.is_sorted : false;
-
-      return std::make_shared<DictionaryPage>(page_buffer, dict_header.num_values,
-                                              FromThrift(dict_header.encoding),
-                                              is_sorted);
-    } else if (current_page_header_.type == format::PageType::DATA_PAGE) {
-      const format::DataPageHeader& header = current_page_header_.data_page_header;
-
-      EncodedStatistics page_statistics;
-      if (header.__isset.statistics) {
-        const format::Statistics& stats = header.statistics;
-        if (stats.__isset.max) {
-          page_statistics.set_max(stats.max);
-        }
-        if (stats.__isset.min) {
-          page_statistics.set_min(stats.min);
-        }
-        if (stats.__isset.null_count) {
-          page_statistics.set_null_count(stats.null_count);
-        }
-        if (stats.__isset.distinct_count) {
-          page_statistics.set_distinct_count(stats.distinct_count);
-        }
-      }
-
-      seen_num_rows_ += header.num_values;
-
-      return std::make_shared<DataPage>(
-          page_buffer, header.num_values, FromThrift(header.encoding),
-          FromThrift(header.definition_level_encoding),
-          FromThrift(header.repetition_level_encoding), page_statistics);
-    } else if (current_page_header_.type == format::PageType::DATA_PAGE_V2) {
-      const format::DataPageHeaderV2& header = current_page_header_.data_page_header_v2;
-      bool is_compressed = header.__isset.is_compressed ? header.is_compressed : false;
-
-      seen_num_rows_ += header.num_values;
-
-      return std::make_shared<DataPageV2>(
-          page_buffer, header.num_values, header.num_nulls, header.num_rows,
-          FromThrift(header.encoding), header.definition_levels_byte_length,
-          header.repetition_levels_byte_length, is_compressed);
-    } else {
-      // We don't know what this page type is. We're allowed to skip non-data
-      // pages.
-      continue;
-    }
-  }
-  return std::shared_ptr<Page>(nullptr);
-}
-
-std::unique_ptr<PageReader> PageReader::Open(std::unique_ptr<InputStream> stream,
-                                             int64_t total_num_rows,
-                                             Compression::type codec,
-                                             ::arrow::MemoryPool* pool) {
-  return std::unique_ptr<PageReader>(
-      new SerializedPageReader(std::move(stream), total_num_rows, codec, pool));
-}
-
-// ----------------------------------------------------------------------
-
-ColumnReader::ColumnReader(const ColumnDescriptor* descr,
-                           std::unique_ptr<PageReader> pager, MemoryPool* pool)
-    : descr_(descr),
-      pager_(std::move(pager)),
-      num_buffered_values_(0),
-      num_decoded_values_(0),
-      pool_(pool) {}
-
-ColumnReader::~ColumnReader() {}
-
-template <typename DType>
-void TypedColumnReader<DType>::ConfigureDictionary(const DictionaryPage* page) {
-  int encoding = static_cast<int>(page->encoding());
-  if (page->encoding() == Encoding::PLAIN_DICTIONARY ||
-      page->encoding() == Encoding::PLAIN) {
-    encoding = static_cast<int>(Encoding::RLE_DICTIONARY);
-  }
-
-  auto it = decoders_.find(encoding);
-  if (it != decoders_.end()) {
-    throw ParquetException("Column cannot have more than one dictionary.");
-  }
-
-  if (page->encoding() == Encoding::PLAIN_DICTIONARY ||
-      page->encoding() == Encoding::PLAIN) {
-    PlainDecoder<DType> dictionary(descr_);
-    dictionary.SetData(page->num_values(), page->data(), page->size());
-
-    // The dictionary is fully decoded during DictionaryDecoder::Init, so the
-    // DictionaryPage buffer is no longer required after this step
-    //
-    // TODO(wesm): investigate whether this all-or-nothing decoding of the
-    // dictionary makes sense and whether performance can be improved
-
-    auto decoder = std::make_shared<DictionaryDecoder<DType>>(descr_, pool_);
-    decoder->SetDict(&dictionary);
-    decoders_[encoding] = decoder;
-  } else {
-    ParquetException::NYI("only plain dictionary encoding has been implemented");
-  }
-
-  current_decoder_ = decoders_[encoding].get();
-}
-
-// PLAIN_DICTIONARY is deprecated but used to be used as a dictionary index
-// encoding.
-static bool IsDictionaryIndexEncoding(const Encoding::type& e) {
-  return e == Encoding::RLE_DICTIONARY || e == Encoding::PLAIN_DICTIONARY;
-}
-
-template <typename DType>
-bool TypedColumnReader<DType>::ReadNewPage() {
-  // Loop until we find the next data page.
-  const uint8_t* buffer;
-
-  while (true) {
-    current_page_ = pager_->NextPage();
-    if (!current_page_) {
-      // EOS
-      return false;
-    }
-
-    if (current_page_->type() == PageType::DICTIONARY_PAGE) {
-      ConfigureDictionary(static_cast<const DictionaryPage*>(current_page_.get()));
-      continue;
-    } else if (current_page_->type() == PageType::DATA_PAGE) {
-      const DataPage* page = static_cast<const DataPage*>(current_page_.get());
-
-      // Read a data page.
-      num_buffered_values_ = page->num_values();
-
-      // Have not decoded any values from the data page yet
-      num_decoded_values_ = 0;
-
-      buffer = page->data();
-
-      // If the data page includes repetition and definition levels, we
-      // initialize the level decoder and subtract the encoded level bytes from
-      // the page size to determine the number of bytes in the encoded data.
-      int64_t data_size = page->size();
-
-      // Data page Layout: Repetition Levels - Definition Levels - encoded values.
-      // Levels are encoded as rle or bit-packed.
-      // Init repetition levels
-      if (descr_->max_repetition_level() > 0) {
-        int64_t rep_levels_bytes = repetition_level_decoder_.SetData(
-            page->repetition_level_encoding(), descr_->max_repetition_level(),
-            static_cast<int>(num_buffered_values_), buffer);
-        buffer += rep_levels_bytes;
-        data_size -= rep_levels_bytes;
-      }
-      // TODO figure a way to set max_definition_level_ to 0
-      // if the initial value is invalid
-
-      // Init definition levels
-      if (descr_->max_definition_level() > 0) {
-        int64_t def_levels_bytes = definition_level_decoder_.SetData(
-            page->definition_level_encoding(), descr_->max_definition_level(),
-            static_cast<int>(num_buffered_values_), buffer);
-        buffer += def_levels_bytes;
-        data_size -= def_levels_bytes;
-      }
-
-      // Get a decoder object for this page or create a new decoder if this is the
-      // first page with this encoding.
-      Encoding::type encoding = page->encoding();
-
-      if (IsDictionaryIndexEncoding(encoding)) {
-        encoding = Encoding::RLE_DICTIONARY;
-      }
-
-      auto it = decoders_.find(static_cast<int>(encoding));
-      if (it != decoders_.end()) {
-        if (encoding == Encoding::RLE_DICTIONARY) {
-          DCHECK(current_decoder_->encoding() == Encoding::RLE_DICTIONARY);
-        }
-        current_decoder_ = it->second.get();
-      } else {
-        switch (encoding) {
-          case Encoding::PLAIN: {
-            std::shared_ptr<DecoderType> decoder(new PlainDecoder<DType>(descr_));
-            decoders_[static_cast<int>(encoding)] = decoder;
-            current_decoder_ = decoder.get();
-            break;
-          }
-          case Encoding::RLE_DICTIONARY:
-            throw ParquetException("Dictionary page must be before data page.");
-
-          case Encoding::DELTA_BINARY_PACKED:
-          case Encoding::DELTA_LENGTH_BYTE_ARRAY:
-          case Encoding::DELTA_BYTE_ARRAY:
-            ParquetException::NYI("Unsupported encoding");
-
-          default:
-            throw ParquetException("Unknown encoding type.");
-        }
-      }
-      current_decoder_->SetData(static_cast<int>(num_buffered_values_), buffer,
-                                static_cast<int>(data_size));
-      return true;
-    } else {
-      // We don't know what this page type is. We're allowed to skip non-data
-      // pages.
-      continue;
-    }
-  }
-  return true;
-}
-
-// ----------------------------------------------------------------------
-// Batch read APIs
-
-int64_t ColumnReader::ReadDefinitionLevels(int64_t batch_size, int16_t* levels) {
-  if (descr_->max_definition_level() == 0) {
-    return 0;
-  }
-  return definition_level_decoder_.Decode(static_cast<int>(batch_size), levels);
-}
-
-int64_t ColumnReader::ReadRepetitionLevels(int64_t batch_size, int16_t* levels) {
-  if (descr_->max_repetition_level() == 0) {
-    return 0;
-  }
-  return repetition_level_decoder_.Decode(static_cast<int>(batch_size), levels);
-}
-
-// ----------------------------------------------------------------------
-// Dynamic column reader constructor
-
-std::shared_ptr<ColumnReader> ColumnReader::Make(const ColumnDescriptor* descr,
-                                                 std::unique_ptr<PageReader> pager,
-                                                 MemoryPool* pool) {
-  switch (descr->physical_type()) {
-    case Type::BOOLEAN:
-      return std::make_shared<BoolReader>(descr, std::move(pager), pool);
-    case Type::INT32:
-      return std::make_shared<Int32Reader>(descr, std::move(pager), pool);
-    case Type::INT64:
-      return std::make_shared<Int64Reader>(descr, std::move(pager), pool);
-    case Type::INT96:
-      return std::make_shared<Int96Reader>(descr, std::move(pager), pool);
-    case Type::FLOAT:
-      return std::make_shared<FloatReader>(descr, std::move(pager), pool);
-    case Type::DOUBLE:
-      return std::make_shared<DoubleReader>(descr, std::move(pager), pool);
-    case Type::BYTE_ARRAY:
-      return std::make_shared<ByteArrayReader>(descr, std::move(pager), pool);
-    case Type::FIXED_LEN_BYTE_ARRAY:
-      return std::make_shared<FixedLenByteArrayReader>(descr, std::move(pager), pool);
-    default:
-      ParquetException::NYI("type reader not implemented");
-  }
-  // Unreachable code, but supress compiler warning
-  return std::shared_ptr<ColumnReader>(nullptr);
-}
-
-// ----------------------------------------------------------------------
-// Instantiate templated classes
-
-template class PARQUET_TEMPLATE_EXPORT TypedColumnReader<BooleanType>;
-template class PARQUET_TEMPLATE_EXPORT TypedColumnReader<Int32Type>;
-template class PARQUET_TEMPLATE_EXPORT TypedColumnReader<Int64Type>;
-template class PARQUET_TEMPLATE_EXPORT TypedColumnReader<Int96Type>;
-template class PARQUET_TEMPLATE_EXPORT TypedColumnReader<FloatType>;
-template class PARQUET_TEMPLATE_EXPORT TypedColumnReader<DoubleType>;
-template class PARQUET_TEMPLATE_EXPORT TypedColumnReader<ByteArrayType>;
-template class PARQUET_TEMPLATE_EXPORT TypedColumnReader<FLBAType>;
-
-}  // namespace parquet
diff --git a/src/parquet/column_reader.h b/src/parquet/column_reader.h
deleted file mode 100644
index 7134632..0000000
--- a/src/parquet/column_reader.h
+++ /dev/null
@@ -1,535 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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.
-
-#ifndef PARQUET_COLUMN_READER_H
-#define PARQUET_COLUMN_READER_H
-
-#include <algorithm>
-#include <climits>
-#include <cstdint>
-#include <cstring>
-#include <iostream>
-#include <memory>
-#include <unordered_map>
-#include <vector>
-
-#include <arrow/buffer.h>
-#include <arrow/builder.h>
-#include <arrow/memory_pool.h>
-#include <arrow/util/bit-util.h>
-
-#include "parquet/column_page.h"
-#include "parquet/encoding.h"
-#include "parquet/exception.h"
-#include "parquet/schema.h"
-#include "parquet/types.h"
-#include "parquet/util/memory.h"
-#include "parquet/util/visibility.h"
-
-namespace arrow {
-
-class BitReader;
-class RleDecoder;
-
-}  // namespace arrow
-
-namespace parquet {
-
-// 16 MB is the default maximum page header size
-static constexpr uint32_t kDefaultMaxPageHeaderSize = 16 * 1024 * 1024;
-
-// 16 KB is the default expected page header size
-static constexpr uint32_t kDefaultPageHeaderSize = 16 * 1024;
-
-namespace BitUtil = ::arrow::BitUtil;
-
-class PARQUET_EXPORT LevelDecoder {
- public:
-  LevelDecoder();
-  ~LevelDecoder();
-
-  // Initialize the LevelDecoder state with new data
-  // and return the number of bytes consumed
-  int SetData(Encoding::type encoding, int16_t max_level, int num_buffered_values,
-              const uint8_t* data);
-
-  // Decodes a batch of levels into an array and returns the number of levels decoded
-  int Decode(int batch_size, int16_t* levels);
-
- private:
-  int bit_width_;
-  int num_values_remaining_;
-  Encoding::type encoding_;
-  std::unique_ptr<::arrow::RleDecoder> rle_decoder_;
-  std::unique_ptr<::arrow::BitReader> bit_packed_decoder_;
-};
-
-// Abstract page iterator interface. This way, we can feed column pages to the
-// ColumnReader through whatever mechanism we choose
-class PARQUET_EXPORT PageReader {
- public:
-  virtual ~PageReader() = default;
-
-  static std::unique_ptr<PageReader> Open(
-      std::unique_ptr<InputStream> stream, int64_t total_num_rows,
-      Compression::type codec,
-      ::arrow::MemoryPool* pool = ::arrow::default_memory_pool());
-
-  // @returns: shared_ptr<Page>(nullptr) on EOS, std::shared_ptr<Page>
-  // containing new Page otherwise
-  virtual std::shared_ptr<Page> NextPage() = 0;
-
-  virtual void set_max_page_header_size(uint32_t size) = 0;
-};
-
-class PARQUET_EXPORT ColumnReader {
- public:
-  ColumnReader(const ColumnDescriptor*, std::unique_ptr<PageReader>,
-               ::arrow::MemoryPool* pool = ::arrow::default_memory_pool());
-  virtual ~ColumnReader();
-
-  static std::shared_ptr<ColumnReader> Make(
-      const ColumnDescriptor* descr, std::unique_ptr<PageReader> pager,
-      ::arrow::MemoryPool* pool = ::arrow::default_memory_pool());
-
-  // Returns true if there are still values in this column.
-  bool HasNext() {
-    // Either there is no data page available yet, or the data page has been
-    // exhausted
-    if (num_buffered_values_ == 0 || num_decoded_values_ == num_buffered_values_) {
-      if (!ReadNewPage() || num_buffered_values_ == 0) {
-        return false;
-      }
-    }
-    return true;
-  }
-
-  Type::type type() const { return descr_->physical_type(); }
-
-  const ColumnDescriptor* descr() const { return descr_; }
-
- protected:
-  virtual bool ReadNewPage() = 0;
-
-  // Read multiple definition levels into preallocated memory
-  //
-  // Returns the number of decoded definition levels
-  int64_t ReadDefinitionLevels(int64_t batch_size, int16_t* levels);
-
-  // Read multiple repetition levels into preallocated memory
-  // Returns the number of decoded repetition levels
-  int64_t ReadRepetitionLevels(int64_t batch_size, int16_t* levels);
-
-  int64_t available_values_current_page() const {
-    return num_buffered_values_ - num_decoded_values_;
-  }
-
-  void ConsumeBufferedValues(int64_t num_values) { num_decoded_values_ += num_values; }
-
-  const ColumnDescriptor* descr_;
-
-  std::unique_ptr<PageReader> pager_;
-  std::shared_ptr<Page> current_page_;
-
-  // Not set if full schema for this field has no optional or repeated elements
-  LevelDecoder definition_level_decoder_;
-
-  // Not set for flat schemas.
-  LevelDecoder repetition_level_decoder_;
-
-  // The total number of values stored in the data page. This is the maximum of
-  // the number of encoded definition levels or encoded values. For
-  // non-repeated, required columns, this is equal to the number of encoded
-  // values. For repeated or optional values, there may be fewer data values
-  // than levels, and this tells you how many encoded levels there are in that
-  // case.
-  int64_t num_buffered_values_;
-
-  // The number of values from the current data page that have been decoded
-  // into memory
-  int64_t num_decoded_values_;
-
-  ::arrow::MemoryPool* pool_;
-};
-
-namespace internal {
-
-static inline void DefinitionLevelsToBitmap(
-    const int16_t* def_levels, int64_t num_def_levels, const int16_t max_definition_level,
-    const int16_t max_repetition_level, int64_t* values_read, int64_t* null_count,
-    uint8_t* valid_bits, const int64_t valid_bits_offset) {
-  ::arrow::internal::BitmapWriter valid_bits_writer(valid_bits, valid_bits_offset,
-                                                    num_def_levels);
-
-  // TODO(itaiin): As an interim solution we are splitting the code path here
-  // between repeated+flat column reads, and non-repeated+nested reads.
-  // Those paths need to be merged in the future
-  for (int i = 0; i < num_def_levels; ++i) {
-    if (def_levels[i] == max_definition_level) {
-      valid_bits_writer.Set();
-    } else if (max_repetition_level > 0) {
-      // repetition+flat case
-      if (def_levels[i] == (max_definition_level - 1)) {
-        valid_bits_writer.Clear();
-        *null_count += 1;
-      } else {
-        continue;
-      }
-    } else {
-      // non-repeated+nested case
-      if (def_levels[i] < max_definition_level) {
-        valid_bits_writer.Clear();
-        *null_count += 1;
-      } else {
-        throw ParquetException("definition level exceeds maximum");
-      }
-    }
-
-    valid_bits_writer.Next();
-  }
-  valid_bits_writer.Finish();
-  *values_read = valid_bits_writer.position();
-}
-
-}  // namespace internal
-
-// API to read values from a single column. This is a main client facing API.
-template <typename DType>
-class PARQUET_EXPORT TypedColumnReader : public ColumnReader {
- public:
-  typedef typename DType::c_type T;
-
-  TypedColumnReader(const ColumnDescriptor* schema, std::unique_ptr<PageReader> pager,
-                    ::arrow::MemoryPool* pool = ::arrow::default_memory_pool())
-      : ColumnReader(schema, std::move(pager), pool), current_decoder_(nullptr) {}
-
-  // Read a batch of repetition levels, definition levels, and values from the
-  // column.
-  //
-  // Since null values are not stored in the values, the number of values read
-  // may be less than the number of repetition and definition levels. With
-  // nested data this is almost certainly true.
-  //
-  // Set def_levels or rep_levels to nullptr if you want to skip reading them.
-  // This is only safe if you know through some other source that there are no
-  // undefined values.
-  //
-  // To fully exhaust a row group, you must read batches until the number of
-  // values read reaches the number of stored values according to the metadata.
-  //
-  // This API is the same for both V1 and V2 of the DataPage
-  //
-  // @returns: actual number of levels read (see values_read for number of values read)
-  int64_t ReadBatch(int64_t batch_size, int16_t* def_levels, int16_t* rep_levels,
-                    T* values, int64_t* values_read);
-
-  /// Read a batch of repetition levels, definition levels, and values from the
-  /// column and leave spaces for null entries on the lowest level in the values
-  /// buffer.
-  ///
-  /// In comparision to ReadBatch the length of repetition and definition levels
-  /// is the same as of the number of values read for max_definition_level == 1.
-  /// In the case of max_definition_level > 1, the repetition and definition
-  /// levels are larger than the values but the values include the null entries
-  /// with definition_level == (max_definition_level - 1).
-  ///
-  /// To fully exhaust a row group, you must read batches until the number of
-  /// values read reaches the number of stored values according to the metadata.
-  ///
-  /// @param batch_size the number of levels to read
-  /// @param[out] def_levels The Parquet definition levels, output has
-  ///   the length levels_read.
-  /// @param[out] rep_levels The Parquet repetition levels, output has
-  ///   the length levels_read.
-  /// @param[out] values The values in the lowest nested level including
-  ///   spacing for nulls on the lowest levels; output has the length
-  ///   values_read.
-  /// @param[out] valid_bits Memory allocated for a bitmap that indicates if
-  ///   the row is null or on the maximum definition level. For performance
-  ///   reasons the underlying buffer should be able to store 1 bit more than
-  ///   required. If this requires an additional byte, this byte is only read
-  ///   but never written to.
-  /// @param valid_bits_offset The offset in bits of the valid_bits where the
-  ///   first relevant bit resides.
-  /// @param[out] levels_read The number of repetition/definition levels that were read.
-  /// @param[out] values_read The number of values read, this includes all
-  ///   non-null entries as well as all null-entries on the lowest level
-  ///   (i.e. definition_level == max_definition_level - 1)
-  /// @param[out] null_count The number of nulls on the lowest levels.
-  ///   (i.e. (values_read - null_count) is total number of non-null entries)
-  int64_t ReadBatchSpaced(int64_t batch_size, int16_t* def_levels, int16_t* rep_levels,
-                          T* values, uint8_t* valid_bits, int64_t valid_bits_offset,
-                          int64_t* levels_read, int64_t* values_read,
-                          int64_t* null_count);
-
-  // Skip reading levels
-  // Returns the number of levels skipped
-  int64_t Skip(int64_t num_rows_to_skip);
-
- private:
-  typedef Decoder<DType> DecoderType;
-
-  // Advance to the next data page
-  bool ReadNewPage() override;
-
-  // Read up to batch_size values from the current data page into the
-  // pre-allocated memory T*
-  //
-  // @returns: the number of values read into the out buffer
-  int64_t ReadValues(int64_t batch_size, T* out);
-
-  // Read up to batch_size values from the current data page into the
-  // pre-allocated memory T*, leaving spaces for null entries according
-  // to the def_levels.
-  //
-  // @returns: the number of values read into the out buffer
-  int64_t ReadValuesSpaced(int64_t batch_size, T* out, int64_t null_count,
-                           uint8_t* valid_bits, int64_t valid_bits_offset);
-
-  // Map of encoding type to the respective decoder object. For example, a
-  // column chunk's data pages may include both dictionary-encoded and
-  // plain-encoded data.
-  std::unordered_map<int, std::shared_ptr<DecoderType>> decoders_;
-
-  void ConfigureDictionary(const DictionaryPage* page);
-
-  DecoderType* current_decoder_;
-};
-
-// ----------------------------------------------------------------------
-// Type column reader implementations
-
-template <typename DType>
-inline int64_t TypedColumnReader<DType>::ReadValues(int64_t batch_size, T* out) {
-  int64_t num_decoded = current_decoder_->Decode(out, static_cast<int>(batch_size));
-  return num_decoded;
-}
-
-template <typename DType>
-inline int64_t TypedColumnReader<DType>::ReadValuesSpaced(int64_t batch_size, T* out,
-                                                          int64_t null_count,
-                                                          uint8_t* valid_bits,
-                                                          int64_t valid_bits_offset) {
-  return current_decoder_->DecodeSpaced(out, static_cast<int>(batch_size),
-                                        static_cast<int>(null_count), valid_bits,
-                                        valid_bits_offset);
-}
-
-template <typename DType>
-inline int64_t TypedColumnReader<DType>::ReadBatch(int64_t batch_size,
-                                                   int16_t* def_levels,
-                                                   int16_t* rep_levels, T* values,
-                                                   int64_t* values_read) {
-  // HasNext invokes ReadNewPage
-  if (!HasNext()) {
-    *values_read = 0;
-    return 0;
-  }
-
-  // TODO(wesm): keep reading data pages until batch_size is reached, or the
-  // row group is finished
-  batch_size = std::min(batch_size, num_buffered_values_ - num_decoded_values_);
-
-  int64_t num_def_levels = 0;
-  int64_t num_rep_levels = 0;
-
-  int64_t values_to_read = 0;
-
-  // If the field is required and non-repeated, there are no definition levels
-  if (descr_->max_definition_level() > 0 && def_levels) {
-    num_def_levels = ReadDefinitionLevels(batch_size, def_levels);
-    // TODO(wesm): this tallying of values-to-decode can be performed with better
-    // cache-efficiency if fused with the level decoding.
-    for (int64_t i = 0; i < num_def_levels; ++i) {
-      if (def_levels[i] == descr_->max_definition_level()) {
-        ++values_to_read;
-      }
-    }
-  } else {
-    // Required field, read all values
-    values_to_read = batch_size;
-  }
-
-  // Not present for non-repeated fields
-  if (descr_->max_repetition_level() > 0 && rep_levels) {
-    num_rep_levels = ReadRepetitionLevels(batch_size, rep_levels);
-    if (def_levels && num_def_levels != num_rep_levels) {
-      throw ParquetException("Number of decoded rep / def levels did not match");
-    }
-  }
-
-  *values_read = ReadValues(values_to_read, values);
-  int64_t total_values = std::max(num_def_levels, *values_read);
-  ConsumeBufferedValues(total_values);
-
-  return total_values;
-}
-
-namespace internal {
-
-// TODO(itaiin): another code path split to merge when the general case is done
-static inline bool HasSpacedValues(const ColumnDescriptor* descr) {
-  if (descr->max_repetition_level() > 0) {
-    // repeated+flat case
-    return !descr->schema_node()->is_required();
-  } else {
-    // non-repeated+nested case
-    // Find if a node forces nulls in the lowest level along the hierarchy
-    const schema::Node* node = descr->schema_node().get();
-    while (node) {
-      if (node->is_optional()) {
-        return true;
-      }
-      node = node->parent();
-    }
-    return false;
-  }
-}
-
-}  // namespace internal
-
-template <typename DType>
-inline int64_t TypedColumnReader<DType>::ReadBatchSpaced(
-    int64_t batch_size, int16_t* def_levels, int16_t* rep_levels, T* values,
-    uint8_t* valid_bits, int64_t valid_bits_offset, int64_t* levels_read,
-    int64_t* values_read, int64_t* null_count_out) {
-  // HasNext invokes ReadNewPage
-  if (!HasNext()) {
-    *levels_read = 0;
-    *values_read = 0;
-    *null_count_out = 0;
-    return 0;
-  }
-
-  int64_t total_values;
-  // TODO(wesm): keep reading data pages until batch_size is reached, or the
-  // row group is finished
-  batch_size = std::min(batch_size, num_buffered_values_ - num_decoded_values_);
-
-  // If the field is required and non-repeated, there are no definition levels
-  if (descr_->max_definition_level() > 0) {
-    int64_t num_def_levels = ReadDefinitionLevels(batch_size, def_levels);
-
-    // Not present for non-repeated fields
-    if (descr_->max_repetition_level() > 0) {
-      int64_t num_rep_levels = ReadRepetitionLevels(batch_size, rep_levels);
-      if (num_def_levels != num_rep_levels) {
-        throw ParquetException("Number of decoded rep / def levels did not match");
-      }
-    }
-
-    const bool has_spaced_values = internal::HasSpacedValues(descr_);
-
-    int64_t null_count = 0;
-    if (!has_spaced_values) {
-      int values_to_read = 0;
-      for (int64_t i = 0; i < num_def_levels; ++i) {
-        if (def_levels[i] == descr_->max_definition_level()) {
-          ++values_to_read;
-        }
-      }
-      total_values = ReadValues(values_to_read, values);
-      for (int64_t i = 0; i < total_values; i++) {
-        ::arrow::BitUtil::SetBit(valid_bits, valid_bits_offset + i);
-      }
-      *values_read = total_values;
-    } else {
-      int16_t max_definition_level = descr_->max_definition_level();
-      int16_t max_repetition_level = descr_->max_repetition_level();
-      internal::DefinitionLevelsToBitmap(def_levels, num_def_levels, max_definition_level,
-                                         max_repetition_level, values_read, &null_count,
-                                         valid_bits, valid_bits_offset);
-      total_values = ReadValuesSpaced(*values_read, values, static_cast<int>(null_count),
-                                      valid_bits, valid_bits_offset);
-    }
-    *levels_read = num_def_levels;
-    *null_count_out = null_count;
-
-  } else {
-    // Required field, read all values
-    total_values = ReadValues(batch_size, values);
-    for (int64_t i = 0; i < total_values; i++) {
-      ::arrow::BitUtil::SetBit(valid_bits, valid_bits_offset + i);
-    }
-    *null_count_out = 0;
-    *levels_read = total_values;
-  }
-
-  ConsumeBufferedValues(*levels_read);
-  return total_values;
-}
-
-template <typename DType>
-int64_t TypedColumnReader<DType>::Skip(int64_t num_rows_to_skip) {
-  int64_t rows_to_skip = num_rows_to_skip;
-  while (HasNext() && rows_to_skip > 0) {
-    // If the number of rows to skip is more than the number of undecoded values, skip the
-    // Page.
-    if (rows_to_skip > (num_buffered_values_ - num_decoded_values_)) {
-      rows_to_skip -= num_buffered_values_ - num_decoded_values_;
-      num_decoded_values_ = num_buffered_values_;
-    } else {
-      // We need to read this Page
-      // Jump to the right offset in the Page
-      int64_t batch_size = 1024;  // ReadBatch with a smaller memory footprint
-      int64_t values_read = 0;
-
-      std::shared_ptr<ResizableBuffer> vals = AllocateBuffer(
-          this->pool_, batch_size * type_traits<DType::type_num>::value_byte_size);
-      std::shared_ptr<ResizableBuffer> def_levels =
-          AllocateBuffer(this->pool_, batch_size * sizeof(int16_t));
-
-      std::shared_ptr<ResizableBuffer> rep_levels =
-          AllocateBuffer(this->pool_, batch_size * sizeof(int16_t));
-
-      do {
-        batch_size = std::min(batch_size, rows_to_skip);
-        values_read = ReadBatch(static_cast<int>(batch_size),
-                                reinterpret_cast<int16_t*>(def_levels->mutable_data()),
-                                reinterpret_cast<int16_t*>(rep_levels->mutable_data()),
-                                reinterpret_cast<T*>(vals->mutable_data()), &values_read);
-        rows_to_skip -= values_read;
-      } while (values_read > 0 && rows_to_skip > 0);
-    }
-  }
-  return num_rows_to_skip - rows_to_skip;
-}
-
-// ----------------------------------------------------------------------
-// Template instantiations
-
-typedef TypedColumnReader<BooleanType> BoolReader;
-typedef TypedColumnReader<Int32Type> Int32Reader;
-typedef TypedColumnReader<Int64Type> Int64Reader;
-typedef TypedColumnReader<Int96Type> Int96Reader;
-typedef TypedColumnReader<FloatType> FloatReader;
-typedef TypedColumnReader<DoubleType> DoubleReader;
-typedef TypedColumnReader<ByteArrayType> ByteArrayReader;
-typedef TypedColumnReader<FLBAType> FixedLenByteArrayReader;
-
-extern template class PARQUET_EXPORT TypedColumnReader<BooleanType>;
-extern template class PARQUET_EXPORT TypedColumnReader<Int32Type>;
-extern template class PARQUET_EXPORT TypedColumnReader<Int64Type>;
-extern template class PARQUET_EXPORT TypedColumnReader<Int96Type>;
-extern template class PARQUET_EXPORT TypedColumnReader<FloatType>;
-extern template class PARQUET_EXPORT TypedColumnReader<DoubleType>;
-extern template class PARQUET_EXPORT TypedColumnReader<ByteArrayType>;
-extern template class PARQUET_EXPORT TypedColumnReader<FLBAType>;
-
-}  // namespace parquet
-
-#endif  // PARQUET_COLUMN_READER_H
diff --git a/src/parquet/column_scanner-test.cc b/src/parquet/column_scanner-test.cc
deleted file mode 100644
index d39b910..0000000
--- a/src/parquet/column_scanner-test.cc
+++ /dev/null
@@ -1,238 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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.
-
-#include <gtest/gtest.h>
-
-#include <algorithm>
-#include <cstdint>
-#include <cstdlib>
-#include <memory>
-#include <string>
-#include <vector>
-
-#include "parquet/column_page.h"
-#include "parquet/column_scanner.h"
-#include "parquet/schema.h"
-#include "parquet/test-specialization.h"
-#include "parquet/test-util.h"
-#include "parquet/types.h"
-#include "parquet/util/test-common.h"
-
-using std::shared_ptr;
-using std::string;
-using std::vector;
-
-namespace parquet {
-
-using schema::NodePtr;
-
-namespace test {
-
-template <>
-void InitDictValues<bool>(int num_values, int dict_per_page, vector<bool>& values,
-                          vector<uint8_t>& buffer) {
-  // No op for bool
-}
-
-template <typename Type>
-class TestFlatScanner : public ::testing::Test {
- public:
-  typedef typename Type::c_type T;
-
-  void InitScanner(const ColumnDescriptor* d) {
-    std::unique_ptr<PageReader> pager(new test::MockPageReader(pages_));
-    scanner_ = Scanner::Make(ColumnReader::Make(d, std::move(pager)));
-  }
-
-  void CheckResults(int batch_size, const ColumnDescriptor* d) {
-    TypedScanner<Type>* scanner = reinterpret_cast<TypedScanner<Type>*>(scanner_.get());
-    T val;
-    bool is_null = false;
-    int16_t def_level;
-    int16_t rep_level;
-    int j = 0;
-    scanner->SetBatchSize(batch_size);
-    for (int i = 0; i < num_levels_; i++) {
-      ASSERT_TRUE(scanner->Next(&val, &def_level, &rep_level, &is_null)) << i << j;
-      if (!is_null) {
-        ASSERT_EQ(values_[j], val) << i << "V" << j;
-        j++;
-      }
-      if (d->max_definition_level() > 0) {
-        ASSERT_EQ(def_levels_[i], def_level) << i << "D" << j;
-      }
-      if (d->max_repetition_level() > 0) {
-        ASSERT_EQ(rep_levels_[i], rep_level) << i << "R" << j;
-      }
-    }
-    ASSERT_EQ(num_values_, j);
-    ASSERT_FALSE(scanner->Next(&val, &def_level, &rep_level, &is_null));
-  }
-
-  void Clear() {
-    pages_.clear();
-    values_.clear();
-    def_levels_.clear();
-    rep_levels_.clear();
-  }
-
-  void Execute(int num_pages, int levels_per_page, int batch_size,
-               const ColumnDescriptor* d, Encoding::type encoding) {
-    num_values_ = MakePages<Type>(d, num_pages, levels_per_page, def_levels_, rep_levels_,
-                                  values_, data_buffer_, pages_, encoding);
-    num_levels_ = num_pages * levels_per_page;
-    InitScanner(d);
-    CheckResults(batch_size, d);
-    Clear();
-  }
-
-  void InitDescriptors(std::shared_ptr<ColumnDescriptor>& d1,
-                       std::shared_ptr<ColumnDescriptor>& d2,
-                       std::shared_ptr<ColumnDescriptor>& d3, int length) {
-    NodePtr type;
-    type = schema::PrimitiveNode::Make("c1", Repetition::REQUIRED, Type::type_num,
-                                       LogicalType::NONE, length);
-    d1.reset(new ColumnDescriptor(type, 0, 0));
-    type = schema::PrimitiveNode::Make("c2", Repetition::OPTIONAL, Type::type_num,
-                                       LogicalType::NONE, length);
-    d2.reset(new ColumnDescriptor(type, 4, 0));
-    type = schema::PrimitiveNode::Make("c3", Repetition::REPEATED, Type::type_num,
-                                       LogicalType::NONE, length);
-    d3.reset(new ColumnDescriptor(type, 4, 2));
-  }
-
-  void ExecuteAll(int num_pages, int num_levels, int batch_size, int type_length,
-                  Encoding::type encoding = Encoding::PLAIN) {
-    std::shared_ptr<ColumnDescriptor> d1;
-    std::shared_ptr<ColumnDescriptor> d2;
-    std::shared_ptr<ColumnDescriptor> d3;
-    InitDescriptors(d1, d2, d3, type_length);
-    // evaluate REQUIRED pages
-    Execute(num_pages, num_levels, batch_size, d1.get(), encoding);
-    // evaluate OPTIONAL pages
-    Execute(num_pages, num_levels, batch_size, d2.get(), encoding);
-    // evaluate REPEATED pages
-    Execute(num_pages, num_levels, batch_size, d3.get(), encoding);
-  }
-
- protected:
-  int num_levels_;
-  int num_values_;
-  vector<shared_ptr<Page>> pages_;
-  std::shared_ptr<Scanner> scanner_;
-  vector<T> values_;
-  vector<int16_t> def_levels_;
-  vector<int16_t> rep_levels_;
-  vector<uint8_t> data_buffer_;  // For BA and FLBA
-};
-
-static int num_levels_per_page = 100;
-static int num_pages = 20;
-static int batch_size = 32;
-
-typedef ::testing::Types<Int32Type, Int64Type, Int96Type, FloatType, DoubleType,
-                         ByteArrayType>
-    TestTypes;
-
-using TestBooleanFlatScanner = TestFlatScanner<BooleanType>;
-using TestFLBAFlatScanner = TestFlatScanner<FLBAType>;
-
-TYPED_TEST_CASE(TestFlatScanner, TestTypes);
-
-TYPED_TEST(TestFlatScanner, TestPlainScanner) {
-  ASSERT_NO_FATAL_FAILURE(
-      this->ExecuteAll(num_pages, num_levels_per_page, batch_size, 0, Encoding::PLAIN));
-}
-
-TYPED_TEST(TestFlatScanner, TestDictScanner) {
-  ASSERT_NO_FATAL_FAILURE(this->ExecuteAll(num_pages, num_levels_per_page, batch_size, 0,
-                                           Encoding::RLE_DICTIONARY));
-}
-
-TEST_F(TestBooleanFlatScanner, TestPlainScanner) {
-  ASSERT_NO_FATAL_FAILURE(
-      this->ExecuteAll(num_pages, num_levels_per_page, batch_size, 0));
-}
-
-TEST_F(TestFLBAFlatScanner, TestPlainScanner) {
-  ASSERT_NO_FATAL_FAILURE(
-      this->ExecuteAll(num_pages, num_levels_per_page, batch_size, FLBA_LENGTH));
-}
-
-TEST_F(TestFLBAFlatScanner, TestDictScanner) {
-  ASSERT_NO_FATAL_FAILURE(this->ExecuteAll(num_pages, num_levels_per_page, batch_size,
-                                           FLBA_LENGTH, Encoding::RLE_DICTIONARY));
-}
-
-TEST_F(TestFLBAFlatScanner, TestPlainDictScanner) {
-  ASSERT_NO_FATAL_FAILURE(this->ExecuteAll(num_pages, num_levels_per_page, batch_size,
-                                           FLBA_LENGTH, Encoding::PLAIN_DICTIONARY));
-}
-
-// PARQUET 502
-TEST_F(TestFLBAFlatScanner, TestSmallBatch) {
-  NodePtr type =
-      schema::PrimitiveNode::Make("c1", Repetition::REQUIRED, Type::FIXED_LEN_BYTE_ARRAY,
-                                  LogicalType::DECIMAL, FLBA_LENGTH, 10, 2);
-  const ColumnDescriptor d(type, 0, 0);
-  num_values_ = MakePages<FLBAType>(&d, 1, 100, def_levels_, rep_levels_, values_,
-                                    data_buffer_, pages_);
-  num_levels_ = 1 * 100;
-  InitScanner(&d);
-  ASSERT_NO_FATAL_FAILURE(CheckResults(1, &d));
-}
-
-TEST_F(TestFLBAFlatScanner, TestDescriptorAPI) {
-  NodePtr type =
-      schema::PrimitiveNode::Make("c1", Repetition::OPTIONAL, Type::FIXED_LEN_BYTE_ARRAY,
-                                  LogicalType::DECIMAL, FLBA_LENGTH, 10, 2);
-  const ColumnDescriptor d(type, 4, 0);
-  num_values_ = MakePages<FLBAType>(&d, 1, 100, def_levels_, rep_levels_, values_,
-                                    data_buffer_, pages_);
-  num_levels_ = 1 * 100;
-  InitScanner(&d);
-  TypedScanner<FLBAType>* scanner =
-      reinterpret_cast<TypedScanner<FLBAType>*>(scanner_.get());
-  ASSERT_EQ(10, scanner->descr()->type_precision());
-  ASSERT_EQ(2, scanner->descr()->type_scale());
-  ASSERT_EQ(FLBA_LENGTH, scanner->descr()->type_length());
-}
-
-TEST_F(TestFLBAFlatScanner, TestFLBAPrinterNext) {
-  NodePtr type =
-      schema::PrimitiveNode::Make("c1", Repetition::OPTIONAL, Type::FIXED_LEN_BYTE_ARRAY,
-                                  LogicalType::DECIMAL, FLBA_LENGTH, 10, 2);
-  const ColumnDescriptor d(type, 4, 0);
-  num_values_ = MakePages<FLBAType>(&d, 1, 100, def_levels_, rep_levels_, values_,
-                                    data_buffer_, pages_);
-  num_levels_ = 1 * 100;
-  InitScanner(&d);
-  TypedScanner<FLBAType>* scanner =
-      reinterpret_cast<TypedScanner<FLBAType>*>(scanner_.get());
-  scanner->SetBatchSize(batch_size);
-  std::stringstream ss_fail;
-  for (int i = 0; i < num_levels_; i++) {
-    std::stringstream ss;
-    scanner->PrintNext(ss, 17);
-    std::string result = ss.str();
-    ASSERT_LE(17, result.size()) << i;
-  }
-  ASSERT_THROW(scanner->PrintNext(ss_fail, 17), ParquetException);
-}
-
-}  // namespace test
-}  // namespace parquet
diff --git a/src/parquet/column_scanner.cc b/src/parquet/column_scanner.cc
deleted file mode 100644
index 51c8773..0000000
--- a/src/parquet/column_scanner.cc
+++ /dev/null
@@ -1,91 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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.
-
-#include "parquet/column_scanner.h"
-
-#include <cstdint>
-#include <memory>
-
-#include "parquet/column_reader.h"
-#include "parquet/util/memory.h"
-
-using arrow::MemoryPool;
-
-namespace parquet {
-
-std::shared_ptr<Scanner> Scanner::Make(std::shared_ptr<ColumnReader> col_reader,
-                                       int64_t batch_size, MemoryPool* pool) {
-  switch (col_reader->type()) {
-    case Type::BOOLEAN:
-      return std::make_shared<BoolScanner>(col_reader, batch_size, pool);
-    case Type::INT32:
-      return std::make_shared<Int32Scanner>(col_reader, batch_size, pool);
-    case Type::INT64:
-      return std::make_shared<Int64Scanner>(col_reader, batch_size, pool);
-    case Type::INT96:
-      return std::make_shared<Int96Scanner>(col_reader, batch_size, pool);
-    case Type::FLOAT:
-      return std::make_shared<FloatScanner>(col_reader, batch_size, pool);
-    case Type::DOUBLE:
-      return std::make_shared<DoubleScanner>(col_reader, batch_size, pool);
-    case Type::BYTE_ARRAY:
-      return std::make_shared<ByteArrayScanner>(col_reader, batch_size, pool);
-    case Type::FIXED_LEN_BYTE_ARRAY:
-      return std::make_shared<FixedLenByteArrayScanner>(col_reader, batch_size, pool);
-    default:
-      ParquetException::NYI("type reader not implemented");
-  }
-  // Unreachable code, but supress compiler warning
-  return std::shared_ptr<Scanner>(nullptr);
-}
-
-int64_t ScanAllValues(int32_t batch_size, int16_t* def_levels, int16_t* rep_levels,
-                      uint8_t* values, int64_t* values_buffered,
-                      parquet::ColumnReader* reader) {
-  switch (reader->type()) {
-    case parquet::Type::BOOLEAN:
-      return ScanAll<parquet::BoolReader>(batch_size, def_levels, rep_levels, values,
-                                          values_buffered, reader);
-    case parquet::Type::INT32:
-      return ScanAll<parquet::Int32Reader>(batch_size, def_levels, rep_levels, values,
-                                           values_buffered, reader);
-    case parquet::Type::INT64:
-      return ScanAll<parquet::Int64Reader>(batch_size, def_levels, rep_levels, values,
-                                           values_buffered, reader);
-    case parquet::Type::INT96:
-      return ScanAll<parquet::Int96Reader>(batch_size, def_levels, rep_levels, values,
-                                           values_buffered, reader);
-    case parquet::Type::FLOAT:
-      return ScanAll<parquet::FloatReader>(batch_size, def_levels, rep_levels, values,
-                                           values_buffered, reader);
-    case parquet::Type::DOUBLE:
-      return ScanAll<parquet::DoubleReader>(batch_size, def_levels, rep_levels, values,
-                                            values_buffered, reader);
-    case parquet::Type::BYTE_ARRAY:
-      return ScanAll<parquet::ByteArrayReader>(batch_size, def_levels, rep_levels, values,
-                                               values_buffered, reader);
-    case parquet::Type::FIXED_LEN_BYTE_ARRAY:
-      return ScanAll<parquet::FixedLenByteArrayReader>(batch_size, def_levels, rep_levels,
-                                                       values, values_buffered, reader);
-    default:
-      parquet::ParquetException::NYI("type reader not implemented");
-  }
-  // Unreachable code, but supress compiler warning
-  return 0;
-}
-
-}  // namespace parquet
diff --git a/src/parquet/column_scanner.h b/src/parquet/column_scanner.h
deleted file mode 100644
index 0a866ee..0000000
--- a/src/parquet/column_scanner.h
+++ /dev/null
@@ -1,257 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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.
-
-#ifndef PARQUET_COLUMN_SCANNER_H
-#define PARQUET_COLUMN_SCANNER_H
-
-#include <stdio.h>
-#include <cstdint>
-#include <memory>
-#include <ostream>
-#include <string>
-#include <vector>
-
-#include "parquet/column_reader.h"
-#include "parquet/exception.h"
-#include "parquet/schema.h"
-#include "parquet/types.h"
-#include "parquet/util/memory.h"
-#include "parquet/util/visibility.h"
-
-namespace parquet {
-
-static constexpr int64_t DEFAULT_SCANNER_BATCH_SIZE = 128;
-
-class PARQUET_EXPORT Scanner {
- public:
-  explicit Scanner(std::shared_ptr<ColumnReader> reader,
-                   int64_t batch_size = DEFAULT_SCANNER_BATCH_SIZE,
-                   ::arrow::MemoryPool* pool = ::arrow::default_memory_pool())
-      : batch_size_(batch_size),
-        level_offset_(0),
-        levels_buffered_(0),
-        value_buffer_(AllocateBuffer(pool)),
-        value_offset_(0),
-        values_buffered_(0),
-        reader_(reader) {
-    def_levels_.resize(descr()->max_definition_level() > 0 ? batch_size_ : 0);
-    rep_levels_.resize(descr()->max_repetition_level() > 0 ? batch_size_ : 0);
-  }
-
-  virtual ~Scanner() {}
-
-  static std::shared_ptr<Scanner> Make(
-      std::shared_ptr<ColumnReader> col_reader,
-      int64_t batch_size = DEFAULT_SCANNER_BATCH_SIZE,
-      ::arrow::MemoryPool* pool = ::arrow::default_memory_pool());
-
-  virtual void PrintNext(std::ostream& out, int width) = 0;
-
-  bool HasNext() { return level_offset_ < levels_buffered_ || reader_->HasNext(); }
-
-  const ColumnDescriptor* descr() const { return reader_->descr(); }
-
-  int64_t batch_size() const { return batch_size_; }
-
-  void SetBatchSize(int64_t batch_size) { batch_size_ = batch_size; }
-
- protected:
-  int64_t batch_size_;
-
-  std::vector<int16_t> def_levels_;
-  std::vector<int16_t> rep_levels_;
-  int level_offset_;
-  int levels_buffered_;
-
-  std::shared_ptr<ResizableBuffer> value_buffer_;
-  int value_offset_;
-  int64_t values_buffered_;
-
- private:
-  std::shared_ptr<ColumnReader> reader_;
-};
-
-template <typename DType>
-class PARQUET_EXPORT TypedScanner : public Scanner {
- public:
-  typedef typename DType::c_type T;
-
-  explicit TypedScanner(std::shared_ptr<ColumnReader> reader,
-                        int64_t batch_size = DEFAULT_SCANNER_BATCH_SIZE,
-                        ::arrow::MemoryPool* pool = ::arrow::default_memory_pool())
-      : Scanner(reader, batch_size, pool) {
-    typed_reader_ = static_cast<TypedColumnReader<DType>*>(reader.get());
-    int value_byte_size = type_traits<DType::type_num>::value_byte_size;
-    PARQUET_THROW_NOT_OK(value_buffer_->Resize(batch_size_ * value_byte_size));
-    values_ = reinterpret_cast<T*>(value_buffer_->mutable_data());
-  }
-
-  virtual ~TypedScanner() {}
-
-  bool NextLevels(int16_t* def_level, int16_t* rep_level) {
-    if (level_offset_ == levels_buffered_) {
-      levels_buffered_ = static_cast<int>(
-          typed_reader_->ReadBatch(static_cast<int>(batch_size_), def_levels_.data(),
-                                   rep_levels_.data(), values_, &values_buffered_));
-
-      value_offset_ = 0;
-      level_offset_ = 0;
-      if (!levels_buffered_) {
-        return false;
-      }
-    }
-    *def_level = descr()->max_definition_level() > 0 ? def_levels_[level_offset_] : 0;
-    *rep_level = descr()->max_repetition_level() > 0 ? rep_levels_[level_offset_] : 0;
-    level_offset_++;
-    return true;
-  }
-
-  bool Next(T* val, int16_t* def_level, int16_t* rep_level, bool* is_null) {
-    if (level_offset_ == levels_buffered_) {
-      if (!HasNext()) {
-        // Out of data pages
-        return false;
-      }
-    }
-
-    NextLevels(def_level, rep_level);
-    *is_null = *def_level < descr()->max_definition_level();
-
-    if (*is_null) {
-      return true;
-    }
-
-    if (value_offset_ == values_buffered_) {
-      throw ParquetException("Value was non-null, but has not been buffered");
-    }
-    *val = values_[value_offset_++];
-    return true;
-  }
-
-  // Returns true if there is a next value
-  bool NextValue(T* val, bool* is_null) {
-    if (level_offset_ == levels_buffered_) {
-      if (!HasNext()) {
-        // Out of data pages
-        return false;
-      }
-    }
-
-    // Out of values
-    int16_t def_level = -1;
-    int16_t rep_level = -1;
-    NextLevels(&def_level, &rep_level);
-    *is_null = def_level < descr()->max_definition_level();
-
-    if (*is_null) {
-      return true;
-    }
-
-    if (value_offset_ == values_buffered_) {
-      throw ParquetException("Value was non-null, but has not been buffered");
-    }
-    *val = values_[value_offset_++];
-    return true;
-  }
-
-  virtual void PrintNext(std::ostream& out, int width) {
-    T val;
-    bool is_null = false;
-    char buffer[25];
-
-    if (!NextValue(&val, &is_null)) {
-      throw ParquetException("No more values buffered");
-    }
-
-    if (is_null) {
-      std::string null_fmt = format_fwf<ByteArrayType>(width);
-      snprintf(buffer, sizeof(buffer), null_fmt.c_str(), "NULL");
-    } else {
-      FormatValue(&val, buffer, sizeof(buffer), width);
-    }
-    out << buffer;
-  }
-
- private:
-  // The ownership of this object is expressed through the reader_ variable in the base
-  TypedColumnReader<DType>* typed_reader_;
-
-  inline void FormatValue(void* val, char* buffer, int bufsize, int width);
-
-  T* values_;
-};
-
-template <typename DType>
-inline void TypedScanner<DType>::FormatValue(void* val, char* buffer, int bufsize,
-                                             int width) {
-  std::string fmt = format_fwf<DType>(width);
-  snprintf(buffer, bufsize, fmt.c_str(), *reinterpret_cast<T*>(val));
-}
-
-template <>
-inline void TypedScanner<Int96Type>::FormatValue(void* val, char* buffer, int bufsize,
-                                                 int width) {
-  std::string fmt = format_fwf<Int96Type>(width);
-  std::string result = Int96ToString(*reinterpret_cast<Int96*>(val));
-  snprintf(buffer, bufsize, fmt.c_str(), result.c_str());
-}
-
-template <>
-inline void TypedScanner<ByteArrayType>::FormatValue(void* val, char* buffer, int bufsize,
-                                                     int width) {
-  std::string fmt = format_fwf<ByteArrayType>(width);
-  std::string result = ByteArrayToString(*reinterpret_cast<ByteArray*>(val));
-  snprintf(buffer, bufsize, fmt.c_str(), result.c_str());
-}
-
-template <>
-inline void TypedScanner<FLBAType>::FormatValue(void* val, char* buffer, int bufsize,
-                                                int width) {
-  std::string fmt = format_fwf<FLBAType>(width);
-  std::string result = FixedLenByteArrayToString(
-      *reinterpret_cast<FixedLenByteArray*>(val), descr()->type_length());
-  snprintf(buffer, bufsize, fmt.c_str(), result.c_str());
-}
-
-typedef TypedScanner<BooleanType> BoolScanner;
-typedef TypedScanner<Int32Type> Int32Scanner;
-typedef TypedScanner<Int64Type> Int64Scanner;
-typedef TypedScanner<Int96Type> Int96Scanner;
-typedef TypedScanner<FloatType> FloatScanner;
-typedef TypedScanner<DoubleType> DoubleScanner;
-typedef TypedScanner<ByteArrayType> ByteArrayScanner;
-typedef TypedScanner<FLBAType> FixedLenByteArrayScanner;
-
-template <typename RType>
-int64_t ScanAll(int32_t batch_size, int16_t* def_levels, int16_t* rep_levels,
-                uint8_t* values, int64_t* values_buffered,
-                parquet::ColumnReader* reader) {
-  typedef typename RType::T Type;
-  auto typed_reader = static_cast<RType*>(reader);
-  auto vals = reinterpret_cast<Type*>(&values[0]);
-  return typed_reader->ReadBatch(batch_size, def_levels, rep_levels, vals,
-                                 values_buffered);
-}
-
-int64_t PARQUET_EXPORT ScanAllValues(int32_t batch_size, int16_t* def_levels,
-                                     int16_t* rep_levels, uint8_t* values,
-                                     int64_t* values_buffered,
-                                     parquet::ColumnReader* reader);
-
-}  // namespace parquet
-
-#endif  // PARQUET_COLUMN_SCANNER_H
diff --git a/src/parquet/column_writer-test.cc b/src/parquet/column_writer-test.cc
deleted file mode 100644
index e87d549..0000000
--- a/src/parquet/column_writer-test.cc
+++ /dev/null
@@ -1,807 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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.
-
-#include <gtest/gtest.h>
-
-#include "parquet/column_reader.h"
-#include "parquet/column_writer.h"
-#include "parquet/parquet_types.h"
-#include "parquet/test-specialization.h"
-#include "parquet/test-util.h"
-#include "parquet/types.h"
-#include "parquet/util/comparison.h"
-#include "parquet/util/memory.h"
-
-namespace parquet {
-
-using schema::NodePtr;
-using schema::PrimitiveNode;
-
-namespace test {
-
-// The default size used in most tests.
-const int SMALL_SIZE = 100;
-#ifdef PARQUET_VALGRIND
-// Larger size to test some corner cases, only used in some specific cases.
-const int LARGE_SIZE = 10000;
-// Very large size to test dictionary fallback.
-const int VERY_LARGE_SIZE = 40000;
-#else
-// Larger size to test some corner cases, only used in some specific cases.
-const int LARGE_SIZE = 100000;
-// Very large size to test dictionary fallback.
-const int VERY_LARGE_SIZE = 400000;
-#endif
-
-template <typename TestType>
-class TestPrimitiveWriter : public PrimitiveTypedTest<TestType> {
- public:
-  typedef typename TestType::c_type T;
-
-  void SetUp() {
-    this->SetupValuesOut(SMALL_SIZE);
-    writer_properties_ = default_writer_properties();
-    definition_levels_out_.resize(SMALL_SIZE);
-    repetition_levels_out_.resize(SMALL_SIZE);
-
-    this->SetUpSchema(Repetition::REQUIRED);
-
-    descr_ = this->schema_.Column(0);
-  }
-
-  Type::type type_num() { return TestType::type_num; }
-
-  void BuildReader(int64_t num_rows,
-                   Compression::type compression = Compression::UNCOMPRESSED) {
-    auto buffer = sink_->GetBuffer();
-    std::unique_ptr<InMemoryInputStream> source(new InMemoryInputStream(buffer));
-    std::unique_ptr<PageReader> page_reader =
-        PageReader::Open(std::move(source), num_rows, compression);
-    reader_.reset(new TypedColumnReader<TestType>(this->descr_, std::move(page_reader)));
-  }
-
-  std::shared_ptr<TypedColumnWriter<TestType>> BuildWriter(
-      int64_t output_size = SMALL_SIZE,
-      const ColumnProperties& column_properties = ColumnProperties()) {
-    sink_.reset(new InMemoryOutputStream());
-    WriterProperties::Builder wp_builder;
-    if (column_properties.encoding() == Encoding::PLAIN_DICTIONARY ||
-        column_properties.encoding() == Encoding::RLE_DICTIONARY) {
-      wp_builder.enable_dictionary();
-    } else {
-      wp_builder.disable_dictionary();
-      wp_builder.encoding(column_properties.encoding());
-    }
-    wp_builder.max_statistics_size(column_properties.max_statistics_size());
-    writer_properties_ = wp_builder.build();
-
-    metadata_ = ColumnChunkMetaDataBuilder::Make(
-        writer_properties_, this->descr_, reinterpret_cast<uint8_t*>(&thrift_metadata_));
-    std::unique_ptr<PageWriter> pager =
-        PageWriter::Open(sink_.get(), column_properties.compression(), metadata_.get());
-    std::shared_ptr<ColumnWriter> writer =
-        ColumnWriter::Make(metadata_.get(), std::move(pager), writer_properties_.get());
-    return std::static_pointer_cast<TypedColumnWriter<TestType>>(writer);
-  }
-
-  void ReadColumn(Compression::type compression = Compression::UNCOMPRESSED) {
-    BuildReader(static_cast<int64_t>(this->values_out_.size()), compression);
-    reader_->ReadBatch(static_cast<int>(this->values_out_.size()),
-                       definition_levels_out_.data(), repetition_levels_out_.data(),
-                       this->values_out_ptr_, &values_read_);
-    this->SyncValuesOut();
-  }
-
-  void ReadColumnFully(Compression::type compression = Compression::UNCOMPRESSED);
-
-  void TestRequiredWithEncoding(Encoding::type encoding) {
-    return TestRequiredWithSettings(encoding, Compression::UNCOMPRESSED, false, false);
-  }
-
-  void TestRequiredWithSettings(Encoding::type encoding, Compression::type compression,
-                                bool enable_dictionary, bool enable_statistics,
-                                int64_t num_rows = SMALL_SIZE) {
-    this->GenerateData(num_rows);
-
-    this->WriteRequiredWithSettings(encoding, compression, enable_dictionary,
-                                    enable_statistics, num_rows);
-    ASSERT_NO_FATAL_FAILURE(this->ReadAndCompare(compression, num_rows));
-
-    this->WriteRequiredWithSettingsSpaced(encoding, compression, enable_dictionary,
-                                          enable_statistics, num_rows);
-    ASSERT_NO_FATAL_FAILURE(this->ReadAndCompare(compression, num_rows));
-  }
-
-  void WriteRequiredWithSettings(Encoding::type encoding, Compression::type compression,
-                                 bool enable_dictionary, bool enable_statistics,
-                                 int64_t num_rows) {
-    ColumnProperties column_properties(encoding, compression, enable_dictionary,
-                                       enable_statistics);
-    std::shared_ptr<TypedColumnWriter<TestType>> writer =
-        this->BuildWriter(num_rows, column_properties);
-    writer->WriteBatch(this->values_.size(), nullptr, nullptr, this->values_ptr_);
-    // The behaviour should be independent from the number of Close() calls
-    writer->Close();
-    writer->Close();
-  }
-
-  void WriteRequiredWithSettingsSpaced(Encoding::type encoding,
-                                       Compression::type compression,
-                                       bool enable_dictionary, bool enable_statistics,
-                                       int64_t num_rows) {
-    std::vector<uint8_t> valid_bits(
-        BitUtil::BytesForBits(static_cast<uint32_t>(this->values_.size())) + 1, 255);
-    ColumnProperties column_properties(encoding, compression, enable_dictionary,
-                                       enable_statistics);
-    std::shared_ptr<TypedColumnWriter<TestType>> writer =
-        this->BuildWriter(num_rows, column_properties);
-    writer->WriteBatchSpaced(this->values_.size(), nullptr, nullptr, valid_bits.data(), 0,
-                             this->values_ptr_);
-    // The behaviour should be independent from the number of Close() calls
-    writer->Close();
-    writer->Close();
-  }
-
-  void ReadAndCompare(Compression::type compression, int64_t num_rows) {
-    this->SetupValuesOut(num_rows);
-    this->ReadColumnFully(compression);
-    std::shared_ptr<CompareDefault<TestType>> compare;
-    compare = std::static_pointer_cast<CompareDefault<TestType>>(
-        Comparator::Make(this->descr_));
-    for (size_t i = 0; i < this->values_.size(); i++) {
-      if ((*compare)(this->values_[i], this->values_out_[i]) ||
-          (*compare)(this->values_out_[i], this->values_[i])) {
-        std::cout << "Failed at " << i << std::endl;
-      }
-      ASSERT_FALSE((*compare)(this->values_[i], this->values_out_[i]));
-      ASSERT_FALSE((*compare)(this->values_out_[i], this->values_[i]));
-    }
-    ASSERT_EQ(this->values_, this->values_out_);
-  }
-
-  int64_t metadata_num_values() {
-    // Metadata accessor must be created lazily.
-    // This is because the ColumnChunkMetaData semantics dictate the metadata object is
-    // complete (no changes to the metadata buffer can be made after instantiation)
-    auto metadata_accessor = ColumnChunkMetaData::Make(
-        reinterpret_cast<const uint8_t*>(&thrift_metadata_), this->descr_);
-    return metadata_accessor->num_values();
-  }
-
-  bool metadata_is_stats_set() {
-    // Metadata accessor must be created lazily.
-    // This is because the ColumnChunkMetaData semantics dictate the metadata object is
-    // complete (no changes to the metadata buffer can be made after instantiation)
-    ApplicationVersion app_version(this->writer_properties_->created_by());
-    auto metadata_accessor = ColumnChunkMetaData::Make(
-        reinterpret_cast<const uint8_t*>(&thrift_metadata_), this->descr_, &app_version);
-    return metadata_accessor->is_stats_set();
-  }
-
-  std::vector<Encoding::type> metadata_encodings() {
-    // Metadata accessor must be created lazily.
-    // This is because the ColumnChunkMetaData semantics dictate the metadata object is
-    // complete (no changes to the metadata buffer can be made after instantiation)
-    auto metadata_accessor = ColumnChunkMetaData::Make(
-        reinterpret_cast<const uint8_t*>(&thrift_metadata_), this->descr_);
-    return metadata_accessor->encodings();
-  }
-
- protected:
-  int64_t values_read_;
-  // Keep the reader alive as for ByteArray the lifetime of the ByteArray
-  // content is bound to the reader.
-  std::unique_ptr<TypedColumnReader<TestType>> reader_;
-
-  std::vector<int16_t> definition_levels_out_;
-  std::vector<int16_t> repetition_levels_out_;
-
-  const ColumnDescriptor* descr_;
-
- private:
-  format::ColumnChunk thrift_metadata_;
-  std::unique_ptr<ColumnChunkMetaDataBuilder> metadata_;
-  std::unique_ptr<InMemoryOutputStream> sink_;
-  std::shared_ptr<WriterProperties> writer_properties_;
-  std::vector<std::vector<uint8_t>> data_buffer_;
-};
-
-template <typename TestType>
-void TestPrimitiveWriter<TestType>::ReadColumnFully(Compression::type compression) {
-  int64_t total_values = static_cast<int64_t>(this->values_out_.size());
-  BuildReader(total_values, compression);
-  values_read_ = 0;
-  while (values_read_ < total_values) {
-    int64_t values_read_recently = 0;
-    reader_->ReadBatch(
-        static_cast<int>(this->values_out_.size()) - static_cast<int>(values_read_),
-        definition_levels_out_.data() + values_read_,
-        repetition_levels_out_.data() + values_read_,
-        this->values_out_ptr_ + values_read_, &values_read_recently);
-    values_read_ += values_read_recently;
-  }
-  this->SyncValuesOut();
-}
-
-template <>
-void TestPrimitiveWriter<Int96Type>::ReadAndCompare(Compression::type compression,
-                                                    int64_t num_rows) {
-  this->SetupValuesOut(num_rows);
-  this->ReadColumnFully(compression);
-  std::shared_ptr<CompareDefault<Int96Type>> compare;
-  compare = std::make_shared<CompareDefaultInt96>();
-  for (size_t i = 0; i < this->values_.size(); i++) {
-    if ((*compare)(this->values_[i], this->values_out_[i]) ||
-        (*compare)(this->values_out_[i], this->values_[i])) {
-      std::cout << "Failed at " << i << std::endl;
-    }
-    ASSERT_FALSE((*compare)(this->values_[i], this->values_out_[i]));
-    ASSERT_FALSE((*compare)(this->values_out_[i], this->values_[i]));
-  }
-  ASSERT_EQ(this->values_, this->values_out_);
-}
-
-template <>
-void TestPrimitiveWriter<FLBAType>::ReadColumnFully(Compression::type compression) {
-  int64_t total_values = static_cast<int64_t>(this->values_out_.size());
-  BuildReader(total_values, compression);
-  this->data_buffer_.clear();
-
-  values_read_ = 0;
-  while (values_read_ < total_values) {
-    int64_t values_read_recently = 0;
-    reader_->ReadBatch(
-        static_cast<int>(this->values_out_.size()) - static_cast<int>(values_read_),
-        definition_levels_out_.data() + values_read_,
-        repetition_levels_out_.data() + values_read_,
-        this->values_out_ptr_ + values_read_, &values_read_recently);
-
-    // Copy contents of the pointers
-    std::vector<uint8_t> data(values_read_recently * this->descr_->type_length());
-    uint8_t* data_ptr = data.data();
-    for (int64_t i = 0; i < values_read_recently; i++) {
-      memcpy(data_ptr + this->descr_->type_length() * i,
-             this->values_out_[i + values_read_].ptr, this->descr_->type_length());
-      this->values_out_[i + values_read_].ptr =
-          data_ptr + this->descr_->type_length() * i;
-    }
-    data_buffer_.emplace_back(std::move(data));
-
-    values_read_ += values_read_recently;
-  }
-  this->SyncValuesOut();
-}
-
-typedef ::testing::Types<Int32Type, Int64Type, Int96Type, FloatType, DoubleType,
-                         BooleanType, ByteArrayType, FLBAType>
-    TestTypes;
-
-TYPED_TEST_CASE(TestPrimitiveWriter, TestTypes);
-
-using TestNullValuesWriter = TestPrimitiveWriter<Int32Type>;
-
-TYPED_TEST(TestPrimitiveWriter, RequiredPlain) {
-  this->TestRequiredWithEncoding(Encoding::PLAIN);
-}
-
-TYPED_TEST(TestPrimitiveWriter, RequiredDictionary) {
-  this->TestRequiredWithEncoding(Encoding::PLAIN_DICTIONARY);
-}
-
-/*
-TYPED_TEST(TestPrimitiveWriter, RequiredRLE) {
-  this->TestRequiredWithEncoding(Encoding::RLE);
-}
-
-TYPED_TEST(TestPrimitiveWriter, RequiredBitPacked) {
-  this->TestRequiredWithEncoding(Encoding::BIT_PACKED);
-}
-
-TYPED_TEST(TestPrimitiveWriter, RequiredDeltaBinaryPacked) {
-  this->TestRequiredWithEncoding(Encoding::DELTA_BINARY_PACKED);
-}
-
-TYPED_TEST(TestPrimitiveWriter, RequiredDeltaLengthByteArray) {
-  this->TestRequiredWithEncoding(Encoding::DELTA_LENGTH_BYTE_ARRAY);
-}
-
-TYPED_TEST(TestPrimitiveWriter, RequiredDeltaByteArray) {
-  this->TestRequiredWithEncoding(Encoding::DELTA_BYTE_ARRAY);
-}
-
-TYPED_TEST(TestPrimitiveWriter, RequiredRLEDictionary) {
-  this->TestRequiredWithEncoding(Encoding::RLE_DICTIONARY);
-}
-*/
-
-TYPED_TEST(TestPrimitiveWriter, RequiredPlainWithSnappyCompression) {
-  this->TestRequiredWithSettings(Encoding::PLAIN, Compression::SNAPPY, false, false,
-                                 LARGE_SIZE);
-}
-
-TYPED_TEST(TestPrimitiveWriter, RequiredPlainWithBrotliCompression) {
-  this->TestRequiredWithSettings(Encoding::PLAIN, Compression::BROTLI, false, false,
-                                 LARGE_SIZE);
-}
-
-TYPED_TEST(TestPrimitiveWriter, RequiredPlainWithGzipCompression) {
-  this->TestRequiredWithSettings(Encoding::PLAIN, Compression::GZIP, false, false,
-                                 LARGE_SIZE);
-}
-
-TYPED_TEST(TestPrimitiveWriter, RequiredPlainWithLz4Compression) {
-  this->TestRequiredWithSettings(Encoding::PLAIN, Compression::LZ4, false, false,
-                                 LARGE_SIZE);
-}
-
-TYPED_TEST(TestPrimitiveWriter, RequiredPlainWithZstdCompression) {
-  this->TestRequiredWithSettings(Encoding::PLAIN, Compression::ZSTD, false, false,
-                                 LARGE_SIZE);
-}
-
-TYPED_TEST(TestPrimitiveWriter, RequiredPlainWithStats) {
-  this->TestRequiredWithSettings(Encoding::PLAIN, Compression::UNCOMPRESSED, false, true,
-                                 LARGE_SIZE);
-}
-
-TYPED_TEST(TestPrimitiveWriter, RequiredPlainWithStatsAndSnappyCompression) {
-  this->TestRequiredWithSettings(Encoding::PLAIN, Compression::SNAPPY, false, true,
-                                 LARGE_SIZE);
-}
-
-TYPED_TEST(TestPrimitiveWriter, RequiredPlainWithStatsAndBrotliCompression) {
-  this->TestRequiredWithSettings(Encoding::PLAIN, Compression::BROTLI, false, true,
-                                 LARGE_SIZE);
-}
-
-TYPED_TEST(TestPrimitiveWriter, RequiredPlainWithStatsAndGzipCompression) {
-  this->TestRequiredWithSettings(Encoding::PLAIN, Compression::GZIP, false, true,
-                                 LARGE_SIZE);
-}
-
-TYPED_TEST(TestPrimitiveWriter, RequiredPlainWithStatsAndLz4Compression) {
-  this->TestRequiredWithSettings(Encoding::PLAIN, Compression::LZ4, false, true,
-                                 LARGE_SIZE);
-}
-
-TYPED_TEST(TestPrimitiveWriter, RequiredPlainWithStatsAndZstdCompression) {
-  this->TestRequiredWithSettings(Encoding::PLAIN, Compression::ZSTD, false, true,
-                                 LARGE_SIZE);
-}
-
-TYPED_TEST(TestPrimitiveWriter, Optional) {
-  // Optional and non-repeated, with definition levels
-  // but no repetition levels
-  this->SetUpSchema(Repetition::OPTIONAL);
-
-  this->GenerateData(SMALL_SIZE);
-  std::vector<int16_t> definition_levels(SMALL_SIZE, 1);
-  definition_levels[1] = 0;
-
-  auto writer = this->BuildWriter();
-  writer->WriteBatch(this->values_.size(), definition_levels.data(), nullptr,
-                     this->values_ptr_);
-  writer->Close();
-
-  // PARQUET-703
-  ASSERT_EQ(100, this->metadata_num_values());
-
-  this->ReadColumn();
-  ASSERT_EQ(99, this->values_read_);
-  this->values_out_.resize(99);
-  this->values_.resize(99);
-  ASSERT_EQ(this->values_, this->values_out_);
-}
-
-TYPED_TEST(TestPrimitiveWriter, OptionalSpaced) {
-  // Optional and non-repeated, with definition levels
-  // but no repetition levels
-  this->SetUpSchema(Repetition::OPTIONAL);
-
-  this->GenerateData(SMALL_SIZE);
-  std::vector<int16_t> definition_levels(SMALL_SIZE, 1);
-  std::vector<uint8_t> valid_bits(::arrow::BitUtil::BytesForBits(SMALL_SIZE), 255);
-
-  definition_levels[SMALL_SIZE - 1] = 0;
-  ::arrow::BitUtil::ClearBit(valid_bits.data(), SMALL_SIZE - 1);
-  definition_levels[1] = 0;
-  ::arrow::BitUtil::ClearBit(valid_bits.data(), 1);
-
-  auto writer = this->BuildWriter();
-  writer->WriteBatchSpaced(this->values_.size(), definition_levels.data(), nullptr,
-                           valid_bits.data(), 0, this->values_ptr_);
-  writer->Close();
-
-  // PARQUET-703
-  ASSERT_EQ(100, this->metadata_num_values());
-
-  this->ReadColumn();
-  ASSERT_EQ(98, this->values_read_);
-  this->values_out_.resize(98);
-  this->values_.resize(99);
-  this->values_.erase(this->values_.begin() + 1);
-  ASSERT_EQ(this->values_, this->values_out_);
-}
-
-TYPED_TEST(TestPrimitiveWriter, Repeated) {
-  // Optional and repeated, so definition and repetition levels
-  this->SetUpSchema(Repetition::REPEATED);
-
-  this->GenerateData(SMALL_SIZE);
-  std::vector<int16_t> definition_levels(SMALL_SIZE, 1);
-  definition_levels[1] = 0;
-  std::vector<int16_t> repetition_levels(SMALL_SIZE, 0);
-
-  auto writer = this->BuildWriter();
-  writer->WriteBatch(this->values_.size(), definition_levels.data(),
-                     repetition_levels.data(), this->values_ptr_);
-  writer->Close();
-
-  this->ReadColumn();
-  ASSERT_EQ(SMALL_SIZE - 1, this->values_read_);
-  this->values_out_.resize(SMALL_SIZE - 1);
-  this->values_.resize(SMALL_SIZE - 1);
-  ASSERT_EQ(this->values_, this->values_out_);
-}
-
-TYPED_TEST(TestPrimitiveWriter, RequiredLargeChunk) {
-  this->GenerateData(LARGE_SIZE);
-
-  // Test case 1: required and non-repeated, so no definition or repetition levels
-  auto writer = this->BuildWriter(LARGE_SIZE);
-  writer->WriteBatch(this->values_.size(), nullptr, nullptr, this->values_ptr_);
-  writer->Close();
-
-  // Just read the first SMALL_SIZE rows to ensure we could read it back in
-  this->ReadColumn();
-  ASSERT_EQ(SMALL_SIZE, this->values_read_);
-  this->values_.resize(SMALL_SIZE);
-  ASSERT_EQ(this->values_, this->values_out_);
-}
-
-// Test case for dictionary fallback encoding
-TYPED_TEST(TestPrimitiveWriter, RequiredVeryLargeChunk) {
-  this->GenerateData(VERY_LARGE_SIZE);
-
-  auto writer = this->BuildWriter(VERY_LARGE_SIZE, Encoding::PLAIN_DICTIONARY);
-  writer->WriteBatch(this->values_.size(), nullptr, nullptr, this->values_ptr_);
-  writer->Close();
-
-  // Read all rows so we are sure that also the non-dictionary pages are read correctly
-  this->SetupValuesOut(VERY_LARGE_SIZE);
-  this->ReadColumnFully();
-  ASSERT_EQ(VERY_LARGE_SIZE, this->values_read_);
-  this->values_.resize(VERY_LARGE_SIZE);
-  ASSERT_EQ(this->values_, this->values_out_);
-  std::vector<Encoding::type> encodings = this->metadata_encodings();
-  // There are 3 encodings (RLE, PLAIN_DICTIONARY, PLAIN) in a fallback case
-  // Dictionary encoding is not allowed for boolean type
-  // There are 2 encodings (RLE, PLAIN) in a non dictionary encoding case
-  if (this->type_num() != Type::BOOLEAN) {
-    ASSERT_EQ(Encoding::PLAIN_DICTIONARY, encodings[0]);
-    ASSERT_EQ(Encoding::PLAIN, encodings[1]);
-    ASSERT_EQ(Encoding::RLE, encodings[2]);
-  } else {
-    ASSERT_EQ(Encoding::PLAIN, encodings[0]);
-    ASSERT_EQ(Encoding::RLE, encodings[1]);
-  }
-}
-
-// PARQUET-719
-// Test case for NULL values
-TEST_F(TestNullValuesWriter, OptionalNullValueChunk) {
-  this->SetUpSchema(Repetition::OPTIONAL);
-
-  this->GenerateData(LARGE_SIZE);
-
-  std::vector<int16_t> definition_levels(LARGE_SIZE, 0);
-  std::vector<int16_t> repetition_levels(LARGE_SIZE, 0);
-
-  auto writer = this->BuildWriter(LARGE_SIZE);
-  // All values being written are NULL
-  writer->WriteBatch(this->values_.size(), definition_levels.data(),
-                     repetition_levels.data(), nullptr);
-  writer->Close();
-
-  // Just read the first SMALL_SIZE rows to ensure we could read it back in
-  this->ReadColumn();
-  ASSERT_EQ(0, this->values_read_);
-}
-
-// PARQUET-764
-// Correct bitpacking for boolean write at non-byte boundaries
-using TestBooleanValuesWriter = TestPrimitiveWriter<BooleanType>;
-TEST_F(TestBooleanValuesWriter, AlternateBooleanValues) {
-  this->SetUpSchema(Repetition::REQUIRED);
-  auto writer = this->BuildWriter();
-  for (int i = 0; i < SMALL_SIZE; i++) {
-    bool value = (i % 2 == 0) ? true : false;
-    writer->WriteBatch(1, nullptr, nullptr, &value);
-  }
-  writer->Close();
-  this->ReadColumn();
-  for (int i = 0; i < SMALL_SIZE; i++) {
-    ASSERT_EQ((i % 2 == 0) ? true : false, this->values_out_[i]) << i;
-  }
-}
-
-// PARQUET-979
-// Prevent writing large stats
-using TestByteArrayValuesWriter = TestPrimitiveWriter<ByteArrayType>;
-TEST_F(TestByteArrayValuesWriter, OmitStats) {
-  int min_len = 1024 * 4;
-  int max_len = 1024 * 8;
-  this->SetUpSchema(Repetition::REQUIRED);
-  auto writer = this->BuildWriter();
-
-  values_.resize(SMALL_SIZE);
-  InitWideByteArrayValues(SMALL_SIZE, this->values_, this->buffer_, min_len, max_len);
-  writer->WriteBatch(SMALL_SIZE, nullptr, nullptr, this->values_.data());
-  writer->Close();
-
-  ASSERT_FALSE(this->metadata_is_stats_set());
-}
-
-TEST_F(TestByteArrayValuesWriter, LimitStats) {
-  int min_len = 1024 * 4;
-  int max_len = 1024 * 8;
-  this->SetUpSchema(Repetition::REQUIRED);
-  ColumnProperties column_properties;
-  column_properties.set_max_statistics_size(static_cast<size_t>(max_len));
-  auto writer = this->BuildWriter(SMALL_SIZE, column_properties);
-
-  values_.resize(SMALL_SIZE);
-  InitWideByteArrayValues(SMALL_SIZE, this->values_, this->buffer_, min_len, max_len);
-  writer->WriteBatch(SMALL_SIZE, nullptr, nullptr, this->values_.data());
-  writer->Close();
-
-  ASSERT_TRUE(this->metadata_is_stats_set());
-}
-
-TEST_F(TestByteArrayValuesWriter, CheckDefaultStats) {
-  this->SetUpSchema(Repetition::REQUIRED);
-  auto writer = this->BuildWriter();
-  this->GenerateData(SMALL_SIZE);
-
-  writer->WriteBatch(SMALL_SIZE, nullptr, nullptr, this->values_ptr_);
-  writer->Close();
-
-  ASSERT_TRUE(this->metadata_is_stats_set());
-}
-
-void GenerateLevels(int min_repeat_factor, int max_repeat_factor, int max_level,
-                    std::vector<int16_t>& input_levels) {
-  // for each repetition count upto max_repeat_factor
-  for (int repeat = min_repeat_factor; repeat <= max_repeat_factor; repeat++) {
-    // repeat count increases by a factor of 2 for every iteration
-    int repeat_count = (1 << repeat);
-    // generate levels for repetition count upto the maximum level
-    int16_t value = 0;
-    int bwidth = 0;
-    while (value <= max_level) {
-      for (int i = 0; i < repeat_count; i++) {
-        input_levels.push_back(value);
-      }
-      value = static_cast<int16_t>((2 << bwidth) - 1);
-      bwidth++;
-    }
-  }
-}
-
-void EncodeLevels(Encoding::type encoding, int16_t max_level, int num_levels,
-                  const int16_t* input_levels, std::vector<uint8_t>& bytes) {
-  LevelEncoder encoder;
-  int levels_count = 0;
-  bytes.resize(2 * num_levels);
-  ASSERT_EQ(2 * num_levels, static_cast<int>(bytes.size()));
-  // encode levels
-  if (encoding == Encoding::RLE) {
-    // leave space to write the rle length value
-    encoder.Init(encoding, max_level, num_levels, bytes.data() + sizeof(int32_t),
-                 static_cast<int>(bytes.size()));
-
-    levels_count = encoder.Encode(num_levels, input_levels);
-    (reinterpret_cast<int32_t*>(bytes.data()))[0] = encoder.len();
-  } else {
-    encoder.Init(encoding, max_level, num_levels, bytes.data(),
-                 static_cast<int>(bytes.size()));
-    levels_count = encoder.Encode(num_levels, input_levels);
-  }
-  ASSERT_EQ(num_levels, levels_count);
-}
-
-void VerifyDecodingLevels(Encoding::type encoding, int16_t max_level,
-                          std::vector<int16_t>& input_levels,
-                          std::vector<uint8_t>& bytes) {
-  LevelDecoder decoder;
-  int levels_count = 0;
-  std::vector<int16_t> output_levels;
-  int num_levels = static_cast<int>(input_levels.size());
-
-  output_levels.resize(num_levels);
-  ASSERT_EQ(num_levels, static_cast<int>(output_levels.size()));
-
-  // Decode levels and test with multiple decode calls
-  decoder.SetData(encoding, max_level, num_levels, bytes.data());
-  int decode_count = 4;
-  int num_inner_levels = num_levels / decode_count;
-  // Try multiple decoding on a single SetData call
-  for (int ct = 0; ct < decode_count; ct++) {
-    int offset = ct * num_inner_levels;
-    levels_count = decoder.Decode(num_inner_levels, output_levels.data());
-    ASSERT_EQ(num_inner_levels, levels_count);
-    for (int i = 0; i < num_inner_levels; i++) {
-      EXPECT_EQ(input_levels[i + offset], output_levels[i]);
-    }
-  }
-  // check the remaining levels
-  int num_levels_completed = decode_count * (num_levels / decode_count);
-  int num_remaining_levels = num_levels - num_levels_completed;
-  if (num_remaining_levels > 0) {
-    levels_count = decoder.Decode(num_remaining_levels, output_levels.data());
-    ASSERT_EQ(num_remaining_levels, levels_count);
-    for (int i = 0; i < num_remaining_levels; i++) {
-      EXPECT_EQ(input_levels[i + num_levels_completed], output_levels[i]);
-    }
-  }
-  // Test zero Decode values
-  ASSERT_EQ(0, decoder.Decode(1, output_levels.data()));
-}
-
-void VerifyDecodingMultipleSetData(Encoding::type encoding, int16_t max_level,
-                                   std::vector<int16_t>& input_levels,
-                                   std::vector<std::vector<uint8_t>>& bytes) {
-  LevelDecoder decoder;
-  int levels_count = 0;
-  std::vector<int16_t> output_levels;
-
-  // Decode levels and test with multiple SetData calls
-  int setdata_count = static_cast<int>(bytes.size());
-  int num_levels = static_cast<int>(input_levels.size()) / setdata_count;
-  output_levels.resize(num_levels);
-  // Try multiple SetData
-  for (int ct = 0; ct < setdata_count; ct++) {
-    int offset = ct * num_levels;
-    ASSERT_EQ(num_levels, static_cast<int>(output_levels.size()));
-    decoder.SetData(encoding, max_level, num_levels, bytes[ct].data());
-    levels_count = decoder.Decode(num_levels, output_levels.data());
-    ASSERT_EQ(num_levels, levels_count);
-    for (int i = 0; i < num_levels; i++) {
-      EXPECT_EQ(input_levels[i + offset], output_levels[i]);
-    }
-  }
-}
-
-// Test levels with maximum bit-width from 1 to 8
-// increase the repetition count for each iteration by a factor of 2
-TEST(TestLevels, TestLevelsDecodeMultipleBitWidth) {
-  int min_repeat_factor = 0;
-  int max_repeat_factor = 7;  // 128
-  int max_bit_width = 8;
-  std::vector<int16_t> input_levels;
-  std::vector<uint8_t> bytes;
-  Encoding::type encodings[2] = {Encoding::RLE, Encoding::BIT_PACKED};
-
-  // for each encoding
-  for (int encode = 0; encode < 2; encode++) {
-    Encoding::type encoding = encodings[encode];
-    // BIT_PACKED requires a sequence of atleast 8
-    if (encoding == Encoding::BIT_PACKED) min_repeat_factor = 3;
-    // for each maximum bit-width
-    for (int bit_width = 1; bit_width <= max_bit_width; bit_width++) {
-      // find the maximum level for the current bit_width
-      int16_t max_level = static_cast<int16_t>((1 << bit_width) - 1);
-      // Generate levels
-      GenerateLevels(min_repeat_factor, max_repeat_factor, max_level, input_levels);
-      ASSERT_NO_FATAL_FAILURE(EncodeLevels(encoding, max_level,
-                                           static_cast<int>(input_levels.size()),
-                                           input_levels.data(), bytes));
-      ASSERT_NO_FATAL_FAILURE(
-          VerifyDecodingLevels(encoding, max_level, input_levels, bytes));
-      input_levels.clear();
-    }
-  }
-}
-
-// Test multiple decoder SetData calls
-TEST(TestLevels, TestLevelsDecodeMultipleSetData) {
-  int min_repeat_factor = 3;
-  int max_repeat_factor = 7;  // 128
-  int bit_width = 8;
-  int16_t max_level = static_cast<int16_t>((1 << bit_width) - 1);
-  std::vector<int16_t> input_levels;
-  std::vector<std::vector<uint8_t>> bytes;
-  Encoding::type encodings[2] = {Encoding::RLE, Encoding::BIT_PACKED};
-  GenerateLevels(min_repeat_factor, max_repeat_factor, max_level, input_levels);
-  int num_levels = static_cast<int>(input_levels.size());
-  int setdata_factor = 8;
-  int split_level_size = num_levels / setdata_factor;
-  bytes.resize(setdata_factor);
-
-  // for each encoding
-  for (int encode = 0; encode < 2; encode++) {
-    Encoding::type encoding = encodings[encode];
-    for (int rf = 0; rf < setdata_factor; rf++) {
-      int offset = rf * split_level_size;
-      ASSERT_NO_FATAL_FAILURE(EncodeLevels(
-          encoding, max_level, split_level_size,
-          reinterpret_cast<int16_t*>(input_levels.data()) + offset, bytes[rf]));
-    }
-    ASSERT_NO_FATAL_FAILURE(
-        VerifyDecodingMultipleSetData(encoding, max_level, input_levels, bytes));
-  }
-}
-
-TEST(TestLevelEncoder, MinimumBufferSize) {
-  // PARQUET-676, PARQUET-698
-  const int kNumToEncode = 1024;
-
-  std::vector<int16_t> levels;
-  for (int i = 0; i < kNumToEncode; ++i) {
-    if (i % 9 == 0) {
-      levels.push_back(0);
-    } else {
-      levels.push_back(1);
-    }
-  }
-
-  std::vector<uint8_t> output(
-      LevelEncoder::MaxBufferSize(Encoding::RLE, 1, kNumToEncode));
-
-  LevelEncoder encoder;
-  encoder.Init(Encoding::RLE, 1, kNumToEncode, output.data(),
-               static_cast<int>(output.size()));
-  int encode_count = encoder.Encode(kNumToEncode, levels.data());
-
-  ASSERT_EQ(kNumToEncode, encode_count);
-}
-
-TEST(TestLevelEncoder, MinimumBufferSize2) {
-  // PARQUET-708
-  // Test the worst case for bit_width=2 consisting of
-  // LiteralRun(size=8)
-  // RepeatedRun(size=8)
-  // LiteralRun(size=8)
-  // ...
-  const int kNumToEncode = 1024;
-
-  std::vector<int16_t> levels;
-  for (int i = 0; i < kNumToEncode; ++i) {
-    // This forces a literal run of 00000001
-    // followed by eight 1s
-    if ((i % 16) < 7) {
-      levels.push_back(0);
-    } else {
-      levels.push_back(1);
-    }
-  }
-
-  for (int16_t bit_width = 1; bit_width <= 8; bit_width++) {
-    std::vector<uint8_t> output(
-        LevelEncoder::MaxBufferSize(Encoding::RLE, bit_width, kNumToEncode));
-
-    LevelEncoder encoder;
-    encoder.Init(Encoding::RLE, bit_width, kNumToEncode, output.data(),
-                 static_cast<int>(output.size()));
-    int encode_count = encoder.Encode(kNumToEncode, levels.data());
-
-    ASSERT_EQ(kNumToEncode, encode_count);
-  }
-}
-
-}  // namespace test
-}  // namespace parquet
diff --git a/src/parquet/column_writer.cc b/src/parquet/column_writer.cc
deleted file mode 100644
index a65bda8..0000000
--- a/src/parquet/column_writer.cc
+++ /dev/null
@@ -1,867 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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.
-
-#include "parquet/column_writer.h"
-
-#include <cstdint>
-#include <memory>
-
-#include "arrow/util/bit-util.h"
-#include "arrow/util/compression.h"
-#include "arrow/util/rle-encoding.h"
-
-#include "parquet/encoding-internal.h"
-#include "parquet/properties.h"
-#include "parquet/statistics.h"
-#include "parquet/thrift.h"
-#include "parquet/util/logging.h"
-#include "parquet/util/memory.h"
-
-namespace parquet {
-
-using BitWriter = ::arrow::BitWriter;
-using RleEncoder = ::arrow::RleEncoder;
-
-LevelEncoder::LevelEncoder() {}
-LevelEncoder::~LevelEncoder() {}
-
-void LevelEncoder::Init(Encoding::type encoding, int16_t max_level,
-                        int num_buffered_values, uint8_t* data, int data_size) {
-  bit_width_ = BitUtil::Log2(max_level + 1);
-  encoding_ = encoding;
-  switch (encoding) {
-    case Encoding::RLE: {
-      rle_encoder_.reset(new RleEncoder(data, data_size, bit_width_));
-      break;
-    }
-    case Encoding::BIT_PACKED: {
-      int num_bytes =
-          static_cast<int>(BitUtil::BytesForBits(num_buffered_values * bit_width_));
-      bit_packed_encoder_.reset(new BitWriter(data, num_bytes));
-      break;
-    }
-    default:
-      throw ParquetException("Unknown encoding type for levels.");
-  }
-}
-
-int LevelEncoder::MaxBufferSize(Encoding::type encoding, int16_t max_level,
-                                int num_buffered_values) {
-  int bit_width = BitUtil::Log2(max_level + 1);
-  int num_bytes = 0;
-  switch (encoding) {
-    case Encoding::RLE: {
-      // TODO: Due to the way we currently check if the buffer is full enough,
-      // we need to have MinBufferSize as head room.
-      num_bytes = RleEncoder::MaxBufferSize(bit_width, num_buffered_values) +
-                  RleEncoder::MinBufferSize(bit_width);
-      break;
-    }
-    case Encoding::BIT_PACKED: {
-      num_bytes =
-          static_cast<int>(BitUtil::BytesForBits(num_buffered_values * bit_width));
-      break;
-    }
-    default:
-      throw ParquetException("Unknown encoding type for levels.");
-  }
-  return num_bytes;
-}
-
-int LevelEncoder::Encode(int batch_size, const int16_t* levels) {
-  int num_encoded = 0;
-  if (!rle_encoder_ && !bit_packed_encoder_) {
-    throw ParquetException("Level encoders are not initialized.");
-  }
-
-  if (encoding_ == Encoding::RLE) {
-    for (int i = 0; i < batch_size; ++i) {
-      if (!rle_encoder_->Put(*(levels + i))) {
-        break;
-      }
-      ++num_encoded;
-    }
-    rle_encoder_->Flush();
-    rle_length_ = rle_encoder_->len();
-  } else {
-    for (int i = 0; i < batch_size; ++i) {
-      if (!bit_packed_encoder_->PutValue(*(levels + i), bit_width_)) {
-        break;
-      }
-      ++num_encoded;
-    }
-    bit_packed_encoder_->Flush();
-  }
-  return num_encoded;
-}
-
-// ----------------------------------------------------------------------
-// PageWriter implementation
-
-static format::Statistics ToThrift(const EncodedStatistics& row_group_statistics) {
-  format::Statistics statistics;
-  if (row_group_statistics.has_min) statistics.__set_min(row_group_statistics.min());
-  if (row_group_statistics.has_max) statistics.__set_max(row_group_statistics.max());
-  if (row_group_statistics.has_null_count)
-    statistics.__set_null_count(row_group_statistics.null_count);
-  if (row_group_statistics.has_distinct_count)
-    statistics.__set_distinct_count(row_group_statistics.distinct_count);
-  return statistics;
-}
-
-// This subclass delimits pages appearing in a serialized stream, each preceded
-// by a serialized Thrift format::PageHeader indicating the type of each page
-// and the page metadata.
-class SerializedPageWriter : public PageWriter {
- public:
-  SerializedPageWriter(OutputStream* sink, Compression::type codec,
-                       ColumnChunkMetaDataBuilder* metadata,
-                       ::arrow::MemoryPool* pool = ::arrow::default_memory_pool())
-      : sink_(sink),
-        metadata_(metadata),
-        pool_(pool),
-        num_values_(0),
-        dictionary_page_offset_(0),
-        data_page_offset_(0),
-        total_uncompressed_size_(0),
-        total_compressed_size_(0) {
-    compressor_ = GetCodecFromArrow(codec);
-  }
-
-  int64_t WriteDictionaryPage(const DictionaryPage& page) override {
-    int64_t uncompressed_size = page.size();
-    std::shared_ptr<Buffer> compressed_data = nullptr;
-    if (has_compressor()) {
-      auto buffer = std::static_pointer_cast<ResizableBuffer>(
-          AllocateBuffer(pool_, uncompressed_size));
-      Compress(*(page.buffer().get()), buffer.get());
-      compressed_data = std::static_pointer_cast<Buffer>(buffer);
-    } else {
-      compressed_data = page.buffer();
-    }
-
-    format::DictionaryPageHeader dict_page_header;
-    dict_page_header.__set_num_values(page.num_values());
-    dict_page_header.__set_encoding(ToThrift(page.encoding()));
-    dict_page_header.__set_is_sorted(page.is_sorted());
-
-    format::PageHeader page_header;
-    page_header.__set_type(format::PageType::DICTIONARY_PAGE);
-    page_header.__set_uncompressed_page_size(static_cast<int32_t>(uncompressed_size));
-    page_header.__set_compressed_page_size(static_cast<int32_t>(compressed_data->size()));
-    page_header.__set_dictionary_page_header(dict_page_header);
-    // TODO(PARQUET-594) crc checksum
-
-    int64_t start_pos = sink_->Tell();
-    if (dictionary_page_offset_ == 0) {
-      dictionary_page_offset_ = start_pos;
-    }
-    int64_t header_size =
-        SerializeThriftMsg(&page_header, sizeof(format::PageHeader), sink_);
-    sink_->Write(compressed_data->data(), compressed_data->size());
-
-    total_uncompressed_size_ += uncompressed_size + header_size;
-    total_compressed_size_ += compressed_data->size() + header_size;
-
-    return sink_->Tell() - start_pos;
-  }
-
-  void Close(bool has_dictionary, bool fallback) override {
-    // index_page_offset = -1 since they are not supported
-    metadata_->Finish(num_values_, dictionary_page_offset_, -1, data_page_offset_,
-                      total_compressed_size_, total_uncompressed_size_, has_dictionary,
-                      fallback);
-
-    // Write metadata at end of column chunk
-    metadata_->WriteTo(sink_);
-  }
-
-  /**
-   * Compress a buffer.
-   */
-  void Compress(const Buffer& src_buffer, ResizableBuffer* dest_buffer) override {
-    DCHECK(compressor_ != nullptr);
-
-    // Compress the data
-    int64_t max_compressed_size =
-        compressor_->MaxCompressedLen(src_buffer.size(), src_buffer.data());
-
-    // Use Arrow::Buffer::shrink_to_fit = false
-    // underlying buffer only keeps growing. Resize to a smaller size does not reallocate.
-    PARQUET_THROW_NOT_OK(dest_buffer->Resize(max_compressed_size, false));
-
-    int64_t compressed_size;
-    PARQUET_THROW_NOT_OK(
-        compressor_->Compress(src_buffer.size(), src_buffer.data(), max_compressed_size,
-                              dest_buffer->mutable_data(), &compressed_size));
-    PARQUET_THROW_NOT_OK(dest_buffer->Resize(compressed_size, false));
-  }
-
-  int64_t WriteDataPage(const CompressedDataPage& page) override {
-    int64_t uncompressed_size = page.uncompressed_size();
-    std::shared_ptr<Buffer> compressed_data = page.buffer();
-
-    format::DataPageHeader data_page_header;
-    data_page_header.__set_num_values(page.num_values());
-    data_page_header.__set_encoding(ToThrift(page.encoding()));
-    data_page_header.__set_definition_level_encoding(
-        ToThrift(page.definition_level_encoding()));
-    data_page_header.__set_repetition_level_encoding(
-        ToThrift(page.repetition_level_encoding()));
-    data_page_header.__set_statistics(ToThrift(page.statistics()));
-
-    format::PageHeader page_header;
-    page_header.__set_type(format::PageType::DATA_PAGE);
-    page_header.__set_uncompressed_page_size(static_cast<int32_t>(uncompressed_size));
-    page_header.__set_compressed_page_size(static_cast<int32_t>(compressed_data->size()));
-    page_header.__set_data_page_header(data_page_header);
-    // TODO(PARQUET-594) crc checksum
-
-    int64_t start_pos = sink_->Tell();
-    if (data_page_offset_ == 0) {
-      data_page_offset_ = start_pos;
-    }
-
-    int64_t header_size =
-        SerializeThriftMsg(&page_header, sizeof(format::PageHeader), sink_);
-    sink_->Write(compressed_data->data(), compressed_data->size());
-
-    total_uncompressed_size_ += uncompressed_size + header_size;
-    total_compressed_size_ += compressed_data->size() + header_size;
-    num_values_ += page.num_values();
-
-    return sink_->Tell() - start_pos;
-  }
-
-  bool has_compressor() override { return (compressor_ != nullptr); }
-
-  int64_t num_values() { return num_values_; }
-
-  int64_t dictionary_page_offset() { return dictionary_page_offset_; }
-
-  int64_t data_page_offset() { return data_page_offset_; }
-
-  int64_t total_compressed_size() { return total_compressed_size_; }
-
-  int64_t total_uncompressed_size() { return total_uncompressed_size_; }
-
- private:
-  OutputStream* sink_;
-  ColumnChunkMetaDataBuilder* metadata_;
-  ::arrow::MemoryPool* pool_;
-  int64_t num_values_;
-  int64_t dictionary_page_offset_;
-  int64_t data_page_offset_;
-  int64_t total_uncompressed_size_;
-  int64_t total_compressed_size_;
-
-  // Compression codec to use.
-  std::unique_ptr<::arrow::Codec> compressor_;
-};
-
-// This implementation of the PageWriter writes to the final sink on Close .
-class BufferedPageWriter : public PageWriter {
- public:
-  BufferedPageWriter(OutputStream* sink, Compression::type codec,
-                     ColumnChunkMetaDataBuilder* metadata,
-                     ::arrow::MemoryPool* pool = ::arrow::default_memory_pool())
-      : final_sink_(sink),
-        metadata_(metadata),
-        in_memory_sink_(new InMemoryOutputStream(pool)),
-        pager_(new SerializedPageWriter(in_memory_sink_.get(), codec, metadata, pool)) {}
-
-  int64_t WriteDictionaryPage(const DictionaryPage& page) override {
-    return pager_->WriteDictionaryPage(page);
-  }
-
-  void Close(bool has_dictionary, bool fallback) override {
-    // index_page_offset = -1 since they are not supported
-    metadata_->Finish(
-        pager_->num_values(), pager_->dictionary_page_offset() + final_sink_->Tell(), -1,
-        pager_->data_page_offset() + final_sink_->Tell(), pager_->total_compressed_size(),
-        pager_->total_uncompressed_size(), has_dictionary, fallback);
-
-    // Write metadata at end of column chunk
-    metadata_->WriteTo(in_memory_sink_.get());
-
-    // flush everything to the serialized sink
-    auto buffer = in_memory_sink_->GetBuffer();
-    final_sink_->Write(buffer->data(), buffer->size());
-  }
-
-  int64_t WriteDataPage(const CompressedDataPage& page) override {
-    return pager_->WriteDataPage(page);
-  }
-
-  void Compress(const Buffer& src_buffer, ResizableBuffer* dest_buffer) override {
-    pager_->Compress(src_buffer, dest_buffer);
-  }
-
-  bool has_compressor() override { return pager_->has_compressor(); }
-
- private:
-  OutputStream* final_sink_;
-  ColumnChunkMetaDataBuilder* metadata_;
-  std::unique_ptr<InMemoryOutputStream> in_memory_sink_;
-  std::unique_ptr<SerializedPageWriter> pager_;
-};
-
-std::unique_ptr<PageWriter> PageWriter::Open(OutputStream* sink, Compression::type codec,
-                                             ColumnChunkMetaDataBuilder* metadata,
-                                             ::arrow::MemoryPool* pool,
-                                             bool buffered_row_group) {
-  if (buffered_row_group) {
-    return std::unique_ptr<PageWriter>(
-        new BufferedPageWriter(sink, codec, metadata, pool));
-  } else {
-    return std::unique_ptr<PageWriter>(
-        new SerializedPageWriter(sink, codec, metadata, pool));
-  }
-}
-
-// ----------------------------------------------------------------------
-// ColumnWriter
-
-std::shared_ptr<WriterProperties> default_writer_properties() {
-  static std::shared_ptr<WriterProperties> default_writer_properties =
-      WriterProperties::Builder().build();
-  return default_writer_properties;
-}
-
-ColumnWriter::ColumnWriter(ColumnChunkMetaDataBuilder* metadata,
-                           std::unique_ptr<PageWriter> pager, bool has_dictionary,
-                           Encoding::type encoding, const WriterProperties* properties)
-    : metadata_(metadata),
-      descr_(metadata->descr()),
-      pager_(std::move(pager)),
-      has_dictionary_(has_dictionary),
-      encoding_(encoding),
-      properties_(properties),
-      allocator_(properties->memory_pool()),
-      pool_(properties->memory_pool()),
-      num_buffered_values_(0),
-      num_buffered_encoded_values_(0),
-      rows_written_(0),
-      total_bytes_written_(0),
-      total_compressed_bytes_(0),
-      closed_(false),
-      fallback_(false) {
-  definition_levels_sink_.reset(new InMemoryOutputStream(allocator_));
-  repetition_levels_sink_.reset(new InMemoryOutputStream(allocator_));
-  definition_levels_rle_ =
-      std::static_pointer_cast<ResizableBuffer>(AllocateBuffer(allocator_, 0));
-  repetition_levels_rle_ =
-      std::static_pointer_cast<ResizableBuffer>(AllocateBuffer(allocator_, 0));
-  uncompressed_data_ =
-      std::static_pointer_cast<ResizableBuffer>(AllocateBuffer(allocator_, 0));
-  if (pager_->has_compressor()) {
-    compressed_data_ =
-        std::static_pointer_cast<ResizableBuffer>(AllocateBuffer(allocator_, 0));
-  }
-}
-
-void ColumnWriter::InitSinks() {
-  definition_levels_sink_->Clear();
-  repetition_levels_sink_->Clear();
-}
-
-void ColumnWriter::WriteDefinitionLevels(int64_t num_levels, const int16_t* levels) {
-  DCHECK(!closed_);
-  definition_levels_sink_->Write(reinterpret_cast<const uint8_t*>(levels),
-                                 sizeof(int16_t) * num_levels);
-}
-
-void ColumnWriter::WriteRepetitionLevels(int64_t num_levels, const int16_t* levels) {
-  DCHECK(!closed_);
-  repetition_levels_sink_->Write(reinterpret_cast<const uint8_t*>(levels),
-                                 sizeof(int16_t) * num_levels);
-}
-
-// return the size of the encoded buffer
-int64_t ColumnWriter::RleEncodeLevels(const Buffer& src_buffer,
-                                      ResizableBuffer* dest_buffer, int16_t max_level) {
-  // TODO: This only works with due to some RLE specifics
-  int64_t rle_size = LevelEncoder::MaxBufferSize(Encoding::RLE, max_level,
-                                                 static_cast<int>(num_buffered_values_)) +
-                     sizeof(int32_t);
-
-  // Use Arrow::Buffer::shrink_to_fit = false
-  // underlying buffer only keeps growing. Resize to a smaller size does not reallocate.
-  PARQUET_THROW_NOT_OK(dest_buffer->Resize(rle_size, false));
-
-  level_encoder_.Init(Encoding::RLE, max_level, static_cast<int>(num_buffered_values_),
-                      dest_buffer->mutable_data() + sizeof(int32_t),
-                      static_cast<int>(dest_buffer->size() - sizeof(int32_t)));
-  int encoded =
-      level_encoder_.Encode(static_cast<int>(num_buffered_values_),
-                            reinterpret_cast<const int16_t*>(src_buffer.data()));
-  DCHECK_EQ(encoded, num_buffered_values_);
-  reinterpret_cast<int32_t*>(dest_buffer->mutable_data())[0] = level_encoder_.len();
-  int64_t encoded_size = level_encoder_.len() + sizeof(int32_t);
-  return encoded_size;
-}
-
-void ColumnWriter::AddDataPage() {
-  int64_t definition_levels_rle_size = 0;
-  int64_t repetition_levels_rle_size = 0;
-
-  std::shared_ptr<Buffer> values = GetValuesBuffer();
-
-  if (descr_->max_definition_level() > 0) {
-    definition_levels_rle_size =
-        RleEncodeLevels(definition_levels_sink_->GetBufferRef(),
-                        definition_levels_rle_.get(), descr_->max_definition_level());
-  }
-
-  if (descr_->max_repetition_level() > 0) {
-    repetition_levels_rle_size =
-        RleEncodeLevels(repetition_levels_sink_->GetBufferRef(),
-                        repetition_levels_rle_.get(), descr_->max_repetition_level());
-  }
-
-  int64_t uncompressed_size =
-      definition_levels_rle_size + repetition_levels_rle_size + values->size();
-
-  // Use Arrow::Buffer::shrink_to_fit = false
-  // underlying buffer only keeps growing. Resize to a smaller size does not reallocate.
-  PARQUET_THROW_NOT_OK(uncompressed_data_->Resize(uncompressed_size, false));
-
-  // Concatenate data into a single buffer
-  uint8_t* uncompressed_ptr = uncompressed_data_->mutable_data();
-  memcpy(uncompressed_ptr, repetition_levels_rle_->data(), repetition_levels_rle_size);
-  uncompressed_ptr += repetition_levels_rle_size;
-  memcpy(uncompressed_ptr, definition_levels_rle_->data(), definition_levels_rle_size);
-  uncompressed_ptr += definition_levels_rle_size;
-  memcpy(uncompressed_ptr, values->data(), values->size());
-
-  EncodedStatistics page_stats = GetPageStatistics();
-  ResetPageStatistics();
-
-  std::shared_ptr<Buffer> compressed_data;
-  if (pager_->has_compressor()) {
-    pager_->Compress(*(uncompressed_data_.get()), compressed_data_.get());
-    compressed_data = compressed_data_;
-  } else {
-    compressed_data = uncompressed_data_;
-  }
-
-  // Write the page to OutputStream eagerly if there is no dictionary or
-  // if dictionary encoding has fallen back to PLAIN
-  if (has_dictionary_ && !fallback_) {  // Save pages until end of dictionary encoding
-    std::shared_ptr<Buffer> compressed_data_copy;
-    PARQUET_THROW_NOT_OK(compressed_data->Copy(0, compressed_data->size(), allocator_,
-                                               &compressed_data_copy));
-    CompressedDataPage page(compressed_data_copy,
-                            static_cast<int32_t>(num_buffered_values_), encoding_,
-                            Encoding::RLE, Encoding::RLE, uncompressed_size, page_stats);
-    total_compressed_bytes_ += page.size() + sizeof(format::PageHeader);
-    data_pages_.push_back(std::move(page));
-  } else {  // Eagerly write pages
-    CompressedDataPage page(compressed_data, static_cast<int32_t>(num_buffered_values_),
-                            encoding_, Encoding::RLE, Encoding::RLE, uncompressed_size,
-                            page_stats);
-    WriteDataPage(page);
-  }
-
-  // Re-initialize the sinks for next Page.
-  InitSinks();
-  num_buffered_values_ = 0;
-  num_buffered_encoded_values_ = 0;
-}
-
-void ColumnWriter::WriteDataPage(const CompressedDataPage& page) {
-  total_bytes_written_ += pager_->WriteDataPage(page);
-}
-
-int64_t ColumnWriter::Close() {
-  if (!closed_) {
-    closed_ = true;
-    if (has_dictionary_ && !fallback_) {
-      WriteDictionaryPage();
-    }
-
-    FlushBufferedDataPages();
-
-    EncodedStatistics chunk_statistics = GetChunkStatistics();
-    // Write stats only if the column has at least one row written
-    // From parquet-mr
-    // Don't write stats larger than the max size rather than truncating. The
-    // rationale is that some engines may use the minimum value in the page as
-    // the true minimum for aggregations and there is no way to mark that a
-    // value has been truncated and is a lower bound and not in the page.
-    if (rows_written_ > 0 && chunk_statistics.is_set() &&
-        chunk_statistics.max_stat_length() <=
-            properties_->max_statistics_size(descr_->path())) {
-      metadata_->SetStatistics(SortOrder::SIGNED == descr_->sort_order(),
-                               chunk_statistics);
-    }
-    pager_->Close(has_dictionary_, fallback_);
-  }
-
-  return total_bytes_written_;
-}
-
-void ColumnWriter::FlushBufferedDataPages() {
-  // Write all outstanding data to a new page
-  if (num_buffered_values_ > 0) {
-    AddDataPage();
-  }
-  for (size_t i = 0; i < data_pages_.size(); i++) {
-    WriteDataPage(data_pages_[i]);
-  }
-  data_pages_.clear();
-  total_compressed_bytes_ = 0;
-}
-
-// ----------------------------------------------------------------------
-// TypedColumnWriter
-
-template <typename Type>
-TypedColumnWriter<Type>::TypedColumnWriter(ColumnChunkMetaDataBuilder* metadata,
-                                           std::unique_ptr<PageWriter> pager,
-                                           Encoding::type encoding,
-                                           const WriterProperties* properties)
-    : ColumnWriter(metadata, std::move(pager),
-                   (encoding == Encoding::PLAIN_DICTIONARY ||
-                    encoding == Encoding::RLE_DICTIONARY),
-                   encoding, properties) {
-  switch (encoding) {
-    case Encoding::PLAIN:
-      current_encoder_.reset(new PlainEncoder<Type>(descr_, properties->memory_pool()));
-      break;
-    case Encoding::PLAIN_DICTIONARY:
-    case Encoding::RLE_DICTIONARY:
-      current_encoder_.reset(
-          new DictEncoder<Type>(descr_, &pool_, properties->memory_pool()));
-      break;
-    default:
-      ParquetException::NYI("Selected encoding is not supported");
-  }
-
-  if (properties->statistics_enabled(descr_->path()) &&
-      (SortOrder::UNKNOWN != descr_->sort_order())) {
-    page_statistics_ = std::unique_ptr<TypedStats>(new TypedStats(descr_, allocator_));
-    chunk_statistics_ = std::unique_ptr<TypedStats>(new TypedStats(descr_, allocator_));
-  }
-}
-
-// Only one Dictionary Page is written.
-// Fallback to PLAIN if dictionary page limit is reached.
-template <typename Type>
-void TypedColumnWriter<Type>::CheckDictionarySizeLimit() {
-  auto dict_encoder = static_cast<DictEncoder<Type>*>(current_encoder_.get());
-  if (dict_encoder->dict_encoded_size() >= properties_->dictionary_pagesize_limit()) {
-    WriteDictionaryPage();
-    // Serialize the buffered Dictionary Indicies
-    FlushBufferedDataPages();
-    fallback_ = true;
-    // Only PLAIN encoding is supported for fallback in V1
-    current_encoder_.reset(new PlainEncoder<Type>(descr_, properties_->memory_pool()));
-    encoding_ = Encoding::PLAIN;
-  }
-}
-
-template <typename Type>
-void TypedColumnWriter<Type>::WriteDictionaryPage() {
-  auto dict_encoder = static_cast<DictEncoder<Type>*>(current_encoder_.get());
-  std::shared_ptr<ResizableBuffer> buffer =
-      AllocateBuffer(properties_->memory_pool(), dict_encoder->dict_encoded_size());
-  dict_encoder->WriteDict(buffer->mutable_data());
-  // TODO Get rid of this deep call
-  dict_encoder->mem_pool()->FreeAll();
-
-  DictionaryPage page(buffer, dict_encoder->num_entries(),
-                      properties_->dictionary_index_encoding());
-  total_bytes_written_ += pager_->WriteDictionaryPage(page);
-}
-
-template <typename Type>
-EncodedStatistics TypedColumnWriter<Type>::GetPageStatistics() {
-  EncodedStatistics result;
-  if (page_statistics_) result = page_statistics_->Encode();
-  return result;
-}
-
-template <typename Type>
-EncodedStatistics TypedColumnWriter<Type>::GetChunkStatistics() {
-  EncodedStatistics result;
-  if (chunk_statistics_) result = chunk_statistics_->Encode();
-  return result;
-}
-
-template <typename Type>
-void TypedColumnWriter<Type>::ResetPageStatistics() {
-  if (chunk_statistics_ != nullptr) {
-    chunk_statistics_->Merge(*page_statistics_);
-    page_statistics_->Reset();
-  }
-}
-
-// ----------------------------------------------------------------------
-// Dynamic column writer constructor
-
-std::shared_ptr<ColumnWriter> ColumnWriter::Make(ColumnChunkMetaDataBuilder* metadata,
-                                                 std::unique_ptr<PageWriter> pager,
-                                                 const WriterProperties* properties) {
-  const ColumnDescriptor* descr = metadata->descr();
-  Encoding::type encoding = properties->encoding(descr->path());
-  if (properties->dictionary_enabled(descr->path()) &&
-      descr->physical_type() != Type::BOOLEAN) {
-    encoding = properties->dictionary_page_encoding();
-  }
-  switch (descr->physical_type()) {
-    case Type::BOOLEAN:
-      return std::make_shared<BoolWriter>(metadata, std::move(pager), encoding,
-                                          properties);
-    case Type::INT32:
-      return std::make_shared<Int32Writer>(metadata, std::move(pager), encoding,
-                                           properties);
-    case Type::INT64:
-      return std::make_shared<Int64Writer>(metadata, std::move(pager), encoding,
-                                           properties);
-    case Type::INT96:
-      return std::make_shared<Int96Writer>(metadata, std::move(pager), encoding,
-                                           properties);
-    case Type::FLOAT:
-      return std::make_shared<FloatWriter>(metadata, std::move(pager), encoding,
-                                           properties);
-    case Type::DOUBLE:
-      return std::make_shared<DoubleWriter>(metadata, std::move(pager), encoding,
-                                            properties);
-    case Type::BYTE_ARRAY:
-      return std::make_shared<ByteArrayWriter>(metadata, std::move(pager), encoding,
-                                               properties);
-    case Type::FIXED_LEN_BYTE_ARRAY:
-      return std::make_shared<FixedLenByteArrayWriter>(metadata, std::move(pager),
-                                                       encoding, properties);
-    default:
-      ParquetException::NYI("type reader not implemented");
-  }
-  // Unreachable code, but supress compiler warning
-  return std::shared_ptr<ColumnWriter>(nullptr);
-}
-
-// ----------------------------------------------------------------------
-// Instantiate templated classes
-
-template <typename DType>
-inline int64_t TypedColumnWriter<DType>::WriteMiniBatch(int64_t num_values,
-                                                        const int16_t* def_levels,
-                                                        const int16_t* rep_levels,
-                                                        const T* values) {
-  int64_t values_to_write = 0;
-  // If the field is required and non-repeated, there are no definition levels
-  if (descr_->max_definition_level() > 0) {
-    for (int64_t i = 0; i < num_values; ++i) {
-      if (def_levels[i] == descr_->max_definition_level()) {
-        ++values_to_write;
-      }
-    }
-
-    WriteDefinitionLevels(num_values, def_levels);
-  } else {
-    // Required field, write all values
-    values_to_write = num_values;
-  }
-
-  // Not present for non-repeated fields
-  if (descr_->max_repetition_level() > 0) {
-    // A row could include more than one value
-    // Count the occasions where we start a new row
-    for (int64_t i = 0; i < num_values; ++i) {
-      if (rep_levels[i] == 0) {
-        rows_written_++;
-      }
-    }
-
-    WriteRepetitionLevels(num_values, rep_levels);
-  } else {
-    // Each value is exactly one row
-    rows_written_ += static_cast<int>(num_values);
-  }
-
-  // PARQUET-780
-  if (values_to_write > 0) {
-    DCHECK(nullptr != values) << "Values ptr cannot be NULL";
-  }
-
-  WriteValues(values_to_write, values);
-
-  if (page_statistics_ != nullptr) {
-    page_statistics_->Update(values, values_to_write, num_values - values_to_write);
-  }
-
-  num_buffered_values_ += num_values;
-  num_buffered_encoded_values_ += values_to_write;
-
-  if (current_encoder_->EstimatedDataEncodedSize() >= properties_->data_pagesize()) {
-    AddDataPage();
-  }
-  if (has_dictionary_ && !fallback_) {
-    CheckDictionarySizeLimit();
-  }
-
-  return values_to_write;
-}
-
-template <typename DType>
-inline int64_t TypedColumnWriter<DType>::WriteMiniBatchSpaced(
-    int64_t num_values, const int16_t* def_levels, const int16_t* rep_levels,
-    const uint8_t* valid_bits, int64_t valid_bits_offset, const T* values,
-    int64_t* num_spaced_written) {
-  int64_t values_to_write = 0;
-  int64_t spaced_values_to_write = 0;
-  // If the field is required and non-repeated, there are no definition levels
-  if (descr_->max_definition_level() > 0) {
-    // Minimal definition level for which spaced values are written
-    int16_t min_spaced_def_level = descr_->max_definition_level();
-    if (descr_->schema_node()->is_optional()) {
-      min_spaced_def_level--;
-    }
-    for (int64_t i = 0; i < num_values; ++i) {
-      if (def_levels[i] == descr_->max_definition_level()) {
-        ++values_to_write;
-      }
-      if (def_levels[i] >= min_spaced_def_level) {
-        ++spaced_values_to_write;
-      }
-    }
-
-    WriteDefinitionLevels(num_values, def_levels);
-  } else {
-    // Required field, write all values
-    values_to_write = num_values;
-    spaced_values_to_write = num_values;
-  }
-
-  // Not present for non-repeated fields
-  if (descr_->max_repetition_level() > 0) {
-    // A row could include more than one value
-    // Count the occasions where we start a new row
-    for (int64_t i = 0; i < num_values; ++i) {
-      if (rep_levels[i] == 0) {
-        rows_written_++;
-      }
-    }
-
-    WriteRepetitionLevels(num_values, rep_levels);
-  } else {
-    // Each value is exactly one row
-    rows_written_ += static_cast<int>(num_values);
-  }
-
-  if (descr_->schema_node()->is_optional()) {
-    WriteValuesSpaced(spaced_values_to_write, valid_bits, valid_bits_offset, values);
-  } else {
-    WriteValues(values_to_write, values);
-  }
-  *num_spaced_written = spaced_values_to_write;
-
-  if (page_statistics_ != nullptr) {
-    page_statistics_->UpdateSpaced(values, valid_bits, valid_bits_offset, values_to_write,
-                                   num_values - values_to_write);
-  }
-
-  num_buffered_values_ += num_values;
-  num_buffered_encoded_values_ += values_to_write;
-
-  if (current_encoder_->EstimatedDataEncodedSize() >= properties_->data_pagesize()) {
-    AddDataPage();
-  }
-  if (has_dictionary_ && !fallback_) {
-    CheckDictionarySizeLimit();
-  }
-
-  return values_to_write;
-}
-
-template <typename DType>
-void TypedColumnWriter<DType>::WriteBatch(int64_t num_values, const int16_t* def_levels,
-                                          const int16_t* rep_levels, const T* values) {
-  // We check for DataPage limits only after we have inserted the values. If a user
-  // writes a large number of values, the DataPage size can be much above the limit.
-  // The purpose of this chunking is to bound this. Even if a user writes large number
-  // of values, the chunking will ensure the AddDataPage() is called at a reasonable
-  // pagesize limit
-  int64_t write_batch_size = properties_->write_batch_size();
-  int num_batches = static_cast<int>(num_values / write_batch_size);
-  int64_t num_remaining = num_values % write_batch_size;
-  int64_t value_offset = 0;
-  for (int round = 0; round < num_batches; round++) {
-    int64_t offset = round * write_batch_size;
-    int64_t num_values = WriteMiniBatch(write_batch_size, &def_levels[offset],
-                                        &rep_levels[offset], &values[value_offset]);
-    value_offset += num_values;
-  }
-  // Write the remaining values
-  int64_t offset = num_batches * write_batch_size;
-  WriteMiniBatch(num_remaining, &def_levels[offset], &rep_levels[offset],
-                 &values[value_offset]);
-}
-
-template <typename DType>
-void TypedColumnWriter<DType>::WriteBatchSpaced(
-    int64_t num_values, const int16_t* def_levels, const int16_t* rep_levels,
-    const uint8_t* valid_bits, int64_t valid_bits_offset, const T* values) {
-  // We check for DataPage limits only after we have inserted the values. If a user
-  // writes a large number of values, the DataPage size can be much above the limit.
-  // The purpose of this chunking is to bound this. Even if a user writes large number
-  // of values, the chunking will ensure the AddDataPage() is called at a reasonable
-  // pagesize limit
-  int64_t write_batch_size = properties_->write_batch_size();
-  int num_batches = static_cast<int>(num_values / write_batch_size);
-  int64_t num_remaining = num_values % write_batch_size;
-  int64_t num_spaced_written = 0;
-  int64_t values_offset = 0;
-  for (int round = 0; round < num_batches; round++) {
-    int64_t offset = round * write_batch_size;
-    WriteMiniBatchSpaced(write_batch_size, &def_levels[offset], &rep_levels[offset],
-                         valid_bits, valid_bits_offset + values_offset,
-                         values + values_offset, &num_spaced_written);
-    values_offset += num_spaced_written;
-  }
-  // Write the remaining values
-  int64_t offset = num_batches * write_batch_size;
-  WriteMiniBatchSpaced(num_remaining, &def_levels[offset], &rep_levels[offset],
-                       valid_bits, valid_bits_offset + values_offset,
-                       values + values_offset, &num_spaced_written);
-}
-
-template <typename DType>
-void TypedColumnWriter<DType>::WriteValues(int64_t num_values, const T* values) {
-  current_encoder_->Put(values, static_cast<int>(num_values));
-}
-
-template <typename DType>
-void TypedColumnWriter<DType>::WriteValuesSpaced(int64_t num_values,
-                                                 const uint8_t* valid_bits,
-                                                 int64_t valid_bits_offset,
-                                                 const T* values) {
-  current_encoder_->PutSpaced(values, static_cast<int>(num_values), valid_bits,
-                              valid_bits_offset);
-}
-
-template class PARQUET_TEMPLATE_EXPORT TypedColumnWriter<BooleanType>;
-template class PARQUET_TEMPLATE_EXPORT TypedColumnWriter<Int32Type>;
-template class PARQUET_TEMPLATE_EXPORT TypedColumnWriter<Int64Type>;
-template class PARQUET_TEMPLATE_EXPORT TypedColumnWriter<Int96Type>;
-template class PARQUET_TEMPLATE_EXPORT TypedColumnWriter<FloatType>;
-template class PARQUET_TEMPLATE_EXPORT TypedColumnWriter<DoubleType>;
-template class PARQUET_TEMPLATE_EXPORT TypedColumnWriter<ByteArrayType>;
-template class PARQUET_TEMPLATE_EXPORT TypedColumnWriter<FLBAType>;
-
-}  // namespace parquet
diff --git a/src/parquet/column_writer.h b/src/parquet/column_writer.h
deleted file mode 100644
index 1ba428a..0000000
--- a/src/parquet/column_writer.h
+++ /dev/null
@@ -1,328 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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.
-
-#ifndef PARQUET_COLUMN_WRITER_H
-#define PARQUET_COLUMN_WRITER_H
-
-#include <vector>
-
-#include "parquet/column_page.h"
-#include "parquet/encoding.h"
-#include "parquet/metadata.h"
-#include "parquet/properties.h"
-#include "parquet/schema.h"
-#include "parquet/statistics.h"
-#include "parquet/types.h"
-#include "parquet/util/memory.h"
-#include "parquet/util/visibility.h"
-
-namespace arrow {
-
-class BitWriter;
-class RleEncoder;
-
-}  // namespace arrow
-
-namespace parquet {
-
-class PARQUET_EXPORT LevelEncoder {
- public:
-  LevelEncoder();
-  ~LevelEncoder();
-
-  static int MaxBufferSize(Encoding::type encoding, int16_t max_level,
-                           int num_buffered_values);
-
-  // Initialize the LevelEncoder.
-  void Init(Encoding::type encoding, int16_t max_level, int num_buffered_values,
-            uint8_t* data, int data_size);
-
-  // Encodes a batch of levels from an array and returns the number of levels encoded
-  int Encode(int batch_size, const int16_t* levels);
-
-  int32_t len() {
-    if (encoding_ != Encoding::RLE) {
-      throw ParquetException("Only implemented for RLE encoding");
-    }
-    return rle_length_;
-  }
-
- private:
-  int bit_width_;
-  int rle_length_;
-  Encoding::type encoding_;
-  std::unique_ptr<::arrow::RleEncoder> rle_encoder_;
-  std::unique_ptr<::arrow::BitWriter> bit_packed_encoder_;
-};
-
-class PageWriter {
- public:
-  virtual ~PageWriter() {}
-
-  static std::unique_ptr<PageWriter> Open(
-      OutputStream* sink, Compression::type codec, ColumnChunkMetaDataBuilder* metadata,
-      ::arrow::MemoryPool* pool = ::arrow::default_memory_pool(),
-      bool buffered_row_group = false);
-
-  // The Column Writer decides if dictionary encoding is used if set and
-  // if the dictionary encoding has fallen back to default encoding on reaching dictionary
-  // page limit
-  virtual void Close(bool has_dictionary, bool fallback) = 0;
-
-  virtual int64_t WriteDataPage(const CompressedDataPage& page) = 0;
-
-  virtual int64_t WriteDictionaryPage(const DictionaryPage& page) = 0;
-
-  virtual bool has_compressor() = 0;
-
-  virtual void Compress(const Buffer& src_buffer, ResizableBuffer* dest_buffer) = 0;
-};
-
-static constexpr int WRITE_BATCH_SIZE = 1000;
-class PARQUET_EXPORT ColumnWriter {
- public:
-  ColumnWriter(ColumnChunkMetaDataBuilder*, std::unique_ptr<PageWriter>,
-               bool has_dictionary, Encoding::type encoding,
-               const WriterProperties* properties);
-
-  virtual ~ColumnWriter() = default;
-
-  static std::shared_ptr<ColumnWriter> Make(ColumnChunkMetaDataBuilder*,
-                                            std::unique_ptr<PageWriter>,
-                                            const WriterProperties* properties);
-
-  Type::type type() const { return descr_->physical_type(); }
-
-  const ColumnDescriptor* descr() const { return descr_; }
-
-  /**
-   * Closes the ColumnWriter, commits any buffered values to pages.
-   *
-   * @return Total size of the column in bytes
-   */
-  int64_t Close();
-
-  int64_t rows_written() const { return rows_written_; }
-
-  // Only considers the size of the compressed pages + page header
-  // Some values might be still buffered an not written to a page yet
-  int64_t total_compressed_bytes() const { return total_compressed_bytes_; }
-
-  int64_t total_bytes_written() const { return total_bytes_written_; }
-
-  const WriterProperties* properties() { return properties_; }
-
- protected:
-  virtual std::shared_ptr<Buffer> GetValuesBuffer() = 0;
-
-  // Serializes Dictionary Page if enabled
-  virtual void WriteDictionaryPage() = 0;
-
-  // Checks if the Dictionary Page size limit is reached
-  // If the limit is reached, the Dictionary and Data Pages are serialized
-  // The encoding is switched to PLAIN
-
-  virtual void CheckDictionarySizeLimit() = 0;
-
-  // Plain-encoded statistics of the current page
-  virtual EncodedStatistics GetPageStatistics() = 0;
-
-  // Plain-encoded statistics of the whole chunk
-  virtual EncodedStatistics GetChunkStatistics() = 0;
-
-  // Merges page statistics into chunk statistics, then resets the values
-  virtual void ResetPageStatistics() = 0;
-
-  // Adds Data Pages to an in memory buffer in dictionary encoding mode
-  // Serializes the Data Pages in other encoding modes
-  void AddDataPage();
-
-  // Serializes Data Pages
-  void WriteDataPage(const CompressedDataPage& page);
-
-  // Write multiple definition levels
-  void WriteDefinitionLevels(int64_t num_levels, const int16_t* levels);
-
-  // Write multiple repetition levels
-  void WriteRepetitionLevels(int64_t num_levels, const int16_t* levels);
-
-  // RLE encode the src_buffer into dest_buffer and return the encoded size
-  int64_t RleEncodeLevels(const Buffer& src_buffer, ResizableBuffer* dest_buffer,
-                          int16_t max_level);
-
-  // Serialize the buffered Data Pages
-  void FlushBufferedDataPages();
-
-  ColumnChunkMetaDataBuilder* metadata_;
-  const ColumnDescriptor* descr_;
-
-  std::unique_ptr<PageWriter> pager_;
-
-  bool has_dictionary_;
-  Encoding::type encoding_;
-  const WriterProperties* properties_;
-
-  LevelEncoder level_encoder_;
-
-  ::arrow::MemoryPool* allocator_;
-  ChunkedAllocator pool_;
-
-  // The total number of values stored in the data page. This is the maximum of
-  // the number of encoded definition levels or encoded values. For
-  // non-repeated, required columns, this is equal to the number of encoded
-  // values. For repeated or optional values, there may be fewer data values
-  // than levels, and this tells you how many encoded levels there are in that
-  // case.
-  int64_t num_buffered_values_;
-
-  // The total number of stored values. For repeated or optional values, this
-  // number may be lower than num_buffered_values_.
-  int64_t num_buffered_encoded_values_;
-
-  // Total number of rows written with this ColumnWriter
-  int rows_written_;
-
-  // Records the total number of bytes written by the serializer
-  int64_t total_bytes_written_;
-
-  // Records the current number of compressed bytes in a column
-  int64_t total_compressed_bytes_;
-
-  // Flag to check if the Writer has been closed
-  bool closed_;
-
-  // Flag to infer if dictionary encoding has fallen back to PLAIN
-  bool fallback_;
-
-  std::unique_ptr<InMemoryOutputStream> definition_levels_sink_;
-  std::unique_ptr<InMemoryOutputStream> repetition_levels_sink_;
-
-  std::shared_ptr<ResizableBuffer> definition_levels_rle_;
-  std::shared_ptr<ResizableBuffer> repetition_levels_rle_;
-
-  std::shared_ptr<ResizableBuffer> uncompressed_data_;
-  std::shared_ptr<ResizableBuffer> compressed_data_;
-
-  std::vector<CompressedDataPage> data_pages_;
-
- private:
-  void InitSinks();
-};
-
-// API to write values to a single column. This is the main client facing API.
-template <typename DType>
-class PARQUET_EXPORT TypedColumnWriter : public ColumnWriter {
- public:
-  typedef typename DType::c_type T;
-
-  TypedColumnWriter(ColumnChunkMetaDataBuilder* metadata,
-                    std::unique_ptr<PageWriter> pager, Encoding::type encoding,
-                    const WriterProperties* properties);
-
-  // Write a batch of repetition levels, definition levels, and values to the
-  // column.
-  void WriteBatch(int64_t num_values, const int16_t* def_levels,
-                  const int16_t* rep_levels, const T* values);
-
-  /// Write a batch of repetition levels, definition levels, and values to the
-  /// column.
-  ///
-  /// In comparision to WriteBatch the length of repetition and definition levels
-  /// is the same as of the number of values read for max_definition_level == 1.
-  /// In the case of max_definition_level > 1, the repetition and definition
-  /// levels are larger than the values but the values include the null entries
-  /// with definition_level == (max_definition_level - 1). Thus we have to differentiate
-  /// in the parameters of this function if the input has the length of num_values or the
-  /// _number of rows in the lowest nesting level_.
-  ///
-  /// In the case that the most inner node in the Parquet is required, the _number of rows
-  /// in the lowest nesting level_ is equal to the number of non-null values. If the
-  /// inner-most schema node is optional, the _number of rows in the lowest nesting level_
-  /// also includes all values with definition_level == (max_definition_level - 1).
-  ///
-  /// @param num_values number of levels to write.
-  /// @param def_levels The Parquet definiton levels, length is num_values
-  /// @param rep_levels The Parquet repetition levels, length is num_values
-  /// @param valid_bits Bitmap that indicates if the row is null on the lowest nesting
-  ///   level. The length is number of rows in the lowest nesting level.
-  /// @param valid_bits_offset The offset in bits of the valid_bits where the
-  ///   first relevant bit resides.
-  /// @param values The values in the lowest nested level including
-  ///   spacing for nulls on the lowest levels; input has the length
-  ///   of the number of rows on the lowest nesting level.
-  void WriteBatchSpaced(int64_t num_values, const int16_t* def_levels,
-                        const int16_t* rep_levels, const uint8_t* valid_bits,
-                        int64_t valid_bits_offset, const T* values);
-
-  // Estimated size of the values that are not written to a page yet
-  int64_t EstimatedBufferedValueBytes() const {
-    return current_encoder_->EstimatedDataEncodedSize();
-  }
-
- protected:
-  std::shared_ptr<Buffer> GetValuesBuffer() override {
-    return current_encoder_->FlushValues();
-  }
-  void WriteDictionaryPage() override;
-  void CheckDictionarySizeLimit() override;
-  EncodedStatistics GetPageStatistics() override;
-  EncodedStatistics GetChunkStatistics() override;
-  void ResetPageStatistics() override;
-
- private:
-  int64_t WriteMiniBatch(int64_t num_values, const int16_t* def_levels,
-                         const int16_t* rep_levels, const T* values);
-
-  int64_t WriteMiniBatchSpaced(int64_t num_values, const int16_t* def_levels,
-                               const int16_t* rep_levels, const uint8_t* valid_bits,
-                               int64_t valid_bits_offset, const T* values,
-                               int64_t* num_spaced_written);
-
-  typedef Encoder<DType> EncoderType;
-
-  // Write values to a temporary buffer before they are encoded into pages
-  void WriteValues(int64_t num_values, const T* values);
-  void WriteValuesSpaced(int64_t num_values, const uint8_t* valid_bits,
-                         int64_t valid_bits_offset, const T* values);
-  std::unique_ptr<EncoderType> current_encoder_;
-
-  typedef TypedRowGroupStatistics<DType> TypedStats;
-  std::unique_ptr<TypedStats> page_statistics_;
-  std::unique_ptr<TypedStats> chunk_statistics_;
-};
-
-typedef TypedColumnWriter<BooleanType> BoolWriter;
-typedef TypedColumnWriter<Int32Type> Int32Writer;
-typedef TypedColumnWriter<Int64Type> Int64Writer;
-typedef TypedColumnWriter<Int96Type> Int96Writer;
-typedef TypedColumnWriter<FloatType> FloatWriter;
-typedef TypedColumnWriter<DoubleType> DoubleWriter;
-typedef TypedColumnWriter<ByteArrayType> ByteArrayWriter;
-typedef TypedColumnWriter<FLBAType> FixedLenByteArrayWriter;
-
-extern template class PARQUET_EXPORT TypedColumnWriter<BooleanType>;
-extern template class PARQUET_EXPORT TypedColumnWriter<Int32Type>;
-extern template class PARQUET_EXPORT TypedColumnWriter<Int64Type>;
-extern template class PARQUET_EXPORT TypedColumnWriter<Int96Type>;
-extern template class PARQUET_EXPORT TypedColumnWriter<FloatType>;
-extern template class PARQUET_EXPORT TypedColumnWriter<DoubleType>;
-extern template class PARQUET_EXPORT TypedColumnWriter<ByteArrayType>;
-extern template class PARQUET_EXPORT TypedColumnWriter<FLBAType>;
-
-}  // namespace parquet
-
-#endif  // PARQUET_COLUMN_READER_H
diff --git a/src/parquet/encoding-benchmark.cc b/src/parquet/encoding-benchmark.cc
deleted file mode 100644
index 364cdba..0000000
--- a/src/parquet/encoding-benchmark.cc
+++ /dev/null
@@ -1,166 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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.
-
-#include "benchmark/benchmark.h"
-
-#include "parquet/encoding-internal.h"
-#include "parquet/util/memory.h"
-
-using arrow::default_memory_pool;
-using arrow::MemoryPool;
-
-namespace parquet {
-
-using schema::PrimitiveNode;
-
-namespace benchmark {
-
-std::shared_ptr<ColumnDescriptor> Int64Schema(Repetition::type repetition) {
-  auto node = PrimitiveNode::Make("int64", repetition, Type::INT64);
-  return std::make_shared<ColumnDescriptor>(node, repetition != Repetition::REQUIRED,
-                                            repetition == Repetition::REPEATED);
-}
-
-static void BM_PlainEncodingBoolean(::benchmark::State& state) {
-  std::vector<bool> values(state.range(0), 64);
-  PlainEncoder<BooleanType> encoder(nullptr);
-
-  while (state.KeepRunning()) {
-    encoder.Put(values, static_cast<int>(values.size()));
-    encoder.FlushValues();
-  }
-  state.SetBytesProcessed(state.iterations() * state.range(0) * sizeof(bool));
-}
-
-BENCHMARK(BM_PlainEncodingBoolean)->Range(1024, 65536);
-
-static void BM_PlainDecodingBoolean(::benchmark::State& state) {
-  std::vector<bool> values(state.range(0), 64);
-  bool* output = new bool[state.range(0)];
-  PlainEncoder<BooleanType> encoder(nullptr);
-  encoder.Put(values, static_cast<int>(values.size()));
-  std::shared_ptr<Buffer> buf = encoder.FlushValues();
-
-  while (state.KeepRunning()) {
-    PlainDecoder<BooleanType> decoder(nullptr);
-    decoder.SetData(static_cast<int>(values.size()), buf->data(),
-                    static_cast<int>(buf->size()));
-    decoder.Decode(output, static_cast<int>(values.size()));
-  }
-
-  state.SetBytesProcessed(state.iterations() * state.range(0) * sizeof(bool));
-  delete[] output;
-}
-
-BENCHMARK(BM_PlainDecodingBoolean)->Range(1024, 65536);
-
-static void BM_PlainEncodingInt64(::benchmark::State& state) {
-  std::vector<int64_t> values(state.range(0), 64);
-  PlainEncoder<Int64Type> encoder(nullptr);
-
-  while (state.KeepRunning()) {
-    encoder.Put(values.data(), static_cast<int>(values.size()));
-    encoder.FlushValues();
-  }
-  state.SetBytesProcessed(state.iterations() * state.range(0) * sizeof(int64_t));
-}
-
-BENCHMARK(BM_PlainEncodingInt64)->Range(1024, 65536);
-
-static void BM_PlainDecodingInt64(::benchmark::State& state) {
-  std::vector<int64_t> values(state.range(0), 64);
-  PlainEncoder<Int64Type> encoder(nullptr);
-  encoder.Put(values.data(), static_cast<int>(values.size()));
-  std::shared_ptr<Buffer> buf = encoder.FlushValues();
-
-  while (state.KeepRunning()) {
-    PlainDecoder<Int64Type> decoder(nullptr);
-    decoder.SetData(static_cast<int>(values.size()), buf->data(),
-                    static_cast<int>(buf->size()));
-    decoder.Decode(values.data(), static_cast<int>(values.size()));
-  }
-  state.SetBytesProcessed(state.iterations() * state.range(0) * sizeof(int64_t));
-}
-
-BENCHMARK(BM_PlainDecodingInt64)->Range(1024, 65536);
-
-template <typename Type>
-static void DecodeDict(std::vector<typename Type::c_type>& values,
-                       ::benchmark::State& state) {
-  typedef typename Type::c_type T;
-  int num_values = static_cast<int>(values.size());
-
-  ChunkedAllocator pool;
-  MemoryPool* allocator = default_memory_pool();
-  std::shared_ptr<ColumnDescriptor> descr = Int64Schema(Repetition::REQUIRED);
-
-  DictEncoder<Type> encoder(descr.get(), &pool, allocator);
-  for (int i = 0; i < num_values; ++i) {
-    encoder.Put(values[i]);
-  }
-
-  std::shared_ptr<ResizableBuffer> dict_buffer =
-      AllocateBuffer(allocator, encoder.dict_encoded_size());
-
-  std::shared_ptr<ResizableBuffer> indices =
-      AllocateBuffer(allocator, encoder.EstimatedDataEncodedSize());
-
-  encoder.WriteDict(dict_buffer->mutable_data());
-  int actual_bytes =
-      encoder.WriteIndices(indices->mutable_data(), static_cast<int>(indices->size()));
-
-  PARQUET_THROW_NOT_OK(indices->Resize(actual_bytes));
-
-  while (state.KeepRunning()) {
-    PlainDecoder<Type> dict_decoder(descr.get());
-    dict_decoder.SetData(encoder.num_entries(), dict_buffer->data(),
-                         static_cast<int>(dict_buffer->size()));
-    DictionaryDecoder<Type> decoder(descr.get());
-    decoder.SetDict(&dict_decoder);
-    decoder.SetData(num_values, indices->data(), static_cast<int>(indices->size()));
-    decoder.Decode(values.data(), num_values);
-  }
-
-  state.SetBytesProcessed(state.iterations() * state.range(0) * sizeof(T));
-}
-
-static void BM_DictDecodingInt64_repeats(::benchmark::State& state) {
-  typedef Int64Type Type;
-  typedef typename Type::c_type T;
-
-  std::vector<T> values(state.range(0), 64);
-  DecodeDict<Type>(values, state);
-}
-
-BENCHMARK(BM_DictDecodingInt64_repeats)->Range(1024, 65536);
-
-static void BM_DictDecodingInt64_literals(::benchmark::State& state) {
-  typedef Int64Type Type;
-  typedef typename Type::c_type T;
-
-  std::vector<T> values(state.range(0));
-  for (size_t i = 0; i < values.size(); ++i) {
-    values[i] = i;
-  }
-  DecodeDict<Type>(values, state);
-}
-
-BENCHMARK(BM_DictDecodingInt64_literals)->Range(1024, 65536);
-
-}  // namespace benchmark
-
-}  // namespace parquet
diff --git a/src/parquet/encoding-internal.h b/src/parquet/encoding-internal.h
deleted file mode 100644
index 2dfb9ff..0000000
--- a/src/parquet/encoding-internal.h
+++ /dev/null
@@ -1,979 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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.
-
-#ifndef PARQUET_ENCODING_INTERNAL_H
-#define PARQUET_ENCODING_INTERNAL_H
-
-#include <algorithm>
-#include <cstdint>
-#include <limits>
-#include <memory>
-#include <vector>
-
-#include "arrow/util/bit-stream-utils.h"
-#include "arrow/util/bit-util.h"
-#include "arrow/util/cpu-info.h"
-#include "arrow/util/hash-util.h"
-#include "arrow/util/macros.h"
-#include "arrow/util/rle-encoding.h"
-
-#include "parquet/encoding.h"
-#include "parquet/exception.h"
-#include "parquet/schema.h"
-#include "parquet/types.h"
-#include "parquet/util/memory.h"
-
-namespace parquet {
-
-namespace BitUtil = ::arrow::BitUtil;
-using HashUtil = ::arrow::HashUtil;
-
-class ColumnDescriptor;
-
-// ----------------------------------------------------------------------
-// Encoding::PLAIN decoder implementation
-
-template <typename DType>
-class PlainDecoder : public Decoder<DType> {
- public:
-  typedef typename DType::c_type T;
-  using Decoder<DType>::num_values_;
-
-  explicit PlainDecoder(const ColumnDescriptor* descr)
-      : Decoder<DType>(descr, Encoding::PLAIN), data_(nullptr), len_(0) {
-    if (descr_ && descr_->physical_type() == Type::FIXED_LEN_BYTE_ARRAY) {
-      type_length_ = descr_->type_length();
-    } else {
-      type_length_ = -1;
-    }
-  }
-
-  virtual void SetData(int num_values, const uint8_t* data, int len) {
-    num_values_ = num_values;
-    data_ = data;
-    len_ = len;
-  }
-
-  virtual int Decode(T* buffer, int max_values);
-
- private:
-  using Decoder<DType>::descr_;
-  const uint8_t* data_;
-  int len_;
-  int type_length_;
-};
-
-// Decode routine templated on C++ type rather than type enum
-template <typename T>
-inline int DecodePlain(const uint8_t* data, int64_t data_size, int num_values,
-                       int type_length, T* out) {
-  int bytes_to_decode = num_values * static_cast<int>(sizeof(T));
-  if (data_size < bytes_to_decode) {
-    ParquetException::EofException();
-  }
-  memcpy(out, data, bytes_to_decode);
-  return bytes_to_decode;
-}
-
-// Template specialization for BYTE_ARRAY. The written values do not own their
-// own data.
-template <>
-inline int DecodePlain<ByteArray>(const uint8_t* data, int64_t data_size, int num_values,
-                                  int type_length, ByteArray* out) {
-  int bytes_decoded = 0;
-  int increment;
-  for (int i = 0; i < num_values; ++i) {
-    uint32_t len = out[i].len = *reinterpret_cast<const uint32_t*>(data);
-    increment = static_cast<int>(sizeof(uint32_t) + len);
-    if (data_size < increment) ParquetException::EofException();
-    out[i].ptr = data + sizeof(uint32_t);
-    data += increment;
-    data_size -= increment;
-    bytes_decoded += increment;
-  }
-  return bytes_decoded;
-}
-
-// Template specialization for FIXED_LEN_BYTE_ARRAY. The written values do not
-// own their own data.
-template <>
-inline int DecodePlain<FixedLenByteArray>(const uint8_t* data, int64_t data_size,
-                                          int num_values, int type_length,
-                                          FixedLenByteArray* out) {
-  int bytes_to_decode = type_length * num_values;
-  if (data_size < bytes_to_decode) {
-    ParquetException::EofException();
-  }
-  for (int i = 0; i < num_values; ++i) {
-    out[i].ptr = data;
-    data += type_length;
-    data_size -= type_length;
-  }
-  return bytes_to_decode;
-}
-
-template <typename DType>
-inline int PlainDecoder<DType>::Decode(T* buffer, int max_values) {
-  max_values = std::min(max_values, num_values_);
-  int bytes_consumed = DecodePlain<T>(data_, len_, max_values, type_length_, buffer);
-  data_ += bytes_consumed;
-  len_ -= bytes_consumed;
-  num_values_ -= max_values;
-  return max_values;
-}
-
-template <>
-class PlainDecoder<BooleanType> : public Decoder<BooleanType> {
- public:
-  explicit PlainDecoder(const ColumnDescriptor* descr)
-      : Decoder<BooleanType>(descr, Encoding::PLAIN) {}
-
-  virtual void SetData(int num_values, const uint8_t* data, int len) {
-    num_values_ = num_values;
-    bit_reader_ = ::arrow::BitReader(data, len);
-  }
-
-  // Two flavors of bool decoding
-  int Decode(uint8_t* buffer, int max_values) {
-    max_values = std::min(max_values, num_values_);
-    bool val;
-    ::arrow::internal::BitmapWriter bit_writer(buffer, 0, max_values);
-    for (int i = 0; i < max_values; ++i) {
-      if (!bit_reader_.GetValue(1, &val)) {
-        ParquetException::EofException();
-      }
-      if (val) {
-        bit_writer.Set();
-      }
-      bit_writer.Next();
-    }
-    bit_writer.Finish();
-    num_values_ -= max_values;
-    return max_values;
-  }
-
-  virtual int Decode(bool* buffer, int max_values) {
-    max_values = std::min(max_values, num_values_);
-    if (bit_reader_.GetBatch(1, buffer, max_values) != max_values) {
-      ParquetException::EofException();
-    }
-    num_values_ -= max_values;
-    return max_values;
-  }
-
- private:
-  ::arrow::BitReader bit_reader_;
-};
-
-// ----------------------------------------------------------------------
-// Encoding::PLAIN encoder implementation
-
-template <typename DType>
-class PlainEncoder : public Encoder<DType> {
- public:
-  typedef typename DType::c_type T;
-
-  explicit PlainEncoder(const ColumnDescriptor* descr,
-                        ::arrow::MemoryPool* pool = ::arrow::default_memory_pool())
-      : Encoder<DType>(descr, Encoding::PLAIN, pool) {
-    values_sink_.reset(new InMemoryOutputStream(pool));
-  }
-
-  int64_t EstimatedDataEncodedSize() override { return values_sink_->Tell(); }
-
-  std::shared_ptr<Buffer> FlushValues() override;
-  void Put(const T* src, int num_values) override;
-
- protected:
-  std::unique_ptr<InMemoryOutputStream> values_sink_;
-};
-
-template <>
-class PlainEncoder<BooleanType> : public Encoder<BooleanType> {
- public:
-  explicit PlainEncoder(const ColumnDescriptor* descr,
-                        ::arrow::MemoryPool* pool = ::arrow::default_memory_pool())
-      : Encoder<BooleanType>(descr, Encoding::PLAIN, pool),
-        bits_available_(kInMemoryDefaultCapacity * 8),
-        bits_buffer_(AllocateBuffer(pool, kInMemoryDefaultCapacity)),
-        values_sink_(new InMemoryOutputStream(pool)) {
-    bit_writer_.reset(new ::arrow::BitWriter(bits_buffer_->mutable_data(),
-                                             static_cast<int>(bits_buffer_->size())));
-  }
-
-  int64_t EstimatedDataEncodedSize() override {
-    return values_sink_->Tell() + bit_writer_->bytes_written();
-  }
-
-  std::shared_ptr<Buffer> FlushValues() override {
-    if (bits_available_ > 0) {
-      bit_writer_->Flush();
-      values_sink_->Write(bit_writer_->buffer(), bit_writer_->bytes_written());
-      bit_writer_->Clear();
-      bits_available_ = static_cast<int>(bits_buffer_->size()) * 8;
-    }
-
-    std::shared_ptr<Buffer> buffer = values_sink_->GetBuffer();
-    values_sink_.reset(new InMemoryOutputStream(this->pool_));
-    return buffer;
-  }
-
-#define PLAINDECODER_BOOLEAN_PUT(input_type, function_attributes)                 \
-  void Put(input_type src, int num_values) function_attributes {                  \
-    int bit_offset = 0;                                                           \
-    if (bits_available_ > 0) {                                                    \
-      int bits_to_write = std::min(bits_available_, num_values);                  \
-      for (int i = 0; i < bits_to_write; i++) {                                   \
-        bit_writer_->PutValue(src[i], 1);                                         \
-      }                                                                           \
-      bits_available_ -= bits_to_write;                                           \
-      bit_offset = bits_to_write;                                                 \
-                                                                                  \
-      if (bits_available_ == 0) {                                                 \
-        bit_writer_->Flush();                                                     \
-        values_sink_->Write(bit_writer_->buffer(), bit_writer_->bytes_written()); \
-        bit_writer_->Clear();                                                     \
-      }                                                                           \
-    }                                                                             \
-                                                                                  \
-    int bits_remaining = num_values - bit_offset;                                 \
-    while (bit_offset < num_values) {                                             \
-      bits_available_ = static_cast<int>(bits_buffer_->size()) * 8;               \
-                                                                                  \
-      int bits_to_write = std::min(bits_available_, bits_remaining);              \
-      for (int i = bit_offset; i < bit_offset + bits_to_write; i++) {             \
-        bit_writer_->PutValue(src[i], 1);                                         \
-      }                                                                           \
-      bit_offset += bits_to_write;                                                \
-      bits_available_ -= bits_to_write;                                           \
-      bits_remaining -= bits_to_write;                                            \
-                                                                                  \
-      if (bits_available_ == 0) {                                                 \
-        bit_writer_->Flush();                                                     \
-        values_sink_->Write(bit_writer_->buffer(), bit_writer_->bytes_written()); \
-        bit_writer_->Clear();                                                     \
-      }                                                                           \
-    }                                                                             \
-  }
-
-  PLAINDECODER_BOOLEAN_PUT(const bool*, override)
-  PLAINDECODER_BOOLEAN_PUT(const std::vector<bool>&, )
-
- protected:
-  int bits_available_;
-  std::unique_ptr<::arrow::BitWriter> bit_writer_;
-  std::shared_ptr<ResizableBuffer> bits_buffer_;
-  std::unique_ptr<InMemoryOutputStream> values_sink_;
-};
-
-template <typename DType>
-inline std::shared_ptr<Buffer> PlainEncoder<DType>::FlushValues() {
-  std::shared_ptr<Buffer> buffer = values_sink_->GetBuffer();
-  values_sink_.reset(new InMemoryOutputStream(this->pool_));
-  return buffer;
-}
-
-template <typename DType>
-inline void PlainEncoder<DType>::Put(const T* buffer, int num_values) {
-  values_sink_->Write(reinterpret_cast<const uint8_t*>(buffer), num_values * sizeof(T));
-}
-
-template <>
-inline void PlainEncoder<ByteArrayType>::Put(const ByteArray* src, int num_values) {
-  for (int i = 0; i < num_values; ++i) {
-    // Write the result to the output stream
-    values_sink_->Write(reinterpret_cast<const uint8_t*>(&src[i].len), sizeof(uint32_t));
-    if (src[i].len > 0) {
-      DCHECK(nullptr != src[i].ptr) << "Value ptr cannot be NULL";
-    }
-    values_sink_->Write(reinterpret_cast<const uint8_t*>(src[i].ptr), src[i].len);
-  }
-}
-
-template <>
-inline void PlainEncoder<FLBAType>::Put(const FixedLenByteArray* src, int num_values) {
-  for (int i = 0; i < num_values; ++i) {
-    // Write the result to the output stream
-    if (descr_->type_length() > 0) {
-      DCHECK(nullptr != src[i].ptr) << "Value ptr cannot be NULL";
-    }
-    values_sink_->Write(reinterpret_cast<const uint8_t*>(src[i].ptr),
-                        descr_->type_length());
-  }
-}
-
-// ----------------------------------------------------------------------
-// Dictionary encoding and decoding
-
-template <typename Type>
-class DictionaryDecoder : public Decoder<Type> {
- public:
-  typedef typename Type::c_type T;
-
-  // Initializes the dictionary with values from 'dictionary'. The data in
-  // dictionary is not guaranteed to persist in memory after this call so the
-  // dictionary decoder needs to copy the data out if necessary.
-  explicit DictionaryDecoder(const ColumnDescriptor* descr,
-                             ::arrow::MemoryPool* pool = ::arrow::default_memory_pool())
-      : Decoder<Type>(descr, Encoding::RLE_DICTIONARY),
-        dictionary_(0, pool),
-        byte_array_data_(AllocateBuffer(pool, 0)) {}
-
-  // Perform type-specific initiatialization
-  void SetDict(Decoder<Type>* dictionary);
-
-  void SetData(int num_values, const uint8_t* data, int len) override {
-    num_values_ = num_values;
-    if (len == 0) return;
-    uint8_t bit_width = *data;
-    ++data;
-    --len;
-    idx_decoder_ = ::arrow::RleDecoder(data, len, bit_width);
-  }
-
-  int Decode(T* buffer, int max_values) override {
-    max_values = std::min(max_values, num_values_);
-    int decoded_values =
-        idx_decoder_.GetBatchWithDict(dictionary_.data(), buffer, max_values);
-    if (decoded_values != max_values) {
-      ParquetException::EofException();
-    }
-    num_values_ -= max_values;
-    return max_values;
-  }
-
-  int DecodeSpaced(T* buffer, int num_values, int null_count, const uint8_t* valid_bits,
-                   int64_t valid_bits_offset) override {
-    int decoded_values =
-        idx_decoder_.GetBatchWithDictSpaced(dictionary_.data(), buffer, num_values,
-                                            null_count, valid_bits, valid_bits_offset);
-    if (decoded_values != num_values) {
-      ParquetException::EofException();
-    }
-    return decoded_values;
-  }
-
- private:
-  using Decoder<Type>::num_values_;
-
-  // Only one is set.
-  Vector<T> dictionary_;
-
-  // Data that contains the byte array data (byte_array_dictionary_ just has the
-  // pointers).
-  std::shared_ptr<ResizableBuffer> byte_array_data_;
-
-  ::arrow::RleDecoder idx_decoder_;
-};
-
-template <typename Type>
-inline void DictionaryDecoder<Type>::SetDict(Decoder<Type>* dictionary) {
-  int num_dictionary_values = dictionary->values_left();
-  dictionary_.Resize(num_dictionary_values);
-  dictionary->Decode(&dictionary_[0], num_dictionary_values);
-}
-
-template <>
-inline void DictionaryDecoder<BooleanType>::SetDict(Decoder<BooleanType>* dictionary) {
-  ParquetException::NYI("Dictionary encoding is not implemented for boolean values");
-}
-
-template <>
-inline void DictionaryDecoder<ByteArrayType>::SetDict(
-    Decoder<ByteArrayType>* dictionary) {
-  int num_dictionary_values = dictionary->values_left();
-  dictionary_.Resize(num_dictionary_values);
-  dictionary->Decode(&dictionary_[0], num_dictionary_values);
-
-  int total_size = 0;
-  for (int i = 0; i < num_dictionary_values; ++i) {
-    total_size += dictionary_[i].len;
-  }
-  if (total_size > 0) {
-    PARQUET_THROW_NOT_OK(byte_array_data_->Resize(total_size, false));
-  }
-
-  int offset = 0;
-  uint8_t* bytes_data = byte_array_data_->mutable_data();
-  for (int i = 0; i < num_dictionary_values; ++i) {
-    memcpy(bytes_data + offset, dictionary_[i].ptr, dictionary_[i].len);
-    dictionary_[i].ptr = bytes_data + offset;
-    offset += dictionary_[i].len;
-  }
-}
-
-template <>
-inline void DictionaryDecoder<FLBAType>::SetDict(Decoder<FLBAType>* dictionary) {
-  int num_dictionary_values = dictionary->values_left();
-  dictionary_.Resize(num_dictionary_values);
-  dictionary->Decode(&dictionary_[0], num_dictionary_values);
-
-  int fixed_len = descr_->type_length();
-  int total_size = num_dictionary_values * fixed_len;
-
-  PARQUET_THROW_NOT_OK(byte_array_data_->Resize(total_size, false));
-  uint8_t* bytes_data = byte_array_data_->mutable_data();
-  for (int32_t i = 0, offset = 0; i < num_dictionary_values; ++i, offset += fixed_len) {
-    memcpy(bytes_data + offset, dictionary_[i].ptr, fixed_len);
-    dictionary_[i].ptr = bytes_data + offset;
-  }
-}
-
-// ----------------------------------------------------------------------
-// Dictionary encoder
-
-// Initially imported from Apache Impala on 2016-02-22, and has been modified
-// since for parquet-cpp
-
-// Initially 1024 elements
-static constexpr int INITIAL_HASH_TABLE_SIZE = 1 << 10;
-
-typedef int32_t hash_slot_t;
-static constexpr hash_slot_t HASH_SLOT_EMPTY = std::numeric_limits<int32_t>::max();
-
-// The maximum load factor for the hash table before resizing.
-static constexpr double MAX_HASH_LOAD = 0.7;
-
-/// See the dictionary encoding section of https://github.com/Parquet/parquet-format.
-/// The encoding supports streaming encoding. Values are encoded as they are added while
-/// the dictionary is being constructed. At any time, the buffered values can be
-/// written out with the current dictionary size. More values can then be added to
-/// the encoder, including new dictionary entries.
-template <typename DType>
-class DictEncoder : public Encoder<DType> {
- public:
-  typedef typename DType::c_type T;
-
-  explicit DictEncoder(const ColumnDescriptor* desc, ChunkedAllocator* pool = nullptr,
-                       ::arrow::MemoryPool* allocator = ::arrow::default_memory_pool())
-      : Encoder<DType>(desc, Encoding::PLAIN_DICTIONARY, allocator),
-        allocator_(allocator),
-        pool_(pool),
-        hash_table_size_(INITIAL_HASH_TABLE_SIZE),
-        mod_bitmask_(hash_table_size_ - 1),
-        hash_slots_(0, allocator),
-        dict_encoded_size_(0),
-        type_length_(desc->type_length()) {
-    hash_slots_.Assign(hash_table_size_, HASH_SLOT_EMPTY);
-    if (!::arrow::CpuInfo::initialized()) {
-      ::arrow::CpuInfo::Init();
-    }
-  }
-
-  ~DictEncoder() override { DCHECK(buffered_indices_.empty()); }
-
-  // TODO(wesm): think about how to address the construction semantics in
-  // encodings/dictionary-encoding.h
-  void set_mem_pool(ChunkedAllocator* pool) { pool_ = pool; }
-
-  void set_type_length(int type_length) { type_length_ = type_length; }
-
-  /// Returns a conservative estimate of the number of bytes needed to encode the buffered
-  /// indices. Used to size the buffer passed to WriteIndices().
-  int64_t EstimatedDataEncodedSize() override {
-    // Note: because of the way RleEncoder::CheckBufferFull() is called, we have to
-    // reserve
-    // an extra "RleEncoder::MinBufferSize" bytes. These extra bytes won't be used
-    // but not reserving them would cause the encoder to fail.
-    return 1 +
-           ::arrow::RleEncoder::MaxBufferSize(
-               bit_width(), static_cast<int>(buffered_indices_.size())) +
-           ::arrow::RleEncoder::MinBufferSize(bit_width());
-  }
-
-  /// The minimum bit width required to encode the currently buffered indices.
-  int bit_width() const {
-    if (ARROW_PREDICT_FALSE(num_entries() == 0)) return 0;
-    if (ARROW_PREDICT_FALSE(num_entries() == 1)) return 1;
-    return BitUtil::Log2(num_entries());
-  }
-
-  /// Writes out any buffered indices to buffer preceded by the bit width of this data.
-  /// Returns the number of bytes written.
-  /// If the supplied buffer is not big enough, returns -1.
-  /// buffer must be preallocated with buffer_len bytes. Use EstimatedDataEncodedSize()
-  /// to size buffer.
-  int WriteIndices(uint8_t* buffer, int buffer_len);
-
-  int hash_table_size() { return hash_table_size_; }
-  int dict_encoded_size() { return dict_encoded_size_; }
-  /// Clears all the indices (but leaves the dictionary).
-  void ClearIndices() { buffered_indices_.clear(); }
-
-  /// Encode value. Note that this does not actually write any data, just
-  /// buffers the value's index to be written later.
-  void Put(const T& value);
-
-  std::shared_ptr<Buffer> FlushValues() override {
-    std::shared_ptr<ResizableBuffer> buffer =
-        AllocateBuffer(this->allocator_, EstimatedDataEncodedSize());
-    int result_size = WriteIndices(buffer->mutable_data(),
-                                   static_cast<int>(EstimatedDataEncodedSize()));
-    ClearIndices();
-    PARQUET_THROW_NOT_OK(buffer->Resize(result_size, false));
-    return buffer;
-  }
-
-  void Put(const T* values, int num_values) override {
-    for (int i = 0; i < num_values; i++) {
-      Put(values[i]);
-    }
-  }
-
-  void PutSpaced(const T* src, int num_values, const uint8_t* valid_bits,
-                 int64_t valid_bits_offset) override {
-    ::arrow::internal::BitmapReader valid_bits_reader(valid_bits, valid_bits_offset,
-                                                      num_values);
-    for (int32_t i = 0; i < num_values; i++) {
-      if (valid_bits_reader.IsSet()) {
-        Put(src[i]);
-      }
-      valid_bits_reader.Next();
-    }
-  }
-
-  /// Writes out the encoded dictionary to buffer. buffer must be preallocated to
-  /// dict_encoded_size() bytes.
-  void WriteDict(uint8_t* buffer);
-
-  ChunkedAllocator* mem_pool() { return pool_; }
-
-  /// The number of entries in the dictionary.
-  int num_entries() const { return static_cast<int>(uniques_.size()); }
-
- private:
-  ::arrow::MemoryPool* allocator_;
-
-  // For ByteArray / FixedLenByteArray data. Not owned
-  ChunkedAllocator* pool_;
-
-  /// Size of the table. Must be a power of 2.
-  int hash_table_size_;
-
-  // Store hash_table_size_ - 1, so that j & mod_bitmask_ is equivalent to j %
-  // hash_table_size_, but uses far fewer CPU cycles
-  int mod_bitmask_;
-
-  // We use a fixed-size hash table with linear probing
-  //
-  // These values correspond to the uniques_ array
-  Vector<hash_slot_t> hash_slots_;
-
-  /// Indices that have not yet be written out by WriteIndices().
-  std::vector<int> buffered_indices_;
-
-  /// The number of bytes needed to encode the dictionary.
-  int dict_encoded_size_;
-
-  // The unique observed values
-  std::vector<T> uniques_;
-
-  bool SlotDifferent(const T& v, hash_slot_t slot);
-  void DoubleTableSize();
-
-  /// Size of each encoded dictionary value. -1 for variable-length types.
-  int type_length_;
-
-  /// Hash function for mapping a value to a bucket.
-  inline int Hash(const T& value) const;
-
-  /// Adds value to the hash table and updates dict_encoded_size_
-  void AddDictKey(const T& value);
-};
-
-template <typename DType>
-inline int DictEncoder<DType>::Hash(const typename DType::c_type& value) const {
-  return HashUtil::Hash(&value, sizeof(value), 0);
-}
-
-template <>
-inline int DictEncoder<ByteArrayType>::Hash(const ByteArray& value) const {
-  if (value.len > 0) {
-    DCHECK_NE(nullptr, value.ptr) << "Value ptr cannot be NULL";
-  }
-  return HashUtil::Hash(value.ptr, value.len, 0);
-}
-
-template <>
-inline int DictEncoder<FLBAType>::Hash(const FixedLenByteArray& value) const {
-  if (type_length_ > 0) {
-    DCHECK_NE(nullptr, value.ptr) << "Value ptr cannot be NULL";
-  }
-  return HashUtil::Hash(value.ptr, type_length_, 0);
-}
-
-template <typename DType>
-inline bool DictEncoder<DType>::SlotDifferent(const typename DType::c_type& v,
-                                              hash_slot_t slot) {
-  return v != uniques_[slot];
-}
-
-template <>
-inline bool DictEncoder<FLBAType>::SlotDifferent(const FixedLenByteArray& v,
-                                                 hash_slot_t slot) {
-  return 0 != memcmp(v.ptr, uniques_[slot].ptr, type_length_);
-}
-
-template <typename DType>
-inline void DictEncoder<DType>::Put(const typename DType::c_type& v) {
-  int j = Hash(v) & mod_bitmask_;
-  hash_slot_t index = hash_slots_[j];
-
-  // Find an empty slot
-  while (HASH_SLOT_EMPTY != index && SlotDifferent(v, index)) {
-    // Linear probing
-    ++j;
-    if (j == hash_table_size_) j = 0;
-    index = hash_slots_[j];
-  }
-
-  if (index == HASH_SLOT_EMPTY) {
-    // Not in the hash table, so we insert it now
-    index = static_cast<hash_slot_t>(uniques_.size());
-    hash_slots_[j] = index;
-    AddDictKey(v);
-
-    if (ARROW_PREDICT_FALSE(static_cast<int>(uniques_.size()) >
-                            hash_table_size_ * MAX_HASH_LOAD)) {
-      DoubleTableSize();
-    }
-  }
-
-  buffered_indices_.push_back(index);
-}
-
-template <typename DType>
-inline void DictEncoder<DType>::DoubleTableSize() {
-  int new_size = hash_table_size_ * 2;
-  Vector<hash_slot_t> new_hash_slots(0, allocator_);
-  new_hash_slots.Assign(new_size, HASH_SLOT_EMPTY);
-  hash_slot_t index, slot;
-  int j;
-  for (int i = 0; i < hash_table_size_; ++i) {
-    index = hash_slots_[i];
-
-    if (index == HASH_SLOT_EMPTY) {
-      continue;
-    }
-
-    // Compute the hash value mod the new table size to start looking for an
-    // empty slot
-    const typename DType::c_type& v = uniques_[index];
-
-    // Find an empty slot in the new hash table
-    j = Hash(v) & (new_size - 1);
-    slot = new_hash_slots[j];
-    while (HASH_SLOT_EMPTY != slot && SlotDifferent(v, slot)) {
-      ++j;
-      if (j == new_size) j = 0;
-      slot = new_hash_slots[j];
-    }
-
-    // Copy the old slot index to the new hash table
-    new_hash_slots[j] = index;
-  }
-
-  hash_table_size_ = new_size;
-  mod_bitmask_ = new_size - 1;
-
-  hash_slots_.Swap(new_hash_slots);
-}
-
-template <typename DType>
-inline void DictEncoder<DType>::AddDictKey(const typename DType::c_type& v) {
-  uniques_.push_back(v);
-  dict_encoded_size_ += static_cast<int>(sizeof(typename DType::c_type));
-}
-
-template <>
-inline void DictEncoder<ByteArrayType>::AddDictKey(const ByteArray& v) {
-  uint8_t* heap = pool_->Allocate(v.len);
-  if (ARROW_PREDICT_FALSE(v.len > 0 && heap == nullptr)) {
-    throw ParquetException("out of memory");
-  }
-  memcpy(heap, v.ptr, v.len);
-  uniques_.push_back(ByteArray(v.len, heap));
-  dict_encoded_size_ += static_cast<int>(v.len + sizeof(uint32_t));
-}
-
-template <>
-inline void DictEncoder<FLBAType>::AddDictKey(const FixedLenByteArray& v) {
-  uint8_t* heap = pool_->Allocate(type_length_);
-  if (ARROW_PREDICT_FALSE(type_length_ > 0 && heap == nullptr)) {
-    throw ParquetException("out of memory");
-  }
-  memcpy(heap, v.ptr, type_length_);
-
-  uniques_.push_back(FixedLenByteArray(heap));
-  dict_encoded_size_ += type_length_;
-}
-
-template <typename DType>
-inline void DictEncoder<DType>::WriteDict(uint8_t* buffer) {
-  // For primitive types, only a memcpy
-  memcpy(buffer, uniques_.data(), sizeof(typename DType::c_type) * uniques_.size());
-}
-
-template <>
-inline void DictEncoder<BooleanType>::WriteDict(uint8_t* buffer) {
-  // For primitive types, only a memcpy
-  // memcpy(buffer, uniques_.data(), sizeof(typename DType::c_type) * uniques_.size());
-  for (size_t i = 0; i < uniques_.size(); i++) {
-    buffer[i] = uniques_[i];
-  }
-}
-
-// ByteArray and FLBA already have the dictionary encoded in their data heaps
-template <>
-inline void DictEncoder<ByteArrayType>::WriteDict(uint8_t* buffer) {
-  for (const ByteArray& v : uniques_) {
-    memcpy(buffer, reinterpret_cast<const void*>(&v.len), sizeof(uint32_t));
-    buffer += sizeof(uint32_t);
-    if (v.len > 0) {
-      DCHECK(nullptr != v.ptr) << "Value ptr cannot be NULL";
-    }
-    memcpy(buffer, v.ptr, v.len);
-    buffer += v.len;
-  }
-}
-
-template <>
-inline void DictEncoder<FLBAType>::WriteDict(uint8_t* buffer) {
-  for (const FixedLenByteArray& v : uniques_) {
-    if (type_length_ > 0) {
-      DCHECK(nullptr != v.ptr) << "Value ptr cannot be NULL";
-    }
-    memcpy(buffer, v.ptr, type_length_);
-    buffer += type_length_;
-  }
-}
-
-template <typename DType>
-inline int DictEncoder<DType>::WriteIndices(uint8_t* buffer, int buffer_len) {
-  // Write bit width in first byte
-  *buffer = static_cast<uint8_t>(bit_width());
-  ++buffer;
-  --buffer_len;
-
-  ::arrow::RleEncoder encoder(buffer, buffer_len, bit_width());
-  for (int index : buffered_indices_) {
-    if (!encoder.Put(index)) return -1;
-  }
-  encoder.Flush();
-
-  ClearIndices();
-  return 1 + encoder.len();
-}
-
-// ----------------------------------------------------------------------
-// DeltaBitPackDecoder
-
-template <typename DType>
-class DeltaBitPackDecoder : public Decoder<DType> {
- public:
-  typedef typename DType::c_type T;
-
-  explicit DeltaBitPackDecoder(const ColumnDescriptor* descr,
-                               ::arrow::MemoryPool* pool = ::arrow::default_memory_pool())
-      : Decoder<DType>(descr, Encoding::DELTA_BINARY_PACKED), pool_(pool) {
-    if (DType::type_num != Type::INT32 && DType::type_num != Type::INT64) {
-      throw ParquetException("Delta bit pack encoding should only be for integer data.");
-    }
-  }
-
-  virtual void SetData(int num_values, const uint8_t* data, int len) {
-    num_values_ = num_values;
-    decoder_ = ::arrow::BitReader(data, len);
-    values_current_block_ = 0;
-    values_current_mini_block_ = 0;
-  }
-
-  virtual int Decode(T* buffer, int max_values) {
-    return GetInternal(buffer, max_values);
-  }
-
- private:
-  using Decoder<DType>::num_values_;
-
-  void InitBlock() {
-    int32_t block_size;
-    if (!decoder_.GetVlqInt(&block_size)) ParquetException::EofException();
-    if (!decoder_.GetVlqInt(&num_mini_blocks_)) ParquetException::EofException();
-    if (!decoder_.GetVlqInt(&values_current_block_)) {
-      ParquetException::EofException();
-    }
-    if (!decoder_.GetZigZagVlqInt(&last_value_)) ParquetException::EofException();
-
-    delta_bit_widths_ = AllocateBuffer(pool_, num_mini_blocks_);
-    uint8_t* bit_width_data = delta_bit_widths_->mutable_data();
-
-    if (!decoder_.GetZigZagVlqInt(&min_delta_)) ParquetException::EofException();
-    for (int i = 0; i < num_mini_blocks_; ++i) {
-      if (!decoder_.GetAligned<uint8_t>(1, bit_width_data + i)) {
-        ParquetException::EofException();
-      }
-    }
-    values_per_mini_block_ = block_size / num_mini_blocks_;
-    mini_block_idx_ = 0;
-    delta_bit_width_ = bit_width_data[0];
-    values_current_mini_block_ = values_per_mini_block_;
-  }
-
-  template <typename T>
-  int GetInternal(T* buffer, int max_values) {
-    max_values = std::min(max_values, num_values_);
-    const uint8_t* bit_width_data = delta_bit_widths_->data();
-    for (int i = 0; i < max_values; ++i) {
-      if (ARROW_PREDICT_FALSE(values_current_mini_block_ == 0)) {
-        ++mini_block_idx_;
-        if (mini_block_idx_ < static_cast<size_t>(delta_bit_widths_->size())) {
-          delta_bit_width_ = bit_width_data[mini_block_idx_];
-          values_current_mini_block_ = values_per_mini_block_;
-        } else {
-          InitBlock();
-          buffer[i] = last_value_;
-          continue;
-        }
-      }
-
-      // TODO: the key to this algorithm is to decode the entire miniblock at once.
-      int64_t delta;
-      if (!decoder_.GetValue(delta_bit_width_, &delta)) ParquetException::EofException();
-      delta += min_delta_;
-      last_value_ += static_cast<int32_t>(delta);
-      buffer[i] = last_value_;
-      --values_current_mini_block_;
-    }
-    num_values_ -= max_values;
-    return max_values;
-  }
-
-  ::arrow::MemoryPool* pool_;
-  ::arrow::BitReader decoder_;
-  int32_t values_current_block_;
-  int32_t num_mini_blocks_;
-  uint64_t values_per_mini_block_;
-  uint64_t values_current_mini_block_;
-
-  int32_t min_delta_;
-  size_t mini_block_idx_;
-  std::shared_ptr<ResizableBuffer> delta_bit_widths_;
-  int delta_bit_width_;
-
-  int32_t last_value_;
-};
-
-// ----------------------------------------------------------------------
-// DELTA_LENGTH_BYTE_ARRAY
-
-class DeltaLengthByteArrayDecoder : public Decoder<ByteArrayType> {
- public:
-  explicit DeltaLengthByteArrayDecoder(
-      const ColumnDescriptor* descr,
-      ::arrow::MemoryPool* pool = ::arrow::default_memory_pool())
-      : Decoder<ByteArrayType>(descr, Encoding::DELTA_LENGTH_BYTE_ARRAY),
-        len_decoder_(nullptr, pool) {}
-
-  virtual void SetData(int num_values, const uint8_t* data, int len) {
-    num_values_ = num_values;
-    if (len == 0) return;
-    int total_lengths_len = *reinterpret_cast<const int*>(data);
-    data += 4;
-    len_decoder_.SetData(num_values, data, total_lengths_len);
-    data_ = data + total_lengths_len;
-    len_ = len - 4 - total_lengths_len;
-  }
-
-  virtual int Decode(ByteArray* buffer, int max_values) {
-    max_values = std::min(max_values, num_values_);
-    std::vector<int> lengths(max_values);
-    len_decoder_.Decode(lengths.data(), max_values);
-    for (int i = 0; i < max_values; ++i) {
-      buffer[i].len = lengths[i];
-      buffer[i].ptr = data_;
-      data_ += lengths[i];
-      len_ -= lengths[i];
-    }
-    num_values_ -= max_values;
-    return max_values;
-  }
-
- private:
-  using Decoder<ByteArrayType>::num_values_;
-  DeltaBitPackDecoder<Int32Type> len_decoder_;
-  const uint8_t* data_;
-  int len_;
-};
-
-// ----------------------------------------------------------------------
-// DELTA_BYTE_ARRAY
-
-class DeltaByteArrayDecoder : public Decoder<ByteArrayType> {
- public:
-  explicit DeltaByteArrayDecoder(
-      const ColumnDescriptor* descr,
-      ::arrow::MemoryPool* pool = ::arrow::default_memory_pool())
-      : Decoder<ByteArrayType>(descr, Encoding::DELTA_BYTE_ARRAY),
-        prefix_len_decoder_(nullptr, pool),
-        suffix_decoder_(nullptr, pool),
-        last_value_(0, nullptr) {}
-
-  virtual void SetData(int num_values, const uint8_t* data, int len) {
-    num_values_ = num_values;
-    if (len == 0) return;
-    int prefix_len_length = *reinterpret_cast<const int*>(data);
-    data += 4;
-    len -= 4;
-    prefix_len_decoder_.SetData(num_values, data, prefix_len_length);
-    data += prefix_len_length;
-    len -= prefix_len_length;
-    suffix_decoder_.SetData(num_values, data, len);
-  }
-
-  // TODO: this doesn't work and requires memory management. We need to allocate
-  // new strings to store the results.
-  virtual int Decode(ByteArray* buffer, int max_values) {
-    max_values = std::min(max_values, num_values_);
-    for (int i = 0; i < max_values; ++i) {
-      int prefix_len = 0;
-      prefix_len_decoder_.Decode(&prefix_len, 1);
-      ByteArray suffix = {0, nullptr};
-      suffix_decoder_.Decode(&suffix, 1);
-      buffer[i].len = prefix_len + suffix.len;
-
-      uint8_t* result = reinterpret_cast<uint8_t*>(malloc(buffer[i].len));
-      memcpy(result, last_value_.ptr, prefix_len);
-      memcpy(result + prefix_len, suffix.ptr, suffix.len);
-
-      buffer[i].ptr = result;
-      last_value_ = buffer[i];
-    }
-    num_values_ -= max_values;
-    return max_values;
-  }
-
- private:
-  using Decoder<ByteArrayType>::num_values_;
-
-  DeltaBitPackDecoder<Int32Type> prefix_len_decoder_;
-  DeltaLengthByteArrayDecoder suffix_decoder_;
-  ByteArray last_value_;
-};
-
-}  // namespace parquet
-
-#endif  // PARQUET_ENCODING_INTERNAL_H
diff --git a/src/parquet/encoding-test.cc b/src/parquet/encoding-test.cc
deleted file mode 100644
index 50e1394..0000000
--- a/src/parquet/encoding-test.cc
+++ /dev/null
@@ -1,313 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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.
-
-#include <gtest/gtest.h>
-#include <cstdint>
-#include <cstdlib>
-#include <cstring>
-#include <string>
-#include <vector>
-
-#include "arrow/util/bit-util.h"
-
-#include "parquet/encoding-internal.h"
-#include "parquet/schema.h"
-#include "parquet/types.h"
-#include "parquet/util/memory.h"
-#include "parquet/util/test-common.h"
-
-using arrow::default_memory_pool;
-using arrow::MemoryPool;
-
-using std::string;
-using std::vector;
-
-namespace parquet {
-
-namespace test {
-
-TEST(VectorBooleanTest, TestEncodeDecode) {
-  // PARQUET-454
-  int nvalues = 10000;
-  int nbytes = static_cast<int>(BitUtil::BytesForBits(nvalues));
-
-  // seed the prng so failure is deterministic
-  vector<bool> draws = flip_coins_seed(nvalues, 0.5, 0);
-
-  PlainEncoder<BooleanType> encoder(nullptr);
-  PlainDecoder<BooleanType> decoder(nullptr);
-
-  encoder.Put(draws, nvalues);
-
-  std::shared_ptr<Buffer> encode_buffer = encoder.FlushValues();
-  ASSERT_EQ(nbytes, encode_buffer->size());
-
-  vector<uint8_t> decode_buffer(nbytes);
-  const uint8_t* decode_data = &decode_buffer[0];
-
-  decoder.SetData(nvalues, encode_buffer->data(),
-                  static_cast<int>(encode_buffer->size()));
-  int values_decoded = decoder.Decode(&decode_buffer[0], nvalues);
-  ASSERT_EQ(nvalues, values_decoded);
-
-  for (int i = 0; i < nvalues; ++i) {
-    ASSERT_EQ(draws[i], BitUtil::GetBit(decode_data, i)) << i;
-  }
-}
-
-// ----------------------------------------------------------------------
-// test data generation
-
-template <typename T>
-void GenerateData(int num_values, T* out, vector<uint8_t>* heap) {
-  // seed the prng so failure is deterministic
-  random_numbers(num_values, 0, std::numeric_limits<T>::min(),
-                 std::numeric_limits<T>::max(), out);
-}
-
-template <>
-void GenerateData<bool>(int num_values, bool* out, vector<uint8_t>* heap) {
-  // seed the prng so failure is deterministic
-  random_bools(num_values, 0.5, 0, out);
-}
-
-template <>
-void GenerateData<Int96>(int num_values, Int96* out, vector<uint8_t>* heap) {
-  // seed the prng so failure is deterministic
-  random_Int96_numbers(num_values, 0, std::numeric_limits<int32_t>::min(),
-                       std::numeric_limits<int32_t>::max(), out);
-}
-
-template <>
-void GenerateData<ByteArray>(int num_values, ByteArray* out, vector<uint8_t>* heap) {
-  // seed the prng so failure is deterministic
-  int max_byte_array_len = 12;
-  heap->resize(num_values * max_byte_array_len);
-  random_byte_array(num_values, 0, heap->data(), out, 2, max_byte_array_len);
-}
-
-static int flba_length = 8;
-
-template <>
-void GenerateData<FLBA>(int num_values, FLBA* out, vector<uint8_t>* heap) {
-  // seed the prng so failure is deterministic
-  heap->resize(num_values * flba_length);
-  random_fixed_byte_array(num_values, 0, heap->data(), flba_length, out);
-}
-
-template <typename T>
-void VerifyResults(T* result, T* expected, int num_values) {
-  for (int i = 0; i < num_values; ++i) {
-    ASSERT_EQ(expected[i], result[i]) << i;
-  }
-}
-
-template <>
-void VerifyResults<FLBA>(FLBA* result, FLBA* expected, int num_values) {
-  for (int i = 0; i < num_values; ++i) {
-    ASSERT_EQ(0, memcmp(expected[i].ptr, result[i].ptr, flba_length)) << i;
-  }
-}
-
-// ----------------------------------------------------------------------
-// Create some column descriptors
-
-template <typename DType>
-std::shared_ptr<ColumnDescriptor> ExampleDescr() {
-  auto node = schema::PrimitiveNode::Make("name", Repetition::OPTIONAL, DType::type_num);
-  return std::make_shared<ColumnDescriptor>(node, 0, 0);
-}
-
-template <>
-std::shared_ptr<ColumnDescriptor> ExampleDescr<FLBAType>() {
-  auto node = schema::PrimitiveNode::Make("name", Repetition::OPTIONAL,
-                                          Type::FIXED_LEN_BYTE_ARRAY,
-                                          LogicalType::DECIMAL, flba_length, 10, 2);
-  return std::make_shared<ColumnDescriptor>(node, 0, 0);
-}
-
-// ----------------------------------------------------------------------
-// Plain encoding tests
-
-template <typename Type>
-class TestEncodingBase : public ::testing::Test {
- public:
-  typedef typename Type::c_type T;
-  static constexpr int TYPE = Type::type_num;
-
-  void SetUp() {
-    descr_ = ExampleDescr<Type>();
-    type_length_ = descr_->type_length();
-    allocator_ = default_memory_pool();
-  }
-
-  void TearDown() { pool_.FreeAll(); }
-
-  void InitData(int nvalues, int repeats) {
-    num_values_ = nvalues * repeats;
-    input_bytes_.resize(num_values_ * sizeof(T));
-    output_bytes_.resize(num_values_ * sizeof(T));
-    draws_ = reinterpret_cast<T*>(input_bytes_.data());
-    decode_buf_ = reinterpret_cast<T*>(output_bytes_.data());
-    GenerateData<T>(nvalues, draws_, &data_buffer_);
-
-    // add some repeated values
-    for (int j = 1; j < repeats; ++j) {
-      for (int i = 0; i < nvalues; ++i) {
-        draws_[nvalues * j + i] = draws_[i];
-      }
-    }
-  }
-
-  virtual void CheckRoundtrip() = 0;
-
-  void Execute(int nvalues, int repeats) {
-    InitData(nvalues, repeats);
-    CheckRoundtrip();
-  }
-
- protected:
-  ChunkedAllocator pool_;
-  MemoryPool* allocator_;
-
-  int num_values_;
-  int type_length_;
-  T* draws_;
-  T* decode_buf_;
-  vector<uint8_t> input_bytes_;
-  vector<uint8_t> output_bytes_;
-  vector<uint8_t> data_buffer_;
-
-  std::shared_ptr<Buffer> encode_buffer_;
-  std::shared_ptr<ColumnDescriptor> descr_;
-};
-
-// Member variables are not visible to templated subclasses. Possibly figure
-// out an alternative to this class layering at some point
-#define USING_BASE_MEMBERS()                    \
-  using TestEncodingBase<Type>::pool_;          \
-  using TestEncodingBase<Type>::allocator_;     \
-  using TestEncodingBase<Type>::descr_;         \
-  using TestEncodingBase<Type>::num_values_;    \
-  using TestEncodingBase<Type>::draws_;         \
-  using TestEncodingBase<Type>::data_buffer_;   \
-  using TestEncodingBase<Type>::type_length_;   \
-  using TestEncodingBase<Type>::encode_buffer_; \
-  using TestEncodingBase<Type>::decode_buf_
-
-template <typename Type>
-class TestPlainEncoding : public TestEncodingBase<Type> {
- public:
-  typedef typename Type::c_type T;
-  static constexpr int TYPE = Type::type_num;
-
-  virtual void CheckRoundtrip() {
-    PlainEncoder<Type> encoder(descr_.get());
-    PlainDecoder<Type> decoder(descr_.get());
-    encoder.Put(draws_, num_values_);
-    encode_buffer_ = encoder.FlushValues();
-
-    decoder.SetData(num_values_, encode_buffer_->data(),
-                    static_cast<int>(encode_buffer_->size()));
-    int values_decoded = decoder.Decode(decode_buf_, num_values_);
-    ASSERT_EQ(num_values_, values_decoded);
-    ASSERT_NO_FATAL_FAILURE(VerifyResults<T>(decode_buf_, draws_, num_values_));
-  }
-
- protected:
-  USING_BASE_MEMBERS();
-};
-
-TYPED_TEST_CASE(TestPlainEncoding, ParquetTypes);
-
-TYPED_TEST(TestPlainEncoding, BasicRoundTrip) {
-  ASSERT_NO_FATAL_FAILURE(this->Execute(10000, 1));
-}
-
-// ----------------------------------------------------------------------
-// Dictionary encoding tests
-
-typedef ::testing::Types<Int32Type, Int64Type, Int96Type, FloatType, DoubleType,
-                         ByteArrayType, FLBAType>
-    DictEncodedTypes;
-
-template <typename Type>
-class TestDictionaryEncoding : public TestEncodingBase<Type> {
- public:
-  typedef typename Type::c_type T;
-  static constexpr int TYPE = Type::type_num;
-
-  void CheckRoundtrip() {
-    std::vector<uint8_t> valid_bits(BitUtil::BytesForBits(num_values_) + 1, 255);
-    DictEncoder<Type> encoder(descr_.get(), &pool_);
-
-    ASSERT_NO_THROW(encoder.Put(draws_, num_values_));
-    dict_buffer_ = AllocateBuffer(default_memory_pool(), encoder.dict_encoded_size());
-    encoder.WriteDict(dict_buffer_->mutable_data());
-    std::shared_ptr<Buffer> indices = encoder.FlushValues();
-
-    DictEncoder<Type> spaced_encoder(descr_.get(), &pool_);
-    // PutSpaced should lead to the same results
-    ASSERT_NO_THROW(spaced_encoder.PutSpaced(draws_, num_values_, valid_bits.data(), 0));
-    std::shared_ptr<Buffer> indices_from_spaced = spaced_encoder.FlushValues();
-    ASSERT_TRUE(indices_from_spaced->Equals(*indices));
-
-    PlainDecoder<Type> dict_decoder(descr_.get());
-    dict_decoder.SetData(encoder.num_entries(), dict_buffer_->data(),
-                         static_cast<int>(dict_buffer_->size()));
-
-    DictionaryDecoder<Type> decoder(descr_.get());
-    decoder.SetDict(&dict_decoder);
-
-    decoder.SetData(num_values_, indices->data(), static_cast<int>(indices->size()));
-    int values_decoded = decoder.Decode(decode_buf_, num_values_);
-    ASSERT_EQ(num_values_, values_decoded);
-
-    // TODO(wesm): The DictionaryDecoder must stay alive because the decoded
-    // values' data is owned by a buffer inside the DictionaryEncoder. We
-    // should revisit when data lifetime is reviewed more generally.
-    ASSERT_NO_FATAL_FAILURE(VerifyResults<T>(decode_buf_, draws_, num_values_));
-
-    // Also test spaced decoding
-    decoder.SetData(num_values_, indices->data(), static_cast<int>(indices->size()));
-    values_decoded =
-        decoder.DecodeSpaced(decode_buf_, num_values_, 0, valid_bits.data(), 0);
-    ASSERT_EQ(num_values_, values_decoded);
-    ASSERT_NO_FATAL_FAILURE(VerifyResults<T>(decode_buf_, draws_, num_values_));
-  }
-
- protected:
-  USING_BASE_MEMBERS();
-  std::shared_ptr<ResizableBuffer> dict_buffer_;
-};
-
-TYPED_TEST_CASE(TestDictionaryEncoding, DictEncodedTypes);
-
-TYPED_TEST(TestDictionaryEncoding, BasicRoundTrip) {
-  ASSERT_NO_FATAL_FAILURE(this->Execute(2500, 2));
-}
-
-TEST(TestDictionaryEncoding, CannotDictDecodeBoolean) {
-  PlainDecoder<BooleanType> dict_decoder(nullptr);
-  DictionaryDecoder<BooleanType> decoder(nullptr);
-
-  ASSERT_THROW(decoder.SetDict(&dict_decoder), ParquetException);
-}
-
-}  // namespace test
-
-}  // namespace parquet
diff --git a/src/parquet/encoding.h b/src/parquet/encoding.h
deleted file mode 100644
index 006f22f..0000000
--- a/src/parquet/encoding.h
+++ /dev/null
@@ -1,152 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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.
-
-#ifndef PARQUET_ENCODING_H
-#define PARQUET_ENCODING_H
-
-#include <cstdint>
-#include <memory>
-#include <sstream>
-
-#include "arrow/status.h"
-#include "arrow/util/bit-util.h"
-
-#include "parquet/exception.h"
-#include "parquet/schema.h"
-#include "parquet/types.h"
-#include "parquet/util/memory.h"
-
-namespace parquet {
-
-class ColumnDescriptor;
-
-// Base class for value encoders. Since encoders may or not have state (e.g.,
-// dictionary encoding) we use a class instance to maintain any state.
-//
-// TODO(wesm): Encode interface API is temporary
-template <typename DType>
-class Encoder {
- public:
-  typedef typename DType::c_type T;
-
-  virtual ~Encoder() {}
-
-  virtual int64_t EstimatedDataEncodedSize() = 0;
-  virtual std::shared_ptr<Buffer> FlushValues() = 0;
-  virtual void Put(const T* src, int num_values) = 0;
-  virtual void PutSpaced(const T* src, int num_values, const uint8_t* valid_bits,
-                         int64_t valid_bits_offset) {
-    std::shared_ptr<ResizableBuffer> buffer;
-    auto status =
-        ::arrow::AllocateResizableBuffer(pool_, num_values * sizeof(T), &buffer);
-    if (!status.ok()) {
-      std::ostringstream ss;
-      ss << "AllocateResizableBuffer failed in Encoder.PutSpaced in " << __FILE__
-         << ", on line " << __LINE__;
-      throw ParquetException(ss.str());
-    }
-    int32_t num_valid_values = 0;
-    ::arrow::internal::BitmapReader valid_bits_reader(valid_bits, valid_bits_offset,
-                                                      num_values);
-    T* data = reinterpret_cast<T*>(buffer->mutable_data());
-    for (int32_t i = 0; i < num_values; i++) {
-      if (valid_bits_reader.IsSet()) {
-        data[num_valid_values++] = src[i];
-      }
-      valid_bits_reader.Next();
-    }
-    Put(data, num_valid_values);
-  }
-
-  Encoding::type encoding() const { return encoding_; }
-
- protected:
-  explicit Encoder(const ColumnDescriptor* descr, Encoding::type encoding,
-                   ::arrow::MemoryPool* pool)
-      : descr_(descr), encoding_(encoding), pool_(pool) {}
-
-  // For accessing type-specific metadata, like FIXED_LEN_BYTE_ARRAY
-  const ColumnDescriptor* descr_;
-  const Encoding::type encoding_;
-  ::arrow::MemoryPool* pool_;
-};
-
-// The Decoder template is parameterized on parquet::DataType subclasses
-template <typename DType>
-class Decoder {
- public:
-  typedef typename DType::c_type T;
-
-  virtual ~Decoder() {}
-
-  // Sets the data for a new page. This will be called multiple times on the same
-  // decoder and should reset all internal state.
-  virtual void SetData(int num_values, const uint8_t* data, int len) = 0;
-
-  // Subclasses should override the ones they support. In each of these functions,
-  // the decoder would decode put to 'max_values', storing the result in 'buffer'.
-  // The function returns the number of values decoded, which should be max_values
-  // except for end of the current data page.
-  virtual int Decode(T* buffer, int max_values) = 0;
-
-  // Decode the values in this data page but leave spaces for null entries.
-  //
-  // num_values is the size of the def_levels and buffer arrays including the number of
-  // null values.
-  virtual int DecodeSpaced(T* buffer, int num_values, int null_count,
-                           const uint8_t* valid_bits, int64_t valid_bits_offset) {
-    int values_to_read = num_values - null_count;
-    int values_read = Decode(buffer, values_to_read);
-    if (values_read != values_to_read) {
-      throw ParquetException("Number of values / definition_levels read did not match");
-    }
-
-    // Depending on the number of nulls, some of the value slots in buffer may
-    // be uninitialized, and this will cause valgrind warnings / potentially UB
-    memset(buffer + values_read, 0, (num_values - values_read) * sizeof(T));
-
-    // Add spacing for null entries. As we have filled the buffer from the front,
-    // we need to add the spacing from the back.
-    int values_to_move = values_read;
-    for (int i = num_values - 1; i >= 0; i--) {
-      if (::arrow::BitUtil::GetBit(valid_bits, valid_bits_offset + i)) {
-        buffer[i] = buffer[--values_to_move];
-      }
-    }
-    return num_values;
-  }
-
-  // Returns the number of values left (for the last call to SetData()). This is
-  // the number of values left in this page.
-  int values_left() const { return num_values_; }
-
-  Encoding::type encoding() const { return encoding_; }
-
- protected:
-  explicit Decoder(const ColumnDescriptor* descr, Encoding::type encoding)
-      : descr_(descr), encoding_(encoding), num_values_(0) {}
-
-  // For accessing type-specific metadata, like FIXED_LEN_BYTE_ARRAY
-  const ColumnDescriptor* descr_;
-
-  const Encoding::type encoding_;
-  int num_values_;
-};
-
-}  // namespace parquet
-
-#endif  // PARQUET_ENCODING_H
diff --git a/src/parquet/exception.cc b/src/parquet/exception.cc
deleted file mode 100644
index 5f5525c..0000000
--- a/src/parquet/exception.cc
+++ /dev/null
@@ -1,57 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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.
-
-#include "parquet/exception.h"
-
-#include <exception>
-#include <sstream>
-#include <string>
-
-#include "parquet/util/macros.h"
-
-namespace parquet {
-
-PARQUET_NORETURN void ParquetException::EofException(const std::string& msg) {
-  std::stringstream ss;
-  ss << "Unexpected end of stream";
-  if (!msg.empty()) {
-    ss << ": " << msg;
-  }
-  throw ParquetException(ss.str());
-}
-
-PARQUET_NORETURN void ParquetException::NYI(const std::string& msg) {
-  std::stringstream ss;
-  ss << "Not yet implemented: " << msg << ".";
-  throw ParquetException(ss.str());
-}
-
-PARQUET_NORETURN void ParquetException::Throw(const std::string& msg) {
-  throw ParquetException(msg);
-}
-
-ParquetException::ParquetException(const char* msg) : msg_(msg) {}
-
-ParquetException::ParquetException(const std::string& msg) : msg_(msg) {}
-
-ParquetException::ParquetException(const char* msg, std::exception& e) : msg_(msg) {}
-
-ParquetException::~ParquetException() throw() {}
-
-const char* ParquetException::what() const throw() { return msg_.c_str(); }
-
-}  // namespace parquet
diff --git a/src/parquet/exception.h b/src/parquet/exception.h
deleted file mode 100644
index 08629be..0000000
--- a/src/parquet/exception.h
+++ /dev/null
@@ -1,79 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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.
-
-#ifndef PARQUET_EXCEPTION_H
-#define PARQUET_EXCEPTION_H
-
-#include <exception>
-#include <sstream>
-#include <string>
-
-#include "arrow/status.h"
-
-#include "parquet/util/macros.h"
-#include "parquet/util/visibility.h"
-
-// PARQUET-1085
-#if !defined(ARROW_UNUSED)
-#define ARROW_UNUSED(x) UNUSED(x)
-#endif
-
-#define PARQUET_CATCH_NOT_OK(s)                    \
-  try {                                            \
-    (s);                                           \
-  } catch (const ::parquet::ParquetException& e) { \
-    return ::arrow::Status::IOError(e.what());     \
-  }
-
-#define PARQUET_IGNORE_NOT_OK(s) \
-  do {                           \
-    ::arrow::Status _s = (s);    \
-    ARROW_UNUSED(_s);            \
-  } while (0)
-
-#define PARQUET_THROW_NOT_OK(s)                     \
-  do {                                              \
-    ::arrow::Status _s = (s);                       \
-    if (!_s.ok()) {                                 \
-      std::stringstream ss;                         \
-      ss << "Arrow error: " << _s.ToString();       \
-      ::parquet::ParquetException::Throw(ss.str()); \
-    }                                               \
-  } while (0)
-
-namespace parquet {
-
-class PARQUET_EXPORT ParquetException : public std::exception {
- public:
-  PARQUET_NORETURN static void EofException(const std::string& msg = "");
-  PARQUET_NORETURN static void NYI(const std::string& msg);
-  PARQUET_NORETURN static void Throw(const std::string& msg);
-
-  explicit ParquetException(const char* msg);
-  explicit ParquetException(const std::string& msg);
-  explicit ParquetException(const char* msg, exception& e);
-
-  virtual ~ParquetException() throw();
-  virtual const char* what() const throw();
-
- private:
-  std::string msg_;
-};
-
-}  // namespace parquet
-
-#endif  // PARQUET_EXCEPTION_H
diff --git a/src/parquet/file-deserialize-test.cc b/src/parquet/file-deserialize-test.cc
deleted file mode 100644
index 6b01ac2..0000000
--- a/src/parquet/file-deserialize-test.cc
+++ /dev/null
@@ -1,299 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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.
-
-#include <gtest/gtest.h>
-
-#include <algorithm>
-#include <cstdint>
-#include <cstdlib>
-#include <cstring>
-#include <exception>
-#include <memory>
-#include <string>
-#include <vector>
-
-#include "parquet/column_reader.h"
-#include "parquet/exception.h"
-#include "parquet/file_reader.h"
-#include "parquet/parquet_types.h"
-#include "parquet/thrift.h"
-#include "parquet/types.h"
-#include "parquet/util/memory.h"
-#include "parquet/util/test-common.h"
-
-namespace parquet {
-
-#define ASSERT_OK(expr)         \
-  do {                          \
-    ::arrow::Status s = (expr); \
-    if (!s.ok()) {              \
-      FAIL() << s.ToString();   \
-    }                           \
-  } while (0)
-
-using ::arrow::io::BufferReader;
-
-// Adds page statistics occupying a certain amount of bytes (for testing very
-// large page headers)
-static inline void AddDummyStats(int stat_size, format::DataPageHeader& data_page) {
-  std::vector<uint8_t> stat_bytes(stat_size);
-  // Some non-zero value
-  std::fill(stat_bytes.begin(), stat_bytes.end(), 1);
-  data_page.statistics.__set_max(
-      std::string(reinterpret_cast<const char*>(stat_bytes.data()), stat_size));
-  data_page.__isset.statistics = true;
-}
-
-class TestPageSerde : public ::testing::Test {
- public:
-  void SetUp() {
-    data_page_header_.encoding = format::Encoding::PLAIN;
-    data_page_header_.definition_level_encoding = format::Encoding::RLE;
-    data_page_header_.repetition_level_encoding = format::Encoding::RLE;
-
-    ResetStream();
-  }
-
-  void InitSerializedPageReader(int64_t num_rows,
-                                Compression::type codec = Compression::UNCOMPRESSED) {
-    EndStream();
-    std::unique_ptr<InputStream> stream;
-    stream.reset(new InMemoryInputStream(out_buffer_));
-    page_reader_ = PageReader::Open(std::move(stream), num_rows, codec);
-  }
-
-  void WriteDataPageHeader(int max_serialized_len = 1024, int32_t uncompressed_size = 0,
-                           int32_t compressed_size = 0) {
-    // Simplifying writing serialized data page headers which may or may not
-    // have meaningful data associated with them
-
-    // Serialize the Page header
-    page_header_.__set_data_page_header(data_page_header_);
-    page_header_.uncompressed_page_size = uncompressed_size;
-    page_header_.compressed_page_size = compressed_size;
-    page_header_.type = format::PageType::DATA_PAGE;
-
-    ASSERT_NO_THROW(
-        SerializeThriftMsg(&page_header_, max_serialized_len, out_stream_.get()));
-  }
-
-  void ResetStream() { out_stream_.reset(new InMemoryOutputStream); }
-
-  void EndStream() { out_buffer_ = out_stream_->GetBuffer(); }
-
- protected:
-  std::unique_ptr<InMemoryOutputStream> out_stream_;
-  std::shared_ptr<Buffer> out_buffer_;
-
-  std::unique_ptr<PageReader> page_reader_;
-  format::PageHeader page_header_;
-  format::DataPageHeader data_page_header_;
-};
-
-void CheckDataPageHeader(const format::DataPageHeader expected, const Page* page) {
-  ASSERT_EQ(PageType::DATA_PAGE, page->type());
-
-  const DataPage* data_page = static_cast<const DataPage*>(page);
-  ASSERT_EQ(expected.num_values, data_page->num_values());
-  ASSERT_EQ(expected.encoding, data_page->encoding());
-  ASSERT_EQ(expected.definition_level_encoding, data_page->definition_level_encoding());
-  ASSERT_EQ(expected.repetition_level_encoding, data_page->repetition_level_encoding());
-
-  if (expected.statistics.__isset.max) {
-    ASSERT_EQ(expected.statistics.max, data_page->statistics().max());
-  }
-  if (expected.statistics.__isset.min) {
-    ASSERT_EQ(expected.statistics.min, data_page->statistics().min());
-  }
-}
-
-TEST_F(TestPageSerde, DataPage) {
-  format::PageHeader out_page_header;
-
-  int stats_size = 512;
-  const int32_t num_rows = 4444;
-  AddDummyStats(stats_size, data_page_header_);
-  data_page_header_.num_values = num_rows;
-
-  ASSERT_NO_FATAL_FAILURE(WriteDataPageHeader());
-  InitSerializedPageReader(num_rows);
-  std::shared_ptr<Page> current_page = page_reader_->NextPage();
-  ASSERT_NO_FATAL_FAILURE(CheckDataPageHeader(data_page_header_, current_page.get()));
-}
-
-TEST_F(TestPageSerde, TestLargePageHeaders) {
-  int stats_size = 256 * 1024;  // 256 KB
-  AddDummyStats(stats_size, data_page_header_);
-
-  // Any number to verify metadata roundtrip
-  const int32_t num_rows = 4141;
-  data_page_header_.num_values = num_rows;
-
-  int max_header_size = 512 * 1024;  // 512 KB
-  ASSERT_NO_FATAL_FAILURE(WriteDataPageHeader(max_header_size));
-  ASSERT_GE(max_header_size, out_stream_->Tell());
-
-  // check header size is between 256 KB to 16 MB
-  ASSERT_LE(stats_size, out_stream_->Tell());
-  ASSERT_GE(kDefaultMaxPageHeaderSize, out_stream_->Tell());
-
-  InitSerializedPageReader(num_rows);
-  std::shared_ptr<Page> current_page = page_reader_->NextPage();
-  ASSERT_NO_FATAL_FAILURE(CheckDataPageHeader(data_page_header_, current_page.get()));
-}
-
-TEST_F(TestPageSerde, TestFailLargePageHeaders) {
-  const int32_t num_rows = 1337;  // dummy value
-
-  int stats_size = 256 * 1024;  // 256 KB
-  AddDummyStats(stats_size, data_page_header_);
-
-  // Serialize the Page header
-  int max_header_size = 512 * 1024;  // 512 KB
-  ASSERT_NO_FATAL_FAILURE(WriteDataPageHeader(max_header_size));
-  ASSERT_GE(max_header_size, out_stream_->Tell());
-
-  int smaller_max_size = 128 * 1024;
-  ASSERT_LE(smaller_max_size, out_stream_->Tell());
-  InitSerializedPageReader(num_rows);
-
-  // Set the max page header size to 128 KB, which is less than the current
-  // header size
-  page_reader_->set_max_page_header_size(smaller_max_size);
-  ASSERT_THROW(page_reader_->NextPage(), ParquetException);
-}
-
-TEST_F(TestPageSerde, Compression) {
-  Compression::type codec_types[5] = {Compression::GZIP, Compression::SNAPPY,
-                                      Compression::BROTLI, Compression::LZ4,
-                                      Compression::ZSTD};
-
-  const int32_t num_rows = 32;  // dummy value
-  data_page_header_.num_values = num_rows;
-
-  int num_pages = 10;
-
-  std::vector<std::vector<uint8_t>> faux_data;
-  faux_data.resize(num_pages);
-  for (int i = 0; i < num_pages; ++i) {
-    // The pages keep getting larger
-    int page_size = (i + 1) * 64;
-    test::random_bytes(page_size, 0, &faux_data[i]);
-  }
-  for (auto codec_type : codec_types) {
-    std::unique_ptr<::arrow::Codec> codec = GetCodecFromArrow(codec_type);
-
-    std::vector<uint8_t> buffer;
-    for (int i = 0; i < num_pages; ++i) {
-      const uint8_t* data = faux_data[i].data();
-      int data_size = static_cast<int>(faux_data[i].size());
-
-      int64_t max_compressed_size = codec->MaxCompressedLen(data_size, data);
-      buffer.resize(max_compressed_size);
-
-      int64_t actual_size;
-      ASSERT_OK(codec->Compress(data_size, data, max_compressed_size, &buffer[0],
-                                &actual_size));
-
-      ASSERT_NO_FATAL_FAILURE(
-          WriteDataPageHeader(1024, data_size, static_cast<int32_t>(actual_size)));
-      out_stream_->Write(buffer.data(), actual_size);
-    }
-
-    InitSerializedPageReader(num_rows * num_pages, codec_type);
-
-    std::shared_ptr<Page> page;
-    const DataPage* data_page;
-    for (int i = 0; i < num_pages; ++i) {
-      int data_size = static_cast<int>(faux_data[i].size());
-      page = page_reader_->NextPage();
-      data_page = static_cast<const DataPage*>(page.get());
-      ASSERT_EQ(data_size, data_page->size());
-      ASSERT_EQ(0, memcmp(faux_data[i].data(), data_page->data(), data_size));
-    }
-
-    ResetStream();
-  }
-}
-
-TEST_F(TestPageSerde, LZONotSupported) {
-  // Must await PARQUET-530
-  int data_size = 1024;
-  std::vector<uint8_t> faux_data(data_size);
-  ASSERT_NO_FATAL_FAILURE(WriteDataPageHeader(1024, data_size, data_size));
-  out_stream_->Write(faux_data.data(), data_size);
-  ASSERT_THROW(InitSerializedPageReader(data_size, Compression::LZO), ParquetException);
-}
-
-// ----------------------------------------------------------------------
-// File structure tests
-
-class TestParquetFileReader : public ::testing::Test {
- public:
-  void AssertInvalidFileThrows(const std::shared_ptr<Buffer>& buffer) {
-    reader_.reset(new ParquetFileReader());
-
-    auto reader = std::make_shared<BufferReader>(buffer);
-    auto wrapper = std::unique_ptr<ArrowInputFile>(new ArrowInputFile(reader));
-
-    ASSERT_THROW(reader_->Open(ParquetFileReader::Contents::Open(std::move(wrapper))),
-                 ParquetException);
-  }
-
- protected:
-  std::unique_ptr<ParquetFileReader> reader_;
-};
-
-TEST_F(TestParquetFileReader, InvalidHeader) {
-  const char* bad_header = "PAR2";
-
-  auto buffer = std::make_shared<Buffer>(reinterpret_cast<const uint8_t*>(bad_header),
-                                         strlen(bad_header));
-  ASSERT_NO_FATAL_FAILURE(AssertInvalidFileThrows(buffer));
-}
-
-TEST_F(TestParquetFileReader, InvalidFooter) {
-  // File is smaller than FOOTER_SIZE
-  const char* bad_file = "PAR1PAR";
-  auto buffer = std::make_shared<Buffer>(reinterpret_cast<const uint8_t*>(bad_file),
-                                         strlen(bad_file));
-  ASSERT_NO_FATAL_FAILURE(AssertInvalidFileThrows(buffer));
-
-  // Magic number incorrect
-  const char* bad_file2 = "PAR1PAR2";
-  buffer = std::make_shared<Buffer>(reinterpret_cast<const uint8_t*>(bad_file2),
-                                    strlen(bad_file2));
-  ASSERT_NO_FATAL_FAILURE(AssertInvalidFileThrows(buffer));
-}
-
-TEST_F(TestParquetFileReader, IncompleteMetadata) {
-  InMemoryOutputStream stream;
-
-  const char* magic = "PAR1";
-
-  stream.Write(reinterpret_cast<const uint8_t*>(magic), strlen(magic));
-  std::vector<uint8_t> bytes(10);
-  stream.Write(bytes.data(), bytes.size());
-  uint32_t metadata_len = 24;
-  stream.Write(reinterpret_cast<const uint8_t*>(&metadata_len), sizeof(uint32_t));
-  stream.Write(reinterpret_cast<const uint8_t*>(magic), strlen(magic));
-
-  auto buffer = stream.GetBuffer();
-  ASSERT_NO_FATAL_FAILURE(AssertInvalidFileThrows(buffer));
-}
-
-}  // namespace parquet
diff --git a/src/parquet/file-serialize-test.cc b/src/parquet/file-serialize-test.cc
deleted file mode 100644
index 750faa2..0000000
--- a/src/parquet/file-serialize-test.cc
+++ /dev/null
@@ -1,310 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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.
-
-#include <gtest/gtest.h>
-
-#include "parquet/column_reader.h"
-#include "parquet/column_writer.h"
-#include "parquet/file_reader.h"
-#include "parquet/file_writer.h"
-#include "parquet/test-specialization.h"
-#include "parquet/test-util.h"
-#include "parquet/types.h"
-#include "parquet/util/memory.h"
-
-namespace parquet {
-
-using schema::GroupNode;
-using schema::NodePtr;
-using schema::PrimitiveNode;
-
-namespace test {
-
-template <typename TestType>
-class TestSerialize : public PrimitiveTypedTest<TestType> {
- public:
-  typedef typename TestType::c_type T;
-
-  void SetUp() {
-    num_columns_ = 4;
-    num_rowgroups_ = 4;
-    rows_per_rowgroup_ = 50;
-    rows_per_batch_ = 10;
-    this->SetUpSchema(Repetition::OPTIONAL, num_columns_);
-  }
-
- protected:
-  int num_columns_;
-  int num_rowgroups_;
-  int rows_per_rowgroup_;
-  int rows_per_batch_;
-
-  void FileSerializeTest(Compression::type codec_type) {
-    std::shared_ptr<InMemoryOutputStream> sink(new InMemoryOutputStream());
-    auto gnode = std::static_pointer_cast<GroupNode>(this->node_);
-
-    WriterProperties::Builder prop_builder;
-
-    for (int i = 0; i < num_columns_; ++i) {
-      prop_builder.compression(this->schema_.Column(i)->name(), codec_type);
-    }
-    std::shared_ptr<WriterProperties> writer_properties = prop_builder.build();
-
-    auto file_writer = ParquetFileWriter::Open(sink, gnode, writer_properties);
-    this->GenerateData(rows_per_rowgroup_);
-    for (int rg = 0; rg < num_rowgroups_ / 2; ++rg) {
-      RowGroupWriter* row_group_writer;
-      row_group_writer = file_writer->AppendRowGroup();
-      for (int col = 0; col < num_columns_; ++col) {
-        auto column_writer =
-            static_cast<TypedColumnWriter<TestType>*>(row_group_writer->NextColumn());
-        column_writer->WriteBatch(rows_per_rowgroup_, this->def_levels_.data(), nullptr,
-                                  this->values_ptr_);
-        column_writer->Close();
-        // Ensure column() API which is specific to BufferedRowGroup cannot be called
-        ASSERT_THROW(row_group_writer->column(col), ParquetException);
-      }
-
-      row_group_writer->Close();
-    }
-    // Write half BufferedRowGroups
-    for (int rg = 0; rg < num_rowgroups_ / 2; ++rg) {
-      RowGroupWriter* row_group_writer;
-      row_group_writer = file_writer->AppendBufferedRowGroup();
-      for (int batch = 0; batch < (rows_per_rowgroup_ / rows_per_batch_); ++batch) {
-        for (int col = 0; col < num_columns_; ++col) {
-          auto column_writer =
-              static_cast<TypedColumnWriter<TestType>*>(row_group_writer->column(col));
-          column_writer->WriteBatch(
-              rows_per_batch_, this->def_levels_.data() + (batch * rows_per_batch_),
-              nullptr, this->values_ptr_ + (batch * rows_per_batch_));
-          // Ensure NextColumn() API which is specific to RowGroup cannot be called
-          ASSERT_THROW(row_group_writer->NextColumn(), ParquetException);
-        }
-      }
-      for (int col = 0; col < num_columns_; ++col) {
-        auto column_writer =
-            static_cast<TypedColumnWriter<TestType>*>(row_group_writer->column(col));
-        column_writer->Close();
-      }
-      row_group_writer->Close();
-    }
-    file_writer->Close();
-
-    auto buffer = sink->GetBuffer();
-    int num_rows_ = num_rowgroups_ * rows_per_rowgroup_;
-
-    auto source = std::make_shared<::arrow::io::BufferReader>(buffer);
-    auto file_reader = ParquetFileReader::Open(source);
-    ASSERT_EQ(num_columns_, file_reader->metadata()->num_columns());
-    ASSERT_EQ(num_rowgroups_, file_reader->metadata()->num_row_groups());
-    ASSERT_EQ(num_rows_, file_reader->metadata()->num_rows());
-
-    for (int rg = 0; rg < num_rowgroups_; ++rg) {
-      auto rg_reader = file_reader->RowGroup(rg);
-      ASSERT_EQ(num_columns_, rg_reader->metadata()->num_columns());
-      ASSERT_EQ(rows_per_rowgroup_, rg_reader->metadata()->num_rows());
-      // Check that the specified compression was actually used.
-      ASSERT_EQ(codec_type, rg_reader->metadata()->ColumnChunk(0)->compression());
-
-      int64_t values_read;
-
-      for (int i = 0; i < num_columns_; ++i) {
-        ASSERT_FALSE(rg_reader->metadata()->ColumnChunk(i)->has_index_page());
-        std::vector<int16_t> def_levels_out(rows_per_rowgroup_);
-        std::vector<int16_t> rep_levels_out(rows_per_rowgroup_);
-        auto col_reader =
-            std::static_pointer_cast<TypedColumnReader<TestType>>(rg_reader->Column(i));
-        this->SetupValuesOut(rows_per_rowgroup_);
-        col_reader->ReadBatch(rows_per_rowgroup_, def_levels_out.data(),
-                              rep_levels_out.data(), this->values_out_ptr_, &values_read);
-        this->SyncValuesOut();
-        ASSERT_EQ(rows_per_rowgroup_, values_read);
-        ASSERT_EQ(this->values_, this->values_out_);
-        ASSERT_EQ(this->def_levels_, def_levels_out);
-      }
-    }
-  }
-
-  void UnequalNumRows(int64_t max_rows, const std::vector<int64_t> rows_per_column) {
-    std::shared_ptr<InMemoryOutputStream> sink(new InMemoryOutputStream());
-    auto gnode = std::static_pointer_cast<GroupNode>(this->node_);
-
-    std::shared_ptr<WriterProperties> props = WriterProperties::Builder().build();
-
-    auto file_writer = ParquetFileWriter::Open(sink, gnode, props);
-
-    RowGroupWriter* row_group_writer;
-    row_group_writer = file_writer->AppendRowGroup();
-
-    this->GenerateData(max_rows);
-    for (int col = 0; col < num_columns_; ++col) {
-      auto column_writer =
-          static_cast<TypedColumnWriter<TestType>*>(row_group_writer->NextColumn());
-      column_writer->WriteBatch(rows_per_column[col], this->def_levels_.data(), nullptr,
-                                this->values_ptr_);
-      column_writer->Close();
-    }
-    row_group_writer->Close();
-    file_writer->Close();
-  }
-
-  void UnequalNumRowsBuffered(int64_t max_rows,
-                              const std::vector<int64_t> rows_per_column) {
-    std::shared_ptr<InMemoryOutputStream> sink(new InMemoryOutputStream());
-    auto gnode = std::static_pointer_cast<GroupNode>(this->node_);
-
-    std::shared_ptr<WriterProperties> props = WriterProperties::Builder().build();
-
-    auto file_writer = ParquetFileWriter::Open(sink, gnode, props);
-
-    RowGroupWriter* row_group_writer;
-    row_group_writer = file_writer->AppendBufferedRowGroup();
-
-    this->GenerateData(max_rows);
-    for (int col = 0; col < num_columns_; ++col) {
-      auto column_writer =
-          static_cast<TypedColumnWriter<TestType>*>(row_group_writer->column(col));
-      column_writer->WriteBatch(rows_per_column[col], this->def_levels_.data(), nullptr,
-                                this->values_ptr_);
-      column_writer->Close();
-    }
-    row_group_writer->Close();
-    file_writer->Close();
-  }
-
-  void RepeatedUnequalRows() {
-    // Optional and repeated, so definition and repetition levels
-    this->SetUpSchema(Repetition::REPEATED);
-
-    const int kNumRows = 100;
-    this->GenerateData(kNumRows);
-
-    std::shared_ptr<InMemoryOutputStream> sink(new InMemoryOutputStream());
-    auto gnode = std::static_pointer_cast<GroupNode>(this->node_);
-    std::shared_ptr<WriterProperties> props = WriterProperties::Builder().build();
-    auto file_writer = ParquetFileWriter::Open(sink, gnode, props);
-
-    RowGroupWriter* row_group_writer;
-    row_group_writer = file_writer->AppendRowGroup();
-
-    this->GenerateData(kNumRows);
-
-    std::vector<int16_t> definition_levels(kNumRows, 1);
-    std::vector<int16_t> repetition_levels(kNumRows, 0);
-
-    {
-      auto column_writer =
-          static_cast<TypedColumnWriter<TestType>*>(row_group_writer->NextColumn());
-      column_writer->WriteBatch(kNumRows, definition_levels.data(),
-                                repetition_levels.data(), this->values_ptr_);
-      column_writer->Close();
-    }
-
-    definition_levels[1] = 0;
-    repetition_levels[3] = 1;
-
-    {
-      auto column_writer =
-          static_cast<TypedColumnWriter<TestType>*>(row_group_writer->NextColumn());
-      column_writer->WriteBatch(kNumRows, definition_levels.data(),
-                                repetition_levels.data(), this->values_ptr_);
-      column_writer->Close();
-    }
-  }
-
-  void ZeroRowsRowGroup() {
-    std::shared_ptr<InMemoryOutputStream> sink(new InMemoryOutputStream());
-    auto gnode = std::static_pointer_cast<GroupNode>(this->node_);
-
-    std::shared_ptr<WriterProperties> props = WriterProperties::Builder().build();
-
-    auto file_writer = ParquetFileWriter::Open(sink, gnode, props);
-
-    RowGroupWriter* row_group_writer;
-
-    row_group_writer = file_writer->AppendRowGroup();
-    for (int col = 0; col < num_columns_; ++col) {
-      auto column_writer =
-          static_cast<TypedColumnWriter<TestType>*>(row_group_writer->NextColumn());
-      column_writer->Close();
-    }
-    row_group_writer->Close();
-
-    row_group_writer = file_writer->AppendBufferedRowGroup();
-    for (int col = 0; col < num_columns_; ++col) {
-      auto column_writer =
-          static_cast<TypedColumnWriter<TestType>*>(row_group_writer->column(col));
-      column_writer->Close();
-    }
-    row_group_writer->Close();
-
-    file_writer->Close();
-  }
-};
-
-typedef ::testing::Types<Int32Type, Int64Type, Int96Type, FloatType, DoubleType,
-                         BooleanType, ByteArrayType, FLBAType>
-    TestTypes;
-
-TYPED_TEST_CASE(TestSerialize, TestTypes);
-
-TYPED_TEST(TestSerialize, SmallFileUncompressed) {
-  ASSERT_NO_FATAL_FAILURE(this->FileSerializeTest(Compression::UNCOMPRESSED));
-}
-
-TYPED_TEST(TestSerialize, TooFewRows) {
-  std::vector<int64_t> num_rows = {100, 100, 100, 99};
-  ASSERT_THROW(this->UnequalNumRows(100, num_rows), ParquetException);
-  ASSERT_THROW(this->UnequalNumRowsBuffered(100, num_rows), ParquetException);
-}
-
-TYPED_TEST(TestSerialize, TooManyRows) {
-  std::vector<int64_t> num_rows = {100, 100, 100, 101};
-  ASSERT_THROW(this->UnequalNumRows(101, num_rows), ParquetException);
-  ASSERT_THROW(this->UnequalNumRowsBuffered(101, num_rows), ParquetException);
-}
-
-TYPED_TEST(TestSerialize, ZeroRows) { ASSERT_NO_THROW(this->ZeroRowsRowGroup()); }
-
-TYPED_TEST(TestSerialize, RepeatedTooFewRows) {
-  ASSERT_THROW(this->RepeatedUnequalRows(), ParquetException);
-}
-
-TYPED_TEST(TestSerialize, SmallFileSnappy) {
-  ASSERT_NO_FATAL_FAILURE(this->FileSerializeTest(Compression::SNAPPY));
-}
-
-TYPED_TEST(TestSerialize, SmallFileBrotli) {
-  ASSERT_NO_FATAL_FAILURE(this->FileSerializeTest(Compression::BROTLI));
-}
-
-TYPED_TEST(TestSerialize, SmallFileGzip) {
-  ASSERT_NO_FATAL_FAILURE(this->FileSerializeTest(Compression::GZIP));
-}
-
-TYPED_TEST(TestSerialize, SmallFileLz4) {
-  ASSERT_NO_FATAL_FAILURE(this->FileSerializeTest(Compression::LZ4));
-}
-
-TYPED_TEST(TestSerialize, SmallFileZstd) {
-  ASSERT_NO_FATAL_FAILURE(this->FileSerializeTest(Compression::ZSTD));
-}
-
-}  // namespace test
-
-}  // namespace parquet
diff --git a/src/parquet/file_reader.cc b/src/parquet/file_reader.cc
deleted file mode 100644
index c5a0f34..0000000
--- a/src/parquet/file_reader.cc
+++ /dev/null
@@ -1,376 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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.
-
-#include "parquet/file_reader.h"
-
-#include <algorithm>
-#include <cstdint>
-#include <cstdio>
-#include <memory>
-#include <sstream>
-#include <string>
-#include <utility>
-#include <vector>
-
-#include "arrow/io/file.h"
-
-#include "parquet/column_page.h"
-#include "parquet/column_reader.h"
-#include "parquet/column_scanner.h"
-#include "parquet/exception.h"
-#include "parquet/metadata.h"
-#include "parquet/parquet_types.h"
-#include "parquet/properties.h"
-#include "parquet/types.h"
-#include "parquet/util/logging.h"
-#include "parquet/util/memory.h"
-
-using std::string;
-
-namespace arrow {
-
-class Codec;
-
-}  // namespace arrow
-
-namespace parquet {
-
-// PARQUET-978: Minimize footer reads by reading 64 KB from the end of the file
-static constexpr int64_t DEFAULT_FOOTER_READ_SIZE = 64 * 1024;
-static constexpr uint32_t FOOTER_SIZE = 8;
-static constexpr uint8_t PARQUET_MAGIC[4] = {'P', 'A', 'R', '1'};
-
-// For PARQUET-816
-static constexpr int64_t kMaxDictHeaderSize = 100;
-
-// ----------------------------------------------------------------------
-// RowGroupReader public API
-
-RowGroupReader::RowGroupReader(std::unique_ptr<Contents> contents)
-    : contents_(std::move(contents)) {}
-
-std::shared_ptr<ColumnReader> RowGroupReader::Column(int i) {
-  DCHECK(i < metadata()->num_columns())
-      << "The RowGroup only has " << metadata()->num_columns()
-      << "columns, requested column: " << i;
-  const ColumnDescriptor* descr = metadata()->schema()->Column(i);
-
-  std::unique_ptr<PageReader> page_reader = contents_->GetColumnPageReader(i);
-  return ColumnReader::Make(
-      descr, std::move(page_reader),
-      const_cast<ReaderProperties*>(contents_->properties())->memory_pool());
-}
-
-std::unique_ptr<PageReader> RowGroupReader::GetColumnPageReader(int i) {
-  DCHECK(i < metadata()->num_columns())
-      << "The RowGroup only has " << metadata()->num_columns()
-      << "columns, requested column: " << i;
-  return contents_->GetColumnPageReader(i);
-}
-
-// Returns the rowgroup metadata
-const RowGroupMetaData* RowGroupReader::metadata() const { return contents_->metadata(); }
-
-// RowGroupReader::Contents implementation for the Parquet file specification
-class SerializedRowGroup : public RowGroupReader::Contents {
- public:
-  SerializedRowGroup(RandomAccessSource* source, FileMetaData* file_metadata,
-                     int row_group_number, const ReaderProperties& props)
-      : source_(source), file_metadata_(file_metadata), properties_(props) {
-    row_group_metadata_ = file_metadata->RowGroup(row_group_number);
-  }
-
-  const RowGroupMetaData* metadata() const override { return row_group_metadata_.get(); }
-
-  const ReaderProperties* properties() const override { return &properties_; }
-
-  std::unique_ptr<PageReader> GetColumnPageReader(int i) override {
-    // Read column chunk from the file
-    auto col = row_group_metadata_->ColumnChunk(i);
-
-    int64_t col_start = col->data_page_offset();
-    if (col->has_dictionary_page() && col_start > col->dictionary_page_offset()) {
-      col_start = col->dictionary_page_offset();
-    }
-
-    int64_t col_length = col->total_compressed_size();
-    std::unique_ptr<InputStream> stream;
-
-    // PARQUET-816 workaround for old files created by older parquet-mr
-    const ApplicationVersion& version = file_metadata_->writer_version();
-    if (version.VersionLt(ApplicationVersion::PARQUET_816_FIXED_VERSION())) {
-      // The Parquet MR writer had a bug in 1.2.8 and below where it didn't include the
-      // dictionary page header size in total_compressed_size and total_uncompressed_size
-      // (see IMPALA-694). We add padding to compensate.
-      int64_t bytes_remaining = source_->Size() - (col_start + col_length);
-      int64_t padding = std::min<int64_t>(kMaxDictHeaderSize, bytes_remaining);
-      col_length += padding;
-    }
-
-    stream = properties_.GetStream(source_, col_start, col_length);
-
-    return PageReader::Open(std::move(stream), col->num_values(), col->compression(),
-                            properties_.memory_pool());
-  }
-
- private:
-  RandomAccessSource* source_;
-  FileMetaData* file_metadata_;
-  std::unique_ptr<RowGroupMetaData> row_group_metadata_;
-  ReaderProperties properties_;
-};
-
-// ----------------------------------------------------------------------
-// SerializedFile: An implementation of ParquetFileReader::Contents that deals
-// with the Parquet file structure, Thrift deserialization, and other internal
-// matters
-
-// This class takes ownership of the provided data source
-class SerializedFile : public ParquetFileReader::Contents {
- public:
-  SerializedFile(std::unique_ptr<RandomAccessSource> source,
-                 const ReaderProperties& props = default_reader_properties())
-      : source_(std::move(source)), properties_(props) {}
-
-  ~SerializedFile() override {
-    try {
-      Close();
-    } catch (...) {
-    }
-  }
-
-  void Close() override { source_->Close(); }
-
-  std::shared_ptr<RowGroupReader> GetRowGroup(int i) override {
-    std::unique_ptr<SerializedRowGroup> contents(
-        new SerializedRowGroup(source_.get(), file_metadata_.get(), i, properties_));
-    return std::make_shared<RowGroupReader>(std::move(contents));
-  }
-
-  std::shared_ptr<FileMetaData> metadata() const override { return file_metadata_; }
-
-  void set_metadata(const std::shared_ptr<FileMetaData>& metadata) {
-    file_metadata_ = metadata;
-  }
-
-  void ParseMetaData() {
-    int64_t file_size = source_->Size();
-
-    if (file_size < FOOTER_SIZE) {
-      throw ParquetException("Corrupted file, smaller than file footer");
-    }
-
-    uint8_t footer_buffer[DEFAULT_FOOTER_READ_SIZE];
-    int64_t footer_read_size = std::min(file_size, DEFAULT_FOOTER_READ_SIZE);
-    int64_t bytes_read =
-        source_->ReadAt(file_size - footer_read_size, footer_read_size, footer_buffer);
-
-    // Check if all bytes are read. Check if last 4 bytes read have the magic bits
-    if (bytes_read != footer_read_size ||
-        memcmp(footer_buffer + footer_read_size - 4, PARQUET_MAGIC, 4) != 0) {
-      throw ParquetException("Invalid parquet file. Corrupt footer.");
-    }
-
-    uint32_t metadata_len =
-        *reinterpret_cast<uint32_t*>(footer_buffer + footer_read_size - FOOTER_SIZE);
-    int64_t metadata_start = file_size - FOOTER_SIZE - metadata_len;
-    if (FOOTER_SIZE + metadata_len > file_size) {
-      throw ParquetException(
-          "Invalid parquet file. File is less than "
-          "file metadata size.");
-    }
-
-    std::shared_ptr<ResizableBuffer> metadata_buffer =
-        AllocateBuffer(properties_.memory_pool(), metadata_len);
-
-    // Check if the footer_buffer contains the entire metadata
-    if (footer_read_size >= (metadata_len + FOOTER_SIZE)) {
-      memcpy(metadata_buffer->mutable_data(),
-             footer_buffer + (footer_read_size - metadata_len - FOOTER_SIZE),
-             metadata_len);
-    } else {
-      bytes_read =
-          source_->ReadAt(metadata_start, metadata_len, metadata_buffer->mutable_data());
-      if (bytes_read != metadata_len) {
-        throw ParquetException("Invalid parquet file. Could not read metadata bytes.");
-      }
-    }
-
-    file_metadata_ = FileMetaData::Make(metadata_buffer->data(), &metadata_len);
-  }
-
- private:
-  std::unique_ptr<RandomAccessSource> source_;
-  std::shared_ptr<FileMetaData> file_metadata_;
-  ReaderProperties properties_;
-};
-
-// ----------------------------------------------------------------------
-// ParquetFileReader public API
-
-ParquetFileReader::ParquetFileReader() {}
-
-ParquetFileReader::~ParquetFileReader() {
-  try {
-    Close();
-  } catch (...) {
-  }
-}
-
-// Open the file. If no metadata is passed, it is parsed from the footer of
-// the file
-std::unique_ptr<ParquetFileReader::Contents> ParquetFileReader::Contents::Open(
-    std::unique_ptr<RandomAccessSource> source, const ReaderProperties& props,
-    const std::shared_ptr<FileMetaData>& metadata) {
-  std::unique_ptr<ParquetFileReader::Contents> result(
-      new SerializedFile(std::move(source), props));
-
-  // Access private methods here, but otherwise unavailable
-  SerializedFile* file = static_cast<SerializedFile*>(result.get());
-
-  if (metadata == nullptr) {
-    // Validates magic bytes, parses metadata, and initializes the SchemaDescriptor
-    file->ParseMetaData();
-  } else {
-    file->set_metadata(metadata);
-  }
-
-  return result;
-}
-
-std::unique_ptr<ParquetFileReader> ParquetFileReader::Open(
-    const std::shared_ptr<::arrow::io::ReadableFileInterface>& source,
-    const ReaderProperties& props, const std::shared_ptr<FileMetaData>& metadata) {
-  std::unique_ptr<RandomAccessSource> io_wrapper(new ArrowInputFile(source));
-  return Open(std::move(io_wrapper), props, metadata);
-}
-
-std::unique_ptr<ParquetFileReader> ParquetFileReader::Open(
-    std::unique_ptr<RandomAccessSource> source, const ReaderProperties& props,
-    const std::shared_ptr<FileMetaData>& metadata) {
-  auto contents = SerializedFile::Open(std::move(source), props, metadata);
-  std::unique_ptr<ParquetFileReader> result(new ParquetFileReader());
-  result->Open(std::move(contents));
-  return result;
-}
-
-std::unique_ptr<ParquetFileReader> ParquetFileReader::OpenFile(
-    const std::string& path, bool memory_map, const ReaderProperties& props,
-    const std::shared_ptr<FileMetaData>& metadata) {
-  std::shared_ptr<::arrow::io::ReadableFileInterface> source;
-  if (memory_map) {
-    std::shared_ptr<::arrow::io::MemoryMappedFile> handle;
-    PARQUET_THROW_NOT_OK(
-        ::arrow::io::MemoryMappedFile::Open(path, ::arrow::io::FileMode::READ, &handle));
-    source = handle;
-  } else {
-    std::shared_ptr<::arrow::io::ReadableFile> handle;
-    PARQUET_THROW_NOT_OK(
-        ::arrow::io::ReadableFile::Open(path, props.memory_pool(), &handle));
-    source = handle;
-  }
-
-  return Open(source, props, metadata);
-}
-
-void ParquetFileReader::Open(std::unique_ptr<ParquetFileReader::Contents> contents) {
-  contents_ = std::move(contents);
-}
-
-void ParquetFileReader::Close() {
-  if (contents_) {
-    contents_->Close();
-  }
-}
-
-std::shared_ptr<FileMetaData> ParquetFileReader::metadata() const {
-  return contents_->metadata();
-}
-
-std::shared_ptr<RowGroupReader> ParquetFileReader::RowGroup(int i) {
-  DCHECK(i < metadata()->num_row_groups())
-      << "The file only has " << metadata()->num_row_groups()
-      << "row groups, requested reader for: " << i;
-  return contents_->GetRowGroup(i);
-}
-
-// ----------------------------------------------------------------------
-// File metadata helpers
-
-std::shared_ptr<FileMetaData> ReadMetaData(
-    const std::shared_ptr<::arrow::io::ReadableFileInterface>& source) {
-  return ParquetFileReader::Open(source)->metadata();
-}
-
-// ----------------------------------------------------------------------
-// File scanner for performance testing
-
-int64_t ScanFileContents(std::vector<int> columns, const int32_t column_batch_size,
-                         ParquetFileReader* reader) {
-  std::vector<int16_t> rep_levels(column_batch_size);
-  std::vector<int16_t> def_levels(column_batch_size);
-
-  int num_columns = static_cast<int>(columns.size());
-
-  // columns are not specified explicitly. Add all columns
-  if (columns.size() == 0) {
-    num_columns = reader->metadata()->num_columns();
-    columns.resize(num_columns);
-    for (int i = 0; i < num_columns; i++) {
-      columns[i] = i;
-    }
-  }
-
-  std::vector<int64_t> total_rows(num_columns, 0);
-
-  for (int r = 0; r < reader->metadata()->num_row_groups(); ++r) {
-    auto group_reader = reader->RowGroup(r);
-    int col = 0;
-    for (auto i : columns) {
-      std::shared_ptr<ColumnReader> col_reader = group_reader->Column(i);
-      size_t value_byte_size = GetTypeByteSize(col_reader->descr()->physical_type());
-      std::vector<uint8_t> values(column_batch_size * value_byte_size);
-
-      int64_t values_read = 0;
-      while (col_reader->HasNext()) {
-        int64_t levels_read =
-            ScanAllValues(column_batch_size, def_levels.data(), rep_levels.data(),
-                          values.data(), &values_read, col_reader.get());
-        if (col_reader->descr()->max_repetition_level() > 0) {
-          for (int64_t i = 0; i < levels_read; i++) {
-            if (rep_levels[i] == 0) {
-              total_rows[col]++;
-            }
-          }
-        } else {
-          total_rows[col] += levels_read;
-        }
-      }
-      col++;
-    }
-  }
-
-  for (int i = 1; i < num_columns; ++i) {
-    if (total_rows[0] != total_rows[i]) {
-      throw ParquetException("Parquet error: Total rows among columns do not match");
-    }
-  }
-
-  return total_rows[0];
-}
-
-}  // namespace parquet
diff --git a/src/parquet/file_reader.h b/src/parquet/file_reader.h
deleted file mode 100644
index f751e9b..0000000
--- a/src/parquet/file_reader.h
+++ /dev/null
@@ -1,142 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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.
-
-#ifndef PARQUET_FILE_READER_H
-#define PARQUET_FILE_READER_H
-
-#include <cstdint>
-#include <iosfwd>
-#include <list>
-#include <memory>
-#include <string>
-#include <vector>
-
-#include "parquet/column_reader.h"
-#include "parquet/metadata.h"
-#include "parquet/properties.h"
-#include "parquet/schema.h"
-#include "parquet/statistics.h"
-#include "parquet/util/memory.h"
-#include "parquet/util/visibility.h"
-
-namespace parquet {
-
-class ColumnReader;
-
-class PARQUET_EXPORT RowGroupReader {
- public:
-  // Forward declare a virtual class 'Contents' to aid dependency injection and more
-  // easily create test fixtures
-  // An implementation of the Contents class is defined in the .cc file
-  struct Contents {
-    virtual ~Contents() {}
-    virtual std::unique_ptr<PageReader> GetColumnPageReader(int i) = 0;
-    virtual const RowGroupMetaData* metadata() const = 0;
-    virtual const ReaderProperties* properties() const = 0;
-  };
-
-  explicit RowGroupReader(std::unique_ptr<Contents> contents);
-
-  // Returns the rowgroup metadata
-  const RowGroupMetaData* metadata() const;
-
-  // Construct a ColumnReader for the indicated row group-relative
-  // column. Ownership is shared with the RowGroupReader.
-  std::shared_ptr<ColumnReader> Column(int i);
-
-  std::unique_ptr<PageReader> GetColumnPageReader(int i);
-
- private:
-  // Holds a pointer to an instance of Contents implementation
-  std::unique_ptr<Contents> contents_;
-};
-
-class PARQUET_EXPORT ParquetFileReader {
- public:
-  // Forward declare a virtual class 'Contents' to aid dependency injection and more
-  // easily create test fixtures
-  // An implementation of the Contents class is defined in the .cc file
-  struct Contents {
-    static std::unique_ptr<Contents> Open(
-        std::unique_ptr<RandomAccessSource> source,
-        const ReaderProperties& props = default_reader_properties(),
-        const std::shared_ptr<FileMetaData>& metadata = nullptr);
-
-    virtual ~Contents() {}
-    // Perform any cleanup associated with the file contents
-    virtual void Close() = 0;
-    virtual std::shared_ptr<RowGroupReader> GetRowGroup(int i) = 0;
-    virtual std::shared_ptr<FileMetaData> metadata() const = 0;
-  };
-
-  ParquetFileReader();
-  ~ParquetFileReader();
-
-  // Create a reader from some implementation of parquet-cpp's generic file
-  // input interface
-  //
-  // If you cannot provide exclusive access to your file resource, create a
-  // subclass of RandomAccessSource that wraps the shared resource
-  static std::unique_ptr<ParquetFileReader> Open(
-      std::unique_ptr<RandomAccessSource> source,
-      const ReaderProperties& props = default_reader_properties(),
-      const std::shared_ptr<FileMetaData>& metadata = nullptr);
-
-  // Create a file reader instance from an Arrow file object. Thread-safety is
-  // the responsibility of the file implementation
-  static std::unique_ptr<ParquetFileReader> Open(
-      const std::shared_ptr<::arrow::io::ReadableFileInterface>& source,
-      const ReaderProperties& props = default_reader_properties(),
-      const std::shared_ptr<FileMetaData>& metadata = nullptr);
-
-  // API Convenience to open a serialized Parquet file on disk, using Arrow IO
-  // interfaces.
-  static std::unique_ptr<ParquetFileReader> OpenFile(
-      const std::string& path, bool memory_map = true,
-      const ReaderProperties& props = default_reader_properties(),
-      const std::shared_ptr<FileMetaData>& metadata = nullptr);
-
-  void Open(std::unique_ptr<Contents> contents);
-  void Close();
-
-  // The RowGroupReader is owned by the FileReader
-  std::shared_ptr<RowGroupReader> RowGroup(int i);
-
-  // Returns the file metadata. Only one instance is ever created
-  std::shared_ptr<FileMetaData> metadata() const;
-
- private:
-  // Holds a pointer to an instance of Contents implementation
-  std::unique_ptr<Contents> contents_;
-};
-
-// Read only Parquet file metadata
-std::shared_ptr<FileMetaData> PARQUET_EXPORT
-ReadMetaData(const std::shared_ptr<::arrow::io::ReadableFileInterface>& source);
-
-/// \brief Scan all values in file. Useful for performance testing
-/// \param[in] columns the column numbers to scan. If empty scans all
-/// \param[in] column_batch_size number of values to read at a time when scanning column
-/// \param[in] reader a ParquetFileReader instance
-/// \return number of semantic rows in file
-PARQUET_EXPORT
-int64_t ScanFileContents(std::vector<int> columns, const int32_t column_batch_size,
-                         ParquetFileReader* reader);
-
-}  // namespace parquet
-
-#endif  // PARQUET_FILE_READER_H
diff --git a/src/parquet/file_writer.cc b/src/parquet/file_writer.cc
deleted file mode 100644
index 30673c5..0000000
--- a/src/parquet/file_writer.cc
+++ /dev/null
@@ -1,419 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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.
-
-#include "parquet/file_writer.h"
-
-#include <vector>
-
-#include "parquet/column_writer.h"
-#include "parquet/schema-internal.h"
-#include "parquet/schema.h"
-#include "parquet/thrift.h"
-#include "parquet/util/memory.h"
-
-using arrow::MemoryPool;
-
-using parquet::schema::GroupNode;
-using parquet::schema::SchemaFlattener;
-
-namespace parquet {
-
-// FIXME: copied from reader-internal.cc
-static constexpr uint8_t PARQUET_MAGIC[4] = {'P', 'A', 'R', '1'};
-
-// ----------------------------------------------------------------------
-// RowGroupWriter public API
-
-RowGroupWriter::RowGroupWriter(std::unique_ptr<Contents> contents)
-    : contents_(std::move(contents)) {}
-
-void RowGroupWriter::Close() {
-  if (contents_) {
-    contents_->Close();
-  }
-}
-
-ColumnWriter* RowGroupWriter::NextColumn() { return contents_->NextColumn(); }
-
-ColumnWriter* RowGroupWriter::column(int i) { return contents_->column(i); }
-
-int64_t RowGroupWriter::total_compressed_bytes() const {
-  return contents_->total_compressed_bytes();
-}
-
-int64_t RowGroupWriter::total_bytes_written() const {
-  return contents_->total_bytes_written();
-}
-
-int RowGroupWriter::current_column() { return contents_->current_column(); }
-
-int RowGroupWriter::num_columns() const { return contents_->num_columns(); }
-
-int64_t RowGroupWriter::num_rows() const { return contents_->num_rows(); }
-
-inline void ThrowRowsMisMatchError(int col, int64_t prev, int64_t curr) {
-  std::stringstream ss;
-  ss << "Column " << col << " had " << curr << " while previous column had " << prev;
-  throw ParquetException(ss.str());
-}
-
-// ----------------------------------------------------------------------
-// RowGroupSerializer
-
-// RowGroupWriter::Contents implementation for the Parquet file specification
-class RowGroupSerializer : public RowGroupWriter::Contents {
- public:
-  RowGroupSerializer(OutputStream* sink, RowGroupMetaDataBuilder* metadata,
-                     const WriterProperties* properties, bool buffered_row_group = false)
-      : sink_(sink),
-        metadata_(metadata),
-        properties_(properties),
-        total_bytes_written_(0),
-        closed_(false),
-        current_column_index_(0),
-        num_rows_(0),
-        buffered_row_group_(buffered_row_group) {
-    if (buffered_row_group) {
-      InitColumns();
-    } else {
-      column_writers_.push_back(nullptr);
-    }
-  }
-
-  int num_columns() const override { return metadata_->num_columns(); }
-
-  int64_t num_rows() const override {
-    CheckRowsWritten();
-    // CheckRowsWritten ensures num_rows_ is set correctly
-    return num_rows_;
-  }
-
-  ColumnWriter* NextColumn() override {
-    if (buffered_row_group_) {
-      throw ParquetException(
-          "NextColumn() is not supported when a RowGroup is written by size");
-    }
-
-    if (column_writers_[0]) {
-      CheckRowsWritten();
-    }
-
-    // Throws an error if more columns are being written
-    auto col_meta = metadata_->NextColumnChunk();
-
-    if (column_writers_[0]) {
-      total_bytes_written_ += column_writers_[0]->Close();
-    }
-
-    ++current_column_index_;
-
-    const ColumnDescriptor* column_descr = col_meta->descr();
-    std::unique_ptr<PageWriter> pager =
-        PageWriter::Open(sink_, properties_->compression(column_descr->path()), col_meta,
-                         properties_->memory_pool());
-    column_writers_[0] = ColumnWriter::Make(col_meta, std::move(pager), properties_);
-    return column_writers_[0].get();
-  }
-
-  ColumnWriter* column(int i) override {
-    if (!buffered_row_group_) {
-      throw ParquetException(
-          "column() is only supported when a BufferedRowGroup is being written");
-    }
-
-    if (i >= 0 && i < static_cast<int>(column_writers_.size())) {
-      return column_writers_[i].get();
-    }
-    return nullptr;
-  }
-
-  int current_column() const override { return metadata_->current_column(); }
-
-  int64_t total_compressed_bytes() const override {
-    int64_t total_compressed_bytes = 0;
-    for (size_t i = 0; i < column_writers_.size(); i++) {
-      if (column_writers_[i]) {
-        total_compressed_bytes += column_writers_[i]->total_compressed_bytes();
-      }
-    }
-    return total_compressed_bytes;
-  }
-
-  int64_t total_bytes_written() const override {
-    int64_t total_bytes_written = 0;
-    for (size_t i = 0; i < column_writers_.size(); i++) {
-      if (column_writers_[i]) {
-        total_bytes_written += column_writers_[i]->total_bytes_written();
-      }
-    }
-    return total_bytes_written;
-  }
-
-  void Close() override {
-    if (!closed_) {
-      closed_ = true;
-      CheckRowsWritten();
-
-      for (size_t i = 0; i < column_writers_.size(); i++) {
-        if (column_writers_[i]) {
-          total_bytes_written_ += column_writers_[i]->Close();
-          column_writers_[i].reset();
-        }
-      }
-
-      column_writers_.clear();
-
-      // Ensures all columns have been written
-      metadata_->set_num_rows(num_rows_);
-      metadata_->Finish(total_bytes_written_);
-    }
-  }
-
- private:
-  OutputStream* sink_;
-  mutable RowGroupMetaDataBuilder* metadata_;
-  const WriterProperties* properties_;
-  int64_t total_bytes_written_;
-  bool closed_;
-  int current_column_index_;
-  mutable int64_t num_rows_;
-  bool buffered_row_group_;
-
-  void CheckRowsWritten() const {
-    // verify when only one column is written at a time
-    if (!buffered_row_group_ && column_writers_.size() > 0 && column_writers_[0]) {
-      int64_t current_col_rows = column_writers_[0]->rows_written();
-      if (num_rows_ == 0) {
-        num_rows_ = current_col_rows;
-      } else if (num_rows_ != current_col_rows) {
-        ThrowRowsMisMatchError(current_column_index_, current_col_rows, num_rows_);
-      }
-    } else if (buffered_row_group_ &&
-               column_writers_.size() > 0) {  // when buffered_row_group = true
-      int64_t current_col_rows = column_writers_[0]->rows_written();
-      for (int i = 1; i < static_cast<int>(column_writers_.size()); i++) {
-        int64_t current_col_rows_i = column_writers_[i]->rows_written();
-        if (current_col_rows != current_col_rows_i) {
-          ThrowRowsMisMatchError(i, current_col_rows_i, current_col_rows);
-        }
-      }
-      num_rows_ = current_col_rows;
-    }
-  }
-
-  void InitColumns() {
-    for (int i = 0; i < num_columns(); i++) {
-      auto col_meta = metadata_->NextColumnChunk();
-      const ColumnDescriptor* column_descr = col_meta->descr();
-      std::unique_ptr<PageWriter> pager =
-          PageWriter::Open(sink_, properties_->compression(column_descr->path()),
-                           col_meta, properties_->memory_pool(), buffered_row_group_);
-      column_writers_.push_back(
-          ColumnWriter::Make(col_meta, std::move(pager), properties_));
-    }
-  }
-
-  std::vector<std::shared_ptr<ColumnWriter>> column_writers_;
-};
-
-// ----------------------------------------------------------------------
-// FileSerializer
-
-// An implementation of ParquetFileWriter::Contents that deals with the Parquet
-// file structure, Thrift serialization, and other internal matters
-
-class FileSerializer : public ParquetFileWriter::Contents {
- public:
-  static std::unique_ptr<ParquetFileWriter::Contents> Open(
-      const std::shared_ptr<OutputStream>& sink, const std::shared_ptr<GroupNode>& schema,
-      const std::shared_ptr<WriterProperties>& properties,
-      const std::shared_ptr<const KeyValueMetadata>& key_value_metadata) {
-    std::unique_ptr<ParquetFileWriter::Contents> result(
-        new FileSerializer(sink, schema, properties, key_value_metadata));
-
-    return result;
-  }
-
-  void Close() override {
-    if (is_open_) {
-      if (row_group_writer_) {
-        num_rows_ += row_group_writer_->num_rows();
-        row_group_writer_->Close();
-      }
-      row_group_writer_.reset();
-
-      // Write magic bytes and metadata
-      auto metadata = metadata_->Finish();
-      WriteFileMetaData(*metadata, sink_.get());
-
-      sink_->Close();
-      is_open_ = false;
-    }
-  }
-
-  int num_columns() const override { return schema_.num_columns(); }
-
-  int num_row_groups() const override { return num_row_groups_; }
-
-  int64_t num_rows() const override { return num_rows_; }
-
-  const std::shared_ptr<WriterProperties>& properties() const override {
-    return properties_;
-  }
-
-  RowGroupWriter* AppendRowGroup(bool buffered_row_group) {
-    if (row_group_writer_) {
-      row_group_writer_->Close();
-    }
-    num_row_groups_++;
-    auto rg_metadata = metadata_->AppendRowGroup();
-    std::unique_ptr<RowGroupWriter::Contents> contents(new RowGroupSerializer(
-        sink_.get(), rg_metadata, properties_.get(), buffered_row_group));
-    row_group_writer_.reset(new RowGroupWriter(std::move(contents)));
-    return row_group_writer_.get();
-  }
-
-  RowGroupWriter* AppendRowGroup() override { return AppendRowGroup(false); }
-
-  RowGroupWriter* AppendBufferedRowGroup() override { return AppendRowGroup(true); }
-
-  ~FileSerializer() override {
-    try {
-      Close();
-    } catch (...) {
-    }
-  }
-
- private:
-  FileSerializer(const std::shared_ptr<OutputStream>& sink,
-                 const std::shared_ptr<GroupNode>& schema,
-                 const std::shared_ptr<WriterProperties>& properties,
-                 const std::shared_ptr<const KeyValueMetadata>& key_value_metadata)
-      : ParquetFileWriter::Contents(schema, key_value_metadata),
-        sink_(sink),
-        is_open_(true),
-        properties_(properties),
-        num_row_groups_(0),
-        num_rows_(0),
-        metadata_(FileMetaDataBuilder::Make(&schema_, properties, key_value_metadata)) {
-    StartFile();
-  }
-
-  std::shared_ptr<OutputStream> sink_;
-  bool is_open_;
-  const std::shared_ptr<WriterProperties> properties_;
-  int num_row_groups_;
-  int64_t num_rows_;
-  std::unique_ptr<FileMetaDataBuilder> metadata_;
-  // Only one of the row group writers is active at a time
-  std::unique_ptr<RowGroupWriter> row_group_writer_;
-
-  void StartFile() {
-    // Parquet files always start with PAR1
-    sink_->Write(PARQUET_MAGIC, 4);
-  }
-};
-
-// ----------------------------------------------------------------------
-// ParquetFileWriter public API
-
-ParquetFileWriter::ParquetFileWriter() {}
-
-ParquetFileWriter::~ParquetFileWriter() {
-  try {
-    Close();
-  } catch (...) {
-  }
-}
-
-std::unique_ptr<ParquetFileWriter> ParquetFileWriter::Open(
-    const std::shared_ptr<::arrow::io::OutputStream>& sink,
-    const std::shared_ptr<GroupNode>& schema,
-    const std::shared_ptr<WriterProperties>& properties,
-    const std::shared_ptr<const KeyValueMetadata>& key_value_metadata) {
-  return Open(std::make_shared<ArrowOutputStream>(sink), schema, properties,
-              key_value_metadata);
-}
-
-std::unique_ptr<ParquetFileWriter> ParquetFileWriter::Open(
-    const std::shared_ptr<OutputStream>& sink,
-    const std::shared_ptr<schema::GroupNode>& schema,
-    const std::shared_ptr<WriterProperties>& properties,
-    const std::shared_ptr<const KeyValueMetadata>& key_value_metadata) {
-  auto contents = FileSerializer::Open(sink, schema, properties, key_value_metadata);
-  std::unique_ptr<ParquetFileWriter> result(new ParquetFileWriter());
-  result->Open(std::move(contents));
-  return result;
-}
-
-void WriteFileMetaData(const FileMetaData& file_metadata, OutputStream* sink) {
-  // Write MetaData
-  uint32_t metadata_len = static_cast<uint32_t>(sink->Tell());
-
-  file_metadata.WriteTo(sink);
-  metadata_len = static_cast<uint32_t>(sink->Tell()) - metadata_len;
-
-  // Write Footer
-  sink->Write(reinterpret_cast<uint8_t*>(&metadata_len), 4);
-  sink->Write(PARQUET_MAGIC, 4);
-}
-
-const SchemaDescriptor* ParquetFileWriter::schema() const { return contents_->schema(); }
-
-const ColumnDescriptor* ParquetFileWriter::descr(int i) const {
-  return contents_->schema()->Column(i);
-}
-
-int ParquetFileWriter::num_columns() const { return contents_->num_columns(); }
-
-int64_t ParquetFileWriter::num_rows() const { return contents_->num_rows(); }
-
-int ParquetFileWriter::num_row_groups() const { return contents_->num_row_groups(); }
-
-const std::shared_ptr<const KeyValueMetadata>& ParquetFileWriter::key_value_metadata()
-    const {
-  return contents_->key_value_metadata();
-}
-
-void ParquetFileWriter::Open(std::unique_ptr<ParquetFileWriter::Contents> contents) {
-  contents_ = std::move(contents);
-}
-
-void ParquetFileWriter::Close() {
-  if (contents_) {
-    contents_->Close();
-    contents_.reset();
-  }
-}
-
-RowGroupWriter* ParquetFileWriter::AppendRowGroup() {
-  return contents_->AppendRowGroup();
-}
-
-RowGroupWriter* ParquetFileWriter::AppendBufferedRowGroup() {
-  return contents_->AppendBufferedRowGroup();
-}
-
-RowGroupWriter* ParquetFileWriter::AppendRowGroup(int64_t num_rows) {
-  return AppendRowGroup();
-}
-
-const std::shared_ptr<WriterProperties>& ParquetFileWriter::properties() const {
-  return contents_->properties();
-}
-
-}  // namespace parquet
diff --git a/src/parquet/file_writer.h b/src/parquet/file_writer.h
deleted file mode 100644
index cdfe06c..0000000
--- a/src/parquet/file_writer.h
+++ /dev/null
@@ -1,219 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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.
-
-#ifndef PARQUET_FILE_WRITER_H
-#define PARQUET_FILE_WRITER_H
-
-#include <cstdint>
-#include <memory>
-
-#include "parquet/metadata.h"
-#include "parquet/properties.h"
-#include "parquet/schema.h"
-#include "parquet/util/memory.h"
-#include "parquet/util/visibility.h"
-
-namespace parquet {
-
-class ColumnWriter;
-class PageWriter;
-class OutputStream;
-
-namespace schema {
-
-class GroupNode;
-
-}  // namespace schema
-
-class PARQUET_EXPORT RowGroupWriter {
- public:
-  // Forward declare a virtual class 'Contents' to aid dependency injection and more
-  // easily create test fixtures
-  // An implementation of the Contents class is defined in the .cc file
-  struct Contents {
-    virtual ~Contents() = default;
-    virtual int num_columns() const = 0;
-    virtual int64_t num_rows() const = 0;
-
-    // to be used only with ParquetFileWriter::AppendRowGroup
-    virtual ColumnWriter* NextColumn() = 0;
-    // to be used only with ParquetFileWriter::AppendBufferedRowGroup
-    virtual ColumnWriter* column(int i) = 0;
-
-    virtual int current_column() const = 0;
-    virtual void Close() = 0;
-
-    // total bytes written by the page writer
-    virtual int64_t total_bytes_written() const = 0;
-    // total bytes still compressed but not written
-    virtual int64_t total_compressed_bytes() const = 0;
-  };
-
-  explicit RowGroupWriter(std::unique_ptr<Contents> contents);
-
-  /// Construct a ColumnWriter for the indicated row group-relative column.
-  ///
-  /// To be used only with ParquetFileWriter::AppendRowGroup
-  /// Ownership is solely within the RowGroupWriter. The ColumnWriter is only
-  /// valid until the next call to NextColumn or Close. As the contents are
-  /// directly written to the sink, once a new column is started, the contents
-  /// of the previous one cannot be modified anymore.
-  ColumnWriter* NextColumn();
-  /// Index of currently written column
-  int current_column();
-  void Close();
-
-  int num_columns() const;
-
-  /// Construct a ColumnWriter for the indicated row group column.
-  ///
-  /// To be used only with ParquetFileWriter::AppendBufferedRowGroup
-  /// Ownership is solely within the RowGroupWriter. The ColumnWriter is
-  /// valid until Close. The contents are buffered in memory and written to sink
-  /// on Close
-  ColumnWriter* column(int i);
-
-  /**
-   * Number of rows that shall be written as part of this RowGroup.
-   */
-  int64_t num_rows() const;
-
-  int64_t total_bytes_written() const;
-  int64_t total_compressed_bytes() const;
-
- private:
-  // Holds a pointer to an instance of Contents implementation
-  std::unique_ptr<Contents> contents_;
-};
-
-PARQUET_EXPORT
-void WriteFileMetaData(const FileMetaData& file_metadata, OutputStream* sink);
-
-class PARQUET_EXPORT ParquetFileWriter {
- public:
-  // Forward declare a virtual class 'Contents' to aid dependency injection and more
-  // easily create test fixtures
-  // An implementation of the Contents class is defined in the .cc file
-  struct Contents {
-    Contents(const std::shared_ptr<::parquet::schema::GroupNode>& schema,
-             const std::shared_ptr<const KeyValueMetadata>& key_value_metadata)
-        : schema_(), key_value_metadata_(key_value_metadata) {
-      schema_.Init(schema);
-    }
-    virtual ~Contents() {}
-    // Perform any cleanup associated with the file contents
-    virtual void Close() = 0;
-
-    /// \note Deprecated since 1.3.0
-    RowGroupWriter* AppendRowGroup(int64_t num_rows);
-
-    virtual RowGroupWriter* AppendRowGroup() = 0;
-    virtual RowGroupWriter* AppendBufferedRowGroup() = 0;
-
-    virtual int64_t num_rows() const = 0;
-    virtual int num_columns() const = 0;
-    virtual int num_row_groups() const = 0;
-
-    virtual const std::shared_ptr<WriterProperties>& properties() const = 0;
-
-    const std::shared_ptr<const KeyValueMetadata>& key_value_metadata() const {
-      return key_value_metadata_;
-    }
-
-    // Return const-pointer to make it clear that this object is not to be copied
-    const SchemaDescriptor* schema() const { return &schema_; }
-
-    SchemaDescriptor schema_;
-
-    /// This should be the only place this is stored. Everything else is a const reference
-    std::shared_ptr<const KeyValueMetadata> key_value_metadata_;
-  };
-
-  ParquetFileWriter();
-  ~ParquetFileWriter();
-
-  static std::unique_ptr<ParquetFileWriter> Open(
-      const std::shared_ptr<::arrow::io::OutputStream>& sink,
-      const std::shared_ptr<schema::GroupNode>& schema,
-      const std::shared_ptr<WriterProperties>& properties = default_writer_properties(),
-      const std::shared_ptr<const KeyValueMetadata>& key_value_metadata = nullptr);
-
-  static std::unique_ptr<ParquetFileWriter> Open(
-      const std::shared_ptr<OutputStream>& sink,
-      const std::shared_ptr<schema::GroupNode>& schema,
-      const std::shared_ptr<WriterProperties>& properties = default_writer_properties(),
-      const std::shared_ptr<const KeyValueMetadata>& key_value_metadata = nullptr);
-
-  void Open(std::unique_ptr<Contents> contents);
-  void Close();
-
-  // Construct a RowGroupWriter for the indicated number of rows.
-  //
-  // Ownership is solely within the ParquetFileWriter. The RowGroupWriter is only valid
-  // until the next call to AppendRowGroup or AppendBufferedRowGroup or Close.
-  // @param num_rows The number of rows that are stored in the new RowGroup
-  //
-  // \deprecated Since 1.3.0
-  RowGroupWriter* AppendRowGroup(int64_t num_rows);
-
-  /// Construct a RowGroupWriter with an arbitrary number of rows.
-  ///
-  /// Ownership is solely within the ParquetFileWriter. The RowGroupWriter is only valid
-  /// until the next call to AppendRowGroup or AppendBufferedRowGroup or Close.
-  RowGroupWriter* AppendRowGroup();
-
-  /// Construct a RowGroupWriter that buffers all the values until the RowGroup is ready.
-  /// Use this if you want to write a RowGroup based on a certain size
-  ///
-  /// Ownership is solely within the ParquetFileWriter. The RowGroupWriter is only valid
-  /// until the next call to AppendRowGroup or AppendBufferedRowGroup or Close.
-  RowGroupWriter* AppendBufferedRowGroup();
-
-  /// Number of columns.
-  ///
-  /// This number is fixed during the lifetime of the writer as it is determined via
-  /// the schema.
-  int num_columns() const;
-
-  /// Number of rows in the yet started RowGroups.
-  ///
-  /// Changes on the addition of a new RowGroup.
-  int64_t num_rows() const;
-
-  /// Number of started RowGroups.
-  int num_row_groups() const;
-
-  /// Configuration passed to the writer, e.g. the used Parquet format version.
-  const std::shared_ptr<WriterProperties>& properties() const;
-
-  /// Returns the file schema descriptor
-  const SchemaDescriptor* schema() const;
-
-  /// Returns a column descriptor in schema
-  const ColumnDescriptor* descr(int i) const;
-
-  /// Returns the file custom metadata
-  const std::shared_ptr<const KeyValueMetadata>& key_value_metadata() const;
-
- private:
-  // Holds a pointer to an instance of Contents implementation
-  std::unique_ptr<Contents> contents_;
-};
-
-}  // namespace parquet
-
-#endif  // PARQUET_FILE_WRITER_H
diff --git a/src/parquet/hasher.h b/src/parquet/hasher.h
deleted file mode 100644
index dc316a0..0000000
--- a/src/parquet/hasher.h
+++ /dev/null
@@ -1,75 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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.
-
-#ifndef PARQUET_HASHER_H
-#define PARQUET_HASHER_H
-
-#include <cstdint>
-#include "parquet/types.h"
-
-namespace parquet {
-// Abstract class for hash
-class Hasher {
- public:
-  /// Compute hash for 32 bits value by using its plain encoding result.
-  ///
-  /// @param value the value to hash.
-  /// @return hash result.
-  virtual uint64_t Hash(int32_t value) const = 0;
-
-  /// Compute hash for 64 bits value by using its plain encoding result.
-  ///
-  /// @param value the value to hash.
-  /// @return hash result.
-  virtual uint64_t Hash(int64_t value) const = 0;
-
-  /// Compute hash for float value by using its plain encoding result.
-  ///
-  /// @param value the value to hash.
-  /// @return hash result.
-  virtual uint64_t Hash(float value) const = 0;
-
-  /// Compute hash for double value by using its plain encoding result.
-  ///
-  /// @param value the value to hash.
-  /// @return hash result.
-  virtual uint64_t Hash(double value) const = 0;
-
-  /// Compute hash for Int96 value by using its plain encoding result.
-  ///
-  /// @param value the value to hash.
-  /// @return hash result.
-  virtual uint64_t Hash(const Int96* value) const = 0;
-
-  /// Compute hash for ByteArray value by using its plain encoding result.
-  ///
-  /// @param value the value to hash.
-  /// @return hash result.
-  virtual uint64_t Hash(const ByteArray* value) const = 0;
-
-  /// Compute hash for fixed byte array value by using its plain encoding result.
-  ///
-  /// @param value the value to hash.
-  /// @return hash result.
-  virtual uint64_t Hash(const FLBA* value, uint32_t len) const = 0;
-
-  virtual ~Hasher() = default;
-};
-
-}  // namespace parquet
-
-#endif  // PARQUET_HASHER_H
diff --git a/src/parquet/metadata-test.cc b/src/parquet/metadata-test.cc
deleted file mode 100644
index 53653bd..0000000
--- a/src/parquet/metadata-test.cc
+++ /dev/null
@@ -1,231 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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.
-
-#include "parquet/metadata.h"
-#include <gtest/gtest.h>
-#include "parquet/schema.h"
-#include "parquet/statistics.h"
-#include "parquet/types.h"
-
-namespace parquet {
-
-namespace metadata {
-
-TEST(Metadata, TestBuildAccess) {
-  parquet::schema::NodeVector fields;
-  parquet::schema::NodePtr root;
-  parquet::SchemaDescriptor schema;
-
-  WriterProperties::Builder prop_builder;
-
-  std::shared_ptr<WriterProperties> props =
-      prop_builder.version(ParquetVersion::PARQUET_2_0)->build();
-
-  fields.push_back(parquet::schema::Int32("int_col", Repetition::REQUIRED));
-  fields.push_back(parquet::schema::Float("float_col", Repetition::REQUIRED));
-  root = parquet::schema::GroupNode::Make("schema", Repetition::REPEATED, fields);
-  schema.Init(root);
-
-  int64_t nrows = 1000;
-  int32_t int_min = 100, int_max = 200;
-  EncodedStatistics stats_int;
-  stats_int.set_null_count(0)
-      .set_distinct_count(nrows)
-      .set_min(std::string(reinterpret_cast<const char*>(&int_min), 4))
-      .set_max(std::string(reinterpret_cast<const char*>(&int_max), 4));
-  EncodedStatistics stats_float;
-  float float_min = 100.100f, float_max = 200.200f;
-  stats_float.set_null_count(0)
-      .set_distinct_count(nrows)
-      .set_min(std::string(reinterpret_cast<const char*>(&float_min), 4))
-      .set_max(std::string(reinterpret_cast<const char*>(&float_max), 4));
-
-  auto f_builder = FileMetaDataBuilder::Make(&schema, props);
-  auto rg1_builder = f_builder->AppendRowGroup();
-  auto rg2_builder = f_builder->AppendRowGroup();
-
-  // Write the metadata
-  // rowgroup1 metadata
-  auto col1_builder = rg1_builder->NextColumnChunk();
-  auto col2_builder = rg1_builder->NextColumnChunk();
-  // column metadata
-  col1_builder->SetStatistics(true, stats_int);
-  col2_builder->SetStatistics(true, stats_float);
-  col1_builder->Finish(nrows / 2, 4, 0, 10, 512, 600, true, false);
-  col2_builder->Finish(nrows / 2, 24, 0, 30, 512, 600, true, false);
-
-  rg1_builder->set_num_rows(nrows / 2);
-  rg1_builder->Finish(1024);
-
-  // rowgroup2 metadata
-  col1_builder = rg2_builder->NextColumnChunk();
-  col2_builder = rg2_builder->NextColumnChunk();
-  // column metadata
-  col1_builder->SetStatistics(true, stats_int);
-  col2_builder->SetStatistics(true, stats_float);
-  col1_builder->Finish(nrows / 2, 6, 0, 10, 512, 600, true, false);
-  col2_builder->Finish(nrows / 2, 16, 0, 26, 512, 600, true, false);
-
-  rg2_builder->set_num_rows(nrows / 2);
-  rg2_builder->Finish(1024);
-
-  // Read the metadata
-  auto f_accessor = f_builder->Finish();
-
-  // file metadata
-  ASSERT_EQ(nrows, f_accessor->num_rows());
-  ASSERT_LE(0, static_cast<int>(f_accessor->size()));
-  ASSERT_EQ(2, f_accessor->num_row_groups());
-  ASSERT_EQ(ParquetVersion::PARQUET_2_0, f_accessor->version());
-  ASSERT_EQ(DEFAULT_CREATED_BY, f_accessor->created_by());
-  ASSERT_EQ(3, f_accessor->num_schema_elements());
-
-  // row group1 metadata
-  auto rg1_accessor = f_accessor->RowGroup(0);
-  ASSERT_EQ(2, rg1_accessor->num_columns());
-  ASSERT_EQ(nrows / 2, rg1_accessor->num_rows());
-  ASSERT_EQ(1024, rg1_accessor->total_byte_size());
-
-  auto rg1_column1 = rg1_accessor->ColumnChunk(0);
-  auto rg1_column2 = rg1_accessor->ColumnChunk(1);
-  ASSERT_EQ(true, rg1_column1->is_stats_set());
-  ASSERT_EQ(true, rg1_column2->is_stats_set());
-  ASSERT_EQ(stats_float.min(), rg1_column2->statistics()->EncodeMin());
-  ASSERT_EQ(stats_float.max(), rg1_column2->statistics()->EncodeMax());
-  ASSERT_EQ(stats_int.min(), rg1_column1->statistics()->EncodeMin());
-  ASSERT_EQ(stats_int.max(), rg1_column1->statistics()->EncodeMax());
-  ASSERT_EQ(0, rg1_column1->statistics()->null_count());
-  ASSERT_EQ(0, rg1_column2->statistics()->null_count());
-  ASSERT_EQ(nrows, rg1_column1->statistics()->distinct_count());
-  ASSERT_EQ(nrows, rg1_column2->statistics()->distinct_count());
-  ASSERT_EQ(DEFAULT_COMPRESSION_TYPE, rg1_column1->compression());
-  ASSERT_EQ(DEFAULT_COMPRESSION_TYPE, rg1_column2->compression());
-  ASSERT_EQ(nrows / 2, rg1_column1->num_values());
-  ASSERT_EQ(nrows / 2, rg1_column2->num_values());
-  ASSERT_EQ(3, rg1_column1->encodings().size());
-  ASSERT_EQ(3, rg1_column2->encodings().size());
-  ASSERT_EQ(512, rg1_column1->total_compressed_size());
-  ASSERT_EQ(512, rg1_column2->total_compressed_size());
-  ASSERT_EQ(600, rg1_column1->total_uncompressed_size());
-  ASSERT_EQ(600, rg1_column2->total_uncompressed_size());
-  ASSERT_EQ(4, rg1_column1->dictionary_page_offset());
-  ASSERT_EQ(24, rg1_column2->dictionary_page_offset());
-  ASSERT_EQ(10, rg1_column1->data_page_offset());
-  ASSERT_EQ(30, rg1_column2->data_page_offset());
-
-  auto rg2_accessor = f_accessor->RowGroup(1);
-  ASSERT_EQ(2, rg2_accessor->num_columns());
-  ASSERT_EQ(nrows / 2, rg2_accessor->num_rows());
-  ASSERT_EQ(1024, rg2_accessor->total_byte_size());
-
-  auto rg2_column1 = rg2_accessor->ColumnChunk(0);
-  auto rg2_column2 = rg2_accessor->ColumnChunk(1);
-  ASSERT_EQ(true, rg2_column1->is_stats_set());
-  ASSERT_EQ(true, rg2_column2->is_stats_set());
-  ASSERT_EQ(stats_float.min(), rg2_column2->statistics()->EncodeMin());
-  ASSERT_EQ(stats_float.max(), rg2_column2->statistics()->EncodeMax());
-  ASSERT_EQ(stats_int.min(), rg1_column1->statistics()->EncodeMin());
-  ASSERT_EQ(stats_int.max(), rg1_column1->statistics()->EncodeMax());
-  ASSERT_EQ(0, rg2_column1->statistics()->null_count());
-  ASSERT_EQ(0, rg2_column2->statistics()->null_count());
-  ASSERT_EQ(nrows, rg2_column1->statistics()->distinct_count());
-  ASSERT_EQ(nrows, rg2_column2->statistics()->distinct_count());
-  ASSERT_EQ(nrows / 2, rg2_column1->num_values());
-  ASSERT_EQ(nrows / 2, rg2_column2->num_values());
-  ASSERT_EQ(DEFAULT_COMPRESSION_TYPE, rg2_column1->compression());
-  ASSERT_EQ(DEFAULT_COMPRESSION_TYPE, rg2_column2->compression());
-  ASSERT_EQ(3, rg2_column1->encodings().size());
-  ASSERT_EQ(3, rg2_column2->encodings().size());
-  ASSERT_EQ(512, rg2_column1->total_compressed_size());
-  ASSERT_EQ(512, rg2_column2->total_compressed_size());
-  ASSERT_EQ(600, rg2_column1->total_uncompressed_size());
-  ASSERT_EQ(600, rg2_column2->total_uncompressed_size());
-  ASSERT_EQ(6, rg2_column1->dictionary_page_offset());
-  ASSERT_EQ(16, rg2_column2->dictionary_page_offset());
-  ASSERT_EQ(10, rg2_column1->data_page_offset());
-  ASSERT_EQ(26, rg2_column2->data_page_offset());
-}
-
-TEST(Metadata, TestV1Version) {
-  // PARQUET-839
-  parquet::schema::NodeVector fields;
-  parquet::schema::NodePtr root;
-  parquet::SchemaDescriptor schema;
-
-  WriterProperties::Builder prop_builder;
-
-  std::shared_ptr<WriterProperties> props =
-      prop_builder.version(ParquetVersion::PARQUET_1_0)->build();
-
-  fields.push_back(parquet::schema::Int32("int_col", Repetition::REQUIRED));
-  fields.push_back(parquet::schema::Float("float_col", Repetition::REQUIRED));
-  root = parquet::schema::GroupNode::Make("schema", Repetition::REPEATED, fields);
-  schema.Init(root);
-
-  auto f_builder = FileMetaDataBuilder::Make(&schema, props);
-
-  // Read the metadata
-  auto f_accessor = f_builder->Finish();
-
-  // file metadata
-  ASSERT_EQ(ParquetVersion::PARQUET_1_0, f_accessor->version());
-}
-
-TEST(ApplicationVersion, Basics) {
-  ApplicationVersion version("parquet-mr version 1.7.9");
-  ApplicationVersion version1("parquet-mr version 1.8.0");
-  ApplicationVersion version2("parquet-cpp version 1.0.0");
-  ApplicationVersion version3("");
-  ApplicationVersion version4("parquet-mr version 1.5.0ab-cdh5.5.0+cd (build abcd)");
-  ApplicationVersion version5("parquet-mr");
-
-  ASSERT_EQ("parquet-mr", version.application_);
-  ASSERT_EQ(1, version.version.major);
-  ASSERT_EQ(7, version.version.minor);
-  ASSERT_EQ(9, version.version.patch);
-
-  ASSERT_EQ("parquet-cpp", version2.application_);
-  ASSERT_EQ(1, version2.version.major);
-  ASSERT_EQ(0, version2.version.minor);
-  ASSERT_EQ(0, version2.version.patch);
-
-  ASSERT_EQ("parquet-mr", version4.application_);
-  ASSERT_EQ("abcd", version4.build_);
-  ASSERT_EQ(1, version4.version.major);
-  ASSERT_EQ(5, version4.version.minor);
-  ASSERT_EQ(0, version4.version.patch);
-  ASSERT_EQ("ab", version4.version.unknown);
-  ASSERT_EQ("cdh5.5.0", version4.version.pre_release);
-  ASSERT_EQ("cd", version4.version.build_info);
-
-  ASSERT_EQ("parquet-mr", version5.application_);
-  ASSERT_EQ(0, version5.version.major);
-  ASSERT_EQ(0, version5.version.minor);
-  ASSERT_EQ(0, version5.version.patch);
-
-  ASSERT_EQ(true, version.VersionLt(version1));
-
-  ASSERT_FALSE(version1.HasCorrectStatistics(Type::INT96, SortOrder::UNKNOWN));
-  ASSERT_TRUE(version.HasCorrectStatistics(Type::INT32, SortOrder::SIGNED));
-  ASSERT_FALSE(version.HasCorrectStatistics(Type::BYTE_ARRAY, SortOrder::SIGNED));
-  ASSERT_TRUE(version1.HasCorrectStatistics(Type::BYTE_ARRAY, SortOrder::SIGNED));
-  ASSERT_TRUE(
-      version3.HasCorrectStatistics(Type::FIXED_LEN_BYTE_ARRAY, SortOrder::SIGNED));
-}
-
-}  // namespace metadata
-}  // namespace parquet
diff --git a/src/parquet/metadata.cc b/src/parquet/metadata.cc
deleted file mode 100644
index 1cab51f..0000000
--- a/src/parquet/metadata.cc
+++ /dev/null
@@ -1,910 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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.
-
-#include <algorithm>
-#include <string>
-#include <vector>
-
-#include "parquet/exception.h"
-#include "parquet/metadata.h"
-#include "parquet/schema-internal.h"
-#include "parquet/schema.h"
-#include "parquet/thrift.h"
-#include "parquet/util/memory.h"
-
-#include <boost/algorithm/string.hpp>
-#include <boost/regex.hpp>
-
-namespace parquet {
-
-const ApplicationVersion& ApplicationVersion::PARQUET_251_FIXED_VERSION() {
-  static ApplicationVersion version("parquet-mr", 1, 8, 0);
-  return version;
-}
-
-const ApplicationVersion& ApplicationVersion::PARQUET_816_FIXED_VERSION() {
-  static ApplicationVersion version("parquet-mr", 1, 2, 9);
-  return version;
-}
-
-const ApplicationVersion& ApplicationVersion::PARQUET_CPP_FIXED_STATS_VERSION() {
-  static ApplicationVersion version("parquet-cpp", 1, 3, 0);
-  return version;
-}
-
-template <typename DType>
-static std::shared_ptr<RowGroupStatistics> MakeTypedColumnStats(
-    const format::ColumnMetaData& metadata, const ColumnDescriptor* descr) {
-  // If ColumnOrder is defined, return max_value and min_value
-  if (descr->column_order().get_order() == ColumnOrder::TYPE_DEFINED_ORDER) {
-    return std::make_shared<TypedRowGroupStatistics<DType>>(
-        descr, metadata.statistics.min_value, metadata.statistics.max_value,
-        metadata.num_values - metadata.statistics.null_count,
-        metadata.statistics.null_count, metadata.statistics.distinct_count, true);
-  }
-  // Default behavior
-  return std::make_shared<TypedRowGroupStatistics<DType>>(
-      descr, metadata.statistics.min, metadata.statistics.max,
-      metadata.num_values - metadata.statistics.null_count,
-      metadata.statistics.null_count, metadata.statistics.distinct_count,
-      metadata.statistics.__isset.max || metadata.statistics.__isset.min);
-}
-
-std::shared_ptr<RowGroupStatistics> MakeColumnStats(
-    const format::ColumnMetaData& meta_data, const ColumnDescriptor* descr) {
-  switch (static_cast<Type::type>(meta_data.type)) {
-    case Type::BOOLEAN:
-      return MakeTypedColumnStats<BooleanType>(meta_data, descr);
-    case Type::INT32:
-      return MakeTypedColumnStats<Int32Type>(meta_data, descr);
-    case Type::INT64:
-      return MakeTypedColumnStats<Int64Type>(meta_data, descr);
-    case Type::INT96:
-      return MakeTypedColumnStats<Int96Type>(meta_data, descr);
-    case Type::DOUBLE:
-      return MakeTypedColumnStats<DoubleType>(meta_data, descr);
-    case Type::FLOAT:
-      return MakeTypedColumnStats<FloatType>(meta_data, descr);
-    case Type::BYTE_ARRAY:
-      return MakeTypedColumnStats<ByteArrayType>(meta_data, descr);
-    case Type::FIXED_LEN_BYTE_ARRAY:
-      return MakeTypedColumnStats<FLBAType>(meta_data, descr);
-  }
-  throw ParquetException("Can't decode page statistics for selected column type");
-}
-
-// MetaData Accessor
-// ColumnChunk metadata
-class ColumnChunkMetaData::ColumnChunkMetaDataImpl {
- public:
-  explicit ColumnChunkMetaDataImpl(const format::ColumnChunk* column,
-                                   const ColumnDescriptor* descr,
-                                   const ApplicationVersion* writer_version)
-      : column_(column), descr_(descr), writer_version_(writer_version) {
-    const format::ColumnMetaData& meta_data = column->meta_data;
-    for (auto encoding : meta_data.encodings) {
-      encodings_.push_back(FromThrift(encoding));
-    }
-    stats_ = nullptr;
-  }
-  ~ColumnChunkMetaDataImpl() {}
-
-  // column chunk
-  inline int64_t file_offset() const { return column_->file_offset; }
-  inline const std::string& file_path() const { return column_->file_path; }
-
-  // column metadata
-  inline Type::type type() const { return FromThrift(column_->meta_data.type); }
-
-  inline int64_t num_values() const { return column_->meta_data.num_values; }
-
-  std::shared_ptr<schema::ColumnPath> path_in_schema() {
-    return std::make_shared<schema::ColumnPath>(column_->meta_data.path_in_schema);
-  }
-
-  // Check if statistics are set and are valid
-  // 1) Must be set in the metadata
-  // 2) Statistics must not be corrupted
-  // 3) parquet-mr and parquet-cpp write statistics by SIGNED order comparison.
-  //    The statistics are corrupted if the type requires UNSIGNED order comparison.
-  //    Eg: UTF8
-  inline bool is_stats_set() const {
-    DCHECK(writer_version_ != nullptr);
-    return column_->meta_data.__isset.statistics &&
-           writer_version_->HasCorrectStatistics(type(), descr_->sort_order());
-  }
-
-  inline std::shared_ptr<RowGroupStatistics> statistics() const {
-    if (stats_ == nullptr && is_stats_set()) {
-      stats_ = MakeColumnStats(column_->meta_data, descr_);
-    }
-    return stats_;
-  }
-
-  inline Compression::type compression() const {
-    return FromThrift(column_->meta_data.codec);
-  }
-
-  const std::vector<Encoding::type>& encodings() const { return encodings_; }
-
-  inline bool has_dictionary_page() const {
-    return column_->meta_data.__isset.dictionary_page_offset;
-  }
-
-  inline int64_t dictionary_page_offset() const {
-    return column_->meta_data.dictionary_page_offset;
-  }
-
-  inline int64_t data_page_offset() const { return column_->meta_data.data_page_offset; }
-
-  inline bool has_index_page() const {
-    return column_->meta_data.__isset.index_page_offset;
-  }
-
-  inline int64_t index_page_offset() const {
-    return column_->meta_data.index_page_offset;
-  }
-
-  inline int64_t total_compressed_size() const {
-    return column_->meta_data.total_compressed_size;
-  }
-
-  inline int64_t total_uncompressed_size() const {
-    return column_->meta_data.total_uncompressed_size;
-  }
-
- private:
-  mutable std::shared_ptr<RowGroupStatistics> stats_;
-  std::vector<Encoding::type> encodings_;
-  const format::ColumnChunk* column_;
-  const ColumnDescriptor* descr_;
-  const ApplicationVersion* writer_version_;
-};
-
-std::unique_ptr<ColumnChunkMetaData> ColumnChunkMetaData::Make(
-    const uint8_t* metadata, const ColumnDescriptor* descr,
-    const ApplicationVersion* writer_version) {
-  return std::unique_ptr<ColumnChunkMetaData>(
-      new ColumnChunkMetaData(metadata, descr, writer_version));
-}
-
-ColumnChunkMetaData::ColumnChunkMetaData(const uint8_t* metadata,
-                                         const ColumnDescriptor* descr,
-                                         const ApplicationVersion* writer_version)
-    : impl_{std::unique_ptr<ColumnChunkMetaDataImpl>(new ColumnChunkMetaDataImpl(
-          reinterpret_cast<const format::ColumnChunk*>(metadata), descr,
-          writer_version))} {}
-ColumnChunkMetaData::~ColumnChunkMetaData() {}
-
-// column chunk
-int64_t ColumnChunkMetaData::file_offset() const { return impl_->file_offset(); }
-
-const std::string& ColumnChunkMetaData::file_path() const { return impl_->file_path(); }
-
-// column metadata
-Type::type ColumnChunkMetaData::type() const { return impl_->type(); }
-
-int64_t ColumnChunkMetaData::num_values() const { return impl_->num_values(); }
-
-std::shared_ptr<schema::ColumnPath> ColumnChunkMetaData::path_in_schema() const {
-  return impl_->path_in_schema();
-}
-
-std::shared_ptr<RowGroupStatistics> ColumnChunkMetaData::statistics() const {
-  return impl_->statistics();
-}
-
-bool ColumnChunkMetaData::is_stats_set() const { return impl_->is_stats_set(); }
-
-bool ColumnChunkMetaData::has_dictionary_page() const {
-  return impl_->has_dictionary_page();
-}
-
-int64_t ColumnChunkMetaData::dictionary_page_offset() const {
-  return impl_->dictionary_page_offset();
-}
-
-int64_t ColumnChunkMetaData::data_page_offset() const {
-  return impl_->data_page_offset();
-}
-
-bool ColumnChunkMetaData::has_index_page() const { return impl_->has_index_page(); }
-
-int64_t ColumnChunkMetaData::index_page_offset() const {
-  return impl_->index_page_offset();
-}
-
-Compression::type ColumnChunkMetaData::compression() const {
-  return impl_->compression();
-}
-
-const std::vector<Encoding::type>& ColumnChunkMetaData::encodings() const {
-  return impl_->encodings();
-}
-
-int64_t ColumnChunkMetaData::total_uncompressed_size() const {
-  return impl_->total_uncompressed_size();
-}
-
-int64_t ColumnChunkMetaData::total_compressed_size() const {
-  return impl_->total_compressed_size();
-}
-
-// row-group metadata
-class RowGroupMetaData::RowGroupMetaDataImpl {
- public:
-  explicit RowGroupMetaDataImpl(const format::RowGroup* row_group,
-                                const SchemaDescriptor* schema,
-                                const ApplicationVersion* writer_version)
-      : row_group_(row_group), schema_(schema), writer_version_(writer_version) {}
-  ~RowGroupMetaDataImpl() {}
-
-  inline int num_columns() const { return static_cast<int>(row_group_->columns.size()); }
-
-  inline int64_t num_rows() const { return row_group_->num_rows; }
-
-  inline int64_t total_byte_size() const { return row_group_->total_byte_size; }
-
-  inline const SchemaDescriptor* schema() const { return schema_; }
-
-  std::unique_ptr<ColumnChunkMetaData> ColumnChunk(int i) {
-    if (!(i < num_columns())) {
-      std::stringstream ss;
-      ss << "The file only has " << num_columns()
-         << " columns, requested metadata for column: " << i;
-      throw ParquetException(ss.str());
-    }
-    return ColumnChunkMetaData::Make(
-        reinterpret_cast<const uint8_t*>(&row_group_->columns[i]), schema_->Column(i),
-        writer_version_);
-  }
-
- private:
-  const format::RowGroup* row_group_;
-  const SchemaDescriptor* schema_;
-  const ApplicationVersion* writer_version_;
-};
-
-std::unique_ptr<RowGroupMetaData> RowGroupMetaData::Make(
-    const uint8_t* metadata, const SchemaDescriptor* schema,
-    const ApplicationVersion* writer_version) {
-  return std::unique_ptr<RowGroupMetaData>(
-      new RowGroupMetaData(metadata, schema, writer_version));
-}
-
-RowGroupMetaData::RowGroupMetaData(const uint8_t* metadata,
-                                   const SchemaDescriptor* schema,
-                                   const ApplicationVersion* writer_version)
-    : impl_{std::unique_ptr<RowGroupMetaDataImpl>(new RowGroupMetaDataImpl(
-          reinterpret_cast<const format::RowGroup*>(metadata), schema, writer_version))} {
-}
-RowGroupMetaData::~RowGroupMetaData() {}
-
-int RowGroupMetaData::num_columns() const { return impl_->num_columns(); }
-
-int64_t RowGroupMetaData::num_rows() const { return impl_->num_rows(); }
-
-int64_t RowGroupMetaData::total_byte_size() const { return impl_->total_byte_size(); }
-
-const SchemaDescriptor* RowGroupMetaData::schema() const { return impl_->schema(); }
-
-std::unique_ptr<ColumnChunkMetaData> RowGroupMetaData::ColumnChunk(int i) const {
-  return impl_->ColumnChunk(i);
-}
-
-// file metadata
-class FileMetaData::FileMetaDataImpl {
- public:
-  FileMetaDataImpl() : metadata_len_(0) {}
-
-  explicit FileMetaDataImpl(const uint8_t* metadata, uint32_t* metadata_len)
-      : metadata_len_(0) {
-    metadata_.reset(new format::FileMetaData);
-    DeserializeThriftMsg(metadata, metadata_len, metadata_.get());
-    metadata_len_ = *metadata_len;
-
-    if (metadata_->__isset.created_by) {
-      writer_version_ = ApplicationVersion(metadata_->created_by);
-    } else {
-      writer_version_ = ApplicationVersion("unknown 0.0.0");
-    }
-
-    InitSchema();
-    InitColumnOrders();
-    InitKeyValueMetadata();
-  }
-  ~FileMetaDataImpl() {}
-
-  inline uint32_t size() const { return metadata_len_; }
-  inline int num_columns() const { return schema_.num_columns(); }
-  inline int64_t num_rows() const { return metadata_->num_rows; }
-  inline int num_row_groups() const {
-    return static_cast<int>(metadata_->row_groups.size());
-  }
-  inline int32_t version() const { return metadata_->version; }
-  inline const std::string& created_by() const { return metadata_->created_by; }
-  inline int num_schema_elements() const {
-    return static_cast<int>(metadata_->schema.size());
-  }
-
-  const ApplicationVersion& writer_version() const { return writer_version_; }
-
-  void WriteTo(OutputStream* dst) const {
-    SerializeThriftMsg(metadata_.get(), 1024, dst);
-  }
-
-  std::unique_ptr<RowGroupMetaData> RowGroup(int i) {
-    if (!(i < num_row_groups())) {
-      std::stringstream ss;
-      ss << "The file only has " << num_row_groups()
-         << " row groups, requested metadata for row group: " << i;
-      throw ParquetException(ss.str());
-    }
-    return RowGroupMetaData::Make(
-        reinterpret_cast<const uint8_t*>(&metadata_->row_groups[i]), &schema_,
-        &writer_version_);
-  }
-
-  const SchemaDescriptor* schema() const { return &schema_; }
-
-  std::shared_ptr<const KeyValueMetadata> key_value_metadata() const {
-    return key_value_metadata_;
-  }
-
- private:
-  friend FileMetaDataBuilder;
-  uint32_t metadata_len_;
-  std::unique_ptr<format::FileMetaData> metadata_;
-  void InitSchema() {
-    schema::FlatSchemaConverter converter(&metadata_->schema[0],
-                                          static_cast<int>(metadata_->schema.size()));
-    schema_.Init(converter.Convert());
-  }
-  void InitColumnOrders() {
-    // update ColumnOrder
-    std::vector<parquet::ColumnOrder> column_orders;
-    if (metadata_->__isset.column_orders) {
-      for (auto column_order : metadata_->column_orders) {
-        if (column_order.__isset.TYPE_ORDER) {
-          column_orders.push_back(ColumnOrder::type_defined_);
-        } else {
-          column_orders.push_back(ColumnOrder::undefined_);
-        }
-      }
-    } else {
-      column_orders.resize(schema_.num_columns(), ColumnOrder::undefined_);
-    }
-
-    schema_.updateColumnOrders(column_orders);
-  }
-  SchemaDescriptor schema_;
-  ApplicationVersion writer_version_;
-
-  void InitKeyValueMetadata() {
-    std::shared_ptr<KeyValueMetadata> metadata = nullptr;
-    if (metadata_->__isset.key_value_metadata) {
-      metadata = std::make_shared<KeyValueMetadata>();
-      for (const auto& it : metadata_->key_value_metadata) {
-        metadata->Append(it.key, it.value);
-      }
-    }
-    key_value_metadata_ = metadata;
-  }
-
-  std::shared_ptr<const KeyValueMetadata> key_value_metadata_;
-};
-
-std::shared_ptr<FileMetaData> FileMetaData::Make(const uint8_t* metadata,
-                                                 uint32_t* metadata_len) {
-  // This FileMetaData ctor is private, not compatible with std::make_shared
-  return std::shared_ptr<FileMetaData>(new FileMetaData(metadata, metadata_len));
-}
-
-FileMetaData::FileMetaData(const uint8_t* metadata, uint32_t* metadata_len)
-    : impl_{std::unique_ptr<FileMetaDataImpl>(
-          new FileMetaDataImpl(metadata, metadata_len))} {}
-
-FileMetaData::FileMetaData()
-    : impl_{std::unique_ptr<FileMetaDataImpl>(new FileMetaDataImpl())} {}
-
-FileMetaData::~FileMetaData() {}
-
-std::unique_ptr<RowGroupMetaData> FileMetaData::RowGroup(int i) const {
-  return impl_->RowGroup(i);
-}
-
-uint32_t FileMetaData::size() const { return impl_->size(); }
-
-int FileMetaData::num_columns() const { return impl_->num_columns(); }
-
-int64_t FileMetaData::num_rows() const { return impl_->num_rows(); }
-
-int FileMetaData::num_row_groups() const { return impl_->num_row_groups(); }
-
-ParquetVersion::type FileMetaData::version() const {
-  switch (impl_->version()) {
-    case 1:
-      return ParquetVersion::PARQUET_1_0;
-    case 2:
-      return ParquetVersion::PARQUET_2_0;
-    default:
-      // Improperly set version, assuming Parquet 1.0
-      break;
-  }
-  return ParquetVersion::PARQUET_1_0;
-}
-
-const ApplicationVersion& FileMetaData::writer_version() const {
-  return impl_->writer_version();
-}
-
-const std::string& FileMetaData::created_by() const { return impl_->created_by(); }
-
-int FileMetaData::num_schema_elements() const { return impl_->num_schema_elements(); }
-
-const SchemaDescriptor* FileMetaData::schema() const { return impl_->schema(); }
-
-std::shared_ptr<const KeyValueMetadata> FileMetaData::key_value_metadata() const {
-  return impl_->key_value_metadata();
-}
-
-void FileMetaData::WriteTo(OutputStream* dst) const { return impl_->WriteTo(dst); }
-
-ApplicationVersion::ApplicationVersion(const std::string& application, int major,
-                                       int minor, int patch)
-    : application_(application), version{major, minor, patch, "", "", ""} {}
-
-ApplicationVersion::ApplicationVersion(const std::string& created_by) {
-  boost::regex app_regex{ApplicationVersion::APPLICATION_FORMAT};
-  boost::regex ver_regex{ApplicationVersion::VERSION_FORMAT};
-  boost::smatch app_matches;
-  boost::smatch ver_matches;
-
-  std::string created_by_lower = created_by;
-  std::transform(created_by_lower.begin(), created_by_lower.end(),
-                 created_by_lower.begin(), ::tolower);
-
-  bool app_success = boost::regex_match(created_by_lower, app_matches, app_regex);
-  bool ver_success = false;
-  std::string version_str;
-
-  if (app_success && app_matches.size() >= 4) {
-    // first match is the entire string. sub-matches start from second.
-    application_ = app_matches[1];
-    version_str = app_matches[3];
-    build_ = app_matches[4];
-    ver_success = boost::regex_match(version_str, ver_matches, ver_regex);
-  } else {
-    application_ = "unknown";
-  }
-
-  if (ver_success && ver_matches.size() >= 7) {
-    version.major = atoi(ver_matches[1].str().c_str());
-    version.minor = atoi(ver_matches[2].str().c_str());
-    version.patch = atoi(ver_matches[3].str().c_str());
-    version.unknown = ver_matches[4].str();
-    version.pre_release = ver_matches[5].str();
-    version.build_info = ver_matches[6].str();
-  } else {
-    version.major = 0;
-    version.minor = 0;
-    version.patch = 0;
-  }
-}
-
-bool ApplicationVersion::VersionLt(const ApplicationVersion& other_version) const {
-  if (application_ != other_version.application_) return false;
-
-  if (version.major < other_version.version.major) return true;
-  if (version.major > other_version.version.major) return false;
-  DCHECK_EQ(version.major, other_version.version.major);
-  if (version.minor < other_version.version.minor) return true;
-  if (version.minor > other_version.version.minor) return false;
-  DCHECK_EQ(version.minor, other_version.version.minor);
-  return version.patch < other_version.version.patch;
-}
-
-bool ApplicationVersion::VersionEq(const ApplicationVersion& other_version) const {
-  return application_ == other_version.application_ &&
-         version.major == other_version.version.major &&
-         version.minor == other_version.version.minor &&
-         version.patch == other_version.version.patch;
-}
-
-// Reference:
-// parquet-mr/parquet-column/src/main/java/org/apache/parquet/CorruptStatistics.java
-// PARQUET-686 has more disussion on statistics
-bool ApplicationVersion::HasCorrectStatistics(Type::type col_type,
-                                              SortOrder::type sort_order) const {
-  // Parquet cpp version 1.3.0 onwards stats are computed correctly for all types
-  if ((application_ != "parquet-cpp") || (VersionLt(PARQUET_CPP_FIXED_STATS_VERSION()))) {
-    // Only SIGNED are valid
-    if (SortOrder::SIGNED != sort_order) {
-      return false;
-    }
-
-    // Statistics of other types are OK
-    if (col_type != Type::FIXED_LEN_BYTE_ARRAY && col_type != Type::BYTE_ARRAY) {
-      return true;
-    }
-  }
-  // created_by is not populated, which could have been caused by
-  // parquet-mr during the same time as PARQUET-251, see PARQUET-297
-  if (application_ == "unknown") {
-    return true;
-  }
-
-  // Unknown sort order has incorrect stats
-  if (SortOrder::UNKNOWN == sort_order) {
-    return false;
-  }
-
-  // PARQUET-251
-  if (VersionLt(PARQUET_251_FIXED_VERSION())) {
-    return false;
-  }
-
-  return true;
-}
-
-// MetaData Builders
-// row-group metadata
-class ColumnChunkMetaDataBuilder::ColumnChunkMetaDataBuilderImpl {
- public:
-  explicit ColumnChunkMetaDataBuilderImpl(const std::shared_ptr<WriterProperties>& props,
-                                          const ColumnDescriptor* column,
-                                          uint8_t* contents)
-      : properties_(props), column_(column) {
-    column_chunk_ = reinterpret_cast<format::ColumnChunk*>(contents);
-    column_chunk_->meta_data.__set_type(ToThrift(column->physical_type()));
-    column_chunk_->meta_data.__set_path_in_schema(column->path()->ToDotVector());
-    column_chunk_->meta_data.__set_codec(
-        ToThrift(properties_->compression(column->path())));
-  }
-  ~ColumnChunkMetaDataBuilderImpl() {}
-
-  // column chunk
-  void set_file_path(const std::string& val) { column_chunk_->__set_file_path(val); }
-
-  // column metadata
-  void SetStatistics(bool is_signed, const EncodedStatistics& val) {
-    format::Statistics stats;
-    stats.null_count = val.null_count;
-    stats.distinct_count = val.distinct_count;
-    stats.max_value = val.max();
-    stats.min_value = val.min();
-    stats.__isset.min_value = val.has_min;
-    stats.__isset.max_value = val.has_max;
-    stats.__isset.null_count = val.has_null_count;
-    stats.__isset.distinct_count = val.has_distinct_count;
-    // If the order is SIGNED, then the old min/max values must be set too.
-    // This for backward compatibility
-    if (is_signed) {
-      stats.max = val.max();
-      stats.min = val.min();
-      stats.__isset.min = val.has_min;
-      stats.__isset.max = val.has_max;
-    }
-
-    column_chunk_->meta_data.__set_statistics(stats);
-  }
-
-  void Finish(int64_t num_values, int64_t dictionary_page_offset,
-              int64_t index_page_offset, int64_t data_page_offset,
-              int64_t compressed_size, int64_t uncompressed_size, bool has_dictionary,
-              bool dictionary_fallback) {
-    if (dictionary_page_offset > 0) {
-      column_chunk_->meta_data.__set_dictionary_page_offset(dictionary_page_offset);
-      column_chunk_->__set_file_offset(dictionary_page_offset + compressed_size);
-    } else {
-      column_chunk_->__set_file_offset(data_page_offset + compressed_size);
-    }
-    column_chunk_->__isset.meta_data = true;
-    column_chunk_->meta_data.__set_num_values(num_values);
-    if (index_page_offset >= 0) {
-      column_chunk_->meta_data.__set_index_page_offset(index_page_offset);
-    }
-    column_chunk_->meta_data.__set_data_page_offset(data_page_offset);
-    column_chunk_->meta_data.__set_total_uncompressed_size(uncompressed_size);
-    column_chunk_->meta_data.__set_total_compressed_size(compressed_size);
-    std::vector<format::Encoding::type> thrift_encodings;
-    if (has_dictionary) {
-      thrift_encodings.push_back(ToThrift(properties_->dictionary_index_encoding()));
-      if (properties_->version() == ParquetVersion::PARQUET_1_0) {
-        thrift_encodings.push_back(ToThrift(Encoding::PLAIN));
-      } else {
-        thrift_encodings.push_back(ToThrift(properties_->dictionary_page_encoding()));
-      }
-    } else {  // Dictionary not enabled
-      thrift_encodings.push_back(ToThrift(properties_->encoding(column_->path())));
-    }
-    thrift_encodings.push_back(ToThrift(Encoding::RLE));
-    // Only PLAIN encoding is supported for fallback in V1
-    // TODO(majetideepak): Use user specified encoding for V2
-    if (dictionary_fallback) {
-      thrift_encodings.push_back(ToThrift(Encoding::PLAIN));
-    }
-    column_chunk_->meta_data.__set_encodings(thrift_encodings);
-  }
-
-  void WriteTo(OutputStream* sink) {
-    SerializeThriftMsg(column_chunk_, sizeof(format::ColumnChunk), sink);
-  }
-
-  const ColumnDescriptor* descr() const { return column_; }
-
- private:
-  format::ColumnChunk* column_chunk_;
-  const std::shared_ptr<WriterProperties> properties_;
-  const ColumnDescriptor* column_;
-};
-
-std::unique_ptr<ColumnChunkMetaDataBuilder> ColumnChunkMetaDataBuilder::Make(
-    const std::shared_ptr<WriterProperties>& props, const ColumnDescriptor* column,
-    uint8_t* contents) {
-  return std::unique_ptr<ColumnChunkMetaDataBuilder>(
-      new ColumnChunkMetaDataBuilder(props, column, contents));
-}
-
-ColumnChunkMetaDataBuilder::ColumnChunkMetaDataBuilder(
-    const std::shared_ptr<WriterProperties>& props, const ColumnDescriptor* column,
-    uint8_t* contents)
-    : impl_{std::unique_ptr<ColumnChunkMetaDataBuilderImpl>(
-          new ColumnChunkMetaDataBuilderImpl(props, column, contents))} {}
-
-ColumnChunkMetaDataBuilder::~ColumnChunkMetaDataBuilder() {}
-
-void ColumnChunkMetaDataBuilder::set_file_path(const std::string& path) {
-  impl_->set_file_path(path);
-}
-
-void ColumnChunkMetaDataBuilder::Finish(int64_t num_values,
-                                        int64_t dictionary_page_offset,
-                                        int64_t index_page_offset,
-                                        int64_t data_page_offset, int64_t compressed_size,
-                                        int64_t uncompressed_size, bool has_dictionary,
-                                        bool dictionary_fallback) {
-  impl_->Finish(num_values, dictionary_page_offset, index_page_offset, data_page_offset,
-                compressed_size, uncompressed_size, has_dictionary, dictionary_fallback);
-}
-
-void ColumnChunkMetaDataBuilder::WriteTo(OutputStream* sink) { impl_->WriteTo(sink); }
-
-const ColumnDescriptor* ColumnChunkMetaDataBuilder::descr() const {
-  return impl_->descr();
-}
-
-void ColumnChunkMetaDataBuilder::SetStatistics(bool is_signed,
-                                               const EncodedStatistics& result) {
-  impl_->SetStatistics(is_signed, result);
-}
-
-class RowGroupMetaDataBuilder::RowGroupMetaDataBuilderImpl {
- public:
-  explicit RowGroupMetaDataBuilderImpl(const std::shared_ptr<WriterProperties>& props,
-                                       const SchemaDescriptor* schema, uint8_t* contents)
-      : properties_(props), schema_(schema), current_column_(0) {
-    row_group_ = reinterpret_cast<format::RowGroup*>(contents);
-    InitializeColumns(schema->num_columns());
-  }
-  ~RowGroupMetaDataBuilderImpl() {}
-
-  ColumnChunkMetaDataBuilder* NextColumnChunk() {
-    if (!(current_column_ < num_columns())) {
-      std::stringstream ss;
-      ss << "The schema only has " << num_columns()
-         << " columns, requested metadata for column: " << current_column_;
-      throw ParquetException(ss.str());
-    }
-    auto column = schema_->Column(current_column_);
-    auto column_builder = ColumnChunkMetaDataBuilder::Make(
-        properties_, column,
-        reinterpret_cast<uint8_t*>(&row_group_->columns[current_column_++]));
-    auto column_builder_ptr = column_builder.get();
-    column_builders_.push_back(std::move(column_builder));
-    return column_builder_ptr;
-  }
-
-  int current_column() { return current_column_; }
-
-  void Finish(int64_t total_bytes_written) {
-    if (!(current_column_ == schema_->num_columns())) {
-      std::stringstream ss;
-      ss << "Only " << current_column_ - 1 << " out of " << schema_->num_columns()
-         << " columns are initialized";
-      throw ParquetException(ss.str());
-    }
-    int64_t total_byte_size = 0;
-
-    for (int i = 0; i < schema_->num_columns(); i++) {
-      if (!(row_group_->columns[i].file_offset >= 0)) {
-        std::stringstream ss;
-        ss << "Column " << i << " is not complete.";
-        throw ParquetException(ss.str());
-      }
-      total_byte_size += row_group_->columns[i].meta_data.total_compressed_size;
-    }
-    DCHECK(total_bytes_written == total_byte_size)
-        << "Total bytes in this RowGroup does not match with compressed sizes of columns";
-
-    row_group_->__set_total_byte_size(total_byte_size);
-  }
-
-  void set_num_rows(int64_t num_rows) { row_group_->num_rows = num_rows; }
-
-  int num_columns() { return static_cast<int>(row_group_->columns.size()); }
-
-  int64_t num_rows() { return row_group_->num_rows; }
-
- private:
-  void InitializeColumns(int ncols) { row_group_->columns.resize(ncols); }
-
-  format::RowGroup* row_group_;
-  const std::shared_ptr<WriterProperties> properties_;
-  const SchemaDescriptor* schema_;
-  std::vector<std::unique_ptr<ColumnChunkMetaDataBuilder>> column_builders_;
-  int current_column_;
-};
-
-std::unique_ptr<RowGroupMetaDataBuilder> RowGroupMetaDataBuilder::Make(
-    const std::shared_ptr<WriterProperties>& props, const SchemaDescriptor* schema_,
-    uint8_t* contents) {
-  return std::unique_ptr<RowGroupMetaDataBuilder>(
-      new RowGroupMetaDataBuilder(props, schema_, contents));
-}
-
-RowGroupMetaDataBuilder::RowGroupMetaDataBuilder(
-    const std::shared_ptr<WriterProperties>& props, const SchemaDescriptor* schema_,
-    uint8_t* contents)
-    : impl_{std::unique_ptr<RowGroupMetaDataBuilderImpl>(
-          new RowGroupMetaDataBuilderImpl(props, schema_, contents))} {}
-
-RowGroupMetaDataBuilder::~RowGroupMetaDataBuilder() {}
-
-ColumnChunkMetaDataBuilder* RowGroupMetaDataBuilder::NextColumnChunk() {
-  return impl_->NextColumnChunk();
-}
-
-int RowGroupMetaDataBuilder::current_column() const { return impl_->current_column(); }
-
-int RowGroupMetaDataBuilder::num_columns() { return impl_->num_columns(); }
-
-int64_t RowGroupMetaDataBuilder::num_rows() { return impl_->num_rows(); }
-
-void RowGroupMetaDataBuilder::set_num_rows(int64_t num_rows) {
-  impl_->set_num_rows(num_rows);
-}
-
-void RowGroupMetaDataBuilder::Finish(int64_t total_bytes_written) {
-  impl_->Finish(total_bytes_written);
-}
-
-// file metadata
-// TODO(PARQUET-595) Support key_value_metadata
-class FileMetaDataBuilder::FileMetaDataBuilderImpl {
- public:
-  explicit FileMetaDataBuilderImpl(
-      const SchemaDescriptor* schema, const std::shared_ptr<WriterProperties>& props,
-      const std::shared_ptr<const KeyValueMetadata>& key_value_metadata)
-      : properties_(props), schema_(schema), key_value_metadata_(key_value_metadata) {
-    metadata_.reset(new format::FileMetaData());
-  }
-  ~FileMetaDataBuilderImpl() {}
-
-  RowGroupMetaDataBuilder* AppendRowGroup() {
-    auto row_group = std::unique_ptr<format::RowGroup>(new format::RowGroup());
-    auto row_group_builder = RowGroupMetaDataBuilder::Make(
-        properties_, schema_, reinterpret_cast<uint8_t*>(row_group.get()));
-    RowGroupMetaDataBuilder* row_group_ptr = row_group_builder.get();
-    row_group_builders_.push_back(std::move(row_group_builder));
-    row_groups_.push_back(std::move(row_group));
-    return row_group_ptr;
-  }
-
-  std::unique_ptr<FileMetaData> Finish() {
-    int64_t total_rows = 0;
-    std::vector<format::RowGroup> row_groups;
-    for (auto row_group = row_groups_.begin(); row_group != row_groups_.end();
-         row_group++) {
-      auto rowgroup = *((*row_group).get());
-      row_groups.push_back(rowgroup);
-      total_rows += rowgroup.num_rows;
-    }
-    metadata_->__set_num_rows(total_rows);
-    metadata_->__set_row_groups(row_groups);
-
-    if (key_value_metadata_) {
-      metadata_->key_value_metadata.clear();
-      metadata_->key_value_metadata.reserve(key_value_metadata_->size());
-      for (int64_t i = 0; i < key_value_metadata_->size(); ++i) {
-        format::KeyValue kv_pair;
-        kv_pair.__set_key(key_value_metadata_->key(i));
-        kv_pair.__set_value(key_value_metadata_->value(i));
-        metadata_->key_value_metadata.push_back(kv_pair);
-      }
-      metadata_->__isset.key_value_metadata = true;
-    }
-
-    int32_t file_version = 0;
-    switch (properties_->version()) {
-      case ParquetVersion::PARQUET_1_0:
-        file_version = 1;
-        break;
-      case ParquetVersion::PARQUET_2_0:
-        file_version = 2;
-        break;
-      default:
-        break;
-    }
-    metadata_->__set_version(file_version);
-    metadata_->__set_created_by(properties_->created_by());
-
-    // Users cannot set the `ColumnOrder` since we donot not have user defined sort order
-    // in the spec yet.
-    // We always default to `TYPE_DEFINED_ORDER`. We can expose it in
-    // the API once we have user defined sort orders in the Parquet format.
-    // TypeDefinedOrder implies choose SortOrder based on LogicalType/PhysicalType
-    format::TypeDefinedOrder type_defined_order;
-    format::ColumnOrder column_order;
-    column_order.__set_TYPE_ORDER(type_defined_order);
-    column_order.__isset.TYPE_ORDER = true;
-    metadata_->column_orders.resize(schema_->num_columns(), column_order);
-    metadata_->__isset.column_orders = true;
-
-    parquet::schema::SchemaFlattener flattener(
-        static_cast<parquet::schema::GroupNode*>(schema_->schema_root().get()),
-        &metadata_->schema);
-    flattener.Flatten();
-    auto file_meta_data = std::unique_ptr<FileMetaData>(new FileMetaData());
-    file_meta_data->impl_->metadata_ = std::move(metadata_);
-    file_meta_data->impl_->InitSchema();
-    return file_meta_data;
-  }
-
- protected:
-  std::unique_ptr<format::FileMetaData> metadata_;
-
- private:
-  const std::shared_ptr<WriterProperties> properties_;
-  std::vector<std::unique_ptr<format::RowGroup>> row_groups_;
-  std::vector<std::unique_ptr<RowGroupMetaDataBuilder>> row_group_builders_;
-  const SchemaDescriptor* schema_;
-  std::shared_ptr<const KeyValueMetadata> key_value_metadata_;
-};
-
-std::unique_ptr<FileMetaDataBuilder> FileMetaDataBuilder::Make(
-    const SchemaDescriptor* schema, const std::shared_ptr<WriterProperties>& props,
-    const std::shared_ptr<const KeyValueMetadata>& key_value_metadata) {
-  return std::unique_ptr<FileMetaDataBuilder>(
-      new FileMetaDataBuilder(schema, props, key_value_metadata));
-}
-
-FileMetaDataBuilder::FileMetaDataBuilder(
-    const SchemaDescriptor* schema, const std::shared_ptr<WriterProperties>& props,
-    const std::shared_ptr<const KeyValueMetadata>& key_value_metadata)
-    : impl_{std::unique_ptr<FileMetaDataBuilderImpl>(
-          new FileMetaDataBuilderImpl(schema, props, key_value_metadata))} {}
-
-FileMetaDataBuilder::~FileMetaDataBuilder() {}
-
-RowGroupMetaDataBuilder* FileMetaDataBuilder::AppendRowGroup() {
-  return impl_->AppendRowGroup();
-}
-
-std::unique_ptr<FileMetaData> FileMetaDataBuilder::Finish() { return impl_->Finish(); }
-
-}  // namespace parquet
diff --git a/src/parquet/metadata.h b/src/parquet/metadata.h
deleted file mode 100644
index 5d51e3d..0000000
--- a/src/parquet/metadata.h
+++ /dev/null
@@ -1,277 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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.
-
-#ifndef PARQUET_FILE_METADATA_H
-#define PARQUET_FILE_METADATA_H
-
-#include <set>
-#include <string>
-#include <vector>
-
-#include "arrow/util/key_value_metadata.h"
-
-#include "parquet/properties.h"
-#include "parquet/schema.h"
-#include "parquet/statistics.h"
-#include "parquet/types.h"
-#include "parquet/util/memory.h"
-#include "parquet/util/visibility.h"
-
-namespace parquet {
-
-using KeyValueMetadata = ::arrow::KeyValueMetadata;
-
-class ApplicationVersion {
- public:
-  // Known Versions with Issues
-  static const ApplicationVersion& PARQUET_251_FIXED_VERSION();
-  static const ApplicationVersion& PARQUET_816_FIXED_VERSION();
-  static const ApplicationVersion& PARQUET_CPP_FIXED_STATS_VERSION();
-  // Regular expression for the version format
-  // major . minor . patch unknown - prerelease.x + build info
-  // Eg: 1.5.0ab-cdh5.5.0+cd
-  static constexpr char const* VERSION_FORMAT =
-      "^(\\d+)\\.(\\d+)\\.(\\d+)([^-+]*)?(?:-([^+]*))?(?:\\+(.*))?$";
-  // Regular expression for the application format
-  // application_name version VERSION_FORMAT (build build_name)
-  // Eg: parquet-cpp version 1.5.0ab-xyz5.5.0+cd (build abcd)
-  static constexpr char const* APPLICATION_FORMAT =
-      "(.*?)\\s*(?:(version\\s*(?:([^(]*?)\\s*(?:\\(\\s*build\\s*([^)]*?)\\s*\\))?)?)?)";
-
-  // Application that wrote the file. e.g. "IMPALA"
-  std::string application_;
-  // Build name
-  std::string build_;
-
-  // Version of the application that wrote the file, expressed as
-  // (<major>.<minor>.<patch>). Unmatched parts default to 0.
-  // "1.2.3"    => {1, 2, 3}
-  // "1.2"      => {0, 0, 0}
-  // "1.2-cdh5" => {0, 0, 0}
-  // TODO (majetideepak): Implement support for pre_release
-  struct {
-    int major;
-    int minor;
-    int patch;
-    std::string unknown;
-    std::string pre_release;
-    std::string build_info;
-  } version;
-
-  ApplicationVersion() {}
-  explicit ApplicationVersion(const std::string& created_by);
-  ApplicationVersion(const std::string& application, int major, int minor, int patch);
-
-  // Returns true if version is strictly less than other_version
-  bool VersionLt(const ApplicationVersion& other_version) const;
-
-  // Returns true if version is strictly less than other_version
-  bool VersionEq(const ApplicationVersion& other_version) const;
-
-  // Checks if the Version has the correct statistics for a given column
-  bool HasCorrectStatistics(Type::type primitive,
-                            SortOrder::type sort_order = SortOrder::SIGNED) const;
-};
-
-class PARQUET_EXPORT ColumnChunkMetaData {
- public:
-  // API convenience to get a MetaData accessor
-  static std::unique_ptr<ColumnChunkMetaData> Make(
-      const uint8_t* metadata, const ColumnDescriptor* descr,
-      const ApplicationVersion* writer_version = nullptr);
-
-  ~ColumnChunkMetaData();
-
-  // column chunk
-  int64_t file_offset() const;
-  // parameter is only used when a dataset is spread across multiple files
-  const std::string& file_path() const;
-  // column metadata
-  Type::type type() const;
-  int64_t num_values() const;
-  std::shared_ptr<schema::ColumnPath> path_in_schema() const;
-  bool is_stats_set() const;
-  std::shared_ptr<RowGroupStatistics> statistics() const;
-  Compression::type compression() const;
-  const std::vector<Encoding::type>& encodings() const;
-  bool has_dictionary_page() const;
-  int64_t dictionary_page_offset() const;
-  int64_t data_page_offset() const;
-  bool has_index_page() const;
-  int64_t index_page_offset() const;
-  int64_t total_compressed_size() const;
-  int64_t total_uncompressed_size() const;
-
- private:
-  explicit ColumnChunkMetaData(const uint8_t* metadata, const ColumnDescriptor* descr,
-                               const ApplicationVersion* writer_version = nullptr);
-  // PIMPL Idiom
-  class ColumnChunkMetaDataImpl;
-  std::unique_ptr<ColumnChunkMetaDataImpl> impl_;
-};
-
-class PARQUET_EXPORT RowGroupMetaData {
- public:
-  // API convenience to get a MetaData accessor
-  static std::unique_ptr<RowGroupMetaData> Make(
-      const uint8_t* metadata, const SchemaDescriptor* schema,
-      const ApplicationVersion* writer_version = nullptr);
-
-  ~RowGroupMetaData();
-
-  // row-group metadata
-  int num_columns() const;
-  int64_t num_rows() const;
-  int64_t total_byte_size() const;
-  // Return const-pointer to make it clear that this object is not to be copied
-  const SchemaDescriptor* schema() const;
-  std::unique_ptr<ColumnChunkMetaData> ColumnChunk(int i) const;
-
- private:
-  explicit RowGroupMetaData(const uint8_t* metadata, const SchemaDescriptor* schema,
-                            const ApplicationVersion* writer_version = nullptr);
-  // PIMPL Idiom
-  class RowGroupMetaDataImpl;
-  std::unique_ptr<RowGroupMetaDataImpl> impl_;
-};
-
-class FileMetaDataBuilder;
-
-class PARQUET_EXPORT FileMetaData {
- public:
-  // API convenience to get a MetaData accessor
-  static std::shared_ptr<FileMetaData> Make(const uint8_t* serialized_metadata,
-                                            uint32_t* metadata_len);
-
-  ~FileMetaData();
-
-  // file metadata
-  uint32_t size() const;
-  int num_columns() const;
-  int64_t num_rows() const;
-  int num_row_groups() const;
-  ParquetVersion::type version() const;
-  const std::string& created_by() const;
-  int num_schema_elements() const;
-  std::unique_ptr<RowGroupMetaData> RowGroup(int i) const;
-
-  const ApplicationVersion& writer_version() const;
-
-  void WriteTo(OutputStream* dst) const;
-
-  // Return const-pointer to make it clear that this object is not to be copied
-  const SchemaDescriptor* schema() const;
-
-  std::shared_ptr<const KeyValueMetadata> key_value_metadata() const;
-
- private:
-  friend FileMetaDataBuilder;
-  explicit FileMetaData(const uint8_t* serialized_metadata, uint32_t* metadata_len);
-
-  // PIMPL Idiom
-  FileMetaData();
-  class FileMetaDataImpl;
-  std::unique_ptr<FileMetaDataImpl> impl_;
-};
-
-// Builder API
-class PARQUET_EXPORT ColumnChunkMetaDataBuilder {
- public:
-  // API convenience to get a MetaData reader
-  static std::unique_ptr<ColumnChunkMetaDataBuilder> Make(
-      const std::shared_ptr<WriterProperties>& props, const ColumnDescriptor* column,
-      uint8_t* contents);
-
-  ~ColumnChunkMetaDataBuilder();
-
-  // column chunk
-  // Used when a dataset is spread across multiple files
-  void set_file_path(const std::string& path);
-  // column metadata
-  void SetStatistics(bool is_signed, const EncodedStatistics& stats);
-  // get the column descriptor
-  const ColumnDescriptor* descr() const;
-  // commit the metadata
-  void Finish(int64_t num_values, int64_t dictonary_page_offset,
-              int64_t index_page_offset, int64_t data_page_offset,
-              int64_t compressed_size, int64_t uncompressed_size, bool has_dictionary,
-              bool dictionary_fallback);
-
-  // For writing metadata at end of column chunk
-  void WriteTo(OutputStream* sink);
-
- private:
-  explicit ColumnChunkMetaDataBuilder(const std::shared_ptr<WriterProperties>& props,
-                                      const ColumnDescriptor* column, uint8_t* contents);
-  // PIMPL Idiom
-  class ColumnChunkMetaDataBuilderImpl;
-  std::unique_ptr<ColumnChunkMetaDataBuilderImpl> impl_;
-};
-
-class PARQUET_EXPORT RowGroupMetaDataBuilder {
- public:
-  // API convenience to get a MetaData reader
-  static std::unique_ptr<RowGroupMetaDataBuilder> Make(
-      const std::shared_ptr<WriterProperties>& props, const SchemaDescriptor* schema_,
-      uint8_t* contents);
-
-  ~RowGroupMetaDataBuilder();
-
-  ColumnChunkMetaDataBuilder* NextColumnChunk();
-  int num_columns();
-  int64_t num_rows();
-  int current_column() const;
-
-  void set_num_rows(int64_t num_rows);
-
-  // commit the metadata
-  void Finish(int64_t total_bytes_written);
-
- private:
-  explicit RowGroupMetaDataBuilder(const std::shared_ptr<WriterProperties>& props,
-                                   const SchemaDescriptor* schema_, uint8_t* contents);
-  // PIMPL Idiom
-  class RowGroupMetaDataBuilderImpl;
-  std::unique_ptr<RowGroupMetaDataBuilderImpl> impl_;
-};
-
-class PARQUET_EXPORT FileMetaDataBuilder {
- public:
-  // API convenience to get a MetaData reader
-  static std::unique_ptr<FileMetaDataBuilder> Make(
-      const SchemaDescriptor* schema, const std::shared_ptr<WriterProperties>& props,
-      const std::shared_ptr<const KeyValueMetadata>& key_value_metadata = nullptr);
-
-  ~FileMetaDataBuilder();
-
-  RowGroupMetaDataBuilder* AppendRowGroup();
-
-  // commit the metadata
-  std::unique_ptr<FileMetaData> Finish();
-
- private:
-  explicit FileMetaDataBuilder(
-      const SchemaDescriptor* schema, const std::shared_ptr<WriterProperties>& props,
-      const std::shared_ptr<const KeyValueMetadata>& key_value_metadata = nullptr);
-  // PIMPL Idiom
-  class FileMetaDataBuilderImpl;
-  std::unique_ptr<FileMetaDataBuilderImpl> impl_;
-};
-
-}  // namespace parquet
-
-#endif  // PARQUET_FILE_METADATA_H
diff --git a/src/parquet/murmur3.cc b/src/parquet/murmur3.cc
deleted file mode 100644
index a19436e..0000000
--- a/src/parquet/murmur3.cc
+++ /dev/null
@@ -1,222 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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.
-
-//-----------------------------------------------------------------------------
-// MurmurHash3 was written by Austin Appleby, and is placed in the public
-// domain. The author hereby disclaims copyright to this source code.
-
-// Note - The x86 and x64 versions do _not_ produce the same results, as the
-// algorithms are optimized for their respective platforms. You can still
-// compile and run any of them on any platform, but your performance with the
-// non-native version will be less than optimal.
-
-#include "parquet/murmur3.h"
-
-namespace parquet {
-
-#if defined(_MSC_VER)
-
-#define FORCE_INLINE __forceinline
-#define ROTL64(x, y) _rotl64(x, y)
-
-#else  // defined(_MSC_VER)
-
-#define FORCE_INLINE inline __attribute__((always_inline))
-inline uint64_t rotl64(uint64_t x, int8_t r) { return (x << r) | (x >> (64 - r)); }
-#define ROTL64(x, y) rotl64(x, y)
-
-#endif  // !defined(_MSC_VER)
-
-#define BIG_CONSTANT(x) (x##LLU)
-
-//-----------------------------------------------------------------------------
-// Block read - if your platform needs to do endian-swapping or can only
-// handle aligned reads, do the conversion here
-
-FORCE_INLINE uint32_t getblock32(const uint32_t* p, int i) { return p[i]; }
-
-FORCE_INLINE uint64_t getblock64(const uint64_t* p, int i) { return p[i]; }
-
-//-----------------------------------------------------------------------------
-// Finalization mix - force all bits of a hash block to avalanche
-
-FORCE_INLINE uint32_t fmix32(uint32_t h) {
-  h ^= h >> 16;
-  h *= 0x85ebca6b;
-  h ^= h >> 13;
-  h *= 0xc2b2ae35;
-  h ^= h >> 16;
-
-  return h;
-}
-
-//----------
-
-FORCE_INLINE uint64_t fmix64(uint64_t k) {
-  k ^= k >> 33;
-  k *= BIG_CONSTANT(0xff51afd7ed558ccd);
-  k ^= k >> 33;
-  k *= BIG_CONSTANT(0xc4ceb9fe1a85ec53);
-  k ^= k >> 33;
-
-  return k;
-}
-
-//-----------------------------------------------------------------------------
-
-void Hash_x64_128(const void* key, const int len, const uint32_t seed, uint64_t out[2]) {
-  const uint8_t* data = (const uint8_t*)key;
-  const int nblocks = len / 16;
-
-  uint64_t h1 = seed;
-  uint64_t h2 = seed;
-
-  const uint64_t c1 = BIG_CONSTANT(0x87c37b91114253d5);
-  const uint64_t c2 = BIG_CONSTANT(0x4cf5ad432745937f);
-
-  //----------
-  // body
-
-  const uint64_t* blocks = (const uint64_t*)(data);
-
-  for (int i = 0; i < nblocks; i++) {
-    uint64_t k1 = getblock64(blocks, i * 2 + 0);
-    uint64_t k2 = getblock64(blocks, i * 2 + 1);
-
-    k1 *= c1;
-    k1 = ROTL64(k1, 31);
-    k1 *= c2;
-    h1 ^= k1;
-
-    h1 = ROTL64(h1, 27);
-    h1 += h2;
-    h1 = h1 * 5 + 0x52dce729;
-
-    k2 *= c2;
-    k2 = ROTL64(k2, 33);
-    k2 *= c1;
-    h2 ^= k2;
-
-    h2 = ROTL64(h2, 31);
-    h2 += h1;
-    h2 = h2 * 5 + 0x38495ab5;
-  }
-
-  //----------
-  // tail
-
-  const uint8_t* tail = (const uint8_t*)(data + nblocks * 16);
-
-  uint64_t k1 = 0;
-  uint64_t k2 = 0;
-
-  switch (len & 15) {
-    case 15:
-      k2 ^= ((uint64_t)tail[14]) << 48;
-    case 14:
-      k2 ^= ((uint64_t)tail[13]) << 40;
-    case 13:
-      k2 ^= ((uint64_t)tail[12]) << 32;
-    case 12:
-      k2 ^= ((uint64_t)tail[11]) << 24;
-    case 11:
-      k2 ^= ((uint64_t)tail[10]) << 16;
-    case 10:
-      k2 ^= ((uint64_t)tail[9]) << 8;
-    case 9:
-      k2 ^= ((uint64_t)tail[8]) << 0;
-      k2 *= c2;
-      k2 = ROTL64(k2, 33);
-      k2 *= c1;
-      h2 ^= k2;
-
-    case 8:
-      k1 ^= ((uint64_t)tail[7]) << 56;
-    case 7:
-      k1 ^= ((uint64_t)tail[6]) << 48;
-    case 6:
-      k1 ^= ((uint64_t)tail[5]) << 40;
-    case 5:
-      k1 ^= ((uint64_t)tail[4]) << 32;
-    case 4:
-      k1 ^= ((uint64_t)tail[3]) << 24;
-    case 3:
-      k1 ^= ((uint64_t)tail[2]) << 16;
-    case 2:
-      k1 ^= ((uint64_t)tail[1]) << 8;
-    case 1:
-      k1 ^= ((uint64_t)tail[0]) << 0;
-      k1 *= c1;
-      k1 = ROTL64(k1, 31);
-      k1 *= c2;
-      h1 ^= k1;
-  }
-
-  //----------
-  // finalization
-
-  h1 ^= len;
-  h2 ^= len;
-
-  h1 += h2;
-  h2 += h1;
-
-  h1 = fmix64(h1);
-  h2 = fmix64(h2);
-
-  h1 += h2;
-  h2 += h1;
-
-  reinterpret_cast<uint64_t*>(out)[0] = h1;
-  reinterpret_cast<uint64_t*>(out)[1] = h2;
-}
-
-template <typename T>
-uint64_t HashHelper(T value, uint32_t seed) {
-  uint64_t output[2];
-  Hash_x64_128(reinterpret_cast<void*>(&value), sizeof(T), seed, output);
-  return output[0];
-}
-
-uint64_t MurmurHash3::Hash(int32_t value) const { return HashHelper(value, seed_); }
-
-uint64_t MurmurHash3::Hash(int64_t value) const { return HashHelper(value, seed_); }
-
-uint64_t MurmurHash3::Hash(float value) const { return HashHelper(value, seed_); }
-
-uint64_t MurmurHash3::Hash(double value) const { return HashHelper(value, seed_); }
-
-uint64_t MurmurHash3::Hash(const FLBA* value, uint32_t len) const {
-  uint64_t out[2];
-  Hash_x64_128(reinterpret_cast<const void*>(value->ptr), len, seed_, out);
-  return out[0];
-}
-
-uint64_t MurmurHash3::Hash(const Int96* value) const {
-  uint64_t out[2];
-  Hash_x64_128(reinterpret_cast<const void*>(value->value), sizeof(value->value), seed_,
-               out);
-  return out[0];
-}
-
-uint64_t MurmurHash3::Hash(const ByteArray* value) const {
-  uint64_t out[2];
-  Hash_x64_128(reinterpret_cast<const void*>(value->ptr), value->len, seed_, out);
-  return out[0];
-}
-
-}  // namespace parquet
diff --git a/src/parquet/murmur3.h b/src/parquet/murmur3.h
deleted file mode 100644
index 84792f3..0000000
--- a/src/parquet/murmur3.h
+++ /dev/null
@@ -1,56 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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.
-
-//-----------------------------------------------------------------------------
-// MurmurHash3 was written by Austin Appleby, and is placed in the public
-// domain. The author hereby disclaims copyright to this source code.
-
-#ifndef PARQUET_MURMURHASH3_H_
-#define PARQUET_MURMURHASH3_H_
-
-#include <cstdint>
-
-#include "parquet/hasher.h"
-#include "parquet/types.h"
-
-namespace parquet {
-
-/// Source:
-/// https://github.com/aappleby/smhasher/blob/master/src/MurmurHash3.cpp
-/// (Modified to adapt to coding conventions and to inherit the Hasher abstract class)
-class MurmurHash3 : public Hasher {
- public:
-  MurmurHash3() : seed_(DEFAULT_SEED) {}
-  uint64_t Hash(int32_t value) const override;
-  uint64_t Hash(int64_t value) const override;
-  uint64_t Hash(float value) const override;
-  uint64_t Hash(double value) const override;
-  uint64_t Hash(const Int96* value) const override;
-  uint64_t Hash(const ByteArray* value) const override;
-  uint64_t Hash(const FLBA* val, uint32_t len) const override;
-
- private:
-  // Default seed for hash which comes from Bloom filter in parquet-mr, it is generated
-  // by System.nanoTime() of java.
-  static constexpr int DEFAULT_SEED = 1361930890;
-
-  uint32_t seed_;
-};
-
-}  // namespace parquet
-
-#endif  // PARQUET_MURMURHASH3_H_
diff --git a/src/parquet/parquet.pc.in b/src/parquet/parquet.pc.in
deleted file mode 100644
index 9313d1f..0000000
--- a/src/parquet/parquet.pc.in
+++ /dev/null
@@ -1,29 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you 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.
-
-prefix=@CMAKE_INSTALL_PREFIX@
-libdir=${prefix}/@CMAKE_INSTALL_LIBDIR@
-includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@
-
-so_version=@PARQUET_SO_VERSION@
-abi_version=@PARQUET_ABI_VERSION@
-
-Name: Apache Parquet
-Description: Apache Parquet is a columnar storage format.
-Version: @PARQUET_VERSION@
-Libs: -L${libdir} -lparquet
-Cflags: -I${includedir}
diff --git a/src/parquet/parquet.thrift b/src/parquet/parquet.thrift
deleted file mode 100644
index aec8e54..0000000
--- a/src/parquet/parquet.thrift
+++ /dev/null
@@ -1,924 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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.
- */
-
-cpp_include "parquet/util/windows_compatibility.h"
-
-/**
- * File format description for the parquet file format
- */
-namespace cpp parquet.format
-namespace java org.apache.parquet.format
-
-/**
- * Types supported by Parquet.  These types are intended to be used in combination
- * with the encodings to control the on disk storage format.
- * For example INT16 is not included as a type since a good encoding of INT32
- * would handle this.
- */
-enum Type {
-  BOOLEAN = 0;
-  INT32 = 1;
-  INT64 = 2;
-  INT96 = 3;
-  FLOAT = 4;
-  DOUBLE = 5;
-  BYTE_ARRAY = 6;
-  FIXED_LEN_BYTE_ARRAY = 7;
-}
-
-/**
- * Common types used by frameworks(e.g. hive, pig) using parquet.  This helps map
- * between types in those frameworks to the base types in parquet.  This is only
- * metadata and not needed to read or write the data.
- */
-enum ConvertedType {
-  /** a BYTE_ARRAY actually contains UTF8 encoded chars */
-  UTF8 = 0;
-
-  /** a map is converted as an optional field containing a repeated key/value pair */
-  MAP = 1;
-
-  /** a key/value pair is converted into a group of two fields */
-  MAP_KEY_VALUE = 2;
-
-  /** a list is converted into an optional field containing a repeated field for its
-   * values */
-  LIST = 3;
-
-  /** an enum is converted into a binary field */
-  ENUM = 4;
-
-  /**
-   * A decimal value.
-   *
-   * This may be used to annotate binary or fixed primitive types. The
-   * underlying byte array stores the unscaled value encoded as two's
-   * complement using big-endian byte order (the most significant byte is the
-   * zeroth element). The value of the decimal is the value * 10^{-scale}.
-   *
-   * This must be accompanied by a (maximum) precision and a scale in the
-   * SchemaElement. The precision specifies the number of digits in the decimal
-   * and the scale stores the location of the decimal point. For example 1.23
-   * would have precision 3 (3 total digits) and scale 2 (the decimal point is
-   * 2 digits over).
-   */
-  DECIMAL = 5;
-
-  /**
-   * A Date
-   *
-   * Stored as days since Unix epoch, encoded as the INT32 physical type.
-   *
-   */
-  DATE = 6;
-
-  /**
-   * A time
-   *
-   * The total number of milliseconds since midnight.  The value is stored
-   * as an INT32 physical type.
-   */
-  TIME_MILLIS = 7;
-
-  /**
-   * A time.
-   *
-   * The total number of microseconds since midnight.  The value is stored as
-   * an INT64 physical type.
-   */
-  TIME_MICROS = 8;
-
-  /**
-   * A date/time combination
-   *
-   * Date and time recorded as milliseconds since the Unix epoch.  Recorded as
-   * a physical type of INT64.
-   */
-  TIMESTAMP_MILLIS = 9;
-
-  /**
-   * A date/time combination
-   *
-   * Date and time recorded as microseconds since the Unix epoch.  The value is
-   * stored as an INT64 physical type.
-   */
-  TIMESTAMP_MICROS = 10;
-
-
-  /**
-   * An unsigned integer value.
-   *
-   * The number describes the maximum number of meainful data bits in
-   * the stored value. 8, 16 and 32 bit values are stored using the
-   * INT32 physical type.  64 bit values are stored using the INT64
-   * physical type.
-   *
-   */
-  UINT_8 = 11;
-  UINT_16 = 12;
-  UINT_32 = 13;
-  UINT_64 = 14;
-
-  /**
-   * A signed integer value.
-   *
-   * The number describes the maximum number of meainful data bits in
-   * the stored value. 8, 16 and 32 bit values are stored using the
-   * INT32 physical type.  64 bit values are stored using the INT64
-   * physical type.
-   *
-   */
-  INT_8 = 15;
-  INT_16 = 16;
-  INT_32 = 17;
-  INT_64 = 18;
-
-  /**
-   * An embedded JSON document
-   *
-   * A JSON document embedded within a single UTF8 column.
-   */
-  JSON = 19;
-
-  /**
-   * An embedded BSON document
-   *
-   * A BSON document embedded within a single BINARY column.
-   */
-  BSON = 20;
-
-  /**
-   * An interval of time
-   *
-   * This type annotates data stored as a FIXED_LEN_BYTE_ARRAY of length 12
-   * This data is composed of three separate little endian unsigned
-   * integers.  Each stores a component of a duration of time.  The first
-   * integer identifies the number of months associated with the duration,
-   * the second identifies the number of days associated with the duration
-   * and the third identifies the number of milliseconds associated with
-   * the provided duration.  This duration of time is independent of any
-   * particular timezone or date.
-   */
-  INTERVAL = 21;
-}
-
-/**
- * Representation of Schemas
- */
-enum FieldRepetitionType {
-  /** This field is required (can not be null) and each record has exactly 1 value. */
-  REQUIRED = 0;
-
-  /** The field is optional (can be null) and each record has 0 or 1 values. */
-  OPTIONAL = 1;
-
-  /** The field is repeated and can contain 0 or more values */
-  REPEATED = 2;
-}
-
-/**
- * Statistics per row group and per page
- * All fields are optional.
- */
-struct Statistics {
-   /**
-    * DEPRECATED: min and max value of the column. Use min_value and max_value.
-    *
-    * Values are encoded using PLAIN encoding, except that variable-length byte
-    * arrays do not include a length prefix.
-    *
-    * These fields encode min and max values determined by signed comparison
-    * only. New files should use the correct order for a column's logical type
-    * and store the values in the min_value and max_value fields.
-    *
-    * To support older readers, these may be set when the column order is
-    * signed.
-    */
-   1: optional binary max;
-   2: optional binary min;
-   /** count of null value in the column */
-   3: optional i64 null_count;
-   /** count of distinct values occurring */
-   4: optional i64 distinct_count;
-   /**
-    * Min and max values for the column, determined by its ColumnOrder.
-    *
-    * Values are encoded using PLAIN encoding, except that variable-length byte
-    * arrays do not include a length prefix.
-    */
-   5: optional binary max_value;
-   6: optional binary min_value;
-}
-
-/** Empty structs to use as logical type annotations */
-struct StringType {}  // allowed for BINARY, must be encoded with UTF-8
-struct UUIDType {}    // allowed for FIXED[16], must encoded raw UUID bytes
-struct MapType {}     // see LogicalTypes.md
-struct ListType {}    // see LogicalTypes.md
-struct EnumType {}    // allowed for BINARY, must be encoded with UTF-8
-struct DateType {}    // allowed for INT32
-
-/**
- * Logical type to annotate a column that is always null.
- *
- * Sometimes when discovering the schema of existing data, values are always
- * null and the physical type can't be determined. This annotation signals
- * the case where the physical type was guessed from all null values.
- */
-struct NullType {}    // allowed for any physical type, only null values stored
-
-/**
- * Decimal logical type annotation
- *
- * To maintain forward-compatibility in v1, implementations using this logical
- * type must also set scale and precision on the annotated SchemaElement.
- *
- * Allowed for physical types: INT32, INT64, FIXED, and BINARY
- */
-struct DecimalType {
-  1: required i32 scale
-  2: required i32 precision
-}
-
-/** Time units for logical types */
-struct MilliSeconds {}
-struct MicroSeconds {}
-union TimeUnit {
-  1: MilliSeconds MILLIS
-  2: MicroSeconds MICROS
-}
-
-/**
- * Timestamp logical type annotation
- *
- * Allowed for physical types: INT64
- */
-struct TimestampType {
-  1: required bool isAdjustedToUTC
-  2: required TimeUnit unit
-}
-
-/**
- * Time logical type annotation
- *
- * Allowed for physical types: INT32 (millis), INT64 (micros)
- */
-struct TimeType {
-  1: required bool isAdjustedToUTC
-  2: required TimeUnit unit
-}
-
-/**
- * Integer logical type annotation
- *
- * bitWidth must be 8, 16, 32, or 64.
- *
- * Allowed for physical types: INT32, INT64
- */
-struct IntType {
-  1: required byte bitWidth
-  2: required bool isSigned
-}
-
-/**
- * Embedded JSON logical type annotation
- *
- * Allowed for physical types: BINARY
- */
-struct JsonType {
-}
-
-/**
- * Embedded BSON logical type annotation
- *
- * Allowed for physical types: BINARY
- */
-struct BsonType {
-}
-
-/**
- * LogicalType annotations to replace ConvertedType.
- *
- * To maintain compatibility, implementations using LogicalType for a
- * SchemaElement must also set the corresponding ConvertedType from the
- * following table.
- */
-union LogicalType {
-  1:  StringType STRING       // use ConvertedType UTF8 if encoding is UTF-8
-  2:  MapType MAP             // use ConvertedType MAP
-  3:  ListType LIST           // use ConvertedType LIST
-  4:  EnumType ENUM           // use ConvertedType ENUM
-  5:  DecimalType DECIMAL     // use ConvertedType DECIMAL
-  6:  DateType DATE           // use ConvertedType DATE
-  7:  TimeType TIME           // use ConvertedType TIME_MICROS or TIME_MILLIS
-  8:  TimestampType TIMESTAMP // use ConvertedType TIMESTAMP_MICROS or TIMESTAMP_MILLIS
-  // 9: reserved for INTERVAL
-  10: IntType INTEGER         // use ConvertedType INT_* or UINT_*
-  11: NullType UNKNOWN        // no compatible ConvertedType
-  12: JsonType JSON           // use ConvertedType JSON
-  13: BsonType BSON           // use ConvertedType BSON
-}
-
-/**
- * Represents a element inside a schema definition.
- *  - if it is a group (inner node) then type is undefined and num_children is defined
- *  - if it is a primitive type (leaf) then type is defined and num_children is undefined
- * the nodes are listed in depth first traversal order.
- */
-struct SchemaElement {
-  /** Data type for this field. Not set if the current element is a non-leaf node */
-  1: optional Type type;
-
-  /** If type is FIXED_LEN_BYTE_ARRAY, this is the byte length of the vales.
-   * Otherwise, if specified, this is the maximum bit length to store any of the values.
-   * (e.g. a low cardinality INT col could have this set to 3).  Note that this is
-   * in the schema, and therefore fixed for the entire file.
-   */
-  2: optional i32 type_length;
-
-  /** repetition of the field. The root of the schema does not have a repetition_type.
-   * All other nodes must have one */
-  3: optional FieldRepetitionType repetition_type;
-
-  /** Name of the field in the schema */
-  4: required string name;
-
-  /** Nested fields.  Since thrift does not support nested fields,
-   * the nesting is flattened to a single list by a depth-first traversal.
-   * The children count is used to construct the nested relationship.
-   * This field is not set when the element is a primitive type
-   */
-  5: optional i32 num_children;
-
-  /** When the schema is the result of a conversion from another model
-   * Used to record the original type to help with cross conversion.
-   */
-  6: optional ConvertedType converted_type;
-
-  /** Used when this column contains decimal data.
-   * See the DECIMAL converted type for more details.
-   */
-  7: optional i32 scale
-  8: optional i32 precision
-
-  /** When the original schema supports field ids, this will save the
-   * original field id in the parquet schema
-   */
-  9: optional i32 field_id;
-
-  /**
-   * The logical type of this SchemaElement; only valid for primitives.
-   *
-   * LogicalType replaces ConvertedType, but ConvertedType is still required
-   * for some logical types to ensure forward-compatibility in format v1.
-   */
-  10: optional LogicalType logicalType
-}
-
-/**
- * Encodings supported by Parquet.  Not all encodings are valid for all types.  These
- * enums are also used to specify the encoding of definition and repetition levels.
- * See the accompanying doc for the details of the more complicated encodings.
- */
-enum Encoding {
-  /** Default encoding.
-   * BOOLEAN - 1 bit per value. 0 is false; 1 is true.
-   * INT32 - 4 bytes per value.  Stored as little-endian.
-   * INT64 - 8 bytes per value.  Stored as little-endian.
-   * FLOAT - 4 bytes per value.  IEEE. Stored as little-endian.
-   * DOUBLE - 8 bytes per value.  IEEE. Stored as little-endian.
-   * BYTE_ARRAY - 4 byte length stored as little endian, followed by bytes.
-   * FIXED_LEN_BYTE_ARRAY - Just the bytes.
-   */
-  PLAIN = 0;
-
-  /** Group VarInt encoding for INT32/INT64.
-   * This encoding is deprecated. It was never used
-   */
-  //  GROUP_VAR_INT = 1;
-
-  /**
-   * Deprecated: Dictionary encoding. The values in the dictionary are encoded in the
-   * plain type.
-   * in a data page use RLE_DICTIONARY instead.
-   * in a Dictionary page use PLAIN instead
-   */
-  PLAIN_DICTIONARY = 2;
-
-  /** Group packed run length encoding. Usable for definition/repetition levels
-   * encoding and Booleans (on one bit: 0 is false; 1 is true.)
-   */
-  RLE = 3;
-
-  /** Bit packed encoding.  This can only be used if the data has a known max
-   * width.  Usable for definition/repetition levels encoding.
-   */
-  BIT_PACKED = 4;
-
-  /** Delta encoding for integers. This can be used for int columns and works best
-   * on sorted data
-   */
-  DELTA_BINARY_PACKED = 5;
-
-  /** Encoding for byte arrays to separate the length values and the data. The lengths
-   * are encoded using DELTA_BINARY_PACKED
-   */
-  DELTA_LENGTH_BYTE_ARRAY = 6;
-
-  /** Incremental-encoded byte array. Prefix lengths are encoded using DELTA_BINARY_PACKED.
-   * Suffixes are stored as delta length byte arrays.
-   */
-  DELTA_BYTE_ARRAY = 7;
-
-  /** Dictionary encoding: the ids are encoded using the RLE encoding
-   */
-  RLE_DICTIONARY = 8;
-}
-
-/**
- * Supported compression algorithms.
- *
- * Codecs added in 2.3.2 can be read by readers based on 2.3.2 and later.
- * Codec support may vary between readers based on the format version and
- * libraries available at runtime. Gzip, Snappy, and LZ4 codecs are
- * widely available, while Zstd and Brotli require additional libraries.
- */
-enum CompressionCodec {
-  UNCOMPRESSED = 0;
-  SNAPPY = 1;
-  GZIP = 2;
-  LZO = 3;
-  BROTLI = 4; // Added in 2.3.2
-  LZ4 = 5;    // Added in 2.3.2
-  ZSTD = 6;   // Added in 2.3.2
-}
-
-enum PageType {
-  DATA_PAGE = 0;
-  INDEX_PAGE = 1;
-  DICTIONARY_PAGE = 2;
-  DATA_PAGE_V2 = 3;
-}
-
-/**
- * Enum to annotate whether lists of min/max elements inside ColumnIndex
- * are ordered and if so, in which direction.
- */
-enum BoundaryOrder {
-  UNORDERED = 0;
-  ASCENDING = 1;
-  DESCENDING = 2;
-}
-
-/** Data page header */
-struct DataPageHeader {
-  /** Number of values, including NULLs, in this data page. **/
-  1: required i32 num_values
-
-  /** Encoding used for this data page **/
-  2: required Encoding encoding
-
-  /** Encoding used for definition levels **/
-  3: required Encoding definition_level_encoding;
-
-  /** Encoding used for repetition levels **/
-  4: required Encoding repetition_level_encoding;
-
-  /** Optional statistics for the data in this page**/
-  5: optional Statistics statistics;
-}
-
-struct IndexPageHeader {
-  /** TODO: **/
-}
-
-struct DictionaryPageHeader {
-  /** Number of values in the dictionary **/
-  1: required i32 num_values;
-
-  /** Encoding using this dictionary page **/
-  2: required Encoding encoding
-
-  /** If true, the entries in the dictionary are sorted in ascending order **/
-  3: optional bool is_sorted;
-}
-
-/**
- * New page format allowing reading levels without decompressing the data
- * Repetition and definition levels are uncompressed
- * The remaining section containing the data is compressed if is_compressed is true
- **/
-struct DataPageHeaderV2 {
-  /** Number of values, including NULLs, in this data page. **/
-  1: required i32 num_values
-  /** Number of NULL values, in this data page.
-      Number of non-null = num_values - num_nulls which is also the number of values in the data section **/
-  2: required i32 num_nulls
-  /** Number of rows in this data page. which means pages change on record boundaries (r = 0) **/
-  3: required i32 num_rows
-  /** Encoding used for data in this page **/
-  4: required Encoding encoding
-
-  // repetition levels and definition levels are always using RLE (without size in it)
-
-  /** length of the definition levels */
-  5: required i32 definition_levels_byte_length;
-  /** length of the repetition levels */
-  6: required i32 repetition_levels_byte_length;
-
-  /**  whether the values are compressed.
-  Which means the section of the page between
-  definition_levels_byte_length + repetition_levels_byte_length + 1 and compressed_page_size (included)
-  is compressed with the compression_codec.
-  If missing it is considered compressed */
-  7: optional bool is_compressed = 1;
-
-  /** optional statistics for this column chunk */
-  8: optional Statistics statistics;
-}
-
-struct PageHeader {
-  /** the type of the page: indicates which of the *_header fields is set **/
-  1: required PageType type
-
-  /** Uncompressed page size in bytes (not including this header) **/
-  2: required i32 uncompressed_page_size
-
-  /** Compressed page size in bytes (not including this header) **/
-  3: required i32 compressed_page_size
-
-  /** 32bit crc for the data below. This allows for disabling checksumming in HDFS
-   *  if only a few pages needs to be read
-   **/
-  4: optional i32 crc
-
-  // Headers for page specific data.  One only will be set.
-  5: optional DataPageHeader data_page_header;
-  6: optional IndexPageHeader index_page_header;
-  7: optional DictionaryPageHeader dictionary_page_header;
-  8: optional DataPageHeaderV2 data_page_header_v2;
-}
-
-/**
- * Wrapper struct to store key values
- */
- struct KeyValue {
-  1: required string key
-  2: optional string value
-}
-
-/**
- * Wrapper struct to specify sort order
- */
-struct SortingColumn {
-  /** The column index (in this row group) **/
-  1: required i32 column_idx
-
-  /** If true, indicates this column is sorted in descending order. **/
-  2: required bool descending
-
-  /** If true, nulls will come before non-null values, otherwise,
-   * nulls go at the end. */
-  3: required bool nulls_first
-}
-
-/**
- * statistics of a given page type and encoding
- */
-struct PageEncodingStats {
-
-  /** the page type (data/dic/...) **/
-  1: required PageType page_type;
-
-  /** encoding of the page **/
-  2: required Encoding encoding;
-
-  /** number of pages of this type with this encoding **/
-  3: required i32 count;
-
-}
-
-/**
- * Description for column metadata
- */
-struct ColumnMetaData {
-  /** Type of this column **/
-  1: required Type type
-
-  /** Set of all encodings used for this column. The purpose is to validate
-   * whether we can decode those pages. **/
-  2: required list<Encoding> encodings
-
-  /** Path in schema **/
-  3: required list<string> path_in_schema
-
-  /** Compression codec **/
-  4: required CompressionCodec codec
-
-  /** Number of values in this column **/
-  5: required i64 num_values
-
-  /** total byte size of all uncompressed pages in this column chunk (including the headers) **/
-  6: required i64 total_uncompressed_size
-
-  /** total byte size of all compressed pages in this column chunk (including the headers) **/
-  7: required i64 total_compressed_size
-
-  /** Optional key/value metadata **/
-  8: optional list<KeyValue> key_value_metadata
-
-  /** Byte offset from beginning of file to first data page **/
-  9: required i64 data_page_offset
-
-  /** Byte offset from beginning of file to root index page **/
-  10: optional i64 index_page_offset
-
-  /** Byte offset from the beginning of file to first (only) dictionary page **/
-  11: optional i64 dictionary_page_offset
-
-  /** optional statistics for this column chunk */
-  12: optional Statistics statistics;
-
-  /** Set of all encodings used for pages in this column chunk.
-   * This information can be used to determine if all data pages are
-   * dictionary encoded for example **/
-  13: optional list<PageEncodingStats> encoding_stats;
-}
-
-struct EncryptionWithFooterKey {
-}
-
-struct EncryptionWithColumnKey {
-  /** Column path in schema **/
-  1: required list<string> path_in_schema
-  
-  /** Retrieval metadata of the column-specific key **/
-  2: optional binary column_key_metadata
-}
-
-union ColumnCryptoMetaData {
-  1: EncryptionWithFooterKey ENCRYPTION_WITH_FOOTER_KEY
-  2: EncryptionWithColumnKey ENCRYPTION_WITH_COLUMN_KEY
-}
-
-struct ColumnChunk {
-  /** File where column data is stored.  If not set, assumed to be same file as
-    * metadata.  This path is relative to the current file.
-    **/
-  1: optional string file_path
-
-  /** Byte offset in file_path to the ColumnMetaData **/
-  2: required i64 file_offset
-
-  /** Column metadata for this chunk. This is the same content as what is at
-   * file_path/file_offset.  Having it here has it replicated in the file
-   * metadata.
-   **/
-  3: optional ColumnMetaData meta_data
-
-  /** File offset of ColumnChunk's OffsetIndex **/
-  4: optional i64 offset_index_offset
-
-  /** Size of ColumnChunk's OffsetIndex, in bytes **/
-  5: optional i32 offset_index_length
-
-  /** File offset of ColumnChunk's ColumnIndex **/
-  6: optional i64 column_index_offset
-
-  /** Size of ColumnChunk's ColumnIndex, in bytes **/
-  7: optional i32 column_index_length
-  
-  /** Crypto metadata of encrypted columns **/
-  8: optional ColumnCryptoMetaData crypto_meta_data
-}
-
-struct RowGroup {
-  /** Metadata for each column chunk in this row group.
-   * This list must have the same order as the SchemaElement list in FileMetaData.
-   **/
-  1: required list<ColumnChunk> columns
-
-  /** Total byte size of all the uncompressed column data in this row group **/
-  2: required i64 total_byte_size
-
-  /** Number of rows in this row group **/
-  3: required i64 num_rows
-
-  /** If set, specifies a sort ordering of the rows in this RowGroup.
-   * The sorting columns can be a subset of all the columns.
-   */
-  4: optional list<SortingColumn> sorting_columns
-}
-
-/** Empty struct to signal the order defined by the physical or logical type */
-struct TypeDefinedOrder {}
-
-/**
- * Union to specify the order used for the min_value and max_value fields for a
- * column. This union takes the role of an enhanced enum that allows rich
- * elements (which will be needed for a collation-based ordering in the future).
- *
- * Possible values are:
- * * TypeDefinedOrder - the column uses the order defined by its logical or
- *                      physical type (if there is no logical type).
- *
- * If the reader does not support the value of this union, min and max stats
- * for this column should be ignored.
- */
-union ColumnOrder {
-
-  /**
-   * The sort orders for logical types are:
-   *   UTF8 - unsigned byte-wise comparison
-   *   INT8 - signed comparison
-   *   INT16 - signed comparison
-   *   INT32 - signed comparison
-   *   INT64 - signed comparison
-   *   UINT8 - unsigned comparison
-   *   UINT16 - unsigned comparison
-   *   UINT32 - unsigned comparison
-   *   UINT64 - unsigned comparison
-   *   DECIMAL - signed comparison of the represented value
-   *   DATE - signed comparison
-   *   TIME_MILLIS - signed comparison
-   *   TIME_MICROS - signed comparison
-   *   TIMESTAMP_MILLIS - signed comparison
-   *   TIMESTAMP_MICROS - signed comparison
-   *   INTERVAL - unsigned comparison
-   *   JSON - unsigned byte-wise comparison
-   *   BSON - unsigned byte-wise comparison
-   *   ENUM - unsigned byte-wise comparison
-   *   LIST - undefined
-   *   MAP - undefined
-   *
-   * In the absence of logical types, the sort order is determined by the physical type:
-   *   BOOLEAN - false, true
-   *   INT32 - signed comparison
-   *   INT64 - signed comparison
-   *   INT96 (only used for legacy timestamps) - unsigned comparison
-   *   FLOAT - signed comparison of the represented value
-   *   DOUBLE - signed comparison of the represented value
-   *   BYTE_ARRAY - unsigned byte-wise comparison
-   *   FIXED_LEN_BYTE_ARRAY - unsigned byte-wise comparison
-   */
-  1: TypeDefinedOrder TYPE_ORDER;
-}
-
-struct PageLocation {
-  /** Offset of the page in the file **/
-  1: required i64 offset
-
-  /**
-   * Size of the page, including header. Sum of compressed_page_size and header
-   * length
-   */
-  2: required i32 compressed_page_size
-
-  /**
-   * Index within the RowGroup of the first row of the page; this means pages
-   * change on record boundaries (r = 0).
-   */
-  3: required i64 first_row_index
-}
-
-struct OffsetIndex {
-  /**
-   * PageLocations, ordered by increasing PageLocation.offset. It is required
-   * that page_locations[i].first_row_index < page_locations[i+1].first_row_index.
-   */
-  1: required list<PageLocation> page_locations
-}
-
-/**
- * Description for ColumnIndex.
- * Each <array-field>[i] refers to the page at OffsetIndex.page_locations[i]
- */
-struct ColumnIndex {
-  /**
-   * A list of Boolean values to determine the validity of the corresponding
-   * min and max values. If true, a page contains only null values, and writers
-   * have to set the corresponding entries in min_values and max_values to
-   * byte[0], so that all lists have the same length. If false, the
-   * corresponding entries in min_values and max_values must be valid.
-   */
-  1: required list<bool> null_pages
-
-  /**
-   * Two lists containing lower and upper bounds for the values of each page.
-   * These may be the actual minimum and maximum values found on a page, but
-   * can also be (more compact) values that do not exist on a page. For
-   * example, instead of storing ""Blart Versenwald III", a writer may set
-   * min_values[i]="B", max_values[i]="C". Such more compact values must still
-   * be valid values within the column's logical type. Readers must make sure
-   * that list entries are populated before using them by inspecting null_pages.
-   */
-  2: required list<binary> min_values
-  3: required list<binary> max_values
-
-  /**
-   * Stores whether both min_values and max_values are orderd and if so, in
-   * which direction. This allows readers to perform binary searches in both
-   * lists. Readers cannot assume that max_values[i] <= min_values[i+1], even
-   * if the lists are ordered.
-   */
-  4: required BoundaryOrder boundary_order
-
-  /** A list containing the number of null values for each page **/
-  5: optional list<i64> null_counts
-}
-
-/**
- * Description for file metadata
- */
-struct FileMetaData {
-  /** Version of this file **/
-  1: required i32 version
-
-  /** Parquet schema for this file.  This schema contains metadata for all the columns.
-   * The schema is represented as a tree with a single root.  The nodes of the tree
-   * are flattened to a list by doing a depth-first traversal.
-   * The column metadata contains the path in the schema for that column which can be
-   * used to map columns to nodes in the schema.
-   * The first element is the root **/
-  2: required list<SchemaElement> schema;
-
-  /** Number of rows in this file **/
-  3: required i64 num_rows
-
-  /** Row groups in this file **/
-  4: required list<RowGroup> row_groups
-
-  /** Optional key/value metadata **/
-  5: optional list<KeyValue> key_value_metadata
-
-  /** String for application that wrote this file.  This should be in the format
-   * <Application> version <App Version> (build <App Build Hash>).
-   * e.g. impala version 1.0 (build 6cf94d29b2b7115df4de2c06e2ab4326d721eb55)
-   **/
-  6: optional string created_by
-
-  /**
-   * Sort order used for the min_value and max_value fields of each column in
-   * this file. Each sort order corresponds to one column, determined by its
-   * position in the list, matching the position of the column in the schema.
-   *
-   * Without column_orders, the meaning of the min_value and max_value fields is
-   * undefined. To ensure well-defined behaviour, if min_value and max_value are
-   * written to a Parquet file, column_orders must be written as well.
-   *
-   * The obsolete min and max fields are always sorted by signed comparison
-   * regardless of column_orders.
-   */
-  7: optional list<ColumnOrder> column_orders;
-}
-
-struct AesGcmV1 {
-  /** Retrieval metadata of AAD used for encryption of pages and structures **/
-  1: optional binary aad_metadata
-}
-
-struct AesGcmCtrV1 {
-  /** Retrieval metadata of AAD used for encryption of structures **/
-  1: optional binary aad_metadata
-}
-
-union EncryptionAlgorithm {
-  1: AesGcmV1 AES_GCM_V1
-  2: AesGcmCtrV1 AES_GCM_CTR_V1
-}
-
-struct FileCryptoMetaData {
-  1: required EncryptionAlgorithm encryption_algorithm
-  
-  /** Parquet footer can be encrypted, or left as plaintext **/
-  2: required bool encrypted_footer
-    
-  /** Retrieval metadata of key used for encryption of footer, 
-   *  and (possibly) columns **/
-  3: optional binary footer_key_metadata
-
-  /** Offset of Parquet footer (encrypted, or plaintext) **/
-  4: required i64 footer_offset
-  
-  /** If file IVs are comprised of a fixed part,
-   *  and variable parts (random or counter), keep the fixed
-   *  part here **/
-  5: optional binary iv_prefix
-}
-
diff --git a/src/parquet/parquet_version.h.in b/src/parquet/parquet_version.h.in
deleted file mode 100644
index db8f396..0000000
--- a/src/parquet/parquet_version.h.in
+++ /dev/null
@@ -1,24 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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.
-
-#ifndef PARQUET_VERSION_H
-#define PARQUET_VERSION_H
-
-// define the parquet created by version
-#define CREATED_BY_VERSION "parquet-cpp version @PARQUET_VERSION@"
-
-#endif  // PARQUET_VERSION_H
diff --git a/src/parquet/printer.cc b/src/parquet/printer.cc
deleted file mode 100644
index 9f26a41..0000000
--- a/src/parquet/printer.cc
+++ /dev/null
@@ -1,254 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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.
-
-#include "parquet/printer.h"
-
-#include <string>
-#include <vector>
-
-#include "parquet/column_scanner.h"
-
-using std::string;
-using std::vector;
-
-namespace parquet {
-// ----------------------------------------------------------------------
-// ParquetFilePrinter::DebugPrint
-
-// the fixed initial size is just for an example
-#define COL_WIDTH "30"
-
-void ParquetFilePrinter::DebugPrint(std::ostream& stream, std::list<int> selected_columns,
-                                    bool print_values, bool print_key_value_metadata,
-                                    const char* filename) {
-  const FileMetaData* file_metadata = fileReader->metadata().get();
-
-  stream << "File Name: " << filename << "\n";
-  stream << "Version: " << file_metadata->version() << "\n";
-  stream << "Created By: " << file_metadata->created_by() << "\n";
-  stream << "Total rows: " << file_metadata->num_rows() << "\n";
-
-  if (print_key_value_metadata) {
-    auto key_value_metadata = file_metadata->key_value_metadata();
-    int64_t size_of_key_value_metadata = key_value_metadata->size();
-    stream << "Key Value File Metadata: " << size_of_key_value_metadata << " entries\n";
-    for (int64_t i = 0; i < size_of_key_value_metadata; i++) {
-      stream << " Key nr " << i << " " << key_value_metadata->key(i) << ": "
-             << key_value_metadata->value(i) << "\n";
-    }
-  }
-
-  stream << "Number of RowGroups: " << file_metadata->num_row_groups() << "\n";
-  stream << "Number of Real Columns: "
-         << file_metadata->schema()->group_node()->field_count() << "\n";
-
-  if (selected_columns.size() == 0) {
-    for (int i = 0; i < file_metadata->num_columns(); i++) {
-      selected_columns.push_back(i);
-    }
-  } else {
-    for (auto i : selected_columns) {
-      if (i < 0 || i >= file_metadata->num_columns()) {
-        throw ParquetException("Selected column is out of range");
-      }
-    }
-  }
-
-  stream << "Number of Columns: " << file_metadata->num_columns() << "\n";
-  stream << "Number of Selected Columns: " << selected_columns.size() << "\n";
-  for (auto i : selected_columns) {
-    const ColumnDescriptor* descr = file_metadata->schema()->Column(i);
-    stream << "Column " << i << ": " << descr->name() << " ("
-           << TypeToString(descr->physical_type()) << ")" << std::endl;
-  }
-
-  for (int r = 0; r < file_metadata->num_row_groups(); ++r) {
-    stream << "--- Row Group " << r << " ---\n";
-
-    auto group_reader = fileReader->RowGroup(r);
-    std::unique_ptr<RowGroupMetaData> group_metadata = file_metadata->RowGroup(r);
-
-    stream << "--- Total Bytes " << group_metadata->total_byte_size() << " ---\n";
-    stream << "  Rows: " << group_metadata->num_rows() << "---\n";
-
-    // Print column metadata
-    for (auto i : selected_columns) {
-      auto column_chunk = group_metadata->ColumnChunk(i);
-      std::shared_ptr<RowGroupStatistics> stats = column_chunk->statistics();
-
-      const ColumnDescriptor* descr = file_metadata->schema()->Column(i);
-      stream << "Column " << i << std::endl << ", Values: " << column_chunk->num_values();
-      if (column_chunk->is_stats_set()) {
-        std::string min = stats->EncodeMin(), max = stats->EncodeMax();
-        stream << ", Null Values: " << stats->null_count()
-               << ", Distinct Values: " << stats->distinct_count() << std::endl
-               << "  Max: " << FormatStatValue(descr->physical_type(), max)
-               << ", Min: " << FormatStatValue(descr->physical_type(), min);
-      } else {
-        stream << "  Statistics Not Set";
-      }
-      stream << std::endl
-             << "  Compression: " << CompressionToString(column_chunk->compression())
-             << ", Encodings: ";
-      for (auto encoding : column_chunk->encodings()) {
-        stream << EncodingToString(encoding) << " ";
-      }
-      stream << std::endl
-             << "  Uncompressed Size: " << column_chunk->total_uncompressed_size()
-             << ", Compressed Size: " << column_chunk->total_compressed_size()
-             << std::endl;
-    }
-
-    if (!print_values) {
-      continue;
-    }
-
-    static constexpr int bufsize = 25;
-    char buffer[bufsize];
-
-    // Create readers for selected columns and print contents
-    vector<std::shared_ptr<Scanner>> scanners(selected_columns.size(), nullptr);
-    int j = 0;
-    for (auto i : selected_columns) {
-      std::shared_ptr<ColumnReader> col_reader = group_reader->Column(i);
-
-      std::stringstream ss;
-      ss << "%-" << COL_WIDTH << "s";
-      std::string fmt = ss.str();
-
-      snprintf(buffer, bufsize, fmt.c_str(),
-               file_metadata->schema()->Column(i)->name().c_str());
-      stream << buffer;
-
-      // This is OK in this method as long as the RowGroupReader does not get
-      // deleted
-      scanners[j++] = Scanner::Make(col_reader);
-    }
-    stream << "\n";
-
-    bool hasRow;
-    do {
-      hasRow = false;
-      for (auto scanner : scanners) {
-        if (scanner->HasNext()) {
-          hasRow = true;
-          scanner->PrintNext(stream, 27);
-        }
-      }
-      stream << "\n";
-    } while (hasRow);
-  }
-}
-
-void ParquetFilePrinter::JSONPrint(std::ostream& stream, std::list<int> selected_columns,
-                                   const char* filename) {
-  const FileMetaData* file_metadata = fileReader->metadata().get();
-  stream << "{\n";
-  stream << "  \"FileName\": \"" << filename << "\",\n";
-  stream << "  \"Version\": \"" << file_metadata->version() << "\",\n";
-  stream << "  \"CreatedBy\": \"" << file_metadata->created_by() << "\",\n";
-  stream << "  \"TotalRows\": \"" << file_metadata->num_rows() << "\",\n";
-  stream << "  \"NumberOfRowGroups\": \"" << file_metadata->num_row_groups() << "\",\n";
-  stream << "  \"NumberOfRealColumns\": \""
-         << file_metadata->schema()->group_node()->field_count() << "\",\n";
-  stream << "  \"NumberOfColumns\": \"" << file_metadata->num_columns() << "\",\n";
-
-  if (selected_columns.size() == 0) {
-    for (int i = 0; i < file_metadata->num_columns(); i++) {
-      selected_columns.push_back(i);
-    }
-  } else {
-    for (auto i : selected_columns) {
-      if (i < 0 || i >= file_metadata->num_columns()) {
-        throw ParquetException("Selected column is out of range");
-      }
-    }
-  }
-
-  stream << "  \"Columns\": [\n";
-  int c = 0;
-  for (auto i : selected_columns) {
-    const ColumnDescriptor* descr = file_metadata->schema()->Column(i);
-    stream << "     { \"Id\": \"" << i << "\", \"Name\": \"" << descr->name() << "\","
-           << " \"PhysicalType\": \"" << TypeToString(descr->physical_type()) << "\","
-           << " \"LogicalType\": \"" << LogicalTypeToString(descr->logical_type())
-           << "\" }";
-    c++;
-    if (c != static_cast<int>(selected_columns.size())) {
-      stream << ",\n";
-    }
-  }
-
-  stream << "\n  ],\n  \"RowGroups\": [\n";
-  for (int r = 0; r < file_metadata->num_row_groups(); ++r) {
-    stream << "     {\n       \"Id\": \"" << r << "\", ";
-
-    auto group_reader = fileReader->RowGroup(r);
-    std::unique_ptr<RowGroupMetaData> group_metadata = file_metadata->RowGroup(r);
-
-    stream << " \"TotalBytes\": \"" << group_metadata->total_byte_size() << "\", ";
-    stream << " \"Rows\": \"" << group_metadata->num_rows() << "\",\n";
-
-    // Print column metadata
-    stream << "       \"ColumnChunks\": [\n";
-    int c1 = 0;
-    for (auto i : selected_columns) {
-      auto column_chunk = group_metadata->ColumnChunk(i);
-      std::shared_ptr<RowGroupStatistics> stats = column_chunk->statistics();
-
-      const ColumnDescriptor* descr = file_metadata->schema()->Column(i);
-      stream << "          {\"Id\": \"" << i << "\", \"Values\": \""
-             << column_chunk->num_values() << "\", "
-             << "\"StatsSet\": ";
-      if (column_chunk->is_stats_set()) {
-        stream << "\"True\", \"Stats\": {";
-        std::string min = stats->EncodeMin(), max = stats->EncodeMax();
-        stream << "\"NumNulls\": \"" << stats->null_count() << "\", "
-               << "\"DistinctValues\": \"" << stats->distinct_count() << "\", "
-               << "\"Max\": \"" << FormatStatValue(descr->physical_type(), max) << "\", "
-               << "\"Min\": \"" << FormatStatValue(descr->physical_type(), min)
-               << "\" },";
-      } else {
-        stream << "\"False\",";
-      }
-      stream << "\n           \"Compression\": \""
-             << CompressionToString(column_chunk->compression())
-             << "\", \"Encodings\": \"";
-      for (auto encoding : column_chunk->encodings()) {
-        stream << EncodingToString(encoding) << " ";
-      }
-      stream << "\", "
-             << "\"UncompressedSize\": \"" << column_chunk->total_uncompressed_size()
-             << "\", \"CompressedSize\": \"" << column_chunk->total_compressed_size();
-
-      // end of a ColumnChunk
-      stream << "\" }";
-      c1++;
-      if (c1 != static_cast<int>(selected_columns.size())) {
-        stream << ",\n";
-      }
-    }
-
-    stream << "\n        ]\n     }";
-    if ((r + 1) != static_cast<int>(file_metadata->num_row_groups())) {
-      stream << ",\n";
-    }
-  }
-  stream << "\n  ]\n}\n";
-}
-
-}  // namespace parquet
diff --git a/src/parquet/printer.h b/src/parquet/printer.h
deleted file mode 100644
index 1113c3f..0000000
--- a/src/parquet/printer.h
+++ /dev/null
@@ -1,50 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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.
-
-#ifndef PARQUET_FILE_PRINTER_H
-#define PARQUET_FILE_PRINTER_H
-
-#include <cstdint>
-#include <iosfwd>
-#include <list>
-#include <memory>
-#include <string>
-#include <vector>
-
-#include "parquet/file_reader.h"
-
-namespace parquet {
-
-class PARQUET_EXPORT ParquetFilePrinter {
- private:
-  ParquetFileReader* fileReader;
-
- public:
-  explicit ParquetFilePrinter(ParquetFileReader* reader) : fileReader(reader) {}
-  ~ParquetFilePrinter() {}
-
-  void DebugPrint(std::ostream& stream, std::list<int> selected_columns,
-                  bool print_values = true, bool print_key_value_metadata = false,
-                  const char* filename = "No Name");
-
-  void JSONPrint(std::ostream& stream, std::list<int> selected_columns,
-                 const char* filename = "No Name");
-};
-
-}  // namespace parquet
-
-#endif  // PARQUET_FILE_PRINTER_H
diff --git a/src/parquet/properties-test.cc b/src/parquet/properties-test.cc
deleted file mode 100644
index c740b59..0000000
--- a/src/parquet/properties-test.cc
+++ /dev/null
@@ -1,66 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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.
-
-#include <gtest/gtest.h>
-
-#include <string>
-
-#include "parquet/file_reader.h"
-#include "parquet/properties.h"
-
-namespace parquet {
-
-using schema::ColumnPath;
-
-namespace test {
-
-TEST(TestReaderProperties, Basics) {
-  ReaderProperties props;
-
-  ASSERT_EQ(DEFAULT_BUFFER_SIZE, props.buffer_size());
-  ASSERT_EQ(DEFAULT_USE_BUFFERED_STREAM, props.is_buffered_stream_enabled());
-}
-
-TEST(TestWriterProperties, Basics) {
-  std::shared_ptr<WriterProperties> props = WriterProperties::Builder().build();
-
-  ASSERT_EQ(DEFAULT_PAGE_SIZE, props->data_pagesize());
-  ASSERT_EQ(DEFAULT_DICTIONARY_PAGE_SIZE_LIMIT, props->dictionary_pagesize_limit());
-  ASSERT_EQ(DEFAULT_WRITER_VERSION, props->version());
-}
-
-TEST(TestWriterProperties, AdvancedHandling) {
-  WriterProperties::Builder builder;
-  builder.compression("gzip", Compression::GZIP);
-  builder.compression("zstd", Compression::ZSTD);
-  builder.compression(Compression::SNAPPY);
-  builder.encoding(Encoding::DELTA_BINARY_PACKED);
-  builder.encoding("delta-length", Encoding::DELTA_LENGTH_BYTE_ARRAY);
-  std::shared_ptr<WriterProperties> props = builder.build();
-
-  ASSERT_EQ(Compression::GZIP, props->compression(ColumnPath::FromDotString("gzip")));
-  ASSERT_EQ(Compression::ZSTD, props->compression(ColumnPath::FromDotString("zstd")));
-  ASSERT_EQ(Compression::SNAPPY,
-            props->compression(ColumnPath::FromDotString("delta-length")));
-  ASSERT_EQ(Encoding::DELTA_BINARY_PACKED,
-            props->encoding(ColumnPath::FromDotString("gzip")));
-  ASSERT_EQ(Encoding::DELTA_LENGTH_BYTE_ARRAY,
-            props->encoding(ColumnPath::FromDotString("delta-length")));
-}
-
-}  // namespace test
-}  // namespace parquet
diff --git a/src/parquet/properties.h b/src/parquet/properties.h
deleted file mode 100644
index 83dc205..0000000
--- a/src/parquet/properties.h
+++ /dev/null
@@ -1,438 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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.
-
-#ifndef PARQUET_COLUMN_PROPERTIES_H
-#define PARQUET_COLUMN_PROPERTIES_H
-
-#include <memory>
-#include <string>
-#include <unordered_map>
-
-#include "parquet/exception.h"
-#include "parquet/parquet_version.h"
-#include "parquet/schema.h"
-#include "parquet/types.h"
-#include "parquet/util/memory.h"
-#include "parquet/util/visibility.h"
-
-namespace parquet {
-
-struct ParquetVersion {
-  enum type { PARQUET_1_0, PARQUET_2_0 };
-};
-
-static int64_t DEFAULT_BUFFER_SIZE = 0;
-static bool DEFAULT_USE_BUFFERED_STREAM = false;
-
-class PARQUET_EXPORT ReaderProperties {
- public:
-  explicit ReaderProperties(::arrow::MemoryPool* pool = ::arrow::default_memory_pool())
-      : pool_(pool) {
-    buffered_stream_enabled_ = DEFAULT_USE_BUFFERED_STREAM;
-    buffer_size_ = DEFAULT_BUFFER_SIZE;
-  }
-
-  ::arrow::MemoryPool* memory_pool() const { return pool_; }
-
-  std::unique_ptr<InputStream> GetStream(RandomAccessSource* source, int64_t start,
-                                         int64_t num_bytes) {
-    std::unique_ptr<InputStream> stream;
-    if (buffered_stream_enabled_) {
-      stream.reset(
-          new BufferedInputStream(pool_, buffer_size_, source, start, num_bytes));
-    } else {
-      stream.reset(new InMemoryInputStream(source, start, num_bytes));
-    }
-    return stream;
-  }
-
-  bool is_buffered_stream_enabled() const { return buffered_stream_enabled_; }
-
-  void enable_buffered_stream() { buffered_stream_enabled_ = true; }
-
-  void disable_buffered_stream() { buffered_stream_enabled_ = false; }
-
-  void set_buffer_size(int64_t buf_size) { buffer_size_ = buf_size; }
-
-  int64_t buffer_size() const { return buffer_size_; }
-
- private:
-  ::arrow::MemoryPool* pool_;
-  int64_t buffer_size_;
-  bool buffered_stream_enabled_;
-};
-
-ReaderProperties PARQUET_EXPORT default_reader_properties();
-
-static constexpr int64_t DEFAULT_PAGE_SIZE = 1024 * 1024;
-static constexpr bool DEFAULT_IS_DICTIONARY_ENABLED = true;
-static constexpr int64_t DEFAULT_DICTIONARY_PAGE_SIZE_LIMIT = DEFAULT_PAGE_SIZE;
-static constexpr int64_t DEFAULT_WRITE_BATCH_SIZE = 1024;
-static constexpr int64_t DEFAULT_MAX_ROW_GROUP_LENGTH = 64 * 1024 * 1024;
-static constexpr bool DEFAULT_ARE_STATISTICS_ENABLED = true;
-static constexpr int64_t DEFAULT_MAX_STATISTICS_SIZE = 4096;
-static constexpr Encoding::type DEFAULT_ENCODING = Encoding::PLAIN;
-static constexpr ParquetVersion::type DEFAULT_WRITER_VERSION =
-    ParquetVersion::PARQUET_1_0;
-static const char DEFAULT_CREATED_BY[] = CREATED_BY_VERSION;
-static constexpr Compression::type DEFAULT_COMPRESSION_TYPE = Compression::UNCOMPRESSED;
-
-class PARQUET_EXPORT ColumnProperties {
- public:
-  ColumnProperties(Encoding::type encoding = DEFAULT_ENCODING,
-                   Compression::type codec = DEFAULT_COMPRESSION_TYPE,
-                   bool dictionary_enabled = DEFAULT_IS_DICTIONARY_ENABLED,
-                   bool statistics_enabled = DEFAULT_ARE_STATISTICS_ENABLED,
-                   size_t max_stats_size = DEFAULT_MAX_STATISTICS_SIZE)
-      : encoding_(encoding),
-        codec_(codec),
-        dictionary_enabled_(dictionary_enabled),
-        statistics_enabled_(statistics_enabled),
-        max_stats_size_(max_stats_size) {}
-
-  void set_encoding(Encoding::type encoding) { encoding_ = encoding; }
-
-  void set_compression(Compression::type codec) { codec_ = codec; }
-
-  void set_dictionary_enabled(bool dictionary_enabled) {
-    dictionary_enabled_ = dictionary_enabled;
-  }
-
-  void set_statistics_enabled(bool statistics_enabled) {
-    statistics_enabled_ = statistics_enabled;
-  }
-
-  void set_max_statistics_size(size_t max_stats_size) {
-    max_stats_size_ = max_stats_size;
-  }
-
-  Encoding::type encoding() const { return encoding_; }
-
-  Compression::type compression() const { return codec_; }
-
-  bool dictionary_enabled() const { return dictionary_enabled_; }
-
-  bool statistics_enabled() const { return statistics_enabled_; }
-
-  size_t max_statistics_size() const { return max_stats_size_; }
-
- private:
-  Encoding::type encoding_;
-  Compression::type codec_;
-  bool dictionary_enabled_;
-  bool statistics_enabled_;
-  size_t max_stats_size_;
-};
-
-class PARQUET_EXPORT WriterProperties {
- public:
-  class Builder {
-   public:
-    Builder()
-        : pool_(::arrow::default_memory_pool()),
-          dictionary_pagesize_limit_(DEFAULT_DICTIONARY_PAGE_SIZE_LIMIT),
-          write_batch_size_(DEFAULT_WRITE_BATCH_SIZE),
-          max_row_group_length_(DEFAULT_MAX_ROW_GROUP_LENGTH),
-          pagesize_(DEFAULT_PAGE_SIZE),
-          version_(DEFAULT_WRITER_VERSION),
-          created_by_(DEFAULT_CREATED_BY) {}
-    virtual ~Builder() {}
-
-    Builder* memory_pool(::arrow::MemoryPool* pool) {
-      pool_ = pool;
-      return this;
-    }
-
-    Builder* enable_dictionary() {
-      default_column_properties_.set_dictionary_enabled(true);
-      return this;
-    }
-
-    Builder* disable_dictionary() {
-      default_column_properties_.set_dictionary_enabled(false);
-      return this;
-    }
-
-    Builder* enable_dictionary(const std::string& path) {
-      dictionary_enabled_[path] = true;
-      return this;
-    }
-
-    Builder* enable_dictionary(const std::shared_ptr<schema::ColumnPath>& path) {
-      return this->enable_dictionary(path->ToDotString());
-    }
-
-    Builder* disable_dictionary(const std::string& path) {
-      dictionary_enabled_[path] = false;
-      return this;
-    }
-
-    Builder* disable_dictionary(const std::shared_ptr<schema::ColumnPath>& path) {
-      return this->disable_dictionary(path->ToDotString());
-    }
-
-    Builder* dictionary_pagesize_limit(int64_t dictionary_psize_limit) {
-      dictionary_pagesize_limit_ = dictionary_psize_limit;
-      return this;
-    }
-
-    Builder* write_batch_size(int64_t write_batch_size) {
-      write_batch_size_ = write_batch_size;
-      return this;
-    }
-
-    Builder* max_row_group_length(int64_t max_row_group_length) {
-      max_row_group_length_ = max_row_group_length;
-      return this;
-    }
-
-    Builder* data_pagesize(int64_t pg_size) {
-      pagesize_ = pg_size;
-      return this;
-    }
-
-    Builder* version(ParquetVersion::type version) {
-      version_ = version;
-      return this;
-    }
-
-    Builder* created_by(const std::string& created_by) {
-      created_by_ = created_by;
-      return this;
-    }
-
-    /**
-     * Define the encoding that is used when we don't utilise dictionary encoding.
-     *
-     * This either apply if dictionary encoding is disabled or if we fallback
-     * as the dictionary grew too large.
-     */
-    Builder* encoding(Encoding::type encoding_type) {
-      if (encoding_type == Encoding::PLAIN_DICTIONARY ||
-          encoding_type == Encoding::RLE_DICTIONARY) {
-        throw ParquetException("Can't use dictionary encoding as fallback encoding");
-      }
-
-      default_column_properties_.set_encoding(encoding_type);
-      return this;
-    }
-
-    /**
-     * Define the encoding that is used when we don't utilise dictionary encoding.
-     *
-     * This either apply if dictionary encoding is disabled or if we fallback
-     * as the dictionary grew too large.
-     */
-    Builder* encoding(const std::string& path, Encoding::type encoding_type) {
-      if (encoding_type == Encoding::PLAIN_DICTIONARY ||
-          encoding_type == Encoding::RLE_DICTIONARY) {
-        throw ParquetException("Can't use dictionary encoding as fallback encoding");
-      }
-
-      encodings_[path] = encoding_type;
-      return this;
-    }
-
-    /**
-     * Define the encoding that is used when we don't utilise dictionary encoding.
-     *
-     * This either apply if dictionary encoding is disabled or if we fallback
-     * as the dictionary grew too large.
-     */
-    Builder* encoding(const std::shared_ptr<schema::ColumnPath>& path,
-                      Encoding::type encoding_type) {
-      return this->encoding(path->ToDotString(), encoding_type);
-    }
-
-    Builder* compression(Compression::type codec) {
-      default_column_properties_.set_compression(codec);
-      return this;
-    }
-
-    Builder* max_statistics_size(size_t max_stats_sz) {
-      default_column_properties_.set_max_statistics_size(max_stats_sz);
-      return this;
-    }
-
-    Builder* compression(const std::string& path, Compression::type codec) {
-      codecs_[path] = codec;
-      return this;
-    }
-
-    Builder* compression(const std::shared_ptr<schema::ColumnPath>& path,
-                         Compression::type codec) {
-      return this->compression(path->ToDotString(), codec);
-    }
-
-    Builder* enable_statistics() {
-      default_column_properties_.set_statistics_enabled(true);
-      return this;
-    }
-
-    Builder* disable_statistics() {
-      default_column_properties_.set_statistics_enabled(false);
-      return this;
-    }
-
-    Builder* enable_statistics(const std::string& path) {
-      statistics_enabled_[path] = true;
-      return this;
-    }
-
-    Builder* enable_statistics(const std::shared_ptr<schema::ColumnPath>& path) {
-      return this->enable_statistics(path->ToDotString());
-    }
-
-    Builder* disable_statistics(const std::string& path) {
-      statistics_enabled_[path] = false;
-      return this;
-    }
-
-    Builder* disable_statistics(const std::shared_ptr<schema::ColumnPath>& path) {
-      return this->disable_statistics(path->ToDotString());
-    }
-
-    std::shared_ptr<WriterProperties> build() {
-      std::unordered_map<std::string, ColumnProperties> column_properties;
-      auto get = [&](const std::string& key) -> ColumnProperties& {
-        auto it = column_properties.find(key);
-        if (it == column_properties.end())
-          return column_properties[key] = default_column_properties_;
-        else
-          return it->second;
-      };
-
-      for (const auto& item : encodings_) get(item.first).set_encoding(item.second);
-      for (const auto& item : codecs_) get(item.first).set_compression(item.second);
-      for (const auto& item : dictionary_enabled_)
-        get(item.first).set_dictionary_enabled(item.second);
-      for (const auto& item : statistics_enabled_)
-        get(item.first).set_statistics_enabled(item.second);
-
-      return std::shared_ptr<WriterProperties>(
-          new WriterProperties(pool_, dictionary_pagesize_limit_, write_batch_size_,
-                               max_row_group_length_, pagesize_, version_, created_by_,
-                               default_column_properties_, column_properties));
-    }
-
-   private:
-    ::arrow::MemoryPool* pool_;
-    int64_t dictionary_pagesize_limit_;
-    int64_t write_batch_size_;
-    int64_t max_row_group_length_;
-    int64_t pagesize_;
-    ParquetVersion::type version_;
-    std::string created_by_;
-
-    // Settings used for each column unless overridden in any of the maps below
-    ColumnProperties default_column_properties_;
-    std::unordered_map<std::string, Encoding::type> encodings_;
-    std::unordered_map<std::string, Compression::type> codecs_;
-    std::unordered_map<std::string, bool> dictionary_enabled_;
-    std::unordered_map<std::string, bool> statistics_enabled_;
-  };
-
-  inline ::arrow::MemoryPool* memory_pool() const { return pool_; }
-
-  inline int64_t dictionary_pagesize_limit() const { return dictionary_pagesize_limit_; }
-
-  inline int64_t write_batch_size() const { return write_batch_size_; }
-
-  inline int64_t max_row_group_length() const { return max_row_group_length_; }
-
-  inline int64_t data_pagesize() const { return pagesize_; }
-
-  inline ParquetVersion::type version() const { return parquet_version_; }
-
-  inline std::string created_by() const { return parquet_created_by_; }
-
-  inline Encoding::type dictionary_index_encoding() const {
-    if (parquet_version_ == ParquetVersion::PARQUET_1_0) {
-      return Encoding::PLAIN_DICTIONARY;
-    } else {
-      return Encoding::RLE_DICTIONARY;
-    }
-  }
-
-  inline Encoding::type dictionary_page_encoding() const {
-    if (parquet_version_ == ParquetVersion::PARQUET_1_0) {
-      return Encoding::PLAIN_DICTIONARY;
-    } else {
-      return Encoding::PLAIN;
-    }
-  }
-
-  const ColumnProperties& column_properties(
-      const std::shared_ptr<schema::ColumnPath>& path) const {
-    auto it = column_properties_.find(path->ToDotString());
-    if (it != column_properties_.end()) return it->second;
-    return default_column_properties_;
-  }
-
-  Encoding::type encoding(const std::shared_ptr<schema::ColumnPath>& path) const {
-    return column_properties(path).encoding();
-  }
-
-  Compression::type compression(const std::shared_ptr<schema::ColumnPath>& path) const {
-    return column_properties(path).compression();
-  }
-
-  bool dictionary_enabled(const std::shared_ptr<schema::ColumnPath>& path) const {
-    return column_properties(path).dictionary_enabled();
-  }
-
-  bool statistics_enabled(const std::shared_ptr<schema::ColumnPath>& path) const {
-    return column_properties(path).statistics_enabled();
-  }
-
-  size_t max_statistics_size(const std::shared_ptr<schema::ColumnPath>& path) const {
-    return column_properties(path).max_statistics_size();
-  }
-
- private:
-  explicit WriterProperties(
-      ::arrow::MemoryPool* pool, int64_t dictionary_pagesize_limit,
-      int64_t write_batch_size, int64_t max_row_group_length, int64_t pagesize,
-      ParquetVersion::type version, const std::string& created_by,
-      const ColumnProperties& default_column_properties,
-      const std::unordered_map<std::string, ColumnProperties>& column_properties)
-      : pool_(pool),
-        dictionary_pagesize_limit_(dictionary_pagesize_limit),
-        write_batch_size_(write_batch_size),
-        max_row_group_length_(max_row_group_length),
-        pagesize_(pagesize),
-        parquet_version_(version),
-        parquet_created_by_(created_by),
-        default_column_properties_(default_column_properties),
-        column_properties_(column_properties) {}
-
-  ::arrow::MemoryPool* pool_;
-  int64_t dictionary_pagesize_limit_;
-  int64_t write_batch_size_;
-  int64_t max_row_group_length_;
-  int64_t pagesize_;
-  ParquetVersion::type parquet_version_;
-  std::string parquet_created_by_;
-  ColumnProperties default_column_properties_;
-  std::unordered_map<std::string, ColumnProperties> column_properties_;
-};
-
-std::shared_ptr<WriterProperties> PARQUET_EXPORT default_writer_properties();
-
-}  // namespace parquet
-
-#endif  // PARQUET_COLUMN_PROPERTIES_H
diff --git a/src/parquet/public-api-test.cc b/src/parquet/public-api-test.cc
deleted file mode 100644
index 958e970..0000000
--- a/src/parquet/public-api-test.cc
+++ /dev/null
@@ -1,49 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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.
-
-#include <gtest/gtest.h>
-
-#include "parquet/api/io.h"
-#include "parquet/api/reader.h"
-#include "parquet/api/schema.h"
-#include "parquet/api/writer.h"
-
-TEST(TestPublicAPI, DoesNotIncludeThrift) {
-#ifdef _THRIFT_THRIFT_H_
-  FAIL() << "Thrift headers should not be in the public API";
-#endif
-}
-
-TEST(TestPublicAPI, DoesNotExportDCHECK) {
-#ifdef DCHECK
-  FAIL() << "parquet/util/logging.h should not be transitively included";
-#endif
-}
-
-TEST(TestPublicAPI, DoesNotIncludeZlib) {
-#ifdef ZLIB_H
-  FAIL() << "zlib.h should not be transitively included";
-#endif
-}
-
-PARQUET_NORETURN void ThrowsParquetException() {
-  throw parquet::ParquetException("This function throws");
-}
-
-TEST(TestPublicAPI, CanThrowParquetException) {
-  ASSERT_THROW(ThrowsParquetException(), parquet::ParquetException);
-}
diff --git a/src/parquet/reader-test.cc b/src/parquet/reader-test.cc
deleted file mode 100644
index d628f47..0000000
--- a/src/parquet/reader-test.cc
+++ /dev/null
@@ -1,325 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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.
-
-#include <fcntl.h>
-#include <gtest/gtest.h>
-#include <cstdint>
-#include <cstdlib>
-#include <iostream>
-#include <memory>
-#include <string>
-
-#include "arrow/io/file.h"
-
-#include "parquet/column_reader.h"
-#include "parquet/column_scanner.h"
-#include "parquet/file_reader.h"
-#include "parquet/printer.h"
-#include "parquet/util/memory.h"
-#include "parquet/util/test-common.h"
-
-using std::string;
-
-namespace parquet {
-
-using ReadableFile = ::arrow::io::ReadableFile;
-
-std::string alltypes_plain() {
-  std::string dir_string(test::get_data_dir());
-  std::stringstream ss;
-  ss << dir_string << "/"
-     << "alltypes_plain.parquet";
-  return ss.str();
-}
-
-std::string nation_dict_truncated_data_page() {
-  std::string dir_string(test::get_data_dir());
-  std::stringstream ss;
-  ss << dir_string << "/"
-     << "nation.dict-malformed.parquet";
-  return ss.str();
-}
-
-class TestAllTypesPlain : public ::testing::Test {
- public:
-  void SetUp() { reader_ = ParquetFileReader::OpenFile(alltypes_plain()); }
-
-  void TearDown() {}
-
- protected:
-  std::unique_ptr<ParquetFileReader> reader_;
-};
-
-TEST_F(TestAllTypesPlain, NoopConstructDestruct) {}
-
-TEST_F(TestAllTypesPlain, TestBatchRead) {
-  std::shared_ptr<RowGroupReader> group = reader_->RowGroup(0);
-
-  // column 0, id
-  std::shared_ptr<Int32Reader> col =
-      std::dynamic_pointer_cast<Int32Reader>(group->Column(0));
-
-  int16_t def_levels[4];
-  int16_t rep_levels[4];
-  int32_t values[4];
-
-  // This file only has 8 rows
-  ASSERT_EQ(8, reader_->metadata()->num_rows());
-  // This file only has 1 row group
-  ASSERT_EQ(1, reader_->metadata()->num_row_groups());
-  // Size of the metadata is 730 bytes
-  ASSERT_EQ(730, reader_->metadata()->size());
-  // This row group must have 8 rows
-  ASSERT_EQ(8, group->metadata()->num_rows());
-
-  ASSERT_TRUE(col->HasNext());
-  int64_t values_read;
-  auto levels_read = col->ReadBatch(4, def_levels, rep_levels, values, &values_read);
-  ASSERT_EQ(4, levels_read);
-  ASSERT_EQ(4, values_read);
-
-  // Now read past the end of the file
-  ASSERT_TRUE(col->HasNext());
-  levels_read = col->ReadBatch(5, def_levels, rep_levels, values, &values_read);
-  ASSERT_EQ(4, levels_read);
-  ASSERT_EQ(4, values_read);
-
-  ASSERT_FALSE(col->HasNext());
-}
-
-TEST_F(TestAllTypesPlain, TestFlatScannerInt32) {
-  std::shared_ptr<RowGroupReader> group = reader_->RowGroup(0);
-
-  // column 0, id
-  std::shared_ptr<Int32Scanner> scanner(new Int32Scanner(group->Column(0)));
-  int32_t val;
-  bool is_null;
-  for (int i = 0; i < 8; ++i) {
-    ASSERT_TRUE(scanner->HasNext());
-    ASSERT_TRUE(scanner->NextValue(&val, &is_null));
-    ASSERT_FALSE(is_null);
-  }
-  ASSERT_FALSE(scanner->HasNext());
-  ASSERT_FALSE(scanner->NextValue(&val, &is_null));
-}
-
-TEST_F(TestAllTypesPlain, TestSetScannerBatchSize) {
-  std::shared_ptr<RowGroupReader> group = reader_->RowGroup(0);
-
-  // column 0, id
-  std::shared_ptr<Int32Scanner> scanner(new Int32Scanner(group->Column(0)));
-
-  ASSERT_EQ(128, scanner->batch_size());
-  scanner->SetBatchSize(1024);
-  ASSERT_EQ(1024, scanner->batch_size());
-}
-
-TEST_F(TestAllTypesPlain, DebugPrintWorks) {
-  std::stringstream ss;
-
-  std::list<int> columns;
-  ParquetFilePrinter printer(reader_.get());
-  printer.DebugPrint(ss, columns);
-
-  std::string result = ss.str();
-  ASSERT_GT(result.size(), 0);
-}
-
-TEST_F(TestAllTypesPlain, ColumnSelection) {
-  std::stringstream ss;
-
-  std::list<int> columns;
-  columns.push_back(5);
-  columns.push_back(0);
-  columns.push_back(10);
-  ParquetFilePrinter printer(reader_.get());
-  printer.DebugPrint(ss, columns);
-
-  std::string result = ss.str();
-  ASSERT_GT(result.size(), 0);
-}
-
-TEST_F(TestAllTypesPlain, ColumnSelectionOutOfRange) {
-  std::stringstream ss;
-
-  std::list<int> columns;
-  columns.push_back(100);
-  ParquetFilePrinter printer1(reader_.get());
-  ASSERT_THROW(printer1.DebugPrint(ss, columns), ParquetException);
-
-  columns.clear();
-  columns.push_back(-1);
-  ParquetFilePrinter printer2(reader_.get());
-  ASSERT_THROW(printer2.DebugPrint(ss, columns), ParquetException);
-}
-
-class TestLocalFile : public ::testing::Test {
- public:
-  void SetUp() {
-    std::string dir_string(test::get_data_dir());
-
-    std::stringstream ss;
-    ss << dir_string << "/"
-       << "alltypes_plain.parquet";
-
-    PARQUET_THROW_NOT_OK(ReadableFile::Open(ss.str(), &handle));
-    fileno = handle->file_descriptor();
-  }
-
-  void TearDown() {}
-
- protected:
-  int fileno;
-  std::shared_ptr<::arrow::io::ReadableFile> handle;
-};
-
-class HelperFileClosed : public ArrowInputFile {
- public:
-  explicit HelperFileClosed(
-      const std::shared_ptr<::arrow::io::ReadableFileInterface>& file, bool* close_called)
-      : ArrowInputFile(file), close_called_(close_called) {}
-
-  void Close() override { *close_called_ = true; }
-
- private:
-  bool* close_called_;
-};
-
-TEST_F(TestLocalFile, FileClosedOnDestruction) {
-  bool close_called = false;
-  {
-    auto contents = ParquetFileReader::Contents::Open(
-        std::unique_ptr<RandomAccessSource>(new HelperFileClosed(handle, &close_called)));
-    std::unique_ptr<ParquetFileReader> result(new ParquetFileReader());
-    result->Open(std::move(contents));
-  }
-  ASSERT_TRUE(close_called);
-}
-
-TEST_F(TestLocalFile, OpenWithMetadata) {
-  // PARQUET-808
-  std::stringstream ss;
-  std::shared_ptr<FileMetaData> metadata = ReadMetaData(handle);
-
-  auto reader = ParquetFileReader::Open(handle, default_reader_properties(), metadata);
-
-  // Compare pointers
-  ASSERT_EQ(metadata.get(), reader->metadata().get());
-
-  std::list<int> columns;
-  ParquetFilePrinter printer(reader.get());
-  printer.DebugPrint(ss, columns, true);
-
-  // Make sure OpenFile passes on the external metadata, too
-  auto reader2 = ParquetFileReader::OpenFile(alltypes_plain(), false,
-                                             default_reader_properties(), metadata);
-
-  // Compare pointers
-  ASSERT_EQ(metadata.get(), reader2->metadata().get());
-}
-
-TEST(TestFileReaderAdHoc, NationDictTruncatedDataPage) {
-  // PARQUET-816. Some files generated by older Parquet implementations may
-  // contain malformed data page metadata, and we can successfully decode them
-  // if we optimistically proceed to decoding, even if there is not enough data
-  // available in the stream. Before, we had quite aggressive checking of
-  // stream reads, which are not found e.g. in Impala's Parquet implementation
-  auto reader = ParquetFileReader::OpenFile(nation_dict_truncated_data_page(), false);
-  std::stringstream ss;
-
-  // empty list means print all
-  std::list<int> columns;
-  ParquetFilePrinter printer1(reader.get());
-  printer1.DebugPrint(ss, columns, true);
-
-  reader = ParquetFileReader::OpenFile(nation_dict_truncated_data_page(), true);
-  std::stringstream ss2;
-  ParquetFilePrinter printer2(reader.get());
-  printer2.DebugPrint(ss2, columns, true);
-
-  // The memory-mapped reads runs over the end of the column chunk and succeeds
-  // by accident
-  ASSERT_EQ(ss2.str(), ss.str());
-}
-
-TEST(TestJSONWithLocalFile, JSONOutput) {
-  std::string jsonOutput = R"###({
-  "FileName": "alltypes_plain.parquet",
-  "Version": "0",
-  "CreatedBy": "impala version 1.3.0-INTERNAL (build 8a48ddb1eff84592b3fc06bc6f51ec120e1fffc9)",
-  "TotalRows": "8",
-  "NumberOfRowGroups": "1",
-  "NumberOfRealColumns": "11",
-  "NumberOfColumns": "11",
-  "Columns": [
-     { "Id": "0", "Name": "id", "PhysicalType": "INT32", "LogicalType": "NONE" },
-     { "Id": "1", "Name": "bool_col", "PhysicalType": "BOOLEAN", "LogicalType": "NONE" },
-     { "Id": "2", "Name": "tinyint_col", "PhysicalType": "INT32", "LogicalType": "NONE" },
-     { "Id": "3", "Name": "smallint_col", "PhysicalType": "INT32", "LogicalType": "NONE" },
-     { "Id": "4", "Name": "int_col", "PhysicalType": "INT32", "LogicalType": "NONE" },
-     { "Id": "5", "Name": "bigint_col", "PhysicalType": "INT64", "LogicalType": "NONE" },
-     { "Id": "6", "Name": "float_col", "PhysicalType": "FLOAT", "LogicalType": "NONE" },
-     { "Id": "7", "Name": "double_col", "PhysicalType": "DOUBLE", "LogicalType": "NONE" },
-     { "Id": "8", "Name": "date_string_col", "PhysicalType": "BYTE_ARRAY", "LogicalType": "NONE" },
-     { "Id": "9", "Name": "string_col", "PhysicalType": "BYTE_ARRAY", "LogicalType": "NONE" },
-     { "Id": "10", "Name": "timestamp_col", "PhysicalType": "INT96", "LogicalType": "NONE" }
-  ],
-  "RowGroups": [
-     {
-       "Id": "0",  "TotalBytes": "671",  "Rows": "8",
-       "ColumnChunks": [
-          {"Id": "0", "Values": "8", "StatsSet": "False",
-           "Compression": "UNCOMPRESSED", "Encodings": "RLE PLAIN_DICTIONARY PLAIN ", "UncompressedSize": "73", "CompressedSize": "73" },
-          {"Id": "1", "Values": "8", "StatsSet": "False",
-           "Compression": "UNCOMPRESSED", "Encodings": "RLE PLAIN_DICTIONARY PLAIN ", "UncompressedSize": "24", "CompressedSize": "24" },
-          {"Id": "2", "Values": "8", "StatsSet": "False",
-           "Compression": "UNCOMPRESSED", "Encodings": "RLE PLAIN_DICTIONARY PLAIN ", "UncompressedSize": "47", "CompressedSize": "47" },
-          {"Id": "3", "Values": "8", "StatsSet": "False",
-           "Compression": "UNCOMPRESSED", "Encodings": "RLE PLAIN_DICTIONARY PLAIN ", "UncompressedSize": "47", "CompressedSize": "47" },
-          {"Id": "4", "Values": "8", "StatsSet": "False",
-           "Compression": "UNCOMPRESSED", "Encodings": "RLE PLAIN_DICTIONARY PLAIN ", "UncompressedSize": "47", "CompressedSize": "47" },
-          {"Id": "5", "Values": "8", "StatsSet": "False",
-           "Compression": "UNCOMPRESSED", "Encodings": "RLE PLAIN_DICTIONARY PLAIN ", "UncompressedSize": "55", "CompressedSize": "55" },
-          {"Id": "6", "Values": "8", "StatsSet": "False",
-           "Compression": "UNCOMPRESSED", "Encodings": "RLE PLAIN_DICTIONARY PLAIN ", "UncompressedSize": "47", "CompressedSize": "47" },
-          {"Id": "7", "Values": "8", "StatsSet": "False",
-           "Compression": "UNCOMPRESSED", "Encodings": "RLE PLAIN_DICTIONARY PLAIN ", "UncompressedSize": "55", "CompressedSize": "55" },
-          {"Id": "8", "Values": "8", "StatsSet": "False",
-           "Compression": "UNCOMPRESSED", "Encodings": "RLE PLAIN_DICTIONARY PLAIN ", "UncompressedSize": "88", "CompressedSize": "88" },
-          {"Id": "9", "Values": "8", "StatsSet": "False",
-           "Compression": "UNCOMPRESSED", "Encodings": "RLE PLAIN_DICTIONARY PLAIN ", "UncompressedSize": "49", "CompressedSize": "49" },
-          {"Id": "10", "Values": "8", "StatsSet": "False",
-           "Compression": "UNCOMPRESSED", "Encodings": "RLE PLAIN_DICTIONARY PLAIN ", "UncompressedSize": "139", "CompressedSize": "139" }
-        ]
-     }
-  ]
-}
-)###";
-
-  std::stringstream ss;
-  // empty list means print all
-  std::list<int> columns;
-
-  auto reader =
-      ParquetFileReader::OpenFile(alltypes_plain(), false, default_reader_properties());
-  ParquetFilePrinter printer(reader.get());
-  printer.JSONPrint(ss, columns, "alltypes_plain.parquet");
-
-  ASSERT_EQ(jsonOutput, ss.str());
-}
-
-}  // namespace parquet
diff --git a/src/parquet/schema-internal.h b/src/parquet/schema-internal.h
deleted file mode 100644
index 53472ab..0000000
--- a/src/parquet/schema-internal.h
+++ /dev/null
@@ -1,83 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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.
-
-// This module contains the logical parquet-cpp types (independent of Thrift
-// structures), schema nodes, and related type tools
-
-#ifndef PARQUET_SCHEMA_INTERNAL_H
-#define PARQUET_SCHEMA_INTERNAL_H
-
-#include <cstdint>
-#include <memory>
-#include <vector>
-
-#include "parquet/parquet_types.h"
-#include "parquet/schema.h"
-#include "parquet/types.h"
-#include "parquet/util/macros.h"
-#include "parquet/util/visibility.h"
-
-namespace parquet {
-namespace schema {
-
-// ----------------------------------------------------------------------
-// Conversion from Parquet Thrift metadata
-
-std::shared_ptr<SchemaDescriptor> FromParquet(
-    const std::vector<format::SchemaElement>& schema);
-
-class FlatSchemaConverter {
- public:
-  FlatSchemaConverter(const format::SchemaElement* elements, int length)
-      : elements_(elements), length_(length), pos_(0), current_id_(0) {}
-
-  std::unique_ptr<Node> Convert();
-
- private:
-  const format::SchemaElement* elements_;
-  int length_;
-  int pos_;
-  int current_id_;
-
-  int next_id() { return current_id_++; }
-
-  const format::SchemaElement& Next();
-
-  std::unique_ptr<Node> NextNode();
-};
-
-// ----------------------------------------------------------------------
-// Conversion to Parquet Thrift metadata
-
-void ToParquet(const GroupNode* schema, std::vector<format::SchemaElement>* out);
-
-// Converts nested parquet schema back to a flat vector of Thrift structs
-class SchemaFlattener {
- public:
-  SchemaFlattener(const GroupNode* schema, std::vector<format::SchemaElement>* out);
-
-  void Flatten();
-
- private:
-  const GroupNode* root_;
-  std::vector<format::SchemaElement>* elements_;
-};
-
-}  // namespace schema
-}  // namespace parquet
-
-#endif  // PARQUET_SCHEMA_INTERNAL_H
diff --git a/src/parquet/schema-test.cc b/src/parquet/schema-test.cc
deleted file mode 100644
index a734a92..0000000
--- a/src/parquet/schema-test.cc
+++ /dev/null
@@ -1,761 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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.
-
-#include <gtest/gtest.h>
-
-#include <cstdlib>
-#include <iosfwd>
-#include <memory>
-#include <string>
-#include <vector>
-
-#include "parquet/exception.h"
-#include "parquet/parquet_types.h"
-#include "parquet/schema-internal.h"
-#include "parquet/schema.h"
-#include "parquet/types.h"
-
-using std::string;
-using std::vector;
-
-namespace parquet {
-
-using format::ConvertedType;
-using format::FieldRepetitionType;
-using format::SchemaElement;
-
-namespace schema {
-
-static inline SchemaElement NewPrimitive(const std::string& name,
-                                         FieldRepetitionType::type repetition,
-                                         format::Type::type type, int id = 0) {
-  SchemaElement result;
-  result.__set_name(name);
-  result.__set_repetition_type(repetition);
-  result.__set_type(type);
-
-  return result;
-}
-
-static inline SchemaElement NewGroup(const std::string& name,
-                                     FieldRepetitionType::type repetition,
-                                     int num_children, int id = 0) {
-  SchemaElement result;
-  result.__set_name(name);
-  result.__set_repetition_type(repetition);
-  result.__set_num_children(num_children);
-
-  return result;
-}
-
-// ----------------------------------------------------------------------
-// ColumnPath
-
-TEST(TestColumnPath, TestAttrs) {
-  ColumnPath path(std::vector<std::string>({"toplevel", "leaf"}));
-
-  ASSERT_EQ(path.ToDotString(), "toplevel.leaf");
-
-  std::shared_ptr<ColumnPath> path_ptr = ColumnPath::FromDotString("toplevel.leaf");
-  ASSERT_EQ(path_ptr->ToDotString(), "toplevel.leaf");
-
-  std::shared_ptr<ColumnPath> extended = path_ptr->extend("anotherlevel");
-  ASSERT_EQ(extended->ToDotString(), "toplevel.leaf.anotherlevel");
-}
-
-// ----------------------------------------------------------------------
-// Primitive node
-
-class TestPrimitiveNode : public ::testing::Test {
- public:
-  void SetUp() {
-    name_ = "name";
-    id_ = 5;
-  }
-
-  void Convert(const format::SchemaElement* element) {
-    node_ = PrimitiveNode::FromParquet(element, id_);
-    ASSERT_TRUE(node_->is_primitive());
-    prim_node_ = static_cast<const PrimitiveNode*>(node_.get());
-  }
-
- protected:
-  std::string name_;
-  const PrimitiveNode* prim_node_;
-
-  int id_;
-  std::unique_ptr<Node> node_;
-};
-
-TEST_F(TestPrimitiveNode, Attrs) {
-  PrimitiveNode node1("foo", Repetition::REPEATED, Type::INT32);
-
-  PrimitiveNode node2("bar", Repetition::OPTIONAL, Type::BYTE_ARRAY, LogicalType::UTF8);
-
-  ASSERT_EQ("foo", node1.name());
-
-  ASSERT_TRUE(node1.is_primitive());
-  ASSERT_FALSE(node1.is_group());
-
-  ASSERT_EQ(Repetition::REPEATED, node1.repetition());
-  ASSERT_EQ(Repetition::OPTIONAL, node2.repetition());
-
-  ASSERT_EQ(Node::PRIMITIVE, node1.node_type());
-
-  ASSERT_EQ(Type::INT32, node1.physical_type());
-  ASSERT_EQ(Type::BYTE_ARRAY, node2.physical_type());
-
-  // logical types
-  ASSERT_EQ(LogicalType::NONE, node1.logical_type());
-  ASSERT_EQ(LogicalType::UTF8, node2.logical_type());
-
-  // repetition
-  PrimitiveNode node3("foo", Repetition::REPEATED, Type::INT32);
-  PrimitiveNode node4("foo", Repetition::REQUIRED, Type::INT32);
-  PrimitiveNode node5("foo", Repetition::OPTIONAL, Type::INT32);
-
-  ASSERT_TRUE(node3.is_repeated());
-  ASSERT_FALSE(node3.is_optional());
-
-  ASSERT_TRUE(node4.is_required());
-
-  ASSERT_TRUE(node5.is_optional());
-  ASSERT_FALSE(node5.is_required());
-}
-
-TEST_F(TestPrimitiveNode, FromParquet) {
-  SchemaElement elt =
-      NewPrimitive(name_, FieldRepetitionType::OPTIONAL, format::Type::INT32, 0);
-  ASSERT_NO_FATAL_FAILURE(Convert(&elt));
-  ASSERT_EQ(name_, prim_node_->name());
-  ASSERT_EQ(id_, prim_node_->id());
-  ASSERT_EQ(Repetition::OPTIONAL, prim_node_->repetition());
-  ASSERT_EQ(Type::INT32, prim_node_->physical_type());
-  ASSERT_EQ(LogicalType::NONE, prim_node_->logical_type());
-
-  // Test a logical type
-  elt = NewPrimitive(name_, FieldRepetitionType::REQUIRED, format::Type::BYTE_ARRAY, 0);
-  elt.__set_converted_type(ConvertedType::UTF8);
-
-  ASSERT_NO_FATAL_FAILURE(Convert(&elt));
-  ASSERT_EQ(Repetition::REQUIRED, prim_node_->repetition());
-  ASSERT_EQ(Type::BYTE_ARRAY, prim_node_->physical_type());
-  ASSERT_EQ(LogicalType::UTF8, prim_node_->logical_type());
-
-  // FIXED_LEN_BYTE_ARRAY
-  elt = NewPrimitive(name_, FieldRepetitionType::OPTIONAL,
-                     format::Type::FIXED_LEN_BYTE_ARRAY, 0);
-  elt.__set_type_length(16);
-
-  ASSERT_NO_FATAL_FAILURE(Convert(&elt));
-  ASSERT_EQ(name_, prim_node_->name());
-  ASSERT_EQ(id_, prim_node_->id());
-  ASSERT_EQ(Repetition::OPTIONAL, prim_node_->repetition());
-  ASSERT_EQ(Type::FIXED_LEN_BYTE_ARRAY, prim_node_->physical_type());
-  ASSERT_EQ(16, prim_node_->type_length());
-
-  // ConvertedType::Decimal
-  elt = NewPrimitive(name_, FieldRepetitionType::OPTIONAL,
-                     format::Type::FIXED_LEN_BYTE_ARRAY, 0);
-  elt.__set_converted_type(ConvertedType::DECIMAL);
-  elt.__set_type_length(6);
-  elt.__set_scale(2);
-  elt.__set_precision(12);
-
-  ASSERT_NO_FATAL_FAILURE(Convert(&elt));
-  ASSERT_EQ(Type::FIXED_LEN_BYTE_ARRAY, prim_node_->physical_type());
-  ASSERT_EQ(LogicalType::DECIMAL, prim_node_->logical_type());
-  ASSERT_EQ(6, prim_node_->type_length());
-  ASSERT_EQ(2, prim_node_->decimal_metadata().scale);
-  ASSERT_EQ(12, prim_node_->decimal_metadata().precision);
-}
-
-TEST_F(TestPrimitiveNode, Equals) {
-  PrimitiveNode node1("foo", Repetition::REQUIRED, Type::INT32);
-  PrimitiveNode node2("foo", Repetition::REQUIRED, Type::INT64);
-  PrimitiveNode node3("bar", Repetition::REQUIRED, Type::INT32);
-  PrimitiveNode node4("foo", Repetition::OPTIONAL, Type::INT32);
-  PrimitiveNode node5("foo", Repetition::REQUIRED, Type::INT32);
-
-  ASSERT_TRUE(node1.Equals(&node1));
-  ASSERT_FALSE(node1.Equals(&node2));
-  ASSERT_FALSE(node1.Equals(&node3));
-  ASSERT_FALSE(node1.Equals(&node4));
-  ASSERT_TRUE(node1.Equals(&node5));
-
-  PrimitiveNode flba1("foo", Repetition::REQUIRED, Type::FIXED_LEN_BYTE_ARRAY,
-                      LogicalType::DECIMAL, 12, 4, 2);
-
-  PrimitiveNode flba2("foo", Repetition::REQUIRED, Type::FIXED_LEN_BYTE_ARRAY,
-                      LogicalType::DECIMAL, 1, 4, 2);
-  flba2.SetTypeLength(12);
-
-  PrimitiveNode flba3("foo", Repetition::REQUIRED, Type::FIXED_LEN_BYTE_ARRAY,
-                      LogicalType::DECIMAL, 1, 4, 2);
-  flba3.SetTypeLength(16);
-
-  PrimitiveNode flba4("foo", Repetition::REQUIRED, Type::FIXED_LEN_BYTE_ARRAY,
-                      LogicalType::DECIMAL, 12, 4, 0);
-
-  PrimitiveNode flba5("foo", Repetition::REQUIRED, Type::FIXED_LEN_BYTE_ARRAY,
-                      LogicalType::NONE, 12, 4, 0);
-
-  ASSERT_TRUE(flba1.Equals(&flba2));
-  ASSERT_FALSE(flba1.Equals(&flba3));
-  ASSERT_FALSE(flba1.Equals(&flba4));
-  ASSERT_FALSE(flba1.Equals(&flba5));
-}
-
-TEST_F(TestPrimitiveNode, PhysicalLogicalMapping) {
-  ASSERT_NO_THROW(
-      PrimitiveNode::Make("foo", Repetition::REQUIRED, Type::INT32, LogicalType::INT_32));
-  ASSERT_NO_THROW(PrimitiveNode::Make("foo", Repetition::REQUIRED, Type::BYTE_ARRAY,
-                                      LogicalType::JSON));
-  ASSERT_THROW(
-      PrimitiveNode::Make("foo", Repetition::REQUIRED, Type::INT32, LogicalType::JSON),
-      ParquetException);
-  ASSERT_NO_THROW(PrimitiveNode::Make("foo", Repetition::REQUIRED, Type::INT64,
-                                      LogicalType::TIMESTAMP_MILLIS));
-  ASSERT_THROW(
-      PrimitiveNode::Make("foo", Repetition::REQUIRED, Type::INT32, LogicalType::INT_64),
-      ParquetException);
-  ASSERT_THROW(PrimitiveNode::Make("foo", Repetition::REQUIRED, Type::BYTE_ARRAY,
-                                   LogicalType::INT_8),
-               ParquetException);
-  ASSERT_THROW(PrimitiveNode::Make("foo", Repetition::REQUIRED, Type::BYTE_ARRAY,
-                                   LogicalType::INTERVAL),
-               ParquetException);
-  ASSERT_THROW(PrimitiveNode::Make("foo", Repetition::REQUIRED,
-                                   Type::FIXED_LEN_BYTE_ARRAY, LogicalType::ENUM),
-               ParquetException);
-  ASSERT_NO_THROW(PrimitiveNode::Make("foo", Repetition::REQUIRED, Type::BYTE_ARRAY,
-                                      LogicalType::ENUM));
-  ASSERT_THROW(
-      PrimitiveNode::Make("foo", Repetition::REQUIRED, Type::FIXED_LEN_BYTE_ARRAY,
-                          LogicalType::DECIMAL, 0, 2, 4),
-      ParquetException);
-  ASSERT_THROW(PrimitiveNode::Make("foo", Repetition::REQUIRED, Type::FLOAT,
-                                   LogicalType::DECIMAL, 0, 2, 4),
-               ParquetException);
-  ASSERT_THROW(
-      PrimitiveNode::Make("foo", Repetition::REQUIRED, Type::FIXED_LEN_BYTE_ARRAY,
-                          LogicalType::DECIMAL, 0, 4, 0),
-      ParquetException);
-  ASSERT_THROW(
-      PrimitiveNode::Make("foo", Repetition::REQUIRED, Type::FIXED_LEN_BYTE_ARRAY,
-                          LogicalType::DECIMAL, 10, 0, 4),
-      ParquetException);
-  ASSERT_THROW(
-      PrimitiveNode::Make("foo", Repetition::REQUIRED, Type::FIXED_LEN_BYTE_ARRAY,
-                          LogicalType::DECIMAL, 10, 4, -1),
-      ParquetException);
-  ASSERT_THROW(
-      PrimitiveNode::Make("foo", Repetition::REQUIRED, Type::FIXED_LEN_BYTE_ARRAY,
-                          LogicalType::DECIMAL, 10, 2, 4),
-      ParquetException);
-  ASSERT_NO_THROW(PrimitiveNode::Make("foo", Repetition::REQUIRED,
-                                      Type::FIXED_LEN_BYTE_ARRAY, LogicalType::DECIMAL,
-                                      10, 6, 4));
-  ASSERT_NO_THROW(PrimitiveNode::Make("foo", Repetition::REQUIRED,
-                                      Type::FIXED_LEN_BYTE_ARRAY, LogicalType::INTERVAL,
-                                      12));
-  ASSERT_THROW(PrimitiveNode::Make("foo", Repetition::REQUIRED,
-                                   Type::FIXED_LEN_BYTE_ARRAY, LogicalType::INTERVAL, 10),
-               ParquetException);
-}
-
-// ----------------------------------------------------------------------
-// Group node
-
-class TestGroupNode : public ::testing::Test {
- public:
-  NodeVector Fields1() {
-    NodeVector fields;
-
-    fields.push_back(Int32("one", Repetition::REQUIRED));
-    fields.push_back(Int64("two"));
-    fields.push_back(Double("three"));
-
-    return fields;
-  }
-
-  NodeVector Fields2() {
-    // Fields with a duplicate name
-    NodeVector fields;
-
-    fields.push_back(Int32("duplicate", Repetition::REQUIRED));
-    fields.push_back(Int64("unique"));
-    fields.push_back(Double("duplicate"));
-
-    return fields;
-  }
-};
-
-TEST_F(TestGroupNode, Attrs) {
-  NodeVector fields = Fields1();
-
-  GroupNode node1("foo", Repetition::REPEATED, fields);
-  GroupNode node2("bar", Repetition::OPTIONAL, fields, LogicalType::LIST);
-
-  ASSERT_EQ("foo", node1.name());
-
-  ASSERT_TRUE(node1.is_group());
-  ASSERT_FALSE(node1.is_primitive());
-
-  ASSERT_EQ(fields.size(), node1.field_count());
-
-  ASSERT_TRUE(node1.is_repeated());
-  ASSERT_TRUE(node2.is_optional());
-
-  ASSERT_EQ(Repetition::REPEATED, node1.repetition());
-  ASSERT_EQ(Repetition::OPTIONAL, node2.repetition());
-
-  ASSERT_EQ(Node::GROUP, node1.node_type());
-
-  // logical types
-  ASSERT_EQ(LogicalType::NONE, node1.logical_type());
-  ASSERT_EQ(LogicalType::LIST, node2.logical_type());
-}
-
-TEST_F(TestGroupNode, Equals) {
-  NodeVector f1 = Fields1();
-  NodeVector f2 = Fields1();
-
-  GroupNode group1("group", Repetition::REPEATED, f1);
-  GroupNode group2("group", Repetition::REPEATED, f2);
-  GroupNode group3("group2", Repetition::REPEATED, f2);
-
-  // This is copied in the GroupNode ctor, so this is okay
-  f2.push_back(Float("four", Repetition::OPTIONAL));
-  GroupNode group4("group", Repetition::REPEATED, f2);
-  GroupNode group5("group", Repetition::REPEATED, Fields1());
-
-  ASSERT_TRUE(group1.Equals(&group1));
-  ASSERT_TRUE(group1.Equals(&group2));
-  ASSERT_FALSE(group1.Equals(&group3));
-
-  ASSERT_FALSE(group1.Equals(&group4));
-  ASSERT_FALSE(group5.Equals(&group4));
-}
-
-TEST_F(TestGroupNode, FieldIndex) {
-  NodeVector fields = Fields1();
-  GroupNode group("group", Repetition::REQUIRED, fields);
-  for (size_t i = 0; i < fields.size(); i++) {
-    auto field = group.field(static_cast<int>(i));
-    ASSERT_EQ(i, group.FieldIndex(*field));
-  }
-
-  // Test a non field node
-  auto non_field_alien = Int32("alien", Repetition::REQUIRED);   // other name
-  auto non_field_familiar = Int32("one", Repetition::REPEATED);  // other node
-  ASSERT_TRUE(group.FieldIndex(*non_field_alien) < 0);
-  ASSERT_TRUE(group.FieldIndex(*non_field_familiar) < 0);
-}
-
-TEST_F(TestGroupNode, FieldIndexDuplicateName) {
-  NodeVector fields = Fields2();
-  GroupNode group("group", Repetition::REQUIRED, fields);
-  for (size_t i = 0; i < fields.size(); i++) {
-    auto field = group.field(static_cast<int>(i));
-    ASSERT_EQ(i, group.FieldIndex(*field));
-  }
-}
-
-// ----------------------------------------------------------------------
-// Test convert group
-
-class TestSchemaConverter : public ::testing::Test {
- public:
-  void setUp() { name_ = "parquet_schema"; }
-
-  void Convert(const parquet::format::SchemaElement* elements, int length) {
-    FlatSchemaConverter converter(elements, length);
-    node_ = converter.Convert();
-    ASSERT_TRUE(node_->is_group());
-    group_ = static_cast<const GroupNode*>(node_.get());
-  }
-
- protected:
-  std::string name_;
-  const GroupNode* group_;
-  std::unique_ptr<Node> node_;
-};
-
-bool check_for_parent_consistency(const GroupNode* node) {
-  // Each node should have the group as parent
-  for (int i = 0; i < node->field_count(); i++) {
-    const NodePtr& field = node->field(i);
-    if (field->parent() != node) {
-      return false;
-    }
-    if (field->is_group()) {
-      const GroupNode* group = static_cast<GroupNode*>(field.get());
-      if (!check_for_parent_consistency(group)) {
-        return false;
-      }
-    }
-  }
-  return true;
-}
-
-TEST_F(TestSchemaConverter, NestedExample) {
-  SchemaElement elt;
-  std::vector<SchemaElement> elements;
-  elements.push_back(NewGroup(name_, FieldRepetitionType::REPEATED, 2, 0));
-
-  // A primitive one
-  elements.push_back(
-      NewPrimitive("a", FieldRepetitionType::REQUIRED, format::Type::INT32, 1));
-
-  // A group
-  elements.push_back(NewGroup("bag", FieldRepetitionType::OPTIONAL, 1, 2));
-
-  // 3-level list encoding, by hand
-  elt = NewGroup("b", FieldRepetitionType::REPEATED, 1, 3);
-  elt.__set_converted_type(ConvertedType::LIST);
-  elements.push_back(elt);
-  elements.push_back(
-      NewPrimitive("item", FieldRepetitionType::OPTIONAL, format::Type::INT64, 4));
-
-  ASSERT_NO_FATAL_FAILURE(Convert(&elements[0], static_cast<int>(elements.size())));
-
-  // Construct the expected schema
-  NodeVector fields;
-  fields.push_back(Int32("a", Repetition::REQUIRED));
-
-  // 3-level list encoding
-  NodePtr item = Int64("item");
-  NodePtr list(GroupNode::Make("b", Repetition::REPEATED, {item}, LogicalType::LIST));
-  NodePtr bag(GroupNode::Make("bag", Repetition::OPTIONAL, {list}));
-  fields.push_back(bag);
-
-  NodePtr schema = GroupNode::Make(name_, Repetition::REPEATED, fields);
-
-  ASSERT_TRUE(schema->Equals(group_));
-
-  // Check that the parent relationship in each node is consitent
-  ASSERT_EQ(group_->parent(), nullptr);
-  ASSERT_TRUE(check_for_parent_consistency(group_));
-}
-
-TEST_F(TestSchemaConverter, InvalidRoot) {
-  // According to the Parquet specification, the first element in the
-  // list<SchemaElement> is a group whose children (and their descendants)
-  // contain all of the rest of the flattened schema elements. If the first
-  // element is not a group, it is a malformed Parquet file.
-
-  SchemaElement elements[2];
-  elements[0] =
-      NewPrimitive("not-a-group", FieldRepetitionType::REQUIRED, format::Type::INT32, 0);
-  ASSERT_THROW(Convert(elements, 2), ParquetException);
-
-  // While the Parquet spec indicates that the root group should have REPEATED
-  // repetition type, some implementations may return REQUIRED or OPTIONAL
-  // groups as the first element. These tests check that this is okay as a
-  // practicality matter.
-  elements[0] = NewGroup("not-repeated", FieldRepetitionType::REQUIRED, 1, 0);
-  elements[1] = NewPrimitive("a", FieldRepetitionType::REQUIRED, format::Type::INT32, 1);
-  ASSERT_NO_FATAL_FAILURE(Convert(elements, 2));
-
-  elements[0] = NewGroup("not-repeated", FieldRepetitionType::OPTIONAL, 1, 0);
-  ASSERT_NO_FATAL_FAILURE(Convert(elements, 2));
-}
-
-TEST_F(TestSchemaConverter, NotEnoughChildren) {
-  // Throw a ParquetException, but don't core dump or anything
-  SchemaElement elt;
-  std::vector<SchemaElement> elements;
-  elements.push_back(NewGroup(name_, FieldRepetitionType::REPEATED, 2, 0));
-  ASSERT_THROW(Convert(&elements[0], 1), ParquetException);
-}
-
-// ----------------------------------------------------------------------
-// Schema tree flatten / unflatten
-
-class TestSchemaFlatten : public ::testing::Test {
- public:
-  void setUp() { name_ = "parquet_schema"; }
-
-  void Flatten(const GroupNode* schema) { ToParquet(schema, &elements_); }
-
- protected:
-  std::string name_;
-  std::vector<format::SchemaElement> elements_;
-};
-
-TEST_F(TestSchemaFlatten, DecimalMetadata) {
-  // Checks that DecimalMetadata is only set for DecimalTypes
-  NodePtr node = PrimitiveNode::Make("decimal", Repetition::REQUIRED, Type::INT64,
-                                     LogicalType::DECIMAL, -1, 8, 4);
-  NodePtr group =
-      GroupNode::Make("group", Repetition::REPEATED, {node}, LogicalType::LIST);
-  Flatten(reinterpret_cast<GroupNode*>(group.get()));
-  ASSERT_EQ("decimal", elements_[1].name);
-  ASSERT_TRUE(elements_[1].__isset.precision);
-  ASSERT_TRUE(elements_[1].__isset.scale);
-
-  elements_.clear();
-  // Not for integers with no logical type
-  group =
-      GroupNode::Make("group", Repetition::REPEATED, {Int64("int64")}, LogicalType::LIST);
-  Flatten(reinterpret_cast<GroupNode*>(group.get()));
-  ASSERT_EQ("int64", elements_[1].name);
-  ASSERT_FALSE(elements_[0].__isset.precision);
-  ASSERT_FALSE(elements_[0].__isset.scale);
-}
-
-TEST_F(TestSchemaFlatten, NestedExample) {
-  SchemaElement elt;
-  std::vector<SchemaElement> elements;
-  elements.push_back(NewGroup(name_, FieldRepetitionType::REPEATED, 2, 0));
-
-  // A primitive one
-  elements.push_back(
-      NewPrimitive("a", FieldRepetitionType::REQUIRED, format::Type::INT32, 1));
-
-  // A group
-  elements.push_back(NewGroup("bag", FieldRepetitionType::OPTIONAL, 1, 2));
-
-  // 3-level list encoding, by hand
-  elt = NewGroup("b", FieldRepetitionType::REPEATED, 1, 3);
-  elt.__set_converted_type(ConvertedType::LIST);
-  elements.push_back(elt);
-  elements.push_back(
-      NewPrimitive("item", FieldRepetitionType::OPTIONAL, format::Type::INT64, 4));
-
-  // Construct the schema
-  NodeVector fields;
-  fields.push_back(Int32("a", Repetition::REQUIRED));
-
-  // 3-level list encoding
-  NodePtr item = Int64("item");
-  NodePtr list(GroupNode::Make("b", Repetition::REPEATED, {item}, LogicalType::LIST));
-  NodePtr bag(GroupNode::Make("bag", Repetition::OPTIONAL, {list}));
-  fields.push_back(bag);
-
-  NodePtr schema = GroupNode::Make(name_, Repetition::REPEATED, fields);
-
-  Flatten(static_cast<GroupNode*>(schema.get()));
-  ASSERT_EQ(elements_.size(), elements.size());
-  for (size_t i = 0; i < elements_.size(); i++) {
-    ASSERT_EQ(elements_[i], elements[i]);
-  }
-}
-
-TEST(TestColumnDescriptor, TestAttrs) {
-  NodePtr node = PrimitiveNode::Make("name", Repetition::OPTIONAL, Type::BYTE_ARRAY,
-                                     LogicalType::UTF8);
-  ColumnDescriptor descr(node, 4, 1);
-
-  ASSERT_EQ("name", descr.name());
-  ASSERT_EQ(4, descr.max_definition_level());
-  ASSERT_EQ(1, descr.max_repetition_level());
-
-  ASSERT_EQ(Type::BYTE_ARRAY, descr.physical_type());
-
-  ASSERT_EQ(-1, descr.type_length());
-
-  // Test FIXED_LEN_BYTE_ARRAY
-  node = PrimitiveNode::Make("name", Repetition::OPTIONAL, Type::FIXED_LEN_BYTE_ARRAY,
-                             LogicalType::DECIMAL, 12, 10, 4);
-  descr = ColumnDescriptor(node, 4, 1);
-
-  ASSERT_EQ(Type::FIXED_LEN_BYTE_ARRAY, descr.physical_type());
-  ASSERT_EQ(12, descr.type_length());
-}
-
-class TestSchemaDescriptor : public ::testing::Test {
- public:
-  void setUp() {}
-
- protected:
-  SchemaDescriptor descr_;
-};
-
-TEST_F(TestSchemaDescriptor, InitNonGroup) {
-  NodePtr node = PrimitiveNode::Make("field", Repetition::OPTIONAL, Type::INT32);
-
-  ASSERT_THROW(descr_.Init(node), ParquetException);
-}
-
-TEST_F(TestSchemaDescriptor, Equals) {
-  NodePtr schema;
-
-  NodePtr inta = Int32("a", Repetition::REQUIRED);
-  NodePtr intb = Int64("b", Repetition::OPTIONAL);
-  NodePtr intb2 = Int64("b2", Repetition::OPTIONAL);
-  NodePtr intc = ByteArray("c", Repetition::REPEATED);
-
-  NodePtr item1 = Int64("item1", Repetition::REQUIRED);
-  NodePtr item2 = Boolean("item2", Repetition::OPTIONAL);
-  NodePtr item3 = Int32("item3", Repetition::REPEATED);
-  NodePtr list(GroupNode::Make("records", Repetition::REPEATED, {item1, item2, item3},
-                               LogicalType::LIST));
-
-  NodePtr bag(GroupNode::Make("bag", Repetition::OPTIONAL, {list}));
-  NodePtr bag2(GroupNode::Make("bag", Repetition::REQUIRED, {list}));
-
-  SchemaDescriptor descr1;
-  descr1.Init(GroupNode::Make("schema", Repetition::REPEATED, {inta, intb, intc, bag}));
-
-  ASSERT_TRUE(descr1.Equals(descr1));
-
-  SchemaDescriptor descr2;
-  descr2.Init(GroupNode::Make("schema", Repetition::REPEATED, {inta, intb, intc, bag2}));
-  ASSERT_FALSE(descr1.Equals(descr2));
-
-  SchemaDescriptor descr3;
-  descr3.Init(GroupNode::Make("schema", Repetition::REPEATED, {inta, intb2, intc, bag}));
-  ASSERT_FALSE(descr1.Equals(descr3));
-
-  // Robust to name of parent node
-  SchemaDescriptor descr4;
-  descr4.Init(GroupNode::Make("SCHEMA", Repetition::REPEATED, {inta, intb, intc, bag}));
-  ASSERT_TRUE(descr1.Equals(descr4));
-
-  SchemaDescriptor descr5;
-  descr5.Init(
-      GroupNode::Make("schema", Repetition::REPEATED, {inta, intb, intc, bag, intb2}));
-  ASSERT_FALSE(descr1.Equals(descr5));
-
-  // Different max repetition / definition levels
-  ColumnDescriptor col1(inta, 5, 1);
-  ColumnDescriptor col2(inta, 6, 1);
-  ColumnDescriptor col3(inta, 5, 2);
-
-  ASSERT_TRUE(col1.Equals(col1));
-  ASSERT_FALSE(col1.Equals(col2));
-  ASSERT_FALSE(col1.Equals(col3));
-}
-
-TEST_F(TestSchemaDescriptor, BuildTree) {
-  NodeVector fields;
-  NodePtr schema;
-
-  NodePtr inta = Int32("a", Repetition::REQUIRED);
-  fields.push_back(inta);
-  fields.push_back(Int64("b", Repetition::OPTIONAL));
-  fields.push_back(ByteArray("c", Repetition::REPEATED));
-
-  // 3-level list encoding
-  NodePtr item1 = Int64("item1", Repetition::REQUIRED);
-  NodePtr item2 = Boolean("item2", Repetition::OPTIONAL);
-  NodePtr item3 = Int32("item3", Repetition::REPEATED);
-  NodePtr list(GroupNode::Make("records", Repetition::REPEATED, {item1, item2, item3},
-                               LogicalType::LIST));
-  NodePtr bag(GroupNode::Make("bag", Repetition::OPTIONAL, {list}));
-  fields.push_back(bag);
-
-  schema = GroupNode::Make("schema", Repetition::REPEATED, fields);
-
-  descr_.Init(schema);
-
-  int nleaves = 6;
-
-  // 6 leaves
-  ASSERT_EQ(nleaves, descr_.num_columns());
-
-  //                             mdef mrep
-  // required int32 a            0    0
-  // optional int64 b            1    0
-  // repeated byte_array c       1    1
-  // optional group bag          1    0
-  //   repeated group records    2    1
-  //     required int64 item1    2    1
-  //     optional boolean item2  3    1
-  //     repeated int32 item3    3    2
-  int16_t ex_max_def_levels[6] = {0, 1, 1, 2, 3, 3};
-  int16_t ex_max_rep_levels[6] = {0, 0, 1, 1, 1, 2};
-
-  for (int i = 0; i < nleaves; ++i) {
-    const ColumnDescriptor* col = descr_.Column(i);
-    EXPECT_EQ(ex_max_def_levels[i], col->max_definition_level()) << i;
-    EXPECT_EQ(ex_max_rep_levels[i], col->max_repetition_level()) << i;
-  }
-
-  ASSERT_EQ(descr_.Column(0)->path()->ToDotString(), "a");
-  ASSERT_EQ(descr_.Column(1)->path()->ToDotString(), "b");
-  ASSERT_EQ(descr_.Column(2)->path()->ToDotString(), "c");
-  ASSERT_EQ(descr_.Column(3)->path()->ToDotString(), "bag.records.item1");
-  ASSERT_EQ(descr_.Column(4)->path()->ToDotString(), "bag.records.item2");
-  ASSERT_EQ(descr_.Column(5)->path()->ToDotString(), "bag.records.item3");
-
-  for (int i = 0; i < nleaves; ++i) {
-    auto col = descr_.Column(i);
-    ASSERT_EQ(i, descr_.ColumnIndex(*col->schema_node()));
-  }
-
-  // Test non-column nodes find
-  NodePtr non_column_alien = Int32("alien", Repetition::REQUIRED);  // other path
-  NodePtr non_column_familiar = Int32("a", Repetition::REPEATED);   // other node
-  ASSERT_TRUE(descr_.ColumnIndex(*non_column_alien) < 0);
-  ASSERT_TRUE(descr_.ColumnIndex(*non_column_familiar) < 0);
-
-  ASSERT_EQ(inta.get(), descr_.GetColumnRoot(0));
-  ASSERT_EQ(bag.get(), descr_.GetColumnRoot(3));
-  ASSERT_EQ(bag.get(), descr_.GetColumnRoot(4));
-  ASSERT_EQ(bag.get(), descr_.GetColumnRoot(5));
-
-  ASSERT_EQ(schema.get(), descr_.group_node());
-
-  // Init clears the leaves
-  descr_.Init(schema);
-  ASSERT_EQ(nleaves, descr_.num_columns());
-}
-
-static std::string Print(const NodePtr& node) {
-  std::stringstream ss;
-  PrintSchema(node.get(), ss);
-  return ss.str();
-}
-
-TEST(TestSchemaPrinter, Examples) {
-  // Test schema 1
-  NodeVector fields;
-  fields.push_back(Int32("a", Repetition::REQUIRED));
-
-  // 3-level list encoding
-  NodePtr item1 = Int64("item1");
-  NodePtr item2 = Boolean("item2", Repetition::REQUIRED);
-  NodePtr list(
-      GroupNode::Make("b", Repetition::REPEATED, {item1, item2}, LogicalType::LIST));
-  NodePtr bag(GroupNode::Make("bag", Repetition::OPTIONAL, {list}));
-  fields.push_back(bag);
-
-  fields.push_back(PrimitiveNode::Make("c", Repetition::REQUIRED, Type::INT32,
-                                       LogicalType::DECIMAL, -1, 3, 2));
-
-  NodePtr schema = GroupNode::Make("schema", Repetition::REPEATED, fields);
-
-  std::string result = Print(schema);
-  std::string expected = R"(message schema {
-  required int32 a;
-  optional group bag {
-    repeated group b (LIST) {
-      optional int64 item1;
-      required boolean item2;
-    }
-  }
-  required int32 c (DECIMAL(3,2));
-}
-)";
-  ASSERT_EQ(expected, result);
-}
-
-}  // namespace schema
-}  // namespace parquet
diff --git a/src/parquet/schema.cc b/src/parquet/schema.cc
deleted file mode 100644
index 7718781..0000000
--- a/src/parquet/schema.cc
+++ /dev/null
@@ -1,756 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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.
-
-#include "parquet/schema.h"
-#include "parquet/schema-internal.h"
-
-#include <algorithm>
-#include <memory>
-#include <sstream>
-#include <string>
-
-#include "parquet/exception.h"
-#include "parquet/parquet_types.h"
-#include "parquet/thrift.h"
-
-using parquet::format::SchemaElement;
-
-namespace parquet {
-
-namespace schema {
-
-// ----------------------------------------------------------------------
-// ColumnPath
-
-std::shared_ptr<ColumnPath> ColumnPath::FromDotString(const std::string& dotstring) {
-  std::stringstream ss(dotstring);
-  std::string item;
-  std::vector<std::string> path;
-  while (std::getline(ss, item, '.')) {
-    path.push_back(item);
-  }
-  return std::shared_ptr<ColumnPath>(new ColumnPath(std::move(path)));
-}
-
-std::shared_ptr<ColumnPath> ColumnPath::FromNode(const Node& node) {
-  // Build the path in reverse order as we traverse the nodes to the top
-  std::vector<std::string> rpath_;
-  const Node* cursor = &node;
-  // The schema node is not part of the ColumnPath
-  while (cursor->parent()) {
-    rpath_.push_back(cursor->name());
-    cursor = cursor->parent();
-  }
-
-  // Build ColumnPath in correct order
-  std::vector<std::string> path(rpath_.crbegin(), rpath_.crend());
-  return std::make_shared<ColumnPath>(std::move(path));
-}
-
-std::shared_ptr<ColumnPath> ColumnPath::extend(const std::string& node_name) const {
-  std::vector<std::string> path;
-  path.reserve(path_.size() + 1);
-  path.resize(path_.size() + 1);
-  std::copy(path_.cbegin(), path_.cend(), path.begin());
-  path[path_.size()] = node_name;
-
-  return std::shared_ptr<ColumnPath>(new ColumnPath(std::move(path)));
-}
-
-std::string ColumnPath::ToDotString() const {
-  std::stringstream ss;
-  for (auto it = path_.cbegin(); it != path_.cend(); ++it) {
-    if (it != path_.cbegin()) {
-      ss << ".";
-    }
-    ss << *it;
-  }
-  return ss.str();
-}
-
-const std::vector<std::string>& ColumnPath::ToDotVector() const { return path_; }
-
-// ----------------------------------------------------------------------
-// Base node
-
-const std::shared_ptr<ColumnPath> Node::path() const {
-  // TODO(itaiin): Cache the result, or more precisely, cache ->ToDotString()
-  //    since it is being used to access the leaf nodes
-  return ColumnPath::FromNode(*this);
-}
-
-bool Node::EqualsInternal(const Node* other) const {
-  return type_ == other->type_ && name_ == other->name_ &&
-         repetition_ == other->repetition_ && logical_type_ == other->logical_type_;
-}
-
-void Node::SetParent(const Node* parent) { parent_ = parent; }
-
-// ----------------------------------------------------------------------
-// Primitive node
-
-PrimitiveNode::PrimitiveNode(const std::string& name, Repetition::type repetition,
-                             Type::type type, LogicalType::type logical_type, int length,
-                             int precision, int scale, int id)
-    : Node(Node::PRIMITIVE, name, repetition, logical_type, id),
-      physical_type_(type),
-      type_length_(length) {
-  std::stringstream ss;
-
-  // PARQUET-842: In an earlier revision, decimal_metadata_.isset was being
-  // set to true, but Impala will raise an incompatible metadata in such cases
-  memset(&decimal_metadata_, 0, sizeof(decimal_metadata_));
-
-  // Check if the physical and logical types match
-  // Mapping referred from Apache parquet-mr as on 2016-02-22
-  switch (logical_type) {
-    case LogicalType::NONE:
-      // Logical type not set
-      break;
-    case LogicalType::UTF8:
-    case LogicalType::JSON:
-    case LogicalType::BSON:
-      if (type != Type::BYTE_ARRAY) {
-        ss << LogicalTypeToString(logical_type);
-        ss << " can only annotate BYTE_ARRAY fields";
-        throw ParquetException(ss.str());
-      }
-      break;
-    case LogicalType::DECIMAL:
-      if ((type != Type::INT32) && (type != Type::INT64) && (type != Type::BYTE_ARRAY) &&
-          (type != Type::FIXED_LEN_BYTE_ARRAY)) {
-        ss << "DECIMAL can only annotate INT32, INT64, BYTE_ARRAY, and FIXED";
-        throw ParquetException(ss.str());
-      }
-      if (precision <= 0) {
-        ss << "Invalid DECIMAL precision: " << precision
-           << ". Precision must be a number between 1 and 38 inclusive";
-        throw ParquetException(ss.str());
-      }
-      if (scale < 0) {
-        ss << "Invalid DECIMAL scale: " << scale
-           << ". Scale must be a number between 0 and precision inclusive";
-        throw ParquetException(ss.str());
-      }
-      if (scale > precision) {
-        ss << "Invalid DECIMAL scale " << scale;
-        ss << " cannot be greater than precision " << precision;
-        throw ParquetException(ss.str());
-      }
-      decimal_metadata_.isset = true;
-      decimal_metadata_.precision = precision;
-      decimal_metadata_.scale = scale;
-      break;
-    case LogicalType::DATE:
-    case LogicalType::TIME_MILLIS:
-    case LogicalType::UINT_8:
-    case LogicalType::UINT_16:
-    case LogicalType::UINT_32:
-    case LogicalType::INT_8:
-    case LogicalType::INT_16:
-    case LogicalType::INT_32:
-      if (type != Type::INT32) {
-        ss << LogicalTypeToString(logical_type);
-        ss << " can only annotate INT32";
-        throw ParquetException(ss.str());
-      }
-      break;
-    case LogicalType::TIME_MICROS:
-    case LogicalType::TIMESTAMP_MILLIS:
-    case LogicalType::TIMESTAMP_MICROS:
-    case LogicalType::UINT_64:
-    case LogicalType::INT_64:
-      if (type != Type::INT64) {
-        ss << LogicalTypeToString(logical_type);
-        ss << " can only annotate INT64";
-        throw ParquetException(ss.str());
-      }
-      break;
-    case LogicalType::INTERVAL:
-      if ((type != Type::FIXED_LEN_BYTE_ARRAY) || (length != 12)) {
-        ss << "INTERVAL can only annotate FIXED_LEN_BYTE_ARRAY(12)";
-        throw ParquetException(ss.str());
-      }
-      break;
-    case LogicalType::ENUM:
-      if (type != Type::BYTE_ARRAY) {
-        ss << "ENUM can only annotate BYTE_ARRAY fields";
-        throw ParquetException(ss.str());
-      }
-      break;
-    case LogicalType::NA:
-      // NA can annotate any type
-      break;
-    default:
-      ss << LogicalTypeToString(logical_type);
-      ss << " can not be applied to a primitive type";
-      throw ParquetException(ss.str());
-  }
-  if (type == Type::FIXED_LEN_BYTE_ARRAY) {
-    if (length <= 0) {
-      ss << "Invalid FIXED_LEN_BYTE_ARRAY length: " << length;
-      throw ParquetException(ss.str());
-    }
-    type_length_ = length;
-  }
-}
-
-bool PrimitiveNode::EqualsInternal(const PrimitiveNode* other) const {
-  bool is_equal = true;
-  if ((physical_type_ != other->physical_type_) ||
-      (logical_type_ != other->logical_type_)) {
-    return false;
-  }
-  if (logical_type_ == LogicalType::DECIMAL) {
-    is_equal &= (decimal_metadata_.precision == other->decimal_metadata_.precision) &&
-                (decimal_metadata_.scale == other->decimal_metadata_.scale);
-  }
-  if (physical_type_ == Type::FIXED_LEN_BYTE_ARRAY) {
-    is_equal &= (type_length_ == other->type_length_);
-  }
-  return is_equal;
-}
-
-bool PrimitiveNode::Equals(const Node* other) const {
-  if (!Node::EqualsInternal(other)) {
-    return false;
-  }
-  return EqualsInternal(static_cast<const PrimitiveNode*>(other));
-}
-
-void PrimitiveNode::Visit(Node::Visitor* visitor) { visitor->Visit(this); }
-
-void PrimitiveNode::VisitConst(Node::ConstVisitor* visitor) const {
-  visitor->Visit(this);
-}
-
-// ----------------------------------------------------------------------
-// Group node
-
-bool GroupNode::EqualsInternal(const GroupNode* other) const {
-  if (this == other) {
-    return true;
-  }
-  if (this->field_count() != other->field_count()) {
-    return false;
-  }
-  for (int i = 0; i < this->field_count(); ++i) {
-    if (!this->field(i)->Equals(other->field(i).get())) {
-      return false;
-    }
-  }
-  return true;
-}
-
-bool GroupNode::Equals(const Node* other) const {
-  if (!Node::EqualsInternal(other)) {
-    return false;
-  }
-  return EqualsInternal(static_cast<const GroupNode*>(other));
-}
-
-int GroupNode::FieldIndex(const std::string& name) const {
-  auto search = field_name_to_idx_.find(name);
-  if (search == field_name_to_idx_.end()) {
-    // Not found
-    return -1;
-  }
-  return search->second;
-}
-
-int GroupNode::FieldIndex(const Node& node) const {
-  auto search = field_name_to_idx_.equal_range(node.name());
-  for (auto it = search.first; it != search.second; ++it) {
-    const int idx = it->second;
-    if (&node == field(idx).get()) {
-      return idx;
-    }
-  }
-  return -1;
-}
-
-void GroupNode::Visit(Node::Visitor* visitor) { visitor->Visit(this); }
-
-void GroupNode::VisitConst(Node::ConstVisitor* visitor) const { visitor->Visit(this); }
-
-// ----------------------------------------------------------------------
-// Node construction from Parquet metadata
-
-struct NodeParams {
-  explicit NodeParams(const std::string& name) : name(name) {}
-
-  const std::string& name;
-  Repetition::type repetition;
-  LogicalType::type logical_type;
-};
-
-static inline NodeParams GetNodeParams(const format::SchemaElement* element) {
-  NodeParams params(element->name);
-
-  params.repetition = FromThrift(element->repetition_type);
-  if (element->__isset.converted_type) {
-    params.logical_type = FromThrift(element->converted_type);
-  } else {
-    params.logical_type = LogicalType::NONE;
-  }
-  return params;
-}
-
-std::unique_ptr<Node> GroupNode::FromParquet(const void* opaque_element, int node_id,
-                                             const NodeVector& fields) {
-  const format::SchemaElement* element =
-      static_cast<const format::SchemaElement*>(opaque_element);
-  NodeParams params = GetNodeParams(element);
-  return std::unique_ptr<Node>(new GroupNode(params.name, params.repetition, fields,
-                                             params.logical_type, node_id));
-}
-
-std::unique_ptr<Node> PrimitiveNode::FromParquet(const void* opaque_element,
-                                                 int node_id) {
-  const format::SchemaElement* element =
-      static_cast<const format::SchemaElement*>(opaque_element);
-  NodeParams params = GetNodeParams(element);
-
-  std::unique_ptr<PrimitiveNode> result =
-      std::unique_ptr<PrimitiveNode>(new PrimitiveNode(
-          params.name, params.repetition, FromThrift(element->type), params.logical_type,
-          element->type_length, element->precision, element->scale, node_id));
-
-  // Return as unique_ptr to the base type
-  return std::unique_ptr<Node>(result.release());
-}
-
-void GroupNode::ToParquet(void* opaque_element) const {
-  format::SchemaElement* element = static_cast<format::SchemaElement*>(opaque_element);
-  element->__set_name(name_);
-  element->__set_num_children(field_count());
-  element->__set_repetition_type(ToThrift(repetition_));
-  if (logical_type_ != LogicalType::NONE) {
-    element->__set_converted_type(ToThrift(logical_type_));
-  }
-}
-
-void PrimitiveNode::ToParquet(void* opaque_element) const {
-  format::SchemaElement* element = static_cast<format::SchemaElement*>(opaque_element);
-
-  element->__set_name(name_);
-  element->__set_repetition_type(ToThrift(repetition_));
-  if (logical_type_ != LogicalType::NONE) {
-    element->__set_converted_type(ToThrift(logical_type_));
-  }
-  element->__set_type(ToThrift(physical_type_));
-  if (physical_type_ == Type::FIXED_LEN_BYTE_ARRAY) {
-    element->__set_type_length(type_length_);
-  }
-  if (decimal_metadata_.isset) {
-    element->__set_precision(decimal_metadata_.precision);
-    element->__set_scale(decimal_metadata_.scale);
-  }
-}
-
-// ----------------------------------------------------------------------
-// Schema converters
-
-std::unique_ptr<Node> FlatSchemaConverter::Convert() {
-  const SchemaElement& root = elements_[0];
-
-  // Validate the root node
-  if (root.num_children == 0) {
-    throw ParquetException("Root node did not have children");
-  }
-
-  // Relaxing this restriction as some implementations don't set this
-  // if (root.repetition_type != FieldRepetitionType::REPEATED) {
-  //   throw ParquetException("Root node was not FieldRepetitionType::REPEATED");
-  // }
-
-  return NextNode();
-}
-
-std::unique_ptr<Node> FlatSchemaConverter::NextNode() {
-  const SchemaElement& element = Next();
-
-  int node_id = next_id();
-
-  const void* opaque_element = static_cast<const void*>(&element);
-
-  if (element.num_children == 0) {
-    // Leaf (primitive) node
-    return PrimitiveNode::FromParquet(opaque_element, node_id);
-  } else {
-    // Group
-    NodeVector fields;
-    for (int i = 0; i < element.num_children; ++i) {
-      std::unique_ptr<Node> field = NextNode();
-      fields.push_back(NodePtr(field.release()));
-    }
-    return GroupNode::FromParquet(opaque_element, node_id, fields);
-  }
-}
-
-const format::SchemaElement& FlatSchemaConverter::Next() {
-  if (pos_ == length_) {
-    throw ParquetException("Malformed schema: not enough SchemaElement values");
-  }
-  return elements_[pos_++];
-}
-
-std::shared_ptr<SchemaDescriptor> FromParquet(const std::vector<SchemaElement>& schema) {
-  FlatSchemaConverter converter(&schema[0], static_cast<int>(schema.size()));
-  std::unique_ptr<Node> root = converter.Convert();
-
-  std::shared_ptr<SchemaDescriptor> descr = std::make_shared<SchemaDescriptor>();
-  descr->Init(std::shared_ptr<GroupNode>(static_cast<GroupNode*>(root.release())));
-
-  return descr;
-}
-
-void ToParquet(const GroupNode* schema, std::vector<format::SchemaElement>* out) {
-  SchemaFlattener flattener(schema, out);
-  flattener.Flatten();
-}
-
-class SchemaVisitor : public Node::ConstVisitor {
- public:
-  explicit SchemaVisitor(std::vector<format::SchemaElement>* elements)
-      : elements_(elements) {}
-
-  void Visit(const Node* node) override {
-    format::SchemaElement element;
-    node->ToParquet(&element);
-    elements_->push_back(element);
-
-    if (node->is_group()) {
-      const GroupNode* group_node = static_cast<const GroupNode*>(node);
-      for (int i = 0; i < group_node->field_count(); ++i) {
-        group_node->field(i)->VisitConst(this);
-      }
-    }
-  }
-
- private:
-  std::vector<format::SchemaElement>* elements_;
-};
-
-SchemaFlattener::SchemaFlattener(const GroupNode* schema,
-                                 std::vector<format::SchemaElement>* out)
-    : root_(schema), elements_(out) {}
-
-void SchemaFlattener::Flatten() {
-  SchemaVisitor visitor(elements_);
-  root_->VisitConst(&visitor);
-}
-
-// ----------------------------------------------------------------------
-// Schema printing
-
-class SchemaPrinter : public Node::ConstVisitor {
- public:
-  explicit SchemaPrinter(std::ostream& stream, int indent_width)
-      : stream_(stream), indent_(0), indent_width_(2) {}
-
-  void Visit(const Node* node) override;
-
- private:
-  void Visit(const PrimitiveNode* node);
-  void Visit(const GroupNode* node);
-
-  void Indent();
-
-  std::ostream& stream_;
-
-  int indent_;
-  int indent_width_;
-};
-
-static void PrintRepLevel(Repetition::type repetition, std::ostream& stream) {
-  switch (repetition) {
-    case Repetition::REQUIRED:
-      stream << "required";
-      break;
-    case Repetition::OPTIONAL:
-      stream << "optional";
-      break;
-    case Repetition::REPEATED:
-      stream << "repeated";
-      break;
-    default:
-      break;
-  }
-}
-
-static void PrintType(const PrimitiveNode* node, std::ostream& stream) {
-  switch (node->physical_type()) {
-    case Type::BOOLEAN:
-      stream << "boolean";
-      break;
-    case Type::INT32:
-      stream << "int32";
-      break;
-    case Type::INT64:
-      stream << "int64";
-      break;
-    case Type::INT96:
-      stream << "int96";
-      break;
-    case Type::FLOAT:
-      stream << "float";
-      break;
-    case Type::DOUBLE:
-      stream << "double";
-      break;
-    case Type::BYTE_ARRAY:
-      stream << "binary";
-      break;
-    case Type::FIXED_LEN_BYTE_ARRAY:
-      stream << "fixed_len_byte_array(" << node->type_length() << ")";
-      break;
-    default:
-      break;
-  }
-}
-
-static void PrintLogicalType(const PrimitiveNode* node, std::ostream& stream) {
-  auto lt = node->logical_type();
-  if (lt == LogicalType::DECIMAL) {
-    stream << " (" << LogicalTypeToString(lt) << "(" << node->decimal_metadata().precision
-           << "," << node->decimal_metadata().scale << "))";
-  } else if (lt != LogicalType::NONE) {
-    stream << " (" << LogicalTypeToString(lt) << ")";
-  }
-}
-
-void SchemaPrinter::Visit(const PrimitiveNode* node) {
-  PrintRepLevel(node->repetition(), stream_);
-  stream_ << " ";
-  PrintType(node, stream_);
-  stream_ << " " << node->name();
-  PrintLogicalType(node, stream_);
-  stream_ << ";" << std::endl;
-}
-
-void SchemaPrinter::Visit(const GroupNode* node) {
-  if (!node->parent()) {
-    stream_ << "message " << node->name() << " {" << std::endl;
-  } else {
-    PrintRepLevel(node->repetition(), stream_);
-    stream_ << " group " << node->name();
-    auto lt = node->logical_type();
-    if (lt != LogicalType::NONE) {
-      stream_ << " (" << LogicalTypeToString(lt) << ")";
-    }
-    stream_ << " {" << std::endl;
-  }
-
-  indent_ += indent_width_;
-  for (int i = 0; i < node->field_count(); ++i) {
-    node->field(i)->VisitConst(this);
-  }
-  indent_ -= indent_width_;
-  Indent();
-  stream_ << "}" << std::endl;
-}
-
-void SchemaPrinter::Indent() {
-  if (indent_ > 0) {
-    std::string spaces(indent_, ' ');
-    stream_ << spaces;
-  }
-}
-
-void SchemaPrinter::Visit(const Node* node) {
-  Indent();
-  if (node->is_group()) {
-    Visit(static_cast<const GroupNode*>(node));
-  } else {
-    // Primitive
-    Visit(static_cast<const PrimitiveNode*>(node));
-  }
-}
-
-void PrintSchema(const Node* schema, std::ostream& stream, int indent_width) {
-  SchemaPrinter printer(stream, indent_width);
-  printer.Visit(schema);
-}
-
-}  // namespace schema
-
-using schema::ColumnPath;
-using schema::GroupNode;
-using schema::Node;
-using schema::NodePtr;
-using schema::PrimitiveNode;
-
-void SchemaDescriptor::Init(std::unique_ptr<schema::Node> schema) {
-  Init(NodePtr(schema.release()));
-}
-
-class SchemaUpdater : public Node::Visitor {
- public:
-  explicit SchemaUpdater(const std::vector<ColumnOrder>& column_orders)
-      : column_orders_(column_orders), leaf_count_(0) {}
-
-  void Visit(Node* node) override {
-    if (node->is_group()) {
-      GroupNode* group_node = static_cast<GroupNode*>(node);
-      for (int i = 0; i < group_node->field_count(); ++i) {
-        group_node->field(i)->Visit(this);
-      }
-    } else {  // leaf node
-      PrimitiveNode* leaf_node = static_cast<PrimitiveNode*>(node);
-      leaf_node->SetColumnOrder(column_orders_[leaf_count_++]);
-    }
-  }
-
- private:
-  const std::vector<ColumnOrder>& column_orders_;
-  int leaf_count_;
-};
-
-void SchemaDescriptor::updateColumnOrders(const std::vector<ColumnOrder>& column_orders) {
-  if (static_cast<int>(column_orders.size()) != num_columns()) {
-    throw ParquetException("Malformed schema: not enough ColumnOrder values");
-  }
-  SchemaUpdater visitor(column_orders);
-  const_cast<GroupNode*>(group_node_)->Visit(&visitor);
-}
-
-void SchemaDescriptor::Init(const NodePtr& schema) {
-  schema_ = schema;
-
-  if (!schema_->is_group()) {
-    throw ParquetException("Must initialize with a schema group");
-  }
-
-  group_node_ = static_cast<const GroupNode*>(schema_.get());
-  leaves_.clear();
-
-  for (int i = 0; i < group_node_->field_count(); ++i) {
-    BuildTree(group_node_->field(i), 0, 0, group_node_->field(i));
-  }
-}
-
-bool SchemaDescriptor::Equals(const SchemaDescriptor& other) const {
-  if (this->num_columns() != other.num_columns()) {
-    return false;
-  }
-
-  for (int i = 0; i < this->num_columns(); ++i) {
-    if (!this->Column(i)->Equals(*other.Column(i))) {
-      return false;
-    }
-  }
-
-  return true;
-}
-
-void SchemaDescriptor::BuildTree(const NodePtr& node, int16_t max_def_level,
-                                 int16_t max_rep_level, const NodePtr& base) {
-  if (node->is_optional()) {
-    ++max_def_level;
-  } else if (node->is_repeated()) {
-    // Repeated fields add a definition level. This is used to distinguish
-    // between an empty list and a list with an item in it.
-    ++max_rep_level;
-    ++max_def_level;
-  }
-
-  // Now, walk the schema and create a ColumnDescriptor for each leaf node
-  if (node->is_group()) {
-    const GroupNode* group = static_cast<const GroupNode*>(node.get());
-    for (int i = 0; i < group->field_count(); ++i) {
-      BuildTree(group->field(i), max_def_level, max_rep_level, base);
-    }
-  } else {
-    // Primitive node, append to leaves
-    leaves_.push_back(ColumnDescriptor(node, max_def_level, max_rep_level, this));
-    leaf_to_base_.emplace(static_cast<int>(leaves_.size()) - 1, base);
-    leaf_to_idx_.emplace(node->path()->ToDotString(),
-                         static_cast<int>(leaves_.size()) - 1);
-  }
-}
-
-ColumnDescriptor::ColumnDescriptor(const schema::NodePtr& node,
-                                   int16_t max_definition_level,
-                                   int16_t max_repetition_level,
-                                   const SchemaDescriptor* schema_descr)
-    : node_(node),
-      max_definition_level_(max_definition_level),
-      max_repetition_level_(max_repetition_level) {
-  if (!node_->is_primitive()) {
-    throw ParquetException("Must be a primitive type");
-  }
-  primitive_node_ = static_cast<const PrimitiveNode*>(node_.get());
-}
-
-bool ColumnDescriptor::Equals(const ColumnDescriptor& other) const {
-  return primitive_node_->Equals(other.primitive_node_) &&
-         max_repetition_level() == other.max_repetition_level() &&
-         max_definition_level() == other.max_definition_level();
-}
-
-const ColumnDescriptor* SchemaDescriptor::Column(int i) const {
-  DCHECK(i >= 0 && i < static_cast<int>(leaves_.size()));
-  return &leaves_[i];
-}
-
-int SchemaDescriptor::ColumnIndex(const std::string& node_path) const {
-  auto search = leaf_to_idx_.find(node_path);
-  if (search == leaf_to_idx_.end()) {
-    // Not found
-    return -1;
-  }
-  return search->second;
-}
-
-int SchemaDescriptor::ColumnIndex(const Node& node) const {
-  auto search = leaf_to_idx_.equal_range(node.path()->ToDotString());
-  for (auto it = search.first; it != search.second; ++it) {
-    const int idx = it->second;
-    if (&node == Column(idx)->schema_node().get()) {
-      return idx;
-    }
-  }
-  return -1;
-}
-
-const schema::Node* SchemaDescriptor::GetColumnRoot(int i) const {
-  DCHECK(i >= 0 && i < static_cast<int>(leaves_.size()));
-  return leaf_to_base_.find(i)->second.get();
-}
-
-std::string SchemaDescriptor::ToString() const {
-  std::ostringstream ss;
-  PrintSchema(schema_.get(), ss);
-  return ss.str();
-}
-
-int ColumnDescriptor::type_scale() const {
-  return primitive_node_->decimal_metadata().scale;
-}
-
-int ColumnDescriptor::type_precision() const {
-  return primitive_node_->decimal_metadata().precision;
-}
-
-int ColumnDescriptor::type_length() const { return primitive_node_->type_length(); }
-
-const std::shared_ptr<ColumnPath> ColumnDescriptor::path() const {
-  return primitive_node_->path();
-}
-
-}  // namespace parquet
diff --git a/src/parquet/schema.h b/src/parquet/schema.h
deleted file mode 100644
index 1a94ed1..0000000
--- a/src/parquet/schema.h
+++ /dev/null
@@ -1,452 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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.
-
-// This module contains the logical parquet-cpp types (independent of Thrift
-// structures), schema nodes, and related type tools
-
-#ifndef PARQUET_SCHEMA_TYPES_H
-#define PARQUET_SCHEMA_TYPES_H
-
-#include <cstdint>
-#include <memory>
-#include <ostream>
-#include <string>
-#include <unordered_map>
-#include <vector>
-
-#include "parquet/types.h"
-#include "parquet/util/macros.h"
-#include "parquet/util/visibility.h"
-
-namespace parquet {
-
-class SchemaDescriptor;
-
-namespace schema {
-
-class Node;
-
-// List encodings: using the terminology from Impala to define different styles
-// of representing logical lists (a.k.a. ARRAY types) in Parquet schemas. Since
-// the converted type named in the Parquet metadata is ConvertedType::LIST we
-// use that terminology here. It also helps distinguish from the *_ARRAY
-// primitive types.
-//
-// One-level encoding: Only allows required lists with required cells
-//   repeated value_type name
-//
-// Two-level encoding: Enables optional lists with only required cells
-//   <required/optional> group list
-//     repeated value_type item
-//
-// Three-level encoding: Enables optional lists with optional cells
-//   <required/optional> group bag
-//     repeated group list
-//       <required/optional> value_type item
-//
-// 2- and 1-level encoding are respectively equivalent to 3-level encoding with
-// the non-repeated nodes set to required.
-//
-// The "official" encoding recommended in the Parquet spec is the 3-level, and
-// we use that as the default when creating list types. For semantic completeness
-// we allow the other two. Since all types of encodings will occur "in the
-// wild" we need to be able to interpret the associated definition levels in
-// the context of the actual encoding used in the file.
-//
-// NB: Some Parquet writers may not set ConvertedType::LIST on the repeated
-// SchemaElement, which could make things challenging if we are trying to infer
-// that a sequence of nodes semantically represents an array according to one
-// of these encodings (versus a struct containing an array). We should refuse
-// the temptation to guess, as they say.
-struct ListEncoding {
-  enum type { ONE_LEVEL, TWO_LEVEL, THREE_LEVEL };
-};
-
-struct DecimalMetadata {
-  bool isset;
-  int32_t scale;
-  int32_t precision;
-};
-
-class PARQUET_EXPORT ColumnPath {
- public:
-  ColumnPath() : path_() {}
-  explicit ColumnPath(const std::vector<std::string>& path) : path_(path) {}
-  explicit ColumnPath(std::vector<std::string>&& path) : path_(path) {}
-
-  static std::shared_ptr<ColumnPath> FromDotString(const std::string& dotstring);
-  static std::shared_ptr<ColumnPath> FromNode(const Node& node);
-
-  std::shared_ptr<ColumnPath> extend(const std::string& node_name) const;
-  std::string ToDotString() const;
-  const std::vector<std::string>& ToDotVector() const;
-
- protected:
-  std::vector<std::string> path_;
-};
-
-class GroupNode;
-
-// Base class for logical schema types. A type has a name, repetition level,
-// and optionally a logical type (ConvertedType in Parquet metadata parlance)
-class PARQUET_EXPORT Node {
- public:
-  enum type { PRIMITIVE, GROUP };
-
-  Node(Node::type type, const std::string& name, Repetition::type repetition,
-       LogicalType::type logical_type = LogicalType::NONE, int id = -1)
-      : type_(type),
-        name_(name),
-        repetition_(repetition),
-        logical_type_(logical_type),
-        id_(id),
-        parent_(nullptr) {}
-
-  virtual ~Node() {}
-
-  bool is_primitive() const { return type_ == Node::PRIMITIVE; }
-
-  bool is_group() const { return type_ == Node::GROUP; }
-
-  bool is_optional() const { return repetition_ == Repetition::OPTIONAL; }
-
-  bool is_repeated() const { return repetition_ == Repetition::REPEATED; }
-
-  bool is_required() const { return repetition_ == Repetition::REQUIRED; }
-
-  virtual bool Equals(const Node* other) const = 0;
-
-  const std::string& name() const { return name_; }
-
-  Node::type node_type() const { return type_; }
-
-  Repetition::type repetition() const { return repetition_; }
-
-  LogicalType::type logical_type() const { return logical_type_; }
-
-  int id() const { return id_; }
-
-  const Node* parent() const { return parent_; }
-
-  const std::shared_ptr<ColumnPath> path() const;
-
-  // ToParquet returns an opaque void* to avoid exporting
-  // parquet::SchemaElement into the public API
-  virtual void ToParquet(void* opaque_element) const = 0;
-
-  // Node::Visitor abstract class for walking schemas with the visitor pattern
-  class Visitor {
-   public:
-    virtual ~Visitor() {}
-
-    virtual void Visit(Node* node) = 0;
-  };
-  class ConstVisitor {
-   public:
-    virtual ~ConstVisitor() {}
-
-    virtual void Visit(const Node* node) = 0;
-  };
-
-  virtual void Visit(Visitor* visitor) = 0;
-  virtual void VisitConst(ConstVisitor* visitor) const = 0;
-
- protected:
-  friend class GroupNode;
-
-  Node::type type_;
-  std::string name_;
-  Repetition::type repetition_;
-  LogicalType::type logical_type_;
-  int id_;
-  // Nodes should not be shared, they have a single parent.
-  const Node* parent_;
-
-  bool EqualsInternal(const Node* other) const;
-  void SetParent(const Node* p_parent);
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(Node);
-};
-
-// Save our breath all over the place with these typedefs
-typedef std::shared_ptr<Node> NodePtr;
-typedef std::vector<NodePtr> NodeVector;
-
-// A type that is one of the primitive Parquet storage types. In addition to
-// the other type metadata (name, repetition level, logical type), also has the
-// physical storage type and their type-specific metadata (byte width, decimal
-// parameters)
-class PARQUET_EXPORT PrimitiveNode : public Node {
- public:
-  // FromParquet accepts an opaque void* to avoid exporting
-  // parquet::SchemaElement into the public API
-  static std::unique_ptr<Node> FromParquet(const void* opaque_element, int id);
-
-  static inline NodePtr Make(const std::string& name, Repetition::type repetition,
-                             Type::type type,
-                             LogicalType::type logical_type = LogicalType::NONE,
-                             int length = -1, int precision = -1, int scale = -1) {
-    return NodePtr(new PrimitiveNode(name, repetition, type, logical_type, length,
-                                     precision, scale));
-  }
-
-  bool Equals(const Node* other) const override;
-
-  Type::type physical_type() const { return physical_type_; }
-
-  ColumnOrder column_order() const { return column_order_; }
-
-  void SetColumnOrder(ColumnOrder column_order) { column_order_ = column_order; }
-
-  int32_t type_length() const { return type_length_; }
-
-  const DecimalMetadata& decimal_metadata() const { return decimal_metadata_; }
-
-  void ToParquet(void* opaque_element) const override;
-  void Visit(Visitor* visitor) override;
-  void VisitConst(ConstVisitor* visitor) const override;
-
- private:
-  PrimitiveNode(const std::string& name, Repetition::type repetition, Type::type type,
-                LogicalType::type logical_type = LogicalType::NONE, int length = -1,
-                int precision = -1, int scale = -1, int id = -1);
-
-  Type::type physical_type_;
-  int32_t type_length_;
-  DecimalMetadata decimal_metadata_;
-  ColumnOrder column_order_;
-
-  // For FIXED_LEN_BYTE_ARRAY
-  void SetTypeLength(int32_t length) { type_length_ = length; }
-
-  // For Decimal logical type: Precision and scale
-  void SetDecimalMetadata(int32_t scale, int32_t precision) {
-    decimal_metadata_.scale = scale;
-    decimal_metadata_.precision = precision;
-  }
-
-  bool EqualsInternal(const PrimitiveNode* other) const;
-
-  FRIEND_TEST(TestPrimitiveNode, Attrs);
-  FRIEND_TEST(TestPrimitiveNode, Equals);
-  FRIEND_TEST(TestPrimitiveNode, PhysicalLogicalMapping);
-  FRIEND_TEST(TestPrimitiveNode, FromParquet);
-};
-
-class PARQUET_EXPORT GroupNode : public Node {
- public:
-  // Like PrimitiveNode, GroupNode::FromParquet accepts an opaque void* to avoid exporting
-  // parquet::SchemaElement into the public API
-  static std::unique_ptr<Node> FromParquet(const void* opaque_element, int id,
-                                           const NodeVector& fields);
-
-  static inline NodePtr Make(const std::string& name, Repetition::type repetition,
-                             const NodeVector& fields,
-                             LogicalType::type logical_type = LogicalType::NONE) {
-    return NodePtr(new GroupNode(name, repetition, fields, logical_type));
-  }
-
-  bool Equals(const Node* other) const override;
-
-  NodePtr field(int i) const { return fields_[i]; }
-  // Get the index of a field by its name, or negative value if not found.
-  // If several fields share the same name, it is unspecified which one
-  // is returned.
-  int FieldIndex(const std::string& name) const;
-  // Get the index of a field by its node, or negative value if not found.
-  int FieldIndex(const Node& node) const;
-
-  int field_count() const { return static_cast<int>(fields_.size()); }
-
-  void ToParquet(void* opaque_element) const override;
-  void Visit(Visitor* visitor) override;
-  void VisitConst(ConstVisitor* visitor) const override;
-
- private:
-  GroupNode(const std::string& name, Repetition::type repetition,
-            const NodeVector& fields, LogicalType::type logical_type = LogicalType::NONE,
-            int id = -1)
-      : Node(Node::GROUP, name, repetition, logical_type, id), fields_(fields) {
-    field_name_to_idx_.clear();
-    auto field_idx = 0;
-    for (NodePtr& field : fields_) {
-      field->SetParent(this);
-      field_name_to_idx_.emplace(field->name(), field_idx++);
-    }
-  }
-
-  NodeVector fields_;
-  bool EqualsInternal(const GroupNode* other) const;
-
-  // Mapping between field name to the field index
-  std::unordered_multimap<std::string, int> field_name_to_idx_;
-
-  FRIEND_TEST(TestGroupNode, Attrs);
-  FRIEND_TEST(TestGroupNode, Equals);
-  FRIEND_TEST(TestGroupNode, FieldIndex);
-  FRIEND_TEST(TestGroupNode, FieldIndexDuplicateName);
-};
-
-// ----------------------------------------------------------------------
-// Convenience primitive type factory functions
-
-#define PRIMITIVE_FACTORY(FuncName, TYPE)                                              \
-  static inline NodePtr FuncName(const std::string& name,                              \
-                                 Repetition::type repetition = Repetition::OPTIONAL) { \
-    return PrimitiveNode::Make(name, repetition, Type::TYPE);                          \
-  }
-
-PRIMITIVE_FACTORY(Boolean, BOOLEAN);
-PRIMITIVE_FACTORY(Int32, INT32);
-PRIMITIVE_FACTORY(Int64, INT64);
-PRIMITIVE_FACTORY(Int96, INT96);
-PRIMITIVE_FACTORY(Float, FLOAT);
-PRIMITIVE_FACTORY(Double, DOUBLE);
-PRIMITIVE_FACTORY(ByteArray, BYTE_ARRAY);
-
-void PARQUET_EXPORT PrintSchema(const schema::Node* schema, std::ostream& stream,
-                                int indent_width = 2);
-
-}  // namespace schema
-
-// The ColumnDescriptor encapsulates information necessary to interpret
-// primitive column data in the context of a particular schema. We have to
-// examine the node structure of a column's path to the root in the schema tree
-// to be able to reassemble the nested structure from the repetition and
-// definition levels.
-class PARQUET_EXPORT ColumnDescriptor {
- public:
-  ColumnDescriptor(const schema::NodePtr& node, int16_t max_definition_level,
-                   int16_t max_repetition_level,
-                   const SchemaDescriptor* schema_descr = nullptr);
-
-  bool Equals(const ColumnDescriptor& other) const;
-
-  int16_t max_definition_level() const { return max_definition_level_; }
-
-  int16_t max_repetition_level() const { return max_repetition_level_; }
-
-  Type::type physical_type() const { return primitive_node_->physical_type(); }
-
-  LogicalType::type logical_type() const { return primitive_node_->logical_type(); }
-
-  ColumnOrder column_order() const { return primitive_node_->column_order(); }
-
-  SortOrder::type sort_order() const {
-    return GetSortOrder(logical_type(), physical_type());
-  }
-
-  const std::string& name() const { return primitive_node_->name(); }
-
-  const std::shared_ptr<schema::ColumnPath> path() const;
-
-  const schema::NodePtr& schema_node() const { return node_; }
-
-  int type_length() const;
-
-  int type_precision() const;
-
-  int type_scale() const;
-
- private:
-  schema::NodePtr node_;
-  const schema::PrimitiveNode* primitive_node_;
-
-  int16_t max_definition_level_;
-  int16_t max_repetition_level_;
-};
-
-// Container for the converted Parquet schema with a computed information from
-// the schema analysis needed for file reading
-//
-// * Column index to Node
-// * Max repetition / definition levels for each primitive node
-//
-// The ColumnDescriptor objects produced by this class can be used to assist in
-// the reconstruction of fully materialized data structures from the
-// repetition-definition level encoding of nested data
-//
-// TODO(wesm): this object can be recomputed from a Schema
-class PARQUET_EXPORT SchemaDescriptor {
- public:
-  SchemaDescriptor() {}
-  ~SchemaDescriptor() {}
-
-  // Analyze the schema
-  void Init(std::unique_ptr<schema::Node> schema);
-  void Init(const schema::NodePtr& schema);
-
-  const ColumnDescriptor* Column(int i) const;
-
-  // Get the index of a column by its dotstring path, or negative value if not found.
-  // If several columns share the same dotstring path, it is unspecified which one
-  // is returned.
-  int ColumnIndex(const std::string& node_path) const;
-  // Get the index of a column by its node, or negative value if not found.
-  int ColumnIndex(const schema::Node& node) const;
-
-  bool Equals(const SchemaDescriptor& other) const;
-
-  // The number of physical columns appearing in the file
-  int num_columns() const { return static_cast<int>(leaves_.size()); }
-
-  const schema::NodePtr& schema_root() const { return schema_; }
-
-  const schema::GroupNode* group_node() const { return group_node_; }
-
-  // Returns the root (child of the schema root) node of the leaf(column) node
-  const schema::Node* GetColumnRoot(int i) const;
-
-  const std::string& name() const { return group_node_->name(); }
-
-  std::string ToString() const;
-
-  void updateColumnOrders(const std::vector<ColumnOrder>& column_orders);
-
- private:
-  friend class ColumnDescriptor;
-
-  // Root Node
-  schema::NodePtr schema_;
-  // Root Node
-  const schema::GroupNode* group_node_;
-
-  void BuildTree(const schema::NodePtr& node, int16_t max_def_level,
-                 int16_t max_rep_level, const schema::NodePtr& base);
-
-  // Result of leaf node / tree analysis
-  std::vector<ColumnDescriptor> leaves_;
-
-  // Mapping between leaf nodes and root group of leaf (first node
-  // below the schema's root group)
-  //
-  // For example, the leaf `a.b.c.d` would have a link back to `a`
-  //
-  // -- a  <------
-  // -- -- b     |
-  // -- -- -- c  |
-  // -- -- -- -- d
-  std::unordered_map<int, const schema::NodePtr> leaf_to_base_;
-
-  // Mapping between ColumnPath DotString to the leaf index
-  std::unordered_multimap<std::string, int> leaf_to_idx_;
-};
-
-}  // namespace parquet
-
-#endif  // PARQUET_SCHEMA_TYPES_H
diff --git a/src/parquet/statistics-test.cc b/src/parquet/statistics-test.cc
deleted file mode 100644
index d2ecede..0000000
--- a/src/parquet/statistics-test.cc
+++ /dev/null
@@ -1,782 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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.
-
-#include <gtest/gtest.h>
-
-#include <algorithm>
-#include <array>
-#include <cstdint>
-#include <cstring>
-#include <memory>
-#include <vector>
-
-#include "parquet/column_reader.h"
-#include "parquet/column_writer.h"
-#include "parquet/file_reader.h"
-#include "parquet/file_writer.h"
-#include "parquet/schema.h"
-#include "parquet/statistics.h"
-#include "parquet/test-specialization.h"
-#include "parquet/test-util.h"
-#include "parquet/thrift.h"
-#include "parquet/types.h"
-#include "parquet/util/memory.h"
-
-using arrow::default_memory_pool;
-using arrow::MemoryPool;
-
-namespace parquet {
-
-using schema::GroupNode;
-using schema::NodePtr;
-using schema::PrimitiveNode;
-
-namespace test {
-
-template <typename TestType>
-class TestRowGroupStatistics : public PrimitiveTypedTest<TestType> {
- public:
-  using T = typename TestType::c_type;
-  using TypedStats = TypedRowGroupStatistics<TestType>;
-
-  std::vector<T> GetDeepCopy(
-      const std::vector<T>&);  // allocates new memory for FLBA/ByteArray
-
-  T* GetValuesPointer(std::vector<T>&);
-  void DeepFree(std::vector<T>&);
-
-  void TestMinMaxEncode() {
-    this->GenerateData(1000);
-
-    TypedStats statistics1(this->schema_.Column(0));
-    statistics1.Update(this->values_ptr_, this->values_.size(), 0);
-    std::string encoded_min = statistics1.EncodeMin();
-    std::string encoded_max = statistics1.EncodeMax();
-
-    TypedStats statistics2(this->schema_.Column(0), encoded_min, encoded_max,
-                           this->values_.size(), 0, 0, true);
-
-    TypedStats statistics3(this->schema_.Column(0));
-    std::vector<uint8_t> valid_bits(
-        BitUtil::BytesForBits(static_cast<uint32_t>(this->values_.size())) + 1, 255);
-    statistics3.UpdateSpaced(this->values_ptr_, valid_bits.data(), 0,
-                             this->values_.size(), 0);
-    std::string encoded_min_spaced = statistics3.EncodeMin();
-    std::string encoded_max_spaced = statistics3.EncodeMax();
-
-    ASSERT_EQ(encoded_min, statistics2.EncodeMin());
-    ASSERT_EQ(encoded_max, statistics2.EncodeMax());
-    ASSERT_EQ(statistics1.min(), statistics2.min());
-    ASSERT_EQ(statistics1.max(), statistics2.max());
-    ASSERT_EQ(encoded_min_spaced, statistics2.EncodeMin());
-    ASSERT_EQ(encoded_max_spaced, statistics2.EncodeMax());
-    ASSERT_EQ(statistics3.min(), statistics2.min());
-    ASSERT_EQ(statistics3.max(), statistics2.max());
-  }
-
-  void TestReset() {
-    this->GenerateData(1000);
-
-    TypedStats statistics(this->schema_.Column(0));
-    statistics.Update(this->values_ptr_, this->values_.size(), 0);
-    ASSERT_EQ(this->values_.size(), statistics.num_values());
-
-    statistics.Reset();
-    ASSERT_EQ(0, statistics.null_count());
-    ASSERT_EQ(0, statistics.num_values());
-    ASSERT_EQ("", statistics.EncodeMin());
-    ASSERT_EQ("", statistics.EncodeMax());
-  }
-
-  void TestMerge() {
-    int num_null[2];
-    random_numbers(2, 42, 0, 100, num_null);
-
-    TypedStats statistics1(this->schema_.Column(0));
-    this->GenerateData(1000);
-    statistics1.Update(this->values_ptr_, this->values_.size() - num_null[0],
-                       num_null[0]);
-
-    TypedStats statistics2(this->schema_.Column(0));
-    this->GenerateData(1000);
-    statistics2.Update(this->values_ptr_, this->values_.size() - num_null[1],
-                       num_null[1]);
-
-    TypedStats total(this->schema_.Column(0));
-    total.Merge(statistics1);
-    total.Merge(statistics2);
-
-    ASSERT_EQ(num_null[0] + num_null[1], total.null_count());
-    ASSERT_EQ(this->values_.size() * 2 - num_null[0] - num_null[1], total.num_values());
-    ASSERT_EQ(total.min(), std::min(statistics1.min(), statistics2.min()));
-    ASSERT_EQ(total.max(), std::max(statistics1.max(), statistics2.max()));
-  }
-
-  void TestFullRoundtrip(int64_t num_values, int64_t null_count) {
-    this->GenerateData(num_values);
-
-    // compute statistics for the whole batch
-    TypedStats expected_stats(this->schema_.Column(0));
-    expected_stats.Update(this->values_ptr_, num_values - null_count, null_count);
-
-    auto sink = std::make_shared<InMemoryOutputStream>();
-    auto gnode = std::static_pointer_cast<GroupNode>(this->node_);
-    std::shared_ptr<WriterProperties> writer_properties =
-        WriterProperties::Builder().enable_statistics("column")->build();
-    auto file_writer = ParquetFileWriter::Open(sink, gnode, writer_properties);
-    auto row_group_writer = file_writer->AppendRowGroup();
-    auto column_writer =
-        static_cast<TypedColumnWriter<TestType>*>(row_group_writer->NextColumn());
-
-    // simulate the case when data comes from multiple buffers,
-    // in which case special care is necessary for FLBA/ByteArray types
-    for (int i = 0; i < 2; i++) {
-      int64_t batch_num_values = i ? num_values - num_values / 2 : num_values / 2;
-      int64_t batch_null_count = i ? null_count : 0;
-      DCHECK(null_count <= num_values);  // avoid too much headache
-      std::vector<int16_t> definition_levels(batch_null_count, 0);
-      definition_levels.insert(definition_levels.end(),
-                               batch_num_values - batch_null_count, 1);
-      auto beg = this->values_.begin() + i * num_values / 2;
-      auto end = beg + batch_num_values;
-      std::vector<T> batch = GetDeepCopy(std::vector<T>(beg, end));
-      T* batch_values_ptr = GetValuesPointer(batch);
-      column_writer->WriteBatch(batch_num_values, definition_levels.data(), nullptr,
-                                batch_values_ptr);
-      DeepFree(batch);
-    }
-    column_writer->Close();
-    row_group_writer->Close();
-    file_writer->Close();
-
-    auto buffer = sink->GetBuffer();
-    auto source = std::make_shared<::arrow::io::BufferReader>(buffer);
-    auto file_reader = ParquetFileReader::Open(source);
-    auto rg_reader = file_reader->RowGroup(0);
-    auto column_chunk = rg_reader->metadata()->ColumnChunk(0);
-    if (!column_chunk->is_stats_set()) return;
-    std::shared_ptr<RowGroupStatistics> stats = column_chunk->statistics();
-    // check values after serialization + deserialization
-    ASSERT_EQ(null_count, stats->null_count());
-    ASSERT_EQ(num_values - null_count, stats->num_values());
-    ASSERT_EQ(expected_stats.EncodeMin(), stats->EncodeMin());
-    ASSERT_EQ(expected_stats.EncodeMax(), stats->EncodeMax());
-  }
-};
-
-template <typename TestType>
-typename TestType::c_type* TestRowGroupStatistics<TestType>::GetValuesPointer(
-    std::vector<typename TestType::c_type>& values) {
-  return values.data();
-}
-
-template <>
-bool* TestRowGroupStatistics<BooleanType>::GetValuesPointer(std::vector<bool>& values) {
-  static std::vector<uint8_t> bool_buffer;
-  bool_buffer.clear();
-  bool_buffer.resize(values.size());
-  std::copy(values.begin(), values.end(), bool_buffer.begin());
-  return reinterpret_cast<bool*>(bool_buffer.data());
-}
-
-template <typename TestType>
-typename std::vector<typename TestType::c_type>
-TestRowGroupStatistics<TestType>::GetDeepCopy(
-    const std::vector<typename TestType::c_type>& values) {
-  return values;
-}
-
-template <>
-std::vector<FLBA> TestRowGroupStatistics<FLBAType>::GetDeepCopy(
-    const std::vector<FLBA>& values) {
-  std::vector<FLBA> copy;
-  MemoryPool* pool = ::arrow::default_memory_pool();
-  for (const FLBA& flba : values) {
-    uint8_t* ptr;
-    PARQUET_THROW_NOT_OK(pool->Allocate(FLBA_LENGTH, &ptr));
-    memcpy(ptr, flba.ptr, FLBA_LENGTH);
-    copy.emplace_back(ptr);
-  }
-  return copy;
-}
-
-template <>
-std::vector<ByteArray> TestRowGroupStatistics<ByteArrayType>::GetDeepCopy(
-    const std::vector<ByteArray>& values) {
-  std::vector<ByteArray> copy;
-  MemoryPool* pool = default_memory_pool();
-  for (const ByteArray& ba : values) {
-    uint8_t* ptr;
-    PARQUET_THROW_NOT_OK(pool->Allocate(ba.len, &ptr));
-    memcpy(ptr, ba.ptr, ba.len);
-    copy.emplace_back(ba.len, ptr);
-  }
-  return copy;
-}
-
-template <typename TestType>
-void TestRowGroupStatistics<TestType>::DeepFree(
-    std::vector<typename TestType::c_type>& values) {}
-
-template <>
-void TestRowGroupStatistics<FLBAType>::DeepFree(std::vector<FLBA>& values) {
-  MemoryPool* pool = default_memory_pool();
-  for (FLBA& flba : values) {
-    auto ptr = const_cast<uint8_t*>(flba.ptr);
-    memset(ptr, 0, FLBA_LENGTH);
-    pool->Free(ptr, FLBA_LENGTH);
-  }
-}
-
-template <>
-void TestRowGroupStatistics<ByteArrayType>::DeepFree(std::vector<ByteArray>& values) {
-  MemoryPool* pool = default_memory_pool();
-  for (ByteArray& ba : values) {
-    auto ptr = const_cast<uint8_t*>(ba.ptr);
-    memset(ptr, 0, ba.len);
-    pool->Free(ptr, ba.len);
-  }
-}
-
-template <>
-void TestRowGroupStatistics<ByteArrayType>::TestMinMaxEncode() {
-  this->GenerateData(1000);
-  // Test that we encode min max strings correctly
-  TypedRowGroupStatistics<ByteArrayType> statistics1(this->schema_.Column(0));
-  statistics1.Update(this->values_ptr_, this->values_.size(), 0);
-  std::string encoded_min = statistics1.EncodeMin();
-  std::string encoded_max = statistics1.EncodeMax();
-
-  // encoded is same as unencoded
-  ASSERT_EQ(encoded_min,
-            std::string((const char*)statistics1.min().ptr, statistics1.min().len));
-  ASSERT_EQ(encoded_max,
-            std::string((const char*)statistics1.max().ptr, statistics1.max().len));
-
-  TypedRowGroupStatistics<ByteArrayType> statistics2(this->schema_.Column(0), encoded_min,
-                                                     encoded_max, this->values_.size(), 0,
-                                                     0, true);
-
-  ASSERT_EQ(encoded_min, statistics2.EncodeMin());
-  ASSERT_EQ(encoded_max, statistics2.EncodeMax());
-  ASSERT_EQ(statistics1.min(), statistics2.min());
-  ASSERT_EQ(statistics1.max(), statistics2.max());
-}
-
-using TestTypes = ::testing::Types<Int32Type, Int64Type, FloatType, DoubleType,
-                                   ByteArrayType, FLBAType, BooleanType>;
-
-TYPED_TEST_CASE(TestRowGroupStatistics, TestTypes);
-
-TYPED_TEST(TestRowGroupStatistics, MinMaxEncode) {
-  this->SetUpSchema(Repetition::REQUIRED);
-  ASSERT_NO_FATAL_FAILURE(this->TestMinMaxEncode());
-}
-
-TYPED_TEST(TestRowGroupStatistics, Reset) {
-  this->SetUpSchema(Repetition::OPTIONAL);
-  ASSERT_NO_FATAL_FAILURE(this->TestReset());
-}
-
-TYPED_TEST(TestRowGroupStatistics, FullRoundtrip) {
-  this->SetUpSchema(Repetition::OPTIONAL);
-  ASSERT_NO_FATAL_FAILURE(this->TestFullRoundtrip(100, 31));
-  ASSERT_NO_FATAL_FAILURE(this->TestFullRoundtrip(1000, 415));
-  ASSERT_NO_FATAL_FAILURE(this->TestFullRoundtrip(10000, 926));
-}
-
-template <typename TestType>
-class TestNumericRowGroupStatistics : public TestRowGroupStatistics<TestType> {};
-
-using NumericTypes = ::testing::Types<Int32Type, Int64Type, FloatType, DoubleType>;
-
-TYPED_TEST_CASE(TestNumericRowGroupStatistics, NumericTypes);
-
-TYPED_TEST(TestNumericRowGroupStatistics, Merge) {
-  this->SetUpSchema(Repetition::OPTIONAL);
-  ASSERT_NO_FATAL_FAILURE(this->TestMerge());
-}
-
-// Statistics are restricted for few types in older parquet version
-TEST(CorruptStatistics, Basics) {
-  ApplicationVersion version("parquet-mr version 1.8.0");
-  SchemaDescriptor schema;
-  schema::NodePtr node;
-  std::vector<schema::NodePtr> fields;
-  // Test Physical Types
-  fields.push_back(schema::PrimitiveNode::Make("col1", Repetition::OPTIONAL, Type::INT32,
-                                               LogicalType::NONE));
-  fields.push_back(schema::PrimitiveNode::Make("col2", Repetition::OPTIONAL,
-                                               Type::BYTE_ARRAY, LogicalType::NONE));
-  // Test Logical Types
-  fields.push_back(schema::PrimitiveNode::Make("col3", Repetition::OPTIONAL, Type::INT32,
-                                               LogicalType::DATE));
-  fields.push_back(schema::PrimitiveNode::Make("col4", Repetition::OPTIONAL, Type::INT32,
-                                               LogicalType::UINT_32));
-  fields.push_back(schema::PrimitiveNode::Make("col5", Repetition::OPTIONAL,
-                                               Type::FIXED_LEN_BYTE_ARRAY,
-                                               LogicalType::INTERVAL, 12));
-  fields.push_back(schema::PrimitiveNode::Make("col6", Repetition::OPTIONAL,
-                                               Type::BYTE_ARRAY, LogicalType::UTF8));
-  node = schema::GroupNode::Make("schema", Repetition::REQUIRED, fields);
-  schema.Init(node);
-
-  format::ColumnChunk col_chunk;
-  col_chunk.meta_data.__isset.statistics = true;
-  auto column_chunk1 = ColumnChunkMetaData::Make(
-      reinterpret_cast<const uint8_t*>(&col_chunk), schema.Column(0), &version);
-  ASSERT_TRUE(column_chunk1->is_stats_set());
-  auto column_chunk2 = ColumnChunkMetaData::Make(
-      reinterpret_cast<const uint8_t*>(&col_chunk), schema.Column(1), &version);
-  ASSERT_FALSE(column_chunk2->is_stats_set());
-  auto column_chunk3 = ColumnChunkMetaData::Make(
-      reinterpret_cast<const uint8_t*>(&col_chunk), schema.Column(2), &version);
-  ASSERT_TRUE(column_chunk3->is_stats_set());
-  auto column_chunk4 = ColumnChunkMetaData::Make(
-      reinterpret_cast<const uint8_t*>(&col_chunk), schema.Column(3), &version);
-  ASSERT_FALSE(column_chunk4->is_stats_set());
-  auto column_chunk5 = ColumnChunkMetaData::Make(
-      reinterpret_cast<const uint8_t*>(&col_chunk), schema.Column(4), &version);
-  ASSERT_FALSE(column_chunk5->is_stats_set());
-  auto column_chunk6 = ColumnChunkMetaData::Make(
-      reinterpret_cast<const uint8_t*>(&col_chunk), schema.Column(5), &version);
-  ASSERT_FALSE(column_chunk6->is_stats_set());
-}
-
-// Statistics for all types have no restrictions in newer parquet version
-TEST(CorrectStatistics, Basics) {
-  ApplicationVersion version("parquet-cpp version 1.3.0");
-  SchemaDescriptor schema;
-  schema::NodePtr node;
-  std::vector<schema::NodePtr> fields;
-  // Test Physical Types
-  fields.push_back(schema::PrimitiveNode::Make("col1", Repetition::OPTIONAL, Type::INT32,
-                                               LogicalType::NONE));
-  fields.push_back(schema::PrimitiveNode::Make("col2", Repetition::OPTIONAL,
-                                               Type::BYTE_ARRAY, LogicalType::NONE));
-  // Test Logical Types
-  fields.push_back(schema::PrimitiveNode::Make("col3", Repetition::OPTIONAL, Type::INT32,
-                                               LogicalType::DATE));
-  fields.push_back(schema::PrimitiveNode::Make("col4", Repetition::OPTIONAL, Type::INT32,
-                                               LogicalType::UINT_32));
-  fields.push_back(schema::PrimitiveNode::Make("col5", Repetition::OPTIONAL,
-                                               Type::FIXED_LEN_BYTE_ARRAY,
-                                               LogicalType::INTERVAL, 12));
-  fields.push_back(schema::PrimitiveNode::Make("col6", Repetition::OPTIONAL,
-                                               Type::BYTE_ARRAY, LogicalType::UTF8));
-  node = schema::GroupNode::Make("schema", Repetition::REQUIRED, fields);
-  schema.Init(node);
-
-  format::ColumnChunk col_chunk;
-  col_chunk.meta_data.__isset.statistics = true;
-  auto column_chunk1 = ColumnChunkMetaData::Make(
-      reinterpret_cast<const uint8_t*>(&col_chunk), schema.Column(0), &version);
-  ASSERT_TRUE(column_chunk1->is_stats_set());
-  auto column_chunk2 = ColumnChunkMetaData::Make(
-      reinterpret_cast<const uint8_t*>(&col_chunk), schema.Column(1), &version);
-  ASSERT_TRUE(column_chunk2->is_stats_set());
-  auto column_chunk3 = ColumnChunkMetaData::Make(
-      reinterpret_cast<const uint8_t*>(&col_chunk), schema.Column(2), &version);
-  ASSERT_TRUE(column_chunk3->is_stats_set());
-  auto column_chunk4 = ColumnChunkMetaData::Make(
-      reinterpret_cast<const uint8_t*>(&col_chunk), schema.Column(3), &version);
-  ASSERT_TRUE(column_chunk4->is_stats_set());
-  auto column_chunk5 = ColumnChunkMetaData::Make(
-      reinterpret_cast<const uint8_t*>(&col_chunk), schema.Column(4), &version);
-  ASSERT_FALSE(column_chunk5->is_stats_set());
-  auto column_chunk6 = ColumnChunkMetaData::Make(
-      reinterpret_cast<const uint8_t*>(&col_chunk), schema.Column(5), &version);
-  ASSERT_TRUE(column_chunk6->is_stats_set());
-}
-
-// Test SortOrder class
-static const int NUM_VALUES = 10;
-
-template <typename TestType>
-class TestStatistics : public ::testing::Test {
- public:
-  typedef typename TestType::c_type T;
-
-  void AddNodes(std::string name) {
-    fields_.push_back(schema::PrimitiveNode::Make(name, Repetition::REQUIRED,
-                                                  TestType::type_num, LogicalType::NONE));
-  }
-
-  void SetUpSchema() {
-    stats_.resize(fields_.size());
-    values_.resize(NUM_VALUES);
-    schema_ = std::static_pointer_cast<GroupNode>(
-        GroupNode::Make("Schema", Repetition::REQUIRED, fields_));
-
-    parquet_sink_ = std::make_shared<InMemoryOutputStream>();
-  }
-
-  void SetValues();
-
-  void WriteParquet() {
-    // Add writer properties
-    parquet::WriterProperties::Builder builder;
-    builder.compression(parquet::Compression::SNAPPY);
-    builder.created_by("parquet-cpp version 1.3.0");
-    std::shared_ptr<parquet::WriterProperties> props = builder.build();
-
-    // Create a ParquetFileWriter instance
-    auto file_writer = parquet::ParquetFileWriter::Open(parquet_sink_, schema_, props);
-
-    // Append a RowGroup with a specific number of rows.
-    auto rg_writer = file_writer->AppendRowGroup();
-
-    this->SetValues();
-
-    // Insert Values
-    for (int i = 0; i < static_cast<int>(fields_.size()); i++) {
-      auto column_writer =
-          static_cast<parquet::TypedColumnWriter<TestType>*>(rg_writer->NextColumn());
-      column_writer->WriteBatch(NUM_VALUES, nullptr, nullptr, values_.data());
-    }
-  }
-
-  void VerifyParquetStats() {
-    auto pbuffer = parquet_sink_->GetBuffer();
-
-    // Create a ParquetReader instance
-    std::unique_ptr<parquet::ParquetFileReader> parquet_reader =
-        parquet::ParquetFileReader::Open(
-            std::make_shared<arrow::io::BufferReader>(pbuffer));
-
-    // Get the File MetaData
-    std::shared_ptr<parquet::FileMetaData> file_metadata = parquet_reader->metadata();
-    std::shared_ptr<parquet::RowGroupMetaData> rg_metadata = file_metadata->RowGroup(0);
-    for (int i = 0; i < static_cast<int>(fields_.size()); i++) {
-      std::shared_ptr<parquet::ColumnChunkMetaData> cc_metadata =
-          rg_metadata->ColumnChunk(i);
-      ASSERT_EQ(stats_[i].min(), cc_metadata->statistics()->EncodeMin());
-      ASSERT_EQ(stats_[i].max(), cc_metadata->statistics()->EncodeMax());
-    }
-  }
-
- protected:
-  std::vector<T> values_;
-  std::vector<uint8_t> values_buf_;
-  std::vector<schema::NodePtr> fields_;
-  std::shared_ptr<schema::GroupNode> schema_;
-  std::shared_ptr<InMemoryOutputStream> parquet_sink_;
-  std::vector<EncodedStatistics> stats_;
-};
-
-using CompareTestTypes = ::testing::Types<Int32Type, Int64Type, FloatType, DoubleType,
-                                          ByteArrayType, FLBAType>;
-
-// TYPE::INT32
-template <>
-void TestStatistics<Int32Type>::AddNodes(std::string name) {
-  // UINT_32 logical type to set Unsigned Statistics
-  fields_.push_back(schema::PrimitiveNode::Make(name, Repetition::REQUIRED, Type::INT32,
-                                                LogicalType::UINT_32));
-  // INT_32 logical type to set Signed Statistics
-  fields_.push_back(schema::PrimitiveNode::Make(name, Repetition::REQUIRED, Type::INT32,
-                                                LogicalType::INT_32));
-}
-
-template <>
-void TestStatistics<Int32Type>::SetValues() {
-  for (int i = 0; i < NUM_VALUES; i++) {
-    values_[i] = i - 5;  // {-5, -4, -3, -2, -1, 0, 1, 2, 3, 4};
-  }
-
-  // Write UINT32 min/max values
-  stats_[0]
-      .set_min(std::string(reinterpret_cast<const char*>(&values_[5]), sizeof(T)))
-      .set_max(std::string(reinterpret_cast<const char*>(&values_[4]), sizeof(T)));
-
-  // Write INT32 min/max values
-  stats_[1]
-      .set_min(std::string(reinterpret_cast<const char*>(&values_[0]), sizeof(T)))
-      .set_max(std::string(reinterpret_cast<const char*>(&values_[9]), sizeof(T)));
-}
-
-// TYPE::INT64
-template <>
-void TestStatistics<Int64Type>::AddNodes(std::string name) {
-  // UINT_64 logical type to set Unsigned Statistics
-  fields_.push_back(schema::PrimitiveNode::Make(name, Repetition::REQUIRED, Type::INT64,
-                                                LogicalType::UINT_64));
-  // INT_64 logical type to set Signed Statistics
-  fields_.push_back(schema::PrimitiveNode::Make(name, Repetition::REQUIRED, Type::INT64,
-                                                LogicalType::INT_64));
-}
-
-template <>
-void TestStatistics<Int64Type>::SetValues() {
-  for (int i = 0; i < NUM_VALUES; i++) {
-    values_[i] = i - 5;  // {-5, -4, -3, -2, -1, 0, 1, 2, 3, 4};
-  }
-
-  // Write UINT64 min/max values
-  stats_[0]
-      .set_min(std::string(reinterpret_cast<const char*>(&values_[5]), sizeof(T)))
-      .set_max(std::string(reinterpret_cast<const char*>(&values_[4]), sizeof(T)));
-
-  // Write INT64 min/max values
-  stats_[1]
-      .set_min(std::string(reinterpret_cast<const char*>(&values_[0]), sizeof(T)))
-      .set_max(std::string(reinterpret_cast<const char*>(&values_[9]), sizeof(T)));
-}
-
-// TYPE::FLOAT
-template <>
-void TestStatistics<FloatType>::SetValues() {
-  for (int i = 0; i < NUM_VALUES; i++) {
-    values_[i] = static_cast<float>(i) -
-                 5;  // {-5.0, -4.0, -3.0, -2.0, -1.0, 0.0, 1.0, 2.0, 3.0, 4.0};
-  }
-
-  // Write Float min/max values
-  stats_[0]
-      .set_min(std::string(reinterpret_cast<const char*>(&values_[0]), sizeof(T)))
-      .set_max(std::string(reinterpret_cast<const char*>(&values_[9]), sizeof(T)));
-}
-
-// TYPE::DOUBLE
-template <>
-void TestStatistics<DoubleType>::SetValues() {
-  for (int i = 0; i < NUM_VALUES; i++) {
-    values_[i] = static_cast<float>(i) -
-                 5;  // {-5.0, -4.0, -3.0, -2.0, -1.0, 0.0, 1.0, 2.0, 3.0, 4.0};
-  }
-
-  // Write Double min/max values
-  stats_[0]
-      .set_min(std::string(reinterpret_cast<const char*>(&values_[0]), sizeof(T)))
-      .set_max(std::string(reinterpret_cast<const char*>(&values_[9]), sizeof(T)));
-}
-
-// TYPE::ByteArray
-template <>
-void TestStatistics<ByteArrayType>::AddNodes(std::string name) {
-  // UTF8 logical type to set Unsigned Statistics
-  fields_.push_back(schema::PrimitiveNode::Make(name, Repetition::REQUIRED,
-                                                Type::BYTE_ARRAY, LogicalType::UTF8));
-}
-
-template <>
-void TestStatistics<ByteArrayType>::SetValues() {
-  int max_byte_array_len = 10;
-  size_t nbytes = NUM_VALUES * max_byte_array_len;
-  values_buf_.resize(nbytes);
-  std::vector<std::string> vals = {u8"c123", u8"b123", u8"a123", u8"d123", u8"e123",
-                                   u8"f123", u8"g123", u8"h123", u8"i123", u8"ü123"};
-
-  uint8_t* base = &values_buf_.data()[0];
-  for (int i = 0; i < NUM_VALUES; i++) {
-    memcpy(base, vals[i].c_str(), vals[i].length());
-    values_[i].ptr = base;
-    values_[i].len = static_cast<uint32_t>(vals[i].length());
-    base += vals[i].length();
-  }
-
-  // Write String min/max values
-  stats_[0]
-      .set_min(
-          std::string(reinterpret_cast<const char*>(vals[2].c_str()), vals[2].length()))
-      .set_max(
-          std::string(reinterpret_cast<const char*>(vals[9].c_str()), vals[9].length()));
-}
-
-// TYPE::FLBAArray
-template <>
-void TestStatistics<FLBAType>::AddNodes(std::string name) {
-  // FLBA has only Unsigned Statistics
-  fields_.push_back(schema::PrimitiveNode::Make(name, Repetition::REQUIRED,
-                                                Type::FIXED_LEN_BYTE_ARRAY,
-                                                LogicalType::NONE, FLBA_LENGTH));
-}
-
-template <>
-void TestStatistics<FLBAType>::SetValues() {
-  size_t nbytes = NUM_VALUES * FLBA_LENGTH;
-  values_buf_.resize(nbytes);
-  char vals[NUM_VALUES][FLBA_LENGTH] = {"b12345", "a12345", "c12345", "d12345", "e12345",
-                                        "f12345", "g12345", "h12345", "z12345", "a12345"};
-
-  uint8_t* base = &values_buf_.data()[0];
-  for (int i = 0; i < NUM_VALUES; i++) {
-    memcpy(base, &vals[i][0], FLBA_LENGTH);
-    values_[i].ptr = base;
-    base += FLBA_LENGTH;
-  }
-
-  // Write FLBA min,max values
-  stats_[0]
-      .set_min(std::string(reinterpret_cast<const char*>(&vals[1][0]), FLBA_LENGTH))
-      .set_max(std::string(reinterpret_cast<const char*>(&vals[8][0]), FLBA_LENGTH));
-}
-
-TYPED_TEST_CASE(TestStatistics, CompareTestTypes);
-
-TYPED_TEST(TestStatistics, MinMax) {
-  this->AddNodes("Column ");
-  this->SetUpSchema();
-  this->WriteParquet();
-  ASSERT_NO_FATAL_FAILURE(this->VerifyParquetStats());
-}
-
-// Ensure UNKNOWN sort order is handled properly
-using TestStatisticsFLBA = TestStatistics<FLBAType>;
-
-TEST_F(TestStatisticsFLBA, UnknownSortOrder) {
-  this->fields_.push_back(schema::PrimitiveNode::Make(
-      "Column 0", Repetition::REQUIRED, Type::FIXED_LEN_BYTE_ARRAY, LogicalType::INTERVAL,
-      FLBA_LENGTH));
-  this->SetUpSchema();
-  this->WriteParquet();
-
-  auto pbuffer = parquet_sink_->GetBuffer();
-  // Create a ParquetReader instance
-  std::unique_ptr<parquet::ParquetFileReader> parquet_reader =
-      parquet::ParquetFileReader::Open(
-          std::make_shared<arrow::io::BufferReader>(pbuffer));
-  // Get the File MetaData
-  std::shared_ptr<parquet::FileMetaData> file_metadata = parquet_reader->metadata();
-  std::shared_ptr<parquet::RowGroupMetaData> rg_metadata = file_metadata->RowGroup(0);
-  std::shared_ptr<parquet::ColumnChunkMetaData> cc_metadata = rg_metadata->ColumnChunk(0);
-
-  // stats should not be set for UNKNOWN sort order
-  ASSERT_FALSE(cc_metadata->is_stats_set());
-}
-
-// PARQUET-1225: Float NaN values may lead to incorrect filtering under certain
-// circumstances
-TEST(TestStatisticsFloatNaN, NaNValues) {
-  constexpr int NUM_VALUES = 10;
-  NodePtr node = PrimitiveNode::Make("nan_float", Repetition::OPTIONAL, Type::FLOAT);
-  ColumnDescriptor descr(node, 1, 1);
-  float values[NUM_VALUES] = {std::nanf(""), -4.0f, -3.0f, -2.0f, -1.0f,
-                              std::nanf(""), 1.0f,  2.0f,  3.0f,  std::nanf("")};
-  float nan_values[NUM_VALUES];
-  for (int i = 0; i < NUM_VALUES; i++) {
-    nan_values[i] = std::nanf("");
-  }
-
-  // Test values
-  TypedRowGroupStatistics<FloatType> nan_stats(&descr);
-  nan_stats.Update(&values[0], NUM_VALUES, 0);
-  float min = nan_stats.min();
-  float max = nan_stats.max();
-  ASSERT_EQ(min, -4.0f);
-  ASSERT_EQ(max, 3.0f);
-
-  // Test all NaNs
-  TypedRowGroupStatistics<FloatType> all_nan_stats(&descr);
-  all_nan_stats.Update(&nan_values[0], NUM_VALUES, 0);
-  min = all_nan_stats.min();
-  max = all_nan_stats.max();
-  ASSERT_TRUE(std::isnan(min));
-  ASSERT_TRUE(std::isnan(max));
-
-  // Test values followed by all NaNs
-  nan_stats.Update(&nan_values[0], NUM_VALUES, 0);
-  min = nan_stats.min();
-  max = nan_stats.max();
-  ASSERT_EQ(min, -4.0f);
-  ASSERT_EQ(max, 3.0f);
-
-  // Test all NaNs followed by values
-  all_nan_stats.Update(&values[0], NUM_VALUES, 0);
-  min = all_nan_stats.min();
-  max = all_nan_stats.max();
-  ASSERT_EQ(min, -4.0f);
-  ASSERT_EQ(max, 3.0f);
-
-  // Test values followed by all NaNs followed by values
-  nan_stats.Update(&values[0], NUM_VALUES, 0);
-  min = nan_stats.min();
-  max = nan_stats.max();
-  ASSERT_EQ(min, -4.0f);
-  ASSERT_EQ(max, 3.0f);
-}
-
-// PARQUET-1225: Float NaN values may lead to incorrect filtering under certain
-// circumstances
-TEST(TestStatisticsFloatNaN, NaNValuesSpaced) {
-  constexpr int NUM_VALUES = 10;
-  NodePtr node = PrimitiveNode::Make("nan_float", Repetition::OPTIONAL, Type::FLOAT);
-  ColumnDescriptor descr(node, 1, 1);
-  float values[NUM_VALUES] = {std::nanf(""), -4.0f, -3.0f, -2.0f, -1.0f,
-                              std::nanf(""), 1.0f,  2.0f,  3.0f,  std::nanf("")};
-  float nan_values[NUM_VALUES];
-  for (int i = 0; i < NUM_VALUES; i++) {
-    nan_values[i] = std::nanf("");
-  }
-  std::vector<uint8_t> valid_bits(BitUtil::BytesForBits(NUM_VALUES) + 1, 255);
-
-  // Test values
-  TypedRowGroupStatistics<FloatType> nan_stats(&descr);
-  nan_stats.UpdateSpaced(&values[0], valid_bits.data(), 0, NUM_VALUES, 0);
-  float min = nan_stats.min();
-  float max = nan_stats.max();
-  ASSERT_EQ(min, -4.0f);
-  ASSERT_EQ(max, 3.0f);
-
-  // Test all NaNs
-  TypedRowGroupStatistics<FloatType> all_nan_stats(&descr);
-  all_nan_stats.UpdateSpaced(&nan_values[0], valid_bits.data(), 0, NUM_VALUES, 0);
-  min = all_nan_stats.min();
-  max = all_nan_stats.max();
-  ASSERT_TRUE(std::isnan(min));
-  ASSERT_TRUE(std::isnan(max));
-
-  // Test values followed by all NaNs
-  nan_stats.UpdateSpaced(&nan_values[0], valid_bits.data(), 0, NUM_VALUES, 0);
-  min = nan_stats.min();
-  max = nan_stats.max();
-  ASSERT_EQ(min, -4.0f);
-  ASSERT_EQ(max, 3.0f);
-
-  // Test all NaNs followed by values
-  all_nan_stats.UpdateSpaced(&values[0], valid_bits.data(), 0, NUM_VALUES, 0);
-  min = all_nan_stats.min();
-  max = all_nan_stats.max();
-  ASSERT_EQ(min, -4.0f);
-  ASSERT_EQ(max, 3.0f);
-
-  // Test values followed by all NaNs followed by values
-  nan_stats.UpdateSpaced(&values[0], valid_bits.data(), 0, NUM_VALUES, 0);
-  min = nan_stats.min();
-  max = nan_stats.max();
-  ASSERT_EQ(min, -4.0f);
-  ASSERT_EQ(max, 3.0f);
-}
-
-// NaN double values may lead to incorrect filtering under certain circumstances
-TEST(TestStatisticsDoubleNaN, NaNValues) {
-  constexpr int NUM_VALUES = 10;
-  NodePtr node = PrimitiveNode::Make("nan_double", Repetition::OPTIONAL, Type::DOUBLE);
-  ColumnDescriptor descr(node, 1, 1);
-  TypedRowGroupStatistics<DoubleType> nan_stats(&descr);
-  double values[NUM_VALUES] = {std::nan(""), std::nan(""), -3.0, -2.0, -1.0,
-                               0.0,          1.0,          2.0,  3.0,  4.0};
-  double* values_ptr = &values[0];
-  nan_stats.Update(values_ptr, NUM_VALUES, 0);
-  double min = nan_stats.min();
-  double max = nan_stats.max();
-
-  ASSERT_EQ(min, -3.0);
-  ASSERT_EQ(max, 4.0);
-}
-}  // namespace test
-}  // namespace parquet
diff --git a/src/parquet/statistics.cc b/src/parquet/statistics.cc
deleted file mode 100644
index ea7f783..0000000
--- a/src/parquet/statistics.cc
+++ /dev/null
@@ -1,334 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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.
-
-#include <algorithm>
-#include <cstring>
-#include <type_traits>
-
-#include "parquet/encoding-internal.h"
-#include "parquet/exception.h"
-#include "parquet/statistics.h"
-#include "parquet/util/memory.h"
-
-using arrow::default_memory_pool;
-using arrow::MemoryPool;
-
-namespace parquet {
-
-template <typename DType>
-TypedRowGroupStatistics<DType>::TypedRowGroupStatistics(const ColumnDescriptor* schema,
-                                                        MemoryPool* pool)
-    : pool_(pool),
-      min_buffer_(AllocateBuffer(pool_, 0)),
-      max_buffer_(AllocateBuffer(pool_, 0)) {
-  SetDescr(schema);
-  Reset();
-}
-
-template <typename DType>
-TypedRowGroupStatistics<DType>::TypedRowGroupStatistics(const typename DType::c_type& min,
-                                                        const typename DType::c_type& max,
-                                                        int64_t num_values,
-                                                        int64_t null_count,
-                                                        int64_t distinct_count)
-    : pool_(default_memory_pool()),
-      min_buffer_(AllocateBuffer(pool_, 0)),
-      max_buffer_(AllocateBuffer(pool_, 0)) {
-  IncrementNumValues(num_values);
-  IncrementNullCount(null_count);
-  IncrementDistinctCount(distinct_count);
-
-  Copy(min, &min_, min_buffer_.get());
-  Copy(max, &max_, max_buffer_.get());
-  has_min_max_ = true;
-}
-
-template <typename DType>
-TypedRowGroupStatistics<DType>::TypedRowGroupStatistics(
-    const ColumnDescriptor* schema, const std::string& encoded_min,
-    const std::string& encoded_max, int64_t num_values, int64_t null_count,
-    int64_t distinct_count, bool has_min_max, MemoryPool* pool)
-    : pool_(pool),
-      min_buffer_(AllocateBuffer(pool_, 0)),
-      max_buffer_(AllocateBuffer(pool_, 0)) {
-  IncrementNumValues(num_values);
-  IncrementNullCount(null_count);
-  IncrementDistinctCount(distinct_count);
-
-  SetDescr(schema);
-
-  if (!encoded_min.empty()) {
-    PlainDecode(encoded_min, &min_);
-  }
-  if (!encoded_max.empty()) {
-    PlainDecode(encoded_max, &max_);
-  }
-  has_min_max_ = has_min_max;
-}
-
-template <typename DType>
-bool TypedRowGroupStatistics<DType>::HasMinMax() const {
-  return has_min_max_;
-}
-
-template <typename DType>
-void TypedRowGroupStatistics<DType>::SetComparator() {
-  comparator_ =
-      std::static_pointer_cast<CompareDefault<DType> >(Comparator::Make(descr_));
-}
-
-template <typename DType>
-void TypedRowGroupStatistics<DType>::Reset() {
-  ResetCounts();
-  has_min_max_ = false;
-}
-
-template <typename DType>
-inline void TypedRowGroupStatistics<DType>::SetMinMax(const T& min, const T& max) {
-  if (!has_min_max_) {
-    has_min_max_ = true;
-    Copy(min, &min_, min_buffer_.get());
-    Copy(max, &max_, max_buffer_.get());
-  } else {
-    Copy(std::min(min_, min, std::ref(*(this->comparator_))), &min_, min_buffer_.get());
-    Copy(std::max(max_, max, std::ref(*(this->comparator_))), &max_, max_buffer_.get());
-  }
-}
-
-template <typename T, typename Enable = void>
-struct StatsHelper {
-  inline int64_t GetValueBeginOffset(const T* values, int64_t count) { return 0; }
-
-  inline int64_t GetValueEndOffset(const T* values, int64_t count) { return count; }
-
-  inline bool IsNaN(const T value) { return false; }
-};
-
-template <typename T>
-struct StatsHelper<T, typename std::enable_if<std::is_floating_point<T>::value>::type> {
-  inline int64_t GetValueBeginOffset(const T* values, int64_t count) {
-    // Skip NaNs
-    for (int64_t i = 0; i < count; i++) {
-      if (!std::isnan(values[i])) {
-        return i;
-      }
-    }
-    return count;
-  }
-
-  inline int64_t GetValueEndOffset(const T* values, int64_t count) {
-    // Skip NaNs
-    for (int64_t i = (count - 1); i >= 0; i--) {
-      if (!std::isnan(values[i])) {
-        return (i + 1);
-      }
-    }
-    return 0;
-  }
-
-  inline bool IsNaN(const T value) { return std::isnan(value); }
-};
-
-template <typename T>
-void SetNaN(T* value) {
-  // no-op
-}
-
-template <>
-void SetNaN<float>(float* value) {
-  *value = std::nanf("");
-}
-
-template <>
-void SetNaN<double>(double* value) {
-  *value = std::nan("");
-}
-
-template <typename DType>
-void TypedRowGroupStatistics<DType>::Update(const T* values, int64_t num_not_null,
-                                            int64_t num_null) {
-  DCHECK(num_not_null >= 0);
-  DCHECK(num_null >= 0);
-
-  IncrementNullCount(num_null);
-  IncrementNumValues(num_not_null);
-  // TODO: support distinct count?
-  if (num_not_null == 0) return;
-
-  // PARQUET-1225: Handle NaNs
-  // The problem arises only if the starting/ending value(s)
-  // of the values-buffer contain NaN
-  StatsHelper<T> helper;
-  int64_t begin_offset = helper.GetValueBeginOffset(values, num_not_null);
-  int64_t end_offset = helper.GetValueEndOffset(values, num_not_null);
-
-  // All values are NaN
-  if (end_offset < begin_offset) {
-    // Set min/max to NaNs in this case.
-    // Don't set has_min_max flag since
-    // these values must be over-written by valid stats later
-    if (!has_min_max_) {
-      SetNaN(&min_);
-      SetNaN(&max_);
-    }
-    return;
-  }
-
-  auto batch_minmax = std::minmax_element(values + begin_offset, values + end_offset,
-                                          std::ref(*(this->comparator_)));
-
-  SetMinMax(*batch_minmax.first, *batch_minmax.second);
-}
-
-template <typename DType>
-void TypedRowGroupStatistics<DType>::UpdateSpaced(const T* values,
-                                                  const uint8_t* valid_bits,
-                                                  int64_t valid_bits_offset,
-                                                  int64_t num_not_null,
-                                                  int64_t num_null) {
-  DCHECK(num_not_null >= 0);
-  DCHECK(num_null >= 0);
-
-  IncrementNullCount(num_null);
-  IncrementNumValues(num_not_null);
-  // TODO: support distinct count?
-  if (num_not_null == 0) return;
-
-  // Find first valid entry and use that for min/max
-  // As (num_not_null != 0) there must be one
-  int64_t length = num_null + num_not_null;
-  int64_t i = 0;
-  ::arrow::internal::BitmapReader valid_bits_reader(valid_bits, valid_bits_offset,
-                                                    length);
-  StatsHelper<T> helper;
-  for (; i < length; i++) {
-    // PARQUET-1225: Handle NaNs
-    if (valid_bits_reader.IsSet() && !helper.IsNaN(values[i])) {
-      break;
-    }
-    valid_bits_reader.Next();
-  }
-
-  // All are NaNs and stats are not set yet
-  if ((i == length) && helper.IsNaN(values[i - 1])) {
-    // Don't set has_min_max flag since
-    // these values must be over-written by valid stats later
-    if (!has_min_max_) {
-      SetNaN(&min_);
-      SetNaN(&max_);
-    }
-    return;
-  }
-
-  T min = values[i];
-  T max = values[i];
-  for (; i < length; i++) {
-    if (valid_bits_reader.IsSet()) {
-      if ((std::ref(*(this->comparator_)))(values[i], min)) {
-        min = values[i];
-      } else if ((std::ref(*(this->comparator_)))(max, values[i])) {
-        max = values[i];
-      }
-    }
-    valid_bits_reader.Next();
-  }
-
-  SetMinMax(min, max);
-}
-
-template <typename DType>
-const typename DType::c_type& TypedRowGroupStatistics<DType>::min() const {
-  return min_;
-}
-
-template <typename DType>
-const typename DType::c_type& TypedRowGroupStatistics<DType>::max() const {
-  return max_;
-}
-
-template <typename DType>
-void TypedRowGroupStatistics<DType>::Merge(const TypedRowGroupStatistics<DType>& other) {
-  this->MergeCounts(other);
-
-  if (!other.HasMinMax()) return;
-
-  SetMinMax(other.min_, other.max_);
-}
-
-template <typename DType>
-std::string TypedRowGroupStatistics<DType>::EncodeMin() {
-  std::string s;
-  if (HasMinMax()) this->PlainEncode(min_, &s);
-  return s;
-}
-
-template <typename DType>
-std::string TypedRowGroupStatistics<DType>::EncodeMax() {
-  std::string s;
-  if (HasMinMax()) this->PlainEncode(max_, &s);
-  return s;
-}
-
-template <typename DType>
-EncodedStatistics TypedRowGroupStatistics<DType>::Encode() {
-  EncodedStatistics s;
-  if (HasMinMax()) {
-    s.set_min(this->EncodeMin());
-    s.set_max(this->EncodeMax());
-  }
-  s.set_null_count(this->null_count());
-  return s;
-}
-
-template <typename DType>
-void TypedRowGroupStatistics<DType>::PlainEncode(const T& src, std::string* dst) {
-  PlainEncoder<DType> encoder(descr(), pool_);
-  encoder.Put(&src, 1);
-  auto buffer = encoder.FlushValues();
-  auto ptr = reinterpret_cast<const char*>(buffer->data());
-  dst->assign(ptr, buffer->size());
-}
-
-template <typename DType>
-void TypedRowGroupStatistics<DType>::PlainDecode(const std::string& src, T* dst) {
-  PlainDecoder<DType> decoder(descr());
-  decoder.SetData(1, reinterpret_cast<const uint8_t*>(src.c_str()),
-                  static_cast<int>(src.size()));
-  decoder.Decode(dst, 1);
-}
-
-template <>
-void TypedRowGroupStatistics<ByteArrayType>::PlainEncode(const T& src, std::string* dst) {
-  dst->assign(reinterpret_cast<const char*>(src.ptr), src.len);
-}
-
-template <>
-void TypedRowGroupStatistics<ByteArrayType>::PlainDecode(const std::string& src, T* dst) {
-  dst->len = static_cast<uint32_t>(src.size());
-  dst->ptr = reinterpret_cast<const uint8_t*>(src.c_str());
-}
-
-template class PARQUET_TEMPLATE_EXPORT TypedRowGroupStatistics<BooleanType>;
-template class PARQUET_TEMPLATE_EXPORT TypedRowGroupStatistics<Int32Type>;
-template class PARQUET_TEMPLATE_EXPORT TypedRowGroupStatistics<Int64Type>;
-template class PARQUET_TEMPLATE_EXPORT TypedRowGroupStatistics<Int96Type>;
-template class PARQUET_TEMPLATE_EXPORT TypedRowGroupStatistics<FloatType>;
-template class PARQUET_TEMPLATE_EXPORT TypedRowGroupStatistics<DoubleType>;
-template class PARQUET_TEMPLATE_EXPORT TypedRowGroupStatistics<ByteArrayType>;
-template class PARQUET_TEMPLATE_EXPORT TypedRowGroupStatistics<FLBAType>;
-
-}  // namespace parquet
diff --git a/src/parquet/statistics.h b/src/parquet/statistics.h
deleted file mode 100644
index d1c4d16..0000000
--- a/src/parquet/statistics.h
+++ /dev/null
@@ -1,249 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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.
-
-#ifndef PARQUET_COLUMN_STATISTICS_H
-#define PARQUET_COLUMN_STATISTICS_H
-
-#include <algorithm>
-#include <cstdint>
-#include <memory>
-#include <string>
-
-#include "parquet/schema.h"
-#include "parquet/types.h"
-#include "parquet/util/comparison.h"
-#include "parquet/util/memory.h"
-#include "parquet/util/visibility.h"
-
-namespace parquet {
-
-class PARQUET_EXPORT EncodedStatistics {
-  std::shared_ptr<std::string> max_, min_;
-
- public:
-  EncodedStatistics()
-      : max_(std::make_shared<std::string>()), min_(std::make_shared<std::string>()) {}
-
-  const std::string& max() const { return *max_; }
-  const std::string& min() const { return *min_; }
-
-  int64_t null_count = 0;
-  int64_t distinct_count = 0;
-
-  bool has_min = false;
-  bool has_max = false;
-  bool has_null_count = false;
-  bool has_distinct_count = false;
-
-  inline bool is_set() const {
-    return has_min || has_max || has_null_count || has_distinct_count;
-  }
-
-  // larger of the max_ and min_ stat values
-  inline size_t max_stat_length() { return std::max(max_->length(), min_->length()); }
-
-  inline EncodedStatistics& set_max(const std::string& value) {
-    *max_ = value;
-    has_max = true;
-    return *this;
-  }
-
-  inline EncodedStatistics& set_min(const std::string& value) {
-    *min_ = value;
-    has_min = true;
-    return *this;
-  }
-
-  inline EncodedStatistics& set_null_count(int64_t value) {
-    null_count = value;
-    has_null_count = true;
-    return *this;
-  }
-
-  inline EncodedStatistics& set_distinct_count(int64_t value) {
-    distinct_count = value;
-    has_distinct_count = true;
-    return *this;
-  }
-};
-
-template <typename DType>
-class PARQUET_EXPORT TypedRowGroupStatistics;
-
-class PARQUET_EXPORT RowGroupStatistics
-    : public std::enable_shared_from_this<RowGroupStatistics> {
- public:
-  int64_t null_count() const { return statistics_.null_count; }
-  int64_t distinct_count() const { return statistics_.distinct_count; }
-  int64_t num_values() const { return num_values_; }
-
-  virtual bool HasMinMax() const = 0;
-  virtual void Reset() = 0;
-
-  // Plain-encoded minimum value
-  virtual std::string EncodeMin() = 0;
-
-  // Plain-encoded maximum value
-  virtual std::string EncodeMax() = 0;
-
-  virtual EncodedStatistics Encode() = 0;
-
-  // Set the Corresponding Comparator
-  virtual void SetComparator() = 0;
-
-  virtual ~RowGroupStatistics() {}
-
-  Type::type physical_type() const { return descr_->physical_type(); }
-
- protected:
-  const ColumnDescriptor* descr() const { return descr_; }
-  void SetDescr(const ColumnDescriptor* schema) {
-    descr_ = schema;
-    SetComparator();
-  }
-
-  void IncrementNullCount(int64_t n) { statistics_.null_count += n; }
-
-  void IncrementNumValues(int64_t n) { num_values_ += n; }
-
-  void IncrementDistinctCount(int64_t n) { statistics_.distinct_count += n; }
-
-  void MergeCounts(const RowGroupStatistics& other) {
-    this->statistics_.null_count += other.statistics_.null_count;
-    this->statistics_.distinct_count += other.statistics_.distinct_count;
-    this->num_values_ += other.num_values_;
-  }
-
-  void ResetCounts() {
-    this->statistics_.null_count = 0;
-    this->statistics_.distinct_count = 0;
-    this->num_values_ = 0;
-  }
-
-  const ColumnDescriptor* descr_ = nullptr;
-  int64_t num_values_ = 0;
-  EncodedStatistics statistics_;
-};
-
-template <typename DType>
-class TypedRowGroupStatistics : public RowGroupStatistics {
- public:
-  using T = typename DType::c_type;
-
-  TypedRowGroupStatistics(const ColumnDescriptor* schema,
-                          ::arrow::MemoryPool* pool = ::arrow::default_memory_pool());
-
-  TypedRowGroupStatistics(const T& min, const T& max, int64_t num_values,
-                          int64_t null_count, int64_t distinct_count);
-
-  TypedRowGroupStatistics(const ColumnDescriptor* schema, const std::string& encoded_min,
-                          const std::string& encoded_max, int64_t num_values,
-                          int64_t null_count, int64_t distinct_count, bool has_min_max,
-                          ::arrow::MemoryPool* pool = ::arrow::default_memory_pool());
-
-  bool HasMinMax() const override;
-  void Reset() override;
-  void SetComparator() override;
-  void Merge(const TypedRowGroupStatistics<DType>& other);
-
-  void Update(const T* values, int64_t num_not_null, int64_t num_null);
-  void UpdateSpaced(const T* values, const uint8_t* valid_bits, int64_t valid_bits_spaced,
-                    int64_t num_not_null, int64_t num_null);
-  void SetMinMax(const T& min, const T& max);
-
-  const T& min() const;
-  const T& max() const;
-
-  std::string EncodeMin() override;
-  std::string EncodeMax() override;
-  EncodedStatistics Encode() override;
-
- private:
-  bool has_min_max_ = false;
-  T min_;
-  T max_;
-  ::arrow::MemoryPool* pool_;
-  std::shared_ptr<CompareDefault<DType> > comparator_;
-
-  void PlainEncode(const T& src, std::string* dst);
-  void PlainDecode(const std::string& src, T* dst);
-  void Copy(const T& src, T* dst, ResizableBuffer* buffer);
-
-  std::shared_ptr<ResizableBuffer> min_buffer_, max_buffer_;
-};
-
-template <typename DType>
-inline void TypedRowGroupStatistics<DType>::Copy(const T& src, T* dst, ResizableBuffer*) {
-  *dst = src;
-}
-
-template <>
-inline void TypedRowGroupStatistics<FLBAType>::Copy(const FLBA& src, FLBA* dst,
-                                                    ResizableBuffer* buffer) {
-  if (dst->ptr == src.ptr) return;
-  uint32_t len = descr_->type_length();
-  PARQUET_THROW_NOT_OK(buffer->Resize(len, false));
-  std::memcpy(buffer->mutable_data(), src.ptr, len);
-  *dst = FLBA(buffer->data());
-}
-
-template <>
-inline void TypedRowGroupStatistics<ByteArrayType>::Copy(const ByteArray& src,
-                                                         ByteArray* dst,
-                                                         ResizableBuffer* buffer) {
-  if (dst->ptr == src.ptr) return;
-  PARQUET_THROW_NOT_OK(buffer->Resize(src.len, false));
-  std::memcpy(buffer->mutable_data(), src.ptr, src.len);
-  *dst = ByteArray(src.len, buffer->data());
-}
-
-template <>
-void TypedRowGroupStatistics<ByteArrayType>::PlainEncode(const T& src, std::string* dst);
-
-template <>
-void TypedRowGroupStatistics<ByteArrayType>::PlainDecode(const std::string& src, T* dst);
-
-typedef TypedRowGroupStatistics<BooleanType> BoolStatistics;
-typedef TypedRowGroupStatistics<Int32Type> Int32Statistics;
-typedef TypedRowGroupStatistics<Int64Type> Int64Statistics;
-typedef TypedRowGroupStatistics<Int96Type> Int96Statistics;
-typedef TypedRowGroupStatistics<FloatType> FloatStatistics;
-typedef TypedRowGroupStatistics<DoubleType> DoubleStatistics;
-typedef TypedRowGroupStatistics<ByteArrayType> ByteArrayStatistics;
-typedef TypedRowGroupStatistics<FLBAType> FLBAStatistics;
-
-#if defined(__GNUC__) && !defined(__clang__)
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wattributes"
-#endif
-
-PARQUET_EXTERN_TEMPLATE TypedRowGroupStatistics<BooleanType>;
-PARQUET_EXTERN_TEMPLATE TypedRowGroupStatistics<Int32Type>;
-PARQUET_EXTERN_TEMPLATE TypedRowGroupStatistics<Int64Type>;
-PARQUET_EXTERN_TEMPLATE TypedRowGroupStatistics<Int96Type>;
-PARQUET_EXTERN_TEMPLATE TypedRowGroupStatistics<FloatType>;
-PARQUET_EXTERN_TEMPLATE TypedRowGroupStatistics<DoubleType>;
-PARQUET_EXTERN_TEMPLATE TypedRowGroupStatistics<ByteArrayType>;
-PARQUET_EXTERN_TEMPLATE TypedRowGroupStatistics<FLBAType>;
-
-#if defined(__GNUC__) && !defined(__clang__)
-#pragma GCC diagnostic pop
-#endif
-
-}  // namespace parquet
-
-#endif  // PARQUET_COLUMN_STATISTICS_H
diff --git a/src/parquet/symbols.map b/src/parquet/symbols.map
deleted file mode 100644
index e00751e..0000000
--- a/src/parquet/symbols.map
+++ /dev/null
@@ -1,38 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you 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.
-
-{
-  # Symbols marked as 'local' are not exported by the DSO and thus may not
-  # be used by client applications.
-  local:
-    # devtoolset / static-libstdc++ symbols
-    __cxa_*;
-
-    extern "C++" {
-      # boost
-      boost::*;
-
-	  # thrift
-	  apache::thrift::*;
-
-      # devtoolset or -static-libstdc++ - the Red Hat devtoolset statically
-      # links c++11 symbols into binaries so that the result may be executed on
-      # a system with an older libstdc++ which doesn't include the necessary
-      # c++11 symbols.
-      std::*;
-    };
-};
diff --git a/src/parquet/test-specialization.h b/src/parquet/test-specialization.h
deleted file mode 100644
index 3d88cfc..0000000
--- a/src/parquet/test-specialization.h
+++ /dev/null
@@ -1,183 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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.
-
-// This module defines an abstract interface for iterating through pages in a
-// Parquet column chunk within a row group. It could be extended in the future
-// to iterate through all data pages in all chunks in a file.
-
-#ifndef PARQUET_COLUMN_TEST_SPECIALIZATION_H
-#define PARQUET_COLUMN_TEST_SPECIALIZATION_H
-
-#include <algorithm>
-#include <limits>
-#include <sstream>
-#include <string>
-#include <vector>
-
-#include "parquet/test-util.h"
-
-namespace parquet {
-
-namespace test {
-
-template <>
-void inline InitValues<bool>(int num_values, vector<bool>& values,
-                             vector<uint8_t>& buffer) {
-  values = flip_coins(num_values, 0);
-}
-
-template <>
-void inline InitValues<ByteArray>(int num_values, vector<ByteArray>& values,
-                                  vector<uint8_t>& buffer) {
-  int max_byte_array_len = 12;
-  int num_bytes = static_cast<int>(max_byte_array_len + sizeof(uint32_t));
-  size_t nbytes = num_values * num_bytes;
-  buffer.resize(nbytes);
-  random_byte_array(num_values, 0, buffer.data(), values.data(), max_byte_array_len);
-}
-
-void inline InitWideByteArrayValues(int num_values, vector<ByteArray>& values,
-                                    vector<uint8_t>& buffer, int min_len, int max_len) {
-  int num_bytes = static_cast<int>(max_len + sizeof(uint32_t));
-  size_t nbytes = num_values * num_bytes;
-  buffer.resize(nbytes);
-  random_byte_array(num_values, 0, buffer.data(), values.data(), min_len, max_len);
-}
-
-template <>
-void inline InitValues<FLBA>(int num_values, vector<FLBA>& values,
-                             vector<uint8_t>& buffer) {
-  size_t nbytes = num_values * FLBA_LENGTH;
-  buffer.resize(nbytes);
-  random_fixed_byte_array(num_values, 0, buffer.data(), FLBA_LENGTH, values.data());
-}
-
-template <>
-void inline InitValues<Int96>(int num_values, vector<Int96>& values,
-                              vector<uint8_t>& buffer) {
-  random_Int96_numbers(num_values, 0, std::numeric_limits<int32_t>::min(),
-                       std::numeric_limits<int32_t>::max(), values.data());
-}
-
-inline std::string TestColumnName(int i) {
-  std::stringstream col_name;
-  col_name << "column_" << i;
-  return col_name.str();
-}
-
-// This class lives here because of its dependency on the InitValues specializations.
-template <typename TestType>
-class PrimitiveTypedTest : public ::testing::Test {
- public:
-  typedef typename TestType::c_type T;
-
-  void SetUpSchema(Repetition::type repetition, int num_columns = 1) {
-    std::vector<schema::NodePtr> fields;
-
-    for (int i = 0; i < num_columns; ++i) {
-      std::string name = TestColumnName(i);
-      fields.push_back(schema::PrimitiveNode::Make(name, repetition, TestType::type_num,
-                                                   LogicalType::NONE, FLBA_LENGTH));
-    }
-    node_ = schema::GroupNode::Make("schema", Repetition::REQUIRED, fields);
-    schema_.Init(node_);
-  }
-
-  void GenerateData(int64_t num_values);
-  void SetupValuesOut(int64_t num_values);
-  void SyncValuesOut();
-
- protected:
-  schema::NodePtr node_;
-  SchemaDescriptor schema_;
-
-  // Input buffers
-  std::vector<T> values_;
-
-  std::vector<int16_t> def_levels_;
-
-  std::vector<uint8_t> buffer_;
-  // Pointer to the values, needed as we cannot use vector<bool>::data()
-  T* values_ptr_;
-  std::vector<uint8_t> bool_buffer_;
-
-  // Output buffers
-  std::vector<T> values_out_;
-  std::vector<uint8_t> bool_buffer_out_;
-  T* values_out_ptr_;
-};
-
-template <typename TestType>
-void PrimitiveTypedTest<TestType>::SyncValuesOut() {}
-
-template <>
-void PrimitiveTypedTest<BooleanType>::SyncValuesOut() {
-  std::vector<uint8_t>::const_iterator source_iterator = bool_buffer_out_.begin();
-  std::vector<T>::iterator destination_iterator = values_out_.begin();
-  while (source_iterator != bool_buffer_out_.end()) {
-    *destination_iterator++ = *source_iterator++ != 0;
-  }
-}
-
-template <typename TestType>
-void PrimitiveTypedTest<TestType>::SetupValuesOut(int64_t num_values) {
-  values_out_.clear();
-  values_out_.resize(num_values);
-  values_out_ptr_ = values_out_.data();
-}
-
-template <>
-void PrimitiveTypedTest<BooleanType>::SetupValuesOut(int64_t num_values) {
-  values_out_.clear();
-  values_out_.resize(num_values);
-
-  bool_buffer_out_.clear();
-  bool_buffer_out_.resize(num_values);
-  // Write once to all values so we can copy it without getting Valgrind errors
-  // about uninitialised values.
-  std::fill(bool_buffer_out_.begin(), bool_buffer_out_.end(), true);
-  values_out_ptr_ = reinterpret_cast<bool*>(bool_buffer_out_.data());
-}
-
-template <typename TestType>
-void PrimitiveTypedTest<TestType>::GenerateData(int64_t num_values) {
-  def_levels_.resize(num_values);
-  values_.resize(num_values);
-
-  InitValues<T>(static_cast<int>(num_values), values_, buffer_);
-  values_ptr_ = values_.data();
-
-  std::fill(def_levels_.begin(), def_levels_.end(), 1);
-}
-
-template <>
-void PrimitiveTypedTest<BooleanType>::GenerateData(int64_t num_values) {
-  def_levels_.resize(num_values);
-  values_.resize(num_values);
-
-  InitValues<T>(static_cast<int>(num_values), values_, buffer_);
-  bool_buffer_.resize(num_values);
-  std::copy(values_.begin(), values_.end(), bool_buffer_.begin());
-  values_ptr_ = reinterpret_cast<bool*>(bool_buffer_.data());
-
-  std::fill(def_levels_.begin(), def_levels_.end(), 1);
-}
-}  // namespace test
-
-}  // namespace parquet
-
-#endif  // PARQUET_COLUMN_TEST_SPECIALIZATION_H
diff --git a/src/parquet/test-util.h b/src/parquet/test-util.h
deleted file mode 100644
index 3e74398..0000000
--- a/src/parquet/test-util.h
+++ /dev/null
@@ -1,447 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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.
-
-// This module defines an abstract interface for iterating through pages in a
-// Parquet column chunk within a row group. It could be extended in the future
-// to iterate through all data pages in all chunks in a file.
-
-#ifndef PARQUET_COLUMN_TEST_UTIL_H
-#define PARQUET_COLUMN_TEST_UTIL_H
-
-#include <algorithm>
-#include <limits>
-#include <memory>
-#include <string>
-#include <vector>
-
-#include <gtest/gtest.h>
-
-#include "parquet/column_page.h"
-#include "parquet/column_reader.h"
-#include "parquet/column_writer.h"
-#include "parquet/encoding-internal.h"
-#include "parquet/util/memory.h"
-#include "parquet/util/test-common.h"
-
-using std::shared_ptr;
-using std::vector;
-
-namespace parquet {
-
-static constexpr int FLBA_LENGTH = 12;
-
-bool operator==(const FixedLenByteArray& a, const FixedLenByteArray& b) {
-  return 0 == memcmp(a.ptr, b.ptr, FLBA_LENGTH);
-}
-
-namespace test {
-
-template <typename T>
-static void InitValues(int num_values, vector<T>& values, vector<uint8_t>& buffer) {
-  random_numbers(num_values, 0, std::numeric_limits<T>::min(),
-                 std::numeric_limits<T>::max(), values.data());
-}
-
-template <typename T>
-static void InitDictValues(int num_values, int num_dicts, vector<T>& values,
-                           vector<uint8_t>& buffer) {
-  int repeat_factor = num_values / num_dicts;
-  InitValues<T>(num_dicts, values, buffer);
-  // add some repeated values
-  for (int j = 1; j < repeat_factor; ++j) {
-    for (int i = 0; i < num_dicts; ++i) {
-      std::memcpy(&values[num_dicts * j + i], &values[i], sizeof(T));
-    }
-  }
-  // computed only dict_per_page * repeat_factor - 1 values < num_values
-  // compute remaining
-  for (int i = num_dicts * repeat_factor; i < num_values; ++i) {
-    std::memcpy(&values[i], &values[i - num_dicts * repeat_factor], sizeof(T));
-  }
-}
-
-class MockPageReader : public PageReader {
- public:
-  explicit MockPageReader(const vector<shared_ptr<Page>>& pages)
-      : pages_(pages), page_index_(0) {}
-
-  shared_ptr<Page> NextPage() override {
-    if (page_index_ == static_cast<int>(pages_.size())) {
-      // EOS to consumer
-      return shared_ptr<Page>(nullptr);
-    }
-    return pages_[page_index_++];
-  }
-
-  // No-op
-  void set_max_page_header_size(uint32_t size) override {}
-
- private:
-  vector<shared_ptr<Page>> pages_;
-  int page_index_;
-};
-
-// TODO(wesm): this is only used for testing for now. Refactor to form part of
-// primary file write path
-template <typename Type>
-class DataPageBuilder {
- public:
-  typedef typename Type::c_type T;
-
-  // This class writes data and metadata to the passed inputs
-  explicit DataPageBuilder(InMemoryOutputStream* sink)
-      : sink_(sink),
-        num_values_(0),
-        encoding_(Encoding::PLAIN),
-        definition_level_encoding_(Encoding::RLE),
-        repetition_level_encoding_(Encoding::RLE),
-        have_def_levels_(false),
-        have_rep_levels_(false),
-        have_values_(false) {}
-
-  void AppendDefLevels(const vector<int16_t>& levels, int16_t max_level,
-                       Encoding::type encoding = Encoding::RLE) {
-    AppendLevels(levels, max_level, encoding);
-
-    num_values_ = std::max(static_cast<int32_t>(levels.size()), num_values_);
-    definition_level_encoding_ = encoding;
-    have_def_levels_ = true;
-  }
-
-  void AppendRepLevels(const vector<int16_t>& levels, int16_t max_level,
-                       Encoding::type encoding = Encoding::RLE) {
-    AppendLevels(levels, max_level, encoding);
-
-    num_values_ = std::max(static_cast<int32_t>(levels.size()), num_values_);
-    repetition_level_encoding_ = encoding;
-    have_rep_levels_ = true;
-  }
-
-  void AppendValues(const ColumnDescriptor* d, const vector<T>& values,
-                    Encoding::type encoding = Encoding::PLAIN) {
-    PlainEncoder<Type> encoder(d);
-    encoder.Put(&values[0], static_cast<int>(values.size()));
-    std::shared_ptr<Buffer> values_sink = encoder.FlushValues();
-    sink_->Write(values_sink->data(), values_sink->size());
-
-    num_values_ = std::max(static_cast<int32_t>(values.size()), num_values_);
-    encoding_ = encoding;
-    have_values_ = true;
-  }
-
-  int32_t num_values() const { return num_values_; }
-
-  Encoding::type encoding() const { return encoding_; }
-
-  Encoding::type rep_level_encoding() const { return repetition_level_encoding_; }
-
-  Encoding::type def_level_encoding() const { return definition_level_encoding_; }
-
- private:
-  InMemoryOutputStream* sink_;
-
-  int32_t num_values_;
-  Encoding::type encoding_;
-  Encoding::type definition_level_encoding_;
-  Encoding::type repetition_level_encoding_;
-
-  bool have_def_levels_;
-  bool have_rep_levels_;
-  bool have_values_;
-
-  // Used internally for both repetition and definition levels
-  void AppendLevels(const vector<int16_t>& levels, int16_t max_level,
-                    Encoding::type encoding) {
-    if (encoding != Encoding::RLE) {
-      ParquetException::NYI("only rle encoding currently implemented");
-    }
-
-    // TODO: compute a more precise maximum size for the encoded levels
-    vector<uint8_t> encode_buffer(levels.size() * 2);
-
-    // We encode into separate memory from the output stream because the
-    // RLE-encoded bytes have to be preceded in the stream by their absolute
-    // size.
-    LevelEncoder encoder;
-    encoder.Init(encoding, max_level, static_cast<int>(levels.size()),
-                 encode_buffer.data(), static_cast<int>(encode_buffer.size()));
-
-    encoder.Encode(static_cast<int>(levels.size()), levels.data());
-
-    int32_t rle_bytes = encoder.len();
-    sink_->Write(reinterpret_cast<const uint8_t*>(&rle_bytes), sizeof(int32_t));
-    sink_->Write(encode_buffer.data(), rle_bytes);
-  }
-};
-
-template <>
-void DataPageBuilder<BooleanType>::AppendValues(const ColumnDescriptor* d,
-                                                const vector<bool>& values,
-                                                Encoding::type encoding) {
-  if (encoding != Encoding::PLAIN) {
-    ParquetException::NYI("only plain encoding currently implemented");
-  }
-  PlainEncoder<BooleanType> encoder(d);
-  encoder.Put(values, static_cast<int>(values.size()));
-  std::shared_ptr<Buffer> buffer = encoder.FlushValues();
-  sink_->Write(buffer->data(), buffer->size());
-
-  num_values_ = std::max(static_cast<int32_t>(values.size()), num_values_);
-  encoding_ = encoding;
-  have_values_ = true;
-}
-
-template <typename Type>
-static shared_ptr<DataPage> MakeDataPage(
-    const ColumnDescriptor* d, const vector<typename Type::c_type>& values, int num_vals,
-    Encoding::type encoding, const uint8_t* indices, int indices_size,
-    const vector<int16_t>& def_levels, int16_t max_def_level,
-    const vector<int16_t>& rep_levels, int16_t max_rep_level) {
-  int num_values = 0;
-
-  InMemoryOutputStream page_stream;
-  test::DataPageBuilder<Type> page_builder(&page_stream);
-
-  if (!rep_levels.empty()) {
-    page_builder.AppendRepLevels(rep_levels, max_rep_level);
-  }
-  if (!def_levels.empty()) {
-    page_builder.AppendDefLevels(def_levels, max_def_level);
-  }
-
-  if (encoding == Encoding::PLAIN) {
-    page_builder.AppendValues(d, values, encoding);
-    num_values = page_builder.num_values();
-  } else {  // DICTIONARY PAGES
-    page_stream.Write(indices, indices_size);
-    num_values = std::max(page_builder.num_values(), num_vals);
-  }
-
-  auto buffer = page_stream.GetBuffer();
-
-  return std::make_shared<DataPage>(buffer, num_values, encoding,
-                                    page_builder.def_level_encoding(),
-                                    page_builder.rep_level_encoding());
-}
-
-template <typename TYPE>
-class DictionaryPageBuilder {
- public:
-  typedef typename TYPE::c_type TC;
-  static constexpr int TN = TYPE::type_num;
-
-  // This class writes data and metadata to the passed inputs
-  explicit DictionaryPageBuilder(const ColumnDescriptor* d)
-      : num_dict_values_(0), have_values_(false) {
-    encoder_.reset(new DictEncoder<TYPE>(d, &pool_));
-  }
-
-  ~DictionaryPageBuilder() { pool_.FreeAll(); }
-
-  shared_ptr<Buffer> AppendValues(const vector<TC>& values) {
-    int num_values = static_cast<int>(values.size());
-    // Dictionary encoding
-    encoder_->Put(values.data(), num_values);
-    num_dict_values_ = encoder_->num_entries();
-    have_values_ = true;
-    return encoder_->FlushValues();
-  }
-
-  shared_ptr<Buffer> WriteDict() {
-    std::shared_ptr<ResizableBuffer> dict_buffer =
-        AllocateBuffer(::arrow::default_memory_pool(), encoder_->dict_encoded_size());
-    encoder_->WriteDict(dict_buffer->mutable_data());
-    return dict_buffer;
-  }
-
-  int32_t num_values() const { return num_dict_values_; }
-
- private:
-  ChunkedAllocator pool_;
-  shared_ptr<DictEncoder<TYPE>> encoder_;
-  int32_t num_dict_values_;
-  bool have_values_;
-};
-
-template <>
-DictionaryPageBuilder<BooleanType>::DictionaryPageBuilder(const ColumnDescriptor* d) {
-  ParquetException::NYI("only plain encoding currently implemented for boolean");
-}
-
-template <>
-shared_ptr<Buffer> DictionaryPageBuilder<BooleanType>::WriteDict() {
-  ParquetException::NYI("only plain encoding currently implemented for boolean");
-  return nullptr;
-}
-
-template <>
-shared_ptr<Buffer> DictionaryPageBuilder<BooleanType>::AppendValues(
-    const vector<TC>& values) {
-  ParquetException::NYI("only plain encoding currently implemented for boolean");
-  return nullptr;
-}
-
-template <typename Type>
-static shared_ptr<DictionaryPage> MakeDictPage(
-    const ColumnDescriptor* d, const vector<typename Type::c_type>& values,
-    const vector<int>& values_per_page, Encoding::type encoding,
-    vector<shared_ptr<Buffer>>& rle_indices) {
-  InMemoryOutputStream page_stream;
-  test::DictionaryPageBuilder<Type> page_builder(d);
-  int num_pages = static_cast<int>(values_per_page.size());
-  int value_start = 0;
-
-  for (int i = 0; i < num_pages; i++) {
-    rle_indices.push_back(page_builder.AppendValues(
-        slice(values, value_start, value_start + values_per_page[i])));
-    value_start += values_per_page[i];
-  }
-
-  auto buffer = page_builder.WriteDict();
-
-  return std::make_shared<DictionaryPage>(buffer, page_builder.num_values(),
-                                          Encoding::PLAIN);
-}
-
-// Given def/rep levels and values create multiple dict pages
-template <typename Type>
-static void PaginateDict(const ColumnDescriptor* d,
-                         const vector<typename Type::c_type>& values,
-                         const vector<int16_t>& def_levels, int16_t max_def_level,
-                         const vector<int16_t>& rep_levels, int16_t max_rep_level,
-                         int num_levels_per_page, const vector<int>& values_per_page,
-                         vector<shared_ptr<Page>>& pages,
-                         Encoding::type encoding = Encoding::RLE_DICTIONARY) {
-  int num_pages = static_cast<int>(values_per_page.size());
-  vector<shared_ptr<Buffer>> rle_indices;
-  shared_ptr<DictionaryPage> dict_page =
-      MakeDictPage<Type>(d, values, values_per_page, encoding, rle_indices);
-  pages.push_back(dict_page);
-  int def_level_start = 0;
-  int def_level_end = 0;
-  int rep_level_start = 0;
-  int rep_level_end = 0;
-  for (int i = 0; i < num_pages; i++) {
-    if (max_def_level > 0) {
-      def_level_start = i * num_levels_per_page;
-      def_level_end = (i + 1) * num_levels_per_page;
-    }
-    if (max_rep_level > 0) {
-      rep_level_start = i * num_levels_per_page;
-      rep_level_end = (i + 1) * num_levels_per_page;
-    }
-    shared_ptr<DataPage> data_page = MakeDataPage<Int32Type>(
-        d, {}, values_per_page[i], encoding, rle_indices[i]->data(),
-        static_cast<int>(rle_indices[i]->size()),
-        slice(def_levels, def_level_start, def_level_end), max_def_level,
-        slice(rep_levels, rep_level_start, rep_level_end), max_rep_level);
-    pages.push_back(data_page);
-  }
-}
-
-// Given def/rep levels and values create multiple plain pages
-template <typename Type>
-static void PaginatePlain(const ColumnDescriptor* d,
-                          const vector<typename Type::c_type>& values,
-                          const vector<int16_t>& def_levels, int16_t max_def_level,
-                          const vector<int16_t>& rep_levels, int16_t max_rep_level,
-                          int num_levels_per_page, const vector<int>& values_per_page,
-                          vector<shared_ptr<Page>>& pages,
-                          Encoding::type encoding = Encoding::PLAIN) {
-  int num_pages = static_cast<int>(values_per_page.size());
-  int def_level_start = 0;
-  int def_level_end = 0;
-  int rep_level_start = 0;
-  int rep_level_end = 0;
-  int value_start = 0;
-  for (int i = 0; i < num_pages; i++) {
-    if (max_def_level > 0) {
-      def_level_start = i * num_levels_per_page;
-      def_level_end = (i + 1) * num_levels_per_page;
-    }
-    if (max_rep_level > 0) {
-      rep_level_start = i * num_levels_per_page;
-      rep_level_end = (i + 1) * num_levels_per_page;
-    }
-    shared_ptr<DataPage> page = MakeDataPage<Type>(
-        d, slice(values, value_start, value_start + values_per_page[i]),
-        values_per_page[i], encoding, nullptr, 0,
-        slice(def_levels, def_level_start, def_level_end), max_def_level,
-        slice(rep_levels, rep_level_start, rep_level_end), max_rep_level);
-    pages.push_back(page);
-    value_start += values_per_page[i];
-  }
-}
-
-// Generates pages from randomly generated data
-template <typename Type>
-static int MakePages(const ColumnDescriptor* d, int num_pages, int levels_per_page,
-                     vector<int16_t>& def_levels, vector<int16_t>& rep_levels,
-                     vector<typename Type::c_type>& values, vector<uint8_t>& buffer,
-                     vector<shared_ptr<Page>>& pages,
-                     Encoding::type encoding = Encoding::PLAIN) {
-  int num_levels = levels_per_page * num_pages;
-  int num_values = 0;
-  uint32_t seed = 0;
-  int16_t zero = 0;
-  int16_t max_def_level = d->max_definition_level();
-  int16_t max_rep_level = d->max_repetition_level();
-  vector<int> values_per_page(num_pages, levels_per_page);
-  // Create definition levels
-  if (max_def_level > 0) {
-    def_levels.resize(num_levels);
-    random_numbers(num_levels, seed, zero, max_def_level, def_levels.data());
-    for (int p = 0; p < num_pages; p++) {
-      int num_values_per_page = 0;
-      for (int i = 0; i < levels_per_page; i++) {
-        if (def_levels[i + p * levels_per_page] == max_def_level) {
-          num_values_per_page++;
-          num_values++;
-        }
-      }
-      values_per_page[p] = num_values_per_page;
-    }
-  } else {
-    num_values = num_levels;
-  }
-  // Create repitition levels
-  if (max_rep_level > 0) {
-    rep_levels.resize(num_levels);
-    random_numbers(num_levels, seed, zero, max_rep_level, rep_levels.data());
-  }
-  // Create values
-  values.resize(num_values);
-  if (encoding == Encoding::PLAIN) {
-    InitValues<typename Type::c_type>(num_values, values, buffer);
-    PaginatePlain<Type>(d, values, def_levels, max_def_level, rep_levels, max_rep_level,
-                        levels_per_page, values_per_page, pages);
-  } else if (encoding == Encoding::RLE_DICTIONARY ||
-             encoding == Encoding::PLAIN_DICTIONARY) {
-    // Calls InitValues and repeats the data
-    InitDictValues<typename Type::c_type>(num_values, levels_per_page, values, buffer);
-    PaginateDict<Type>(d, values, def_levels, max_def_level, rep_levels, max_rep_level,
-                       levels_per_page, values_per_page, pages);
-  }
-
-  return num_values;
-}
-
-}  // namespace test
-
-}  // namespace parquet
-
-#endif  // PARQUET_COLUMN_TEST_UTIL_H
diff --git a/src/parquet/thrift.h b/src/parquet/thrift.h
deleted file mode 100644
index ec7ac90..0000000
--- a/src/parquet/thrift.h
+++ /dev/null
@@ -1,159 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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.
-
-#ifndef PARQUET_THRIFT_UTIL_H
-#define PARQUET_THRIFT_UTIL_H
-
-#include <cstdint>
-// Check if thrift version < 0.11.0
-// or if FORCE_BOOST_SMART_PTR is defined. Ref: https://thrift.apache.org/lib/cpp
-#if defined(PARQUET_THRIFT_USE_BOOST) || defined(FORCE_BOOST_SMART_PTR)
-#include <boost/shared_ptr.hpp>
-#else
-#include <memory>
-#endif
-
-// TCompactProtocol requires some #defines to work right.
-#define SIGNED_RIGHT_SHIFT_IS 1
-#define ARITHMETIC_RIGHT_SHIFT 1
-#include <thrift/TApplicationException.h>
-#include <thrift/protocol/TCompactProtocol.h>
-#include <thrift/protocol/TDebugProtocol.h>
-
-#include <thrift/protocol/TBinaryProtocol.h>
-#include <thrift/transport/TBufferTransports.h>
-#include <sstream>
-
-#include "parquet/exception.h"
-#include "parquet/parquet_types.h"
-#include "parquet/util/logging.h"
-#include "parquet/util/memory.h"
-
-namespace parquet {
-
-// Check if thrift version < 0.11.0
-// or if FORCE_BOOST_SMART_PTR is defined. Ref: https://thrift.apache.org/lib/cpp
-#if defined(PARQUET_THRIFT_USE_BOOST) || defined(FORCE_BOOST_SMART_PTR)
-using ::boost::shared_ptr;
-#else
-using ::std::shared_ptr;
-#endif
-
-// ----------------------------------------------------------------------
-// Convert Thrift enums to / from parquet enums
-
-static inline Type::type FromThrift(format::Type::type type) {
-  return static_cast<Type::type>(type);
-}
-
-static inline LogicalType::type FromThrift(format::ConvertedType::type type) {
-  // item 0 is NONE
-  return static_cast<LogicalType::type>(static_cast<int>(type) + 1);
-}
-
-static inline Repetition::type FromThrift(format::FieldRepetitionType::type type) {
-  return static_cast<Repetition::type>(type);
-}
-
-static inline Encoding::type FromThrift(format::Encoding::type type) {
-  return static_cast<Encoding::type>(type);
-}
-
-static inline Compression::type FromThrift(format::CompressionCodec::type type) {
-  return static_cast<Compression::type>(type);
-}
-
-static inline format::Type::type ToThrift(Type::type type) {
-  return static_cast<format::Type::type>(type);
-}
-
-static inline format::ConvertedType::type ToThrift(LogicalType::type type) {
-  // item 0 is NONE
-  DCHECK_NE(type, LogicalType::NONE);
-  return static_cast<format::ConvertedType::type>(static_cast<int>(type) - 1);
-}
-
-static inline format::FieldRepetitionType::type ToThrift(Repetition::type type) {
-  return static_cast<format::FieldRepetitionType::type>(type);
-}
-
-static inline format::Encoding::type ToThrift(Encoding::type type) {
-  return static_cast<format::Encoding::type>(type);
-}
-
-static inline format::CompressionCodec::type ToThrift(Compression::type type) {
-  return static_cast<format::CompressionCodec::type>(type);
-}
-
-// ----------------------------------------------------------------------
-// Thrift struct serialization / deserialization utilities
-
-// Deserialize a thrift message from buf/len.  buf/len must at least contain
-// all the bytes needed to store the thrift message.  On return, len will be
-// set to the actual length of the header.
-template <class T>
-inline void DeserializeThriftMsg(const uint8_t* buf, uint32_t* len, T* deserialized_msg) {
-  // Deserialize msg bytes into c++ thrift msg using memory transport.
-  shared_ptr<apache::thrift::transport::TMemoryBuffer> tmem_transport(
-      new apache::thrift::transport::TMemoryBuffer(const_cast<uint8_t*>(buf), *len));
-  apache::thrift::protocol::TCompactProtocolFactoryT<
-      apache::thrift::transport::TMemoryBuffer>
-      tproto_factory;
-  shared_ptr<apache::thrift::protocol::TProtocol> tproto =
-      tproto_factory.getProtocol(tmem_transport);
-  try {
-    deserialized_msg->read(tproto.get());
-  } catch (std::exception& e) {
-    std::stringstream ss;
-    ss << "Couldn't deserialize thrift: " << e.what() << "\n";
-    throw ParquetException(ss.str());
-  }
-  uint32_t bytes_left = tmem_transport->available_read();
-  *len = *len - bytes_left;
-}
-
-// Serialize obj into a buffer. The result is returned as a string.
-// The arguments are the object to be serialized and
-// the expected size of the serialized object
-template <class T>
-inline int64_t SerializeThriftMsg(T* obj, uint32_t len, OutputStream* out) {
-  shared_ptr<apache::thrift::transport::TMemoryBuffer> mem_buffer(
-      new apache::thrift::transport::TMemoryBuffer(len));
-  apache::thrift::protocol::TCompactProtocolFactoryT<
-      apache::thrift::transport::TMemoryBuffer>
-      tproto_factory;
-  shared_ptr<apache::thrift::protocol::TProtocol> tproto =
-      tproto_factory.getProtocol(mem_buffer);
-  try {
-    mem_buffer->resetBuffer();
-    obj->write(tproto.get());
-  } catch (std::exception& e) {
-    std::stringstream ss;
-    ss << "Couldn't serialize thrift: " << e.what() << "\n";
-    throw ParquetException(ss.str());
-  }
-
-  uint8_t* out_buffer;
-  uint32_t out_length;
-  mem_buffer->getBuffer(&out_buffer, &out_length);
-  out->Write(out_buffer, out_length);
-  return out_length;
-}
-
-}  // namespace parquet
-
-#endif  // PARQUET_THRIFT_UTIL_H
diff --git a/src/parquet/types-test.cc b/src/parquet/types-test.cc
deleted file mode 100644
index 6b184e3..0000000
--- a/src/parquet/types-test.cc
+++ /dev/null
@@ -1,142 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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.
-
-#include <gtest/gtest.h>
-
-#include <string>
-
-#include "parquet/types.h"
-
-namespace parquet {
-
-TEST(TestTypeToString, PhysicalTypes) {
-  ASSERT_STREQ("BOOLEAN", TypeToString(Type::BOOLEAN).c_str());
-  ASSERT_STREQ("INT32", TypeToString(Type::INT32).c_str());
-  ASSERT_STREQ("INT64", TypeToString(Type::INT64).c_str());
-  ASSERT_STREQ("INT96", TypeToString(Type::INT96).c_str());
-  ASSERT_STREQ("FLOAT", TypeToString(Type::FLOAT).c_str());
-  ASSERT_STREQ("DOUBLE", TypeToString(Type::DOUBLE).c_str());
-  ASSERT_STREQ("BYTE_ARRAY", TypeToString(Type::BYTE_ARRAY).c_str());
-  ASSERT_STREQ("FIXED_LEN_BYTE_ARRAY", TypeToString(Type::FIXED_LEN_BYTE_ARRAY).c_str());
-}
-
-TEST(TestLogicalTypeToString, LogicalTypes) {
-  ASSERT_STREQ("NONE", LogicalTypeToString(LogicalType::NONE).c_str());
-  ASSERT_STREQ("UTF8", LogicalTypeToString(LogicalType::UTF8).c_str());
-  ASSERT_STREQ("MAP_KEY_VALUE", LogicalTypeToString(LogicalType::MAP_KEY_VALUE).c_str());
-  ASSERT_STREQ("LIST", LogicalTypeToString(LogicalType::LIST).c_str());
-  ASSERT_STREQ("ENUM", LogicalTypeToString(LogicalType::ENUM).c_str());
-  ASSERT_STREQ("DECIMAL", LogicalTypeToString(LogicalType::DECIMAL).c_str());
-  ASSERT_STREQ("DATE", LogicalTypeToString(LogicalType::DATE).c_str());
-  ASSERT_STREQ("TIME_MILLIS", LogicalTypeToString(LogicalType::TIME_MILLIS).c_str());
-  ASSERT_STREQ("TIME_MICROS", LogicalTypeToString(LogicalType::TIME_MICROS).c_str());
-  ASSERT_STREQ("TIMESTAMP_MILLIS",
-               LogicalTypeToString(LogicalType::TIMESTAMP_MILLIS).c_str());
-  ASSERT_STREQ("TIMESTAMP_MICROS",
-               LogicalTypeToString(LogicalType::TIMESTAMP_MICROS).c_str());
-  ASSERT_STREQ("UINT_8", LogicalTypeToString(LogicalType::UINT_8).c_str());
-  ASSERT_STREQ("UINT_16", LogicalTypeToString(LogicalType::UINT_16).c_str());
-  ASSERT_STREQ("UINT_32", LogicalTypeToString(LogicalType::UINT_32).c_str());
-  ASSERT_STREQ("UINT_64", LogicalTypeToString(LogicalType::UINT_64).c_str());
-  ASSERT_STREQ("INT_8", LogicalTypeToString(LogicalType::INT_8).c_str());
-  ASSERT_STREQ("INT_16", LogicalTypeToString(LogicalType::INT_16).c_str());
-  ASSERT_STREQ("INT_32", LogicalTypeToString(LogicalType::INT_32).c_str());
-  ASSERT_STREQ("INT_64", LogicalTypeToString(LogicalType::INT_64).c_str());
-  ASSERT_STREQ("JSON", LogicalTypeToString(LogicalType::JSON).c_str());
-  ASSERT_STREQ("BSON", LogicalTypeToString(LogicalType::BSON).c_str());
-  ASSERT_STREQ("INTERVAL", LogicalTypeToString(LogicalType::INTERVAL).c_str());
-}
-
-TEST(TypePrinter, StatisticsTypes) {
-#if !(defined(_WIN32) || defined(__CYGWIN__))
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
-#endif
-  std::string smin;
-  std::string smax;
-  int32_t int_min = 1024;
-  int32_t int_max = 2048;
-  smin = std::string(reinterpret_cast<char*>(&int_min), sizeof(int32_t));
-  smax = std::string(reinterpret_cast<char*>(&int_max), sizeof(int32_t));
-  ASSERT_STREQ("1024", FormatStatValue(Type::INT32, smin).c_str());
-  ASSERT_STREQ("1024", FormatStatValue(Type::INT32, smin.c_str()).c_str());
-  ASSERT_STREQ("2048", FormatStatValue(Type::INT32, smax).c_str());
-  ASSERT_STREQ("2048", FormatStatValue(Type::INT32, smax.c_str()).c_str());
-
-  int64_t int64_min = 10240000000000;
-  int64_t int64_max = 20480000000000;
-  smin = std::string(reinterpret_cast<char*>(&int64_min), sizeof(int64_t));
-  smax = std::string(reinterpret_cast<char*>(&int64_max), sizeof(int64_t));
-  ASSERT_STREQ("10240000000000", FormatStatValue(Type::INT64, smin).c_str());
-  ASSERT_STREQ("10240000000000", FormatStatValue(Type::INT64, smin.c_str()).c_str());
-  ASSERT_STREQ("20480000000000", FormatStatValue(Type::INT64, smax).c_str());
-  ASSERT_STREQ("20480000000000", FormatStatValue(Type::INT64, smax.c_str()).c_str());
-
-  float float_min = 1.024f;
-  float float_max = 2.048f;
-  smin = std::string(reinterpret_cast<char*>(&float_min), sizeof(float));
-  smax = std::string(reinterpret_cast<char*>(&float_max), sizeof(float));
-  ASSERT_STREQ("1.024", FormatStatValue(Type::FLOAT, smin).c_str());
-  ASSERT_STREQ("1.024", FormatStatValue(Type::FLOAT, smin.c_str()).c_str());
-  ASSERT_STREQ("2.048", FormatStatValue(Type::FLOAT, smax).c_str());
-  ASSERT_STREQ("2.048", FormatStatValue(Type::FLOAT, smax.c_str()).c_str());
-
-  double double_min = 1.0245;
-  double double_max = 2.0489;
-  smin = std::string(reinterpret_cast<char*>(&double_min), sizeof(double));
-  smax = std::string(reinterpret_cast<char*>(&double_max), sizeof(double));
-  ASSERT_STREQ("1.0245", FormatStatValue(Type::DOUBLE, smin).c_str());
-  ASSERT_STREQ("1.0245", FormatStatValue(Type::DOUBLE, smin.c_str()).c_str());
-  ASSERT_STREQ("2.0489", FormatStatValue(Type::DOUBLE, smax).c_str());
-  ASSERT_STREQ("2.0489", FormatStatValue(Type::DOUBLE, smax.c_str()).c_str());
-
-  Int96 Int96_min = {{1024, 2048, 4096}};
-  Int96 Int96_max = {{2048, 4096, 8192}};
-  smin = std::string(reinterpret_cast<char*>(&Int96_min), sizeof(Int96));
-  smax = std::string(reinterpret_cast<char*>(&Int96_max), sizeof(Int96));
-  ASSERT_STREQ("1024 2048 4096", FormatStatValue(Type::INT96, smin).c_str());
-  ASSERT_STREQ("1024 2048 4096", FormatStatValue(Type::INT96, smin.c_str()).c_str());
-  ASSERT_STREQ("2048 4096 8192", FormatStatValue(Type::INT96, smax).c_str());
-  ASSERT_STREQ("2048 4096 8192", FormatStatValue(Type::INT96, smax.c_str()).c_str());
-
-  smin = std::string("abcdef");
-  smax = std::string("ijklmnop");
-  ASSERT_STREQ("abcdef", FormatStatValue(Type::BYTE_ARRAY, smin).c_str());
-  ASSERT_STREQ("abcdef", FormatStatValue(Type::BYTE_ARRAY, smin.c_str()).c_str());
-  ASSERT_STREQ("ijklmnop", FormatStatValue(Type::BYTE_ARRAY, smax).c_str());
-  ASSERT_STREQ("ijklmnop", FormatStatValue(Type::BYTE_ARRAY, smax.c_str()).c_str());
-
-  // PARQUET-1357: FormatStatValue truncates binary statistics on zero character
-  smax.push_back('\0');
-  ASSERT_EQ(smax, FormatStatValue(Type::BYTE_ARRAY, smax));
-  // This fails, thus the call to FormatStatValue(.., const char*) was deprecated.
-  // ASSERT_EQ(smax, FormatStatValue(Type::BYTE_ARRAY, smax.c_str()));
-
-  smin = std::string("abcdefgh");
-  smax = std::string("ijklmnop");
-  ASSERT_STREQ("abcdefgh", FormatStatValue(Type::FIXED_LEN_BYTE_ARRAY, smin).c_str());
-  ASSERT_STREQ("abcdefgh",
-               FormatStatValue(Type::FIXED_LEN_BYTE_ARRAY, smin.c_str()).c_str());
-  ASSERT_STREQ("ijklmnop", FormatStatValue(Type::FIXED_LEN_BYTE_ARRAY, smax).c_str());
-  ASSERT_STREQ("ijklmnop",
-               FormatStatValue(Type::FIXED_LEN_BYTE_ARRAY, smax.c_str()).c_str());
-#if !(defined(_WIN32) || defined(__CYGWIN__))
-#pragma GCC diagnostic pop
-#endif
-}
-
-}  // namespace parquet
diff --git a/src/parquet/types.cc b/src/parquet/types.cc
deleted file mode 100644
index 3120963..0000000
--- a/src/parquet/types.cc
+++ /dev/null
@@ -1,295 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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.
-
-#include <cstdint>
-#include <cstring>
-#include <sstream>
-#include <string>
-
-#include "parquet/types.h"
-
-namespace parquet {
-
-std::string FormatStatValue(Type::type parquet_type, const std::string& val) {
-  std::stringstream result;
-  switch (parquet_type) {
-    case Type::BOOLEAN:
-      result << reinterpret_cast<const bool*>(val.c_str())[0];
-      break;
-    case Type::INT32:
-      result << reinterpret_cast<const int32_t*>(val.c_str())[0];
-      break;
-    case Type::INT64:
-      result << reinterpret_cast<const int64_t*>(val.c_str())[0];
-      break;
-    case Type::DOUBLE:
-      result << reinterpret_cast<const double*>(val.c_str())[0];
-      break;
-    case Type::FLOAT:
-      result << reinterpret_cast<const float*>(val.c_str())[0];
-      break;
-    case Type::INT96: {
-      auto const i32_val = reinterpret_cast<const int32_t*>(val.c_str());
-      result << i32_val[0] << " " << i32_val[1] << " " << i32_val[2];
-      break;
-    }
-    case Type::BYTE_ARRAY: {
-      return val;
-    }
-    case Type::FIXED_LEN_BYTE_ARRAY: {
-      return val;
-    }
-    default:
-      break;
-  }
-  return result.str();
-}
-
-std::string FormatStatValue(Type::type parquet_type, const char* val) {
-  std::stringstream result;
-  switch (parquet_type) {
-    case Type::BOOLEAN:
-      result << reinterpret_cast<const bool*>(val)[0];
-      break;
-    case Type::INT32:
-      result << reinterpret_cast<const int32_t*>(val)[0];
-      break;
-    case Type::INT64:
-      result << reinterpret_cast<const int64_t*>(val)[0];
-      break;
-    case Type::DOUBLE:
-      result << reinterpret_cast<const double*>(val)[0];
-      break;
-    case Type::FLOAT:
-      result << reinterpret_cast<const float*>(val)[0];
-      break;
-    case Type::INT96: {
-      auto const i32_val = reinterpret_cast<const int32_t*>(val);
-      result << i32_val[0] << " " << i32_val[1] << " " << i32_val[2];
-      break;
-    }
-    case Type::BYTE_ARRAY: {
-      result << val;
-      break;
-    }
-    case Type::FIXED_LEN_BYTE_ARRAY: {
-      result << val;
-      break;
-    }
-    default:
-      break;
-  }
-  return result.str();
-}
-
-std::string EncodingToString(Encoding::type t) {
-  switch (t) {
-    case Encoding::PLAIN:
-      return "PLAIN";
-    case Encoding::PLAIN_DICTIONARY:
-      return "PLAIN_DICTIONARY";
-    case Encoding::RLE:
-      return "RLE";
-    case Encoding::BIT_PACKED:
-      return "BIT_PACKED";
-    case Encoding::DELTA_BINARY_PACKED:
-      return "DELTA_BINARY_PACKED";
-    case Encoding::DELTA_LENGTH_BYTE_ARRAY:
-      return "DELTA_LENGTH_BYTE_ARRAY";
-    case Encoding::DELTA_BYTE_ARRAY:
-      return "DELTA_BYTE_ARRAY";
-    case Encoding::RLE_DICTIONARY:
-      return "RLE_DICTIONARY";
-    default:
-      return "UNKNOWN";
-  }
-}
-
-std::string CompressionToString(Compression::type t) {
-  switch (t) {
-    case Compression::UNCOMPRESSED:
-      return "UNCOMPRESSED";
-    case Compression::SNAPPY:
-      return "SNAPPY";
-    case Compression::GZIP:
-      return "GZIP";
-    case Compression::LZO:
-      return "LZO";
-    case Compression::LZ4:
-      return "LZ4";
-    case Compression::ZSTD:
-      return "ZSTD";
-    default:
-      return "UNKNOWN";
-  }
-}
-
-std::string TypeToString(Type::type t) {
-  switch (t) {
-    case Type::BOOLEAN:
-      return "BOOLEAN";
-    case Type::INT32:
-      return "INT32";
-    case Type::INT64:
-      return "INT64";
-    case Type::INT96:
-      return "INT96";
-    case Type::FLOAT:
-      return "FLOAT";
-    case Type::DOUBLE:
-      return "DOUBLE";
-    case Type::BYTE_ARRAY:
-      return "BYTE_ARRAY";
-    case Type::FIXED_LEN_BYTE_ARRAY:
-      return "FIXED_LEN_BYTE_ARRAY";
-    default:
-      return "UNKNOWN";
-  }
-}
-
-std::string LogicalTypeToString(LogicalType::type t) {
-  switch (t) {
-    case LogicalType::NONE:
-      return "NONE";
-    case LogicalType::UTF8:
-      return "UTF8";
-    case LogicalType::MAP_KEY_VALUE:
-      return "MAP_KEY_VALUE";
-    case LogicalType::LIST:
-      return "LIST";
-    case LogicalType::ENUM:
-      return "ENUM";
-    case LogicalType::DECIMAL:
-      return "DECIMAL";
-    case LogicalType::DATE:
-      return "DATE";
-    case LogicalType::TIME_MILLIS:
-      return "TIME_MILLIS";
-    case LogicalType::TIME_MICROS:
-      return "TIME_MICROS";
-    case LogicalType::TIMESTAMP_MILLIS:
-      return "TIMESTAMP_MILLIS";
-    case LogicalType::TIMESTAMP_MICROS:
-      return "TIMESTAMP_MICROS";
-    case LogicalType::UINT_8:
-      return "UINT_8";
-    case LogicalType::UINT_16:
-      return "UINT_16";
-    case LogicalType::UINT_32:
-      return "UINT_32";
-    case LogicalType::UINT_64:
-      return "UINT_64";
-    case LogicalType::INT_8:
-      return "INT_8";
-    case LogicalType::INT_16:
-      return "INT_16";
-    case LogicalType::INT_32:
-      return "INT_32";
-    case LogicalType::INT_64:
-      return "INT_64";
-    case LogicalType::JSON:
-      return "JSON";
-    case LogicalType::BSON:
-      return "BSON";
-    case LogicalType::INTERVAL:
-      return "INTERVAL";
-    default:
-      return "UNKNOWN";
-  }
-}
-
-int GetTypeByteSize(Type::type parquet_type) {
-  switch (parquet_type) {
-    case Type::BOOLEAN:
-      return type_traits<BooleanType::type_num>::value_byte_size;
-    case Type::INT32:
-      return type_traits<Int32Type::type_num>::value_byte_size;
-    case Type::INT64:
-      return type_traits<Int64Type::type_num>::value_byte_size;
-    case Type::INT96:
-      return type_traits<Int96Type::type_num>::value_byte_size;
-    case Type::DOUBLE:
-      return type_traits<DoubleType::type_num>::value_byte_size;
-    case Type::FLOAT:
-      return type_traits<FloatType::type_num>::value_byte_size;
-    case Type::BYTE_ARRAY:
-      return type_traits<ByteArrayType::type_num>::value_byte_size;
-    case Type::FIXED_LEN_BYTE_ARRAY:
-      return type_traits<FLBAType::type_num>::value_byte_size;
-    default:
-      return 0;
-  }
-  return 0;
-}
-
-// Return the Sort Order of the Parquet Physical Types
-SortOrder::type DefaultSortOrder(Type::type primitive) {
-  switch (primitive) {
-    case Type::BOOLEAN:
-    case Type::INT32:
-    case Type::INT64:
-    case Type::FLOAT:
-    case Type::DOUBLE:
-      return SortOrder::SIGNED;
-    case Type::BYTE_ARRAY:
-    case Type::FIXED_LEN_BYTE_ARRAY:
-      return SortOrder::UNSIGNED;
-    case Type::INT96:
-      return SortOrder::UNKNOWN;
-  }
-  return SortOrder::UNKNOWN;
-}
-
-// Return the SortOrder of the Parquet Types using Logical or Physical Types
-SortOrder::type GetSortOrder(LogicalType::type converted, Type::type primitive) {
-  if (converted == LogicalType::NONE) return DefaultSortOrder(primitive);
-  switch (converted) {
-    case LogicalType::INT_8:
-    case LogicalType::INT_16:
-    case LogicalType::INT_32:
-    case LogicalType::INT_64:
-    case LogicalType::DATE:
-    case LogicalType::TIME_MICROS:
-    case LogicalType::TIME_MILLIS:
-    case LogicalType::TIMESTAMP_MICROS:
-    case LogicalType::TIMESTAMP_MILLIS:
-      return SortOrder::SIGNED;
-    case LogicalType::UINT_8:
-    case LogicalType::UINT_16:
-    case LogicalType::UINT_32:
-    case LogicalType::UINT_64:
-    case LogicalType::ENUM:
-    case LogicalType::UTF8:
-    case LogicalType::BSON:
-    case LogicalType::JSON:
-      return SortOrder::UNSIGNED;
-    case LogicalType::DECIMAL:
-    case LogicalType::LIST:
-    case LogicalType::MAP:
-    case LogicalType::MAP_KEY_VALUE:
-    case LogicalType::INTERVAL:
-    case LogicalType::NONE:  // required instead of default
-    case LogicalType::NA:    // required instead of default
-      return SortOrder::UNKNOWN;
-  }
-  return SortOrder::UNKNOWN;
-}
-
-ColumnOrder ColumnOrder::undefined_ = ColumnOrder(ColumnOrder::UNDEFINED);
-ColumnOrder ColumnOrder::type_defined_ = ColumnOrder(ColumnOrder::TYPE_DEFINED_ORDER);
-
-}  // namespace parquet
diff --git a/src/parquet/types.h b/src/parquet/types.h
deleted file mode 100644
index 10789cb..0000000
--- a/src/parquet/types.h
+++ /dev/null
@@ -1,316 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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.
-
-#ifndef PARQUET_TYPES_H
-#define PARQUET_TYPES_H
-
-#include <algorithm>
-#include <cstdint>
-#include <cstring>
-#include <iterator>
-#include <sstream>
-#include <string>
-
-#include "arrow/util/macros.h"
-
-#include "parquet/util/macros.h"
-#include "parquet/util/visibility.h"
-
-namespace parquet {
-
-// ----------------------------------------------------------------------
-// Metadata enums to match Thrift metadata
-//
-// The reason we maintain our own enums is to avoid transitive dependency on
-// the compiled Thrift headers (and thus thrift/Thrift.h) for users of the
-// public API. After building parquet-cpp, you should not need to include
-// Thrift headers in your application. This means some boilerplate to convert
-// between our types and Parquet's Thrift types.
-//
-// We can also add special values like NONE to distinguish between metadata
-// values being set and not set. As an example consider ConvertedType and
-// CompressionCodec
-
-// Mirrors parquet::Type
-struct Type {
-  enum type {
-    BOOLEAN = 0,
-    INT32 = 1,
-    INT64 = 2,
-    INT96 = 3,
-    FLOAT = 4,
-    DOUBLE = 5,
-    BYTE_ARRAY = 6,
-    FIXED_LEN_BYTE_ARRAY = 7
-  };
-};
-
-// Mirrors parquet::ConvertedType
-struct LogicalType {
-  enum type {
-    NONE,
-    UTF8,
-    MAP,
-    MAP_KEY_VALUE,
-    LIST,
-    ENUM,
-    DECIMAL,
-    DATE,
-    TIME_MILLIS,
-    TIME_MICROS,
-    TIMESTAMP_MILLIS,
-    TIMESTAMP_MICROS,
-    UINT_8,
-    UINT_16,
-    UINT_32,
-    UINT_64,
-    INT_8,
-    INT_16,
-    INT_32,
-    INT_64,
-    JSON,
-    BSON,
-    INTERVAL,
-    NA = 25
-  };
-};
-
-// Mirrors parquet::FieldRepetitionType
-struct Repetition {
-  enum type { REQUIRED = 0, OPTIONAL = 1, REPEATED = 2 };
-};
-
-// Data encodings. Mirrors parquet::Encoding
-struct Encoding {
-  enum type {
-    PLAIN = 0,
-    PLAIN_DICTIONARY = 2,
-    RLE = 3,
-    BIT_PACKED = 4,
-    DELTA_BINARY_PACKED = 5,
-    DELTA_LENGTH_BYTE_ARRAY = 6,
-    DELTA_BYTE_ARRAY = 7,
-    RLE_DICTIONARY = 8
-  };
-};
-
-// Compression, mirrors parquet::CompressionCodec
-struct Compression {
-  enum type { UNCOMPRESSED, SNAPPY, GZIP, LZO, BROTLI, LZ4, ZSTD };
-};
-
-struct Encryption {
-  enum type { AES_GCM_V1 = 0, AES_GCM_CTR_V1 = 1 };
-};
-
-// parquet::PageType
-struct PageType {
-  enum type { DATA_PAGE, INDEX_PAGE, DICTIONARY_PAGE, DATA_PAGE_V2 };
-};
-
-// Reference:
-// parquet-mr/parquet-hadoop/src/main/java/org/apache/parquet/
-//                            format/converter/ParquetMetadataConverter.java
-// Sort order for page and column statistics. Types are associated with sort
-// orders (e.g., UTF8 columns should use UNSIGNED) and column stats are
-// aggregated using a sort order. As of parquet-format version 2.3.1, the
-// order used to aggregate stats is always SIGNED and is not stored in the
-// Parquet file. These stats are discarded for types that need unsigned.
-// See PARQUET-686.
-struct SortOrder {
-  enum type { SIGNED, UNSIGNED, UNKNOWN };
-};
-
-class ColumnOrder {
- public:
-  enum type { UNDEFINED, TYPE_DEFINED_ORDER };
-  explicit ColumnOrder(ColumnOrder::type column_order) : column_order_(column_order) {}
-  // Default to Type Defined Order
-  ColumnOrder() : column_order_(type::TYPE_DEFINED_ORDER) {}
-  ColumnOrder::type get_order() { return column_order_; }
-
-  static ColumnOrder undefined_;
-  static ColumnOrder type_defined_;
-
- private:
-  ColumnOrder::type column_order_;
-};
-
-// ----------------------------------------------------------------------
-
-struct ByteArray {
-  ByteArray() : len(0), ptr(nullptr) {}
-  ByteArray(uint32_t len, const uint8_t* ptr) : len(len), ptr(ptr) {}
-  uint32_t len;
-  const uint8_t* ptr;
-};
-
-inline bool operator==(const ByteArray& left, const ByteArray& right) {
-  return left.len == right.len && 0 == std::memcmp(left.ptr, right.ptr, left.len);
-}
-
-inline bool operator!=(const ByteArray& left, const ByteArray& right) {
-  return !(left == right);
-}
-
-struct FixedLenByteArray {
-  FixedLenByteArray() : ptr(nullptr) {}
-  explicit FixedLenByteArray(const uint8_t* ptr) : ptr(ptr) {}
-  const uint8_t* ptr;
-};
-
-using FLBA = FixedLenByteArray;
-
-MANUALLY_ALIGNED_STRUCT(1) Int96 { uint32_t value[3]; };
-STRUCT_END(Int96, 12);
-
-inline bool operator==(const Int96& left, const Int96& right) {
-  return std::equal(left.value, left.value + 3, right.value);
-}
-
-inline bool operator!=(const Int96& left, const Int96& right) { return !(left == right); }
-
-static inline std::string ByteArrayToString(const ByteArray& a) {
-  return std::string(reinterpret_cast<const char*>(a.ptr), a.len);
-}
-
-static inline std::string Int96ToString(const Int96& a) {
-  std::ostringstream result;
-  std::copy(a.value, a.value + 3, std::ostream_iterator<uint32_t>(result, " "));
-  return result.str();
-}
-
-static inline std::string FixedLenByteArrayToString(const FixedLenByteArray& a, int len) {
-  std::ostringstream result;
-  std::copy(a.ptr, a.ptr + len, std::ostream_iterator<uint32_t>(result, " "));
-  return result.str();
-}
-
-template <Type::type TYPE>
-struct type_traits {};
-
-template <>
-struct type_traits<Type::BOOLEAN> {
-  using value_type = bool;
-
-  static constexpr int value_byte_size = 1;
-  static constexpr const char* printf_code = "d";
-};
-
-template <>
-struct type_traits<Type::INT32> {
-  using value_type = int32_t;
-
-  static constexpr int value_byte_size = 4;
-  static constexpr const char* printf_code = "d";
-};
-
-template <>
-struct type_traits<Type::INT64> {
-  using value_type = int64_t;
-
-  static constexpr int value_byte_size = 8;
-  static constexpr const char* printf_code = "ld";
-};
-
-template <>
-struct type_traits<Type::INT96> {
-  using value_type = Int96;
-
-  static constexpr int value_byte_size = 12;
-  static constexpr const char* printf_code = "s";
-};
-
-template <>
-struct type_traits<Type::FLOAT> {
-  using value_type = float;
-
-  static constexpr int value_byte_size = 4;
-  static constexpr const char* printf_code = "f";
-};
-
-template <>
-struct type_traits<Type::DOUBLE> {
-  using value_type = double;
-
-  static constexpr int value_byte_size = 8;
-  static constexpr const char* printf_code = "lf";
-};
-
-template <>
-struct type_traits<Type::BYTE_ARRAY> {
-  using value_type = ByteArray;
-
-  static constexpr int value_byte_size = sizeof(ByteArray);
-  static constexpr const char* printf_code = "s";
-};
-
-template <>
-struct type_traits<Type::FIXED_LEN_BYTE_ARRAY> {
-  using value_type = FixedLenByteArray;
-
-  static constexpr int value_byte_size = sizeof(FixedLenByteArray);
-  static constexpr const char* printf_code = "s";
-};
-
-template <Type::type TYPE>
-struct DataType {
-  using c_type = typename type_traits<TYPE>::value_type;
-  static constexpr Type::type type_num = TYPE;
-};
-
-using BooleanType = DataType<Type::BOOLEAN>;
-using Int32Type = DataType<Type::INT32>;
-using Int64Type = DataType<Type::INT64>;
-using Int96Type = DataType<Type::INT96>;
-using FloatType = DataType<Type::FLOAT>;
-using DoubleType = DataType<Type::DOUBLE>;
-using ByteArrayType = DataType<Type::BYTE_ARRAY>;
-using FLBAType = DataType<Type::FIXED_LEN_BYTE_ARRAY>;
-
-template <typename Type>
-inline std::string format_fwf(int width) {
-  std::stringstream ss;
-  ss << "%-" << width << type_traits<Type::type_num>::printf_code;
-  return ss.str();
-}
-
-PARQUET_EXPORT std::string CompressionToString(Compression::type t);
-
-PARQUET_EXPORT std::string EncodingToString(Encoding::type t);
-
-PARQUET_EXPORT std::string LogicalTypeToString(LogicalType::type t);
-
-PARQUET_EXPORT std::string TypeToString(Type::type t);
-
-PARQUET_EXPORT std::string FormatStatValue(Type::type parquet_type,
-                                           const std::string& val);
-
-/// \deprecated Since 1.5.0
-PARQUET_DEPRECATED("Use std::string instead of char* as input")
-PARQUET_EXPORT std::string FormatStatValue(Type::type parquet_type, const char* val);
-
-PARQUET_EXPORT int GetTypeByteSize(Type::type t);
-
-PARQUET_EXPORT SortOrder::type DefaultSortOrder(Type::type primitive);
-
-PARQUET_EXPORT SortOrder::type GetSortOrder(LogicalType::type converted,
-                                            Type::type primitive);
-
-}  // namespace parquet
-
-#endif  // PARQUET_TYPES_H
diff --git a/src/parquet/util/CMakeLists.txt b/src/parquet/util/CMakeLists.txt
deleted file mode 100644
index 7b13886..0000000
--- a/src/parquet/util/CMakeLists.txt
+++ /dev/null
@@ -1,49 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you 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.
-
-# Headers: util
-install(FILES
-  buffer-builder.h
-  comparison.h
-  logging.h
-  macros.h
-  memory.h
-  stopwatch.h
-  visibility.h
-  DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/parquet/util")
-
-if (PARQUET_BUILD_BENCHMARKS)
-  add_library(parquet_benchmark_main benchmark_main.cc)
-  if (APPLE)
-    target_link_libraries(parquet_benchmark_main
-      gbenchmark
-    )
-  elseif(WIN32)
-    target_link_libraries(parquet_benchmark_main
-      gbenchmark
-      shlwapi.lib # workaround for bug(?) in gbenchmark: unresolved external symbol __imp_SHGetValueA
-    )
-  else()
-    target_link_libraries(parquet_benchmark_main
-      gbenchmark
-      pthread
-    )
-  endif()
-endif()
-
-ADD_PARQUET_TEST(comparison-test)
-ADD_PARQUET_TEST(memory-test)
diff --git a/src/parquet/util/benchmark_main.cc b/src/parquet/util/benchmark_main.cc
deleted file mode 100644
index c9739af..0000000
--- a/src/parquet/util/benchmark_main.cc
+++ /dev/null
@@ -1,24 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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.
-
-#include "benchmark/benchmark.h"
-
-int main(int argc, char** argv) {
-  benchmark::Initialize(&argc, argv);
-  benchmark::RunSpecifiedBenchmarks();
-  return 0;
-}
diff --git a/src/parquet/util/buffer-builder.h b/src/parquet/util/buffer-builder.h
deleted file mode 100644
index 26f134e..0000000
--- a/src/parquet/util/buffer-builder.h
+++ /dev/null
@@ -1,58 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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.
-
-// Initially imported from Impala on 2016-02-23
-
-#ifndef PARQUET_UTIL_BUFFER_BUILDER_H
-#define PARQUET_UTIL_BUFFER_BUILDER_H
-
-#include <stdlib.h>
-#include <cstdint>
-
-namespace parquet {
-
-/// Utility class to build an in-memory buffer.
-class BufferBuilder {
- public:
-  BufferBuilder(uint8_t* dst_buffer, int dst_len)
-      : buffer_(dst_buffer), capacity_(dst_len), size_(0) {}
-
-  BufferBuilder(char* dst_buffer, int dst_len)
-      : buffer_(reinterpret_cast<uint8_t*>(dst_buffer)), capacity_(dst_len), size_(0) {}
-
-  inline void Append(const void* buffer, int len) {
-    memcpy(buffer_ + size_, buffer, len);
-    size_ += len;
-  }
-
-  template <typename T>
-  inline void Append(const T& v) {
-    Append(&v, sizeof(T));
-  }
-
-  int capacity() const { return capacity_; }
-  int size() const { return size_; }
-
- private:
-  uint8_t* buffer_;
-  int capacity_;
-  int size_;
-};
-
-}  // namespace parquet
-
-#endif  // PARQUET_UTIL_BUFFER_BUILDER_H
diff --git a/src/parquet/util/comparison-test.cc b/src/parquet/util/comparison-test.cc
deleted file mode 100644
index c05f934..0000000
--- a/src/parquet/util/comparison-test.cc
+++ /dev/null
@@ -1,247 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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.
-
-#include <gtest/gtest.h>
-
-#include <cstdint>
-#include <iostream>
-#include <vector>
-
-#include "parquet/schema.h"
-#include "parquet/types.h"
-#include "parquet/util/comparison.h"
-
-namespace parquet {
-
-namespace test {
-
-using parquet::schema::NodePtr;
-using parquet::schema::PrimitiveNode;
-
-static ByteArray ByteArrayFromString(const std::string& s) {
-  auto ptr = reinterpret_cast<const uint8_t*>(s.data());
-  return ByteArray(static_cast<uint32_t>(s.size()), ptr);
-}
-
-static FLBA FLBAFromString(const std::string& s) {
-  auto ptr = reinterpret_cast<const uint8_t*>(s.data());
-  return FLBA(ptr);
-}
-
-TEST(Comparison, signedByteArray) {
-  NodePtr node =
-      PrimitiveNode::Make("SignedByteArray", Repetition::REQUIRED, Type::BYTE_ARRAY);
-  ColumnDescriptor descr(node, 0, 0);
-
-  CompareDefaultByteArray less;
-
-  std::string s1 = "12345";
-  std::string s2 = "12345678";
-  ByteArray s1ba = ByteArrayFromString(s1);
-  ByteArray s2ba = ByteArrayFromString(s2);
-  ASSERT_TRUE(less(s1ba, s2ba));
-
-  // This is case where signed comparision UTF-8 (PARQUET-686) is incorrect
-  // This example is to only check signed comparison and not UTF-8.
-  s1 = u8"bügeln";
-  s2 = u8"braten";
-  s1ba = ByteArrayFromString(s1);
-  s2ba = ByteArrayFromString(s2);
-  ASSERT_TRUE(less(s1ba, s2ba));
-}
-
-TEST(Comparison, UnsignedByteArray) {
-  NodePtr node = PrimitiveNode::Make("UnsignedByteArray", Repetition::REQUIRED,
-                                     Type::BYTE_ARRAY, LogicalType::UTF8);
-  ColumnDescriptor descr(node, 0, 0);
-
-  // Check if UTF-8 is compared using unsigned correctly
-  CompareUnsignedByteArray uless;
-
-  std::string s1 = "arrange";
-  std::string s2 = "arrangement";
-  ByteArray s1ba = ByteArrayFromString(s1);
-  ByteArray s2ba = ByteArrayFromString(s2);
-  ASSERT_TRUE(uless(s1ba, s2ba));
-
-  // Multi-byte UTF-8 characters
-  s1 = u8"braten";
-  s2 = u8"bügeln";
-  s1ba = ByteArrayFromString(s1);
-  s2ba = ByteArrayFromString(s2);
-  ASSERT_TRUE(uless(s1ba, s2ba));
-
-  s1 = u8"ünk123456";  // ü = 252
-  s2 = u8"ănk123456";  // ă = 259
-  s1ba = ByteArrayFromString(s1);
-  s2ba = ByteArrayFromString(s2);
-  ASSERT_TRUE(uless(s1ba, s2ba));
-}
-
-TEST(Comparison, SignedFLBA) {
-  int size = 10;
-  NodePtr node = PrimitiveNode::Make("SignedFLBA", Repetition::REQUIRED,
-                                     Type::FIXED_LEN_BYTE_ARRAY, LogicalType::NONE, size);
-  ColumnDescriptor descr(node, 0, 0);
-
-  CompareDefaultFLBA less(descr.type_length());
-
-  std::string s1 = "Anti123456";
-  std::string s2 = "Bunkd123456";
-  FLBA s1flba = FLBAFromString(s1);
-  FLBA s2flba = FLBAFromString(s2);
-  ASSERT_TRUE(less(s1flba, s2flba));
-
-  s1 = "Bünk123456";
-  s2 = "Bunk123456";
-  s1flba = FLBAFromString(s1);
-  s2flba = FLBAFromString(s2);
-  ASSERT_TRUE(less(s1flba, s2flba));
-}
-
-TEST(Comparison, UnsignedFLBA) {
-  int size = 10;
-  NodePtr node = PrimitiveNode::Make("UnsignedFLBA", Repetition::REQUIRED,
-                                     Type::FIXED_LEN_BYTE_ARRAY, LogicalType::NONE, size);
-  ColumnDescriptor descr(node, 0, 0);
-
-  CompareUnsignedFLBA uless(descr.type_length());
-
-  std::string s1 = "Anti123456";
-  std::string s2 = "Bunkd123456";
-  FLBA s1flba = FLBAFromString(s1);
-  FLBA s2flba = FLBAFromString(s2);
-  ASSERT_TRUE(uless(s1flba, s2flba));
-
-  s1 = "Bunk123456";
-  s2 = "Bünk123456";
-  s1flba = FLBAFromString(s1);
-  s2flba = FLBAFromString(s2);
-  ASSERT_TRUE(uless(s1flba, s2flba));
-}
-
-TEST(Comparison, SignedInt96) {
-  parquet::Int96 a{{1, 41, 14}}, b{{1, 41, 42}};
-  parquet::Int96 aa{{1, 41, 14}}, bb{{1, 41, 14}};
-  parquet::Int96 aaa{{1, 41, static_cast<uint32_t>(-14)}}, bbb{{1, 41, 42}};
-
-  NodePtr node = PrimitiveNode::Make("SignedInt96", Repetition::REQUIRED, Type::INT96);
-  ColumnDescriptor descr(node, 0, 0);
-
-  CompareDefaultInt96 less;
-
-  ASSERT_TRUE(less(a, b));
-  ASSERT_TRUE(!less(aa, bb) && !less(bb, aa));
-  ASSERT_TRUE(less(aaa, bbb));
-}
-
-TEST(Comparison, UnsignedInt96) {
-  parquet::Int96 a{{1, 41, 14}}, b{{1, static_cast<uint32_t>(-41), 42}};
-  parquet::Int96 aa{{1, 41, 14}}, bb{{1, 41, static_cast<uint32_t>(-14)}};
-  parquet::Int96 aaa, bbb;
-
-  NodePtr node = PrimitiveNode::Make("UnsignedInt96", Repetition::REQUIRED, Type::INT96);
-  ColumnDescriptor descr(node, 0, 0);
-
-  CompareUnsignedInt96 uless;
-
-  ASSERT_TRUE(uless(a, b));
-  ASSERT_TRUE(uless(aa, bb));
-
-  // INT96 Timestamp
-  aaa.value[2] = 2451545;  // 2000-01-01
-  bbb.value[2] = 2451546;  // 2000-01-02
-  // 12 hours + 34 minutes + 56 seconds.
-  reinterpret_cast<uint64_t*>(&aaa.value[0])[0] = 45296000000000;
-  // 12 hours + 34 minutes + 50 seconds.
-  reinterpret_cast<uint64_t*>(&bbb.value[0])[0] = 45290000000000;
-  ASSERT_TRUE(uless(aaa, bbb));
-
-  aaa.value[2] = 2451545;  // 2000-01-01
-  bbb.value[2] = 2451545;  // 2000-01-01
-  // 11 hours + 34 minutes + 56 seconds.
-  reinterpret_cast<uint64_t*>(&aaa.value[0])[0] = 41696000000000;
-  // 12 hours + 34 minutes + 50 seconds.
-  reinterpret_cast<uint64_t*>(&bbb.value[0])[0] = 45290000000000;
-  ASSERT_TRUE(uless(aaa, bbb));
-
-  aaa.value[2] = 2451545;  // 2000-01-01
-  bbb.value[2] = 2451545;  // 2000-01-01
-  // 12 hours + 34 minutes + 55 seconds.
-  reinterpret_cast<uint64_t*>(&aaa.value[0])[0] = 45295000000000;
-  // 12 hours + 34 minutes + 56 seconds.
-  reinterpret_cast<uint64_t*>(&bbb.value[0])[0] = 45296000000000;
-  ASSERT_TRUE(uless(aaa, bbb));
-}
-
-TEST(Comparison, SignedInt64) {
-  int64_t a = 1, b = 4;
-  int64_t aa = 1, bb = 1;
-  int64_t aaa = -1, bbb = 1;
-
-  NodePtr node = PrimitiveNode::Make("SignedInt64", Repetition::REQUIRED, Type::INT64);
-  ColumnDescriptor descr(node, 0, 0);
-
-  CompareDefaultInt64 less;
-
-  ASSERT_TRUE(less(a, b));
-  ASSERT_TRUE(!less(aa, bb) && !less(bb, aa));
-  ASSERT_TRUE(less(aaa, bbb));
-}
-
-TEST(Comparison, UnsignedInt64) {
-  uint64_t a = 1, b = 4;
-  uint64_t aa = 1, bb = 1;
-  uint64_t aaa = 1, bbb = -1;
-
-  NodePtr node = PrimitiveNode::Make("UnsignedInt64", Repetition::REQUIRED, Type::INT64);
-  ColumnDescriptor descr(node, 0, 0);
-
-  CompareUnsignedInt64 less;
-
-  ASSERT_TRUE(less(a, b));
-  ASSERT_TRUE(!less(aa, bb) && !less(bb, aa));
-  ASSERT_TRUE(less(aaa, bbb));
-}
-
-TEST(Comparison, UnsignedInt32) {
-  uint32_t a = 1, b = 4;
-  uint32_t aa = 1, bb = 1;
-  uint32_t aaa = 1, bbb = -1;
-
-  NodePtr node = PrimitiveNode::Make("UnsignedInt32", Repetition::REQUIRED, Type::INT32);
-  ColumnDescriptor descr(node, 0, 0);
-
-  CompareUnsignedInt32 less;
-
-  ASSERT_TRUE(less(a, b));
-  ASSERT_TRUE(!less(aa, bb) && !less(bb, aa));
-  ASSERT_TRUE(less(aaa, bbb));
-}
-
-TEST(Comparison, UnknownSortOrder) {
-  NodePtr node =
-      PrimitiveNode::Make("Unknown", Repetition::REQUIRED, Type::FIXED_LEN_BYTE_ARRAY,
-                          LogicalType::INTERVAL, 12);
-  ColumnDescriptor descr(node, 0, 0);
-
-  ASSERT_THROW(Comparator::Make(&descr), ParquetException);
-}
-
-}  // namespace test
-
-}  // namespace parquet
diff --git a/src/parquet/util/comparison.cc b/src/parquet/util/comparison.cc
deleted file mode 100644
index a0768b3..0000000
--- a/src/parquet/util/comparison.cc
+++ /dev/null
@@ -1,75 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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.
-
-#include <algorithm>
-
-#include "parquet/exception.h"
-#include "parquet/schema.h"
-#include "parquet/types.h"
-#include "parquet/util/comparison.h"
-
-namespace parquet {
-
-std::shared_ptr<Comparator> Comparator::Make(const ColumnDescriptor* descr) {
-  if (SortOrder::SIGNED == descr->sort_order()) {
-    switch (descr->physical_type()) {
-      case Type::BOOLEAN:
-        return std::make_shared<CompareDefaultBoolean>();
-      case Type::INT32:
-        return std::make_shared<CompareDefaultInt32>();
-      case Type::INT64:
-        return std::make_shared<CompareDefaultInt64>();
-      case Type::FLOAT:
-        return std::make_shared<CompareDefaultFloat>();
-      case Type::DOUBLE:
-        return std::make_shared<CompareDefaultDouble>();
-      case Type::BYTE_ARRAY:
-        return std::make_shared<CompareDefaultByteArray>();
-      case Type::FIXED_LEN_BYTE_ARRAY:
-        return std::make_shared<CompareDefaultFLBA>(descr->type_length());
-      default:
-        ParquetException::NYI("Signed Compare not implemented");
-    }
-  } else if (SortOrder::UNSIGNED == descr->sort_order()) {
-    switch (descr->physical_type()) {
-      case Type::INT32:
-        return std::make_shared<CompareUnsignedInt32>();
-      case Type::INT64:
-        return std::make_shared<CompareUnsignedInt64>();
-      case Type::BYTE_ARRAY:
-        return std::make_shared<CompareUnsignedByteArray>();
-      case Type::FIXED_LEN_BYTE_ARRAY:
-        return std::make_shared<CompareUnsignedFLBA>(descr->type_length());
-      default:
-        ParquetException::NYI("Unsigned Compare not implemented");
-    }
-  } else {
-    throw ParquetException("UNKNOWN Sort Order");
-  }
-  return nullptr;
-}
-
-template class PARQUET_TEMPLATE_EXPORT CompareDefault<BooleanType>;
-template class PARQUET_TEMPLATE_EXPORT CompareDefault<Int32Type>;
-template class PARQUET_TEMPLATE_EXPORT CompareDefault<Int64Type>;
-template class PARQUET_TEMPLATE_EXPORT CompareDefault<Int96Type>;
-template class PARQUET_TEMPLATE_EXPORT CompareDefault<FloatType>;
-template class PARQUET_TEMPLATE_EXPORT CompareDefault<DoubleType>;
-template class PARQUET_TEMPLATE_EXPORT CompareDefault<ByteArrayType>;
-template class PARQUET_TEMPLATE_EXPORT CompareDefault<FLBAType>;
-
-}  // namespace parquet
diff --git a/src/parquet/util/comparison.h b/src/parquet/util/comparison.h
deleted file mode 100644
index 7070a0f..0000000
--- a/src/parquet/util/comparison.h
+++ /dev/null
@@ -1,166 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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.
-
-#ifndef PARQUET_UTIL_COMPARISON_H
-#define PARQUET_UTIL_COMPARISON_H
-
-#include <algorithm>
-
-#include "parquet/exception.h"
-#include "parquet/schema.h"
-#include "parquet/types.h"
-
-namespace parquet {
-
-class PARQUET_EXPORT Comparator {
- public:
-  virtual ~Comparator() {}
-  static std::shared_ptr<Comparator> Make(const ColumnDescriptor* descr);
-};
-
-// The default comparison is SIGNED
-template <typename DType>
-class PARQUET_EXPORT CompareDefault : public Comparator {
- public:
-  typedef typename DType::c_type T;
-  CompareDefault() {}
-  virtual bool operator()(const T& a, const T& b) { return a < b; }
-};
-
-template <>
-class PARQUET_EXPORT CompareDefault<Int96Type> : public Comparator {
- public:
-  CompareDefault() {}
-  virtual bool operator()(const Int96& a, const Int96& b) {
-    // Only the MSB bit is by Signed comparison
-    // For little-endian, this is the last bit of Int96 type
-    const int32_t amsb = static_cast<const int32_t>(a.value[2]);
-    const int32_t bmsb = static_cast<const int32_t>(b.value[2]);
-    if (amsb != bmsb) {
-      return (amsb < bmsb);
-    } else if (a.value[1] != b.value[1]) {
-      return (a.value[1] < b.value[1]);
-    }
-    return (a.value[0] < b.value[0]);
-  }
-};
-
-template <>
-class PARQUET_EXPORT CompareDefault<ByteArrayType> : public Comparator {
- public:
-  CompareDefault() {}
-  virtual bool operator()(const ByteArray& a, const ByteArray& b) {
-    const int8_t* aptr = reinterpret_cast<const int8_t*>(a.ptr);
-    const int8_t* bptr = reinterpret_cast<const int8_t*>(b.ptr);
-    return std::lexicographical_compare(aptr, aptr + a.len, bptr, bptr + b.len);
-  }
-};
-
-template <>
-class PARQUET_EXPORT CompareDefault<FLBAType> : public Comparator {
- public:
-  explicit CompareDefault(int length) : type_length_(length) {}
-  virtual bool operator()(const FLBA& a, const FLBA& b) {
-    const int8_t* aptr = reinterpret_cast<const int8_t*>(a.ptr);
-    const int8_t* bptr = reinterpret_cast<const int8_t*>(b.ptr);
-    return std::lexicographical_compare(aptr, aptr + type_length_, bptr,
-                                        bptr + type_length_);
-  }
-  int32_t type_length_;
-};
-
-typedef CompareDefault<BooleanType> CompareDefaultBoolean;
-typedef CompareDefault<Int32Type> CompareDefaultInt32;
-typedef CompareDefault<Int64Type> CompareDefaultInt64;
-typedef CompareDefault<Int96Type> CompareDefaultInt96;
-typedef CompareDefault<FloatType> CompareDefaultFloat;
-typedef CompareDefault<DoubleType> CompareDefaultDouble;
-typedef CompareDefault<ByteArrayType> CompareDefaultByteArray;
-typedef CompareDefault<FLBAType> CompareDefaultFLBA;
-
-#if defined(__GNUC__) && !defined(__clang__)
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wattributes"
-#endif
-
-PARQUET_EXTERN_TEMPLATE CompareDefault<BooleanType>;
-PARQUET_EXTERN_TEMPLATE CompareDefault<Int32Type>;
-PARQUET_EXTERN_TEMPLATE CompareDefault<Int64Type>;
-PARQUET_EXTERN_TEMPLATE CompareDefault<Int96Type>;
-PARQUET_EXTERN_TEMPLATE CompareDefault<FloatType>;
-PARQUET_EXTERN_TEMPLATE CompareDefault<DoubleType>;
-PARQUET_EXTERN_TEMPLATE CompareDefault<ByteArrayType>;
-PARQUET_EXTERN_TEMPLATE CompareDefault<FLBAType>;
-
-#if defined(__GNUC__) && !defined(__clang__)
-#pragma GCC diagnostic pop
-#endif
-
-// Define Unsigned Comparators
-class PARQUET_EXPORT CompareUnsignedInt32 : public CompareDefaultInt32 {
- public:
-  bool operator()(const int32_t& a, const int32_t& b) override {
-    const uint32_t ua = a;
-    const uint32_t ub = b;
-    return (ua < ub);
-  }
-};
-
-class PARQUET_EXPORT CompareUnsignedInt64 : public CompareDefaultInt64 {
- public:
-  bool operator()(const int64_t& a, const int64_t& b) override {
-    const uint64_t ua = a;
-    const uint64_t ub = b;
-    return (ua < ub);
-  }
-};
-
-class PARQUET_EXPORT CompareUnsignedInt96 : public CompareDefaultInt96 {
- public:
-  bool operator()(const Int96& a, const Int96& b) override {
-    if (a.value[2] != b.value[2]) {
-      return (a.value[2] < b.value[2]);
-    } else if (a.value[1] != b.value[1]) {
-      return (a.value[1] < b.value[1]);
-    }
-    return (a.value[0] < b.value[0]);
-  }
-};
-
-class PARQUET_EXPORT CompareUnsignedByteArray : public CompareDefaultByteArray {
- public:
-  bool operator()(const ByteArray& a, const ByteArray& b) override {
-    const uint8_t* aptr = reinterpret_cast<const uint8_t*>(a.ptr);
-    const uint8_t* bptr = reinterpret_cast<const uint8_t*>(b.ptr);
-    return std::lexicographical_compare(aptr, aptr + a.len, bptr, bptr + b.len);
-  }
-};
-
-class PARQUET_EXPORT CompareUnsignedFLBA : public CompareDefaultFLBA {
- public:
-  explicit CompareUnsignedFLBA(int length) : CompareDefaultFLBA(length) {}
-  bool operator()(const FLBA& a, const FLBA& b) override {
-    const uint8_t* aptr = reinterpret_cast<const uint8_t*>(a.ptr);
-    const uint8_t* bptr = reinterpret_cast<const uint8_t*>(b.ptr);
-    return std::lexicographical_compare(aptr, aptr + type_length_, bptr,
-                                        bptr + type_length_);
-  }
-};
-
-}  // namespace parquet
-
-#endif  // PARQUET_UTIL_COMPARISON_H
diff --git a/src/parquet/util/crypto.cc b/src/parquet/util/crypto.cc
deleted file mode 100644
index 59383d1..0000000
--- a/src/parquet/util/crypto.cc
+++ /dev/null
@@ -1,369 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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.
-
-#include "parquet/util/crypto.h"
-#include <openssl/aes.h>
-#include <openssl/evp.h>
-#include <openssl/rand.h>
-#include <algorithm>
-#include <iostream>
-#include <memory>
-#include <sstream>
-#include <string>
-#include "parquet/exception.h"
-
-using parquet::ParquetException;
-
-namespace parquet_encryption {
-
-constexpr int aesGcm = 0;
-constexpr int aesCtr = 1;
-constexpr int encryptType = 0;
-constexpr int decryptType = 1;
-constexpr int gcmTagLen = 16;
-constexpr int gcmIvLen = 12;
-constexpr int ctrIvLen = 16;
-constexpr int rndMaxBytes = 32;
-
-#define ENCRYPT_INIT(CTX, ALG)                                        \
-  if (1 != EVP_EncryptInit_ex(CTX, ALG, nullptr, nullptr, nullptr)) { \
-    throw ParquetException("Couldn't init ALG encryption");           \
-  }
-
-#define DECRYPT_INIT(CTX, ALG)                                        \
-  if (1 != EVP_DecryptInit_ex(CTX, ALG, nullptr, nullptr, nullptr)) { \
-    throw ParquetException("Couldn't init ALG decryption");           \
-  }
-
-class EvpCipher {
- public:
-  explicit EvpCipher(int cipher, int key_len, int type) {
-    ctx_ = nullptr;
-
-    if (aesGcm != cipher && aesCtr != cipher) {
-      std::stringstream ss;
-      ss << "Wrong cipher: " << cipher;
-      throw ParquetException(ss.str());
-    }
-
-    if (16 != key_len && 24 != key_len && 32 != key_len) {
-      std::stringstream ss;
-      ss << "Wrong key length: " << key_len;
-      throw ParquetException(ss.str());
-    }
-
-    if (encryptType != type && decryptType != type) {
-      std::stringstream ss;
-      ss << "Wrong cipher type: " << type;
-      throw ParquetException(ss.str());
-    }
-
-    ctx_ = EVP_CIPHER_CTX_new();
-    if (nullptr == ctx_) {
-      throw ParquetException("Couldn't init cipher context");
-    }
-
-    if (aesGcm == cipher) {
-      // Init AES-GCM with specified key length
-      if (16 == key_len) {
-        if (encryptType == type) {
-          ENCRYPT_INIT(ctx_, EVP_aes_128_gcm());
-        } else {
-          DECRYPT_INIT(ctx_, EVP_aes_128_gcm());
-        }
-      } else if (24 == key_len) {
-        if (encryptType == type) {
-          ENCRYPT_INIT(ctx_, EVP_aes_192_gcm());
-        } else {
-          DECRYPT_INIT(ctx_, EVP_aes_192_gcm());
-        }
-      } else if (32 == key_len) {
-        if (encryptType == type) {
-          ENCRYPT_INIT(ctx_, EVP_aes_256_gcm());
-        } else {
-          DECRYPT_INIT(ctx_, EVP_aes_256_gcm());
-        }
-      }
-    } else {
-      // Init AES-CTR with specified key length
-      if (16 == key_len) {
-        if (encryptType == type) {
-          ENCRYPT_INIT(ctx_, EVP_aes_128_ctr());
-        } else {
-          DECRYPT_INIT(ctx_, EVP_aes_128_ctr());
-        }
-      } else if (24 == key_len) {
-        if (encryptType == type) {
-          ENCRYPT_INIT(ctx_, EVP_aes_192_ctr());
-        } else {
-          DECRYPT_INIT(ctx_, EVP_aes_192_ctr());
-        }
-      } else if (32 == key_len) {
-        if (encryptType == type) {
-          ENCRYPT_INIT(ctx_, EVP_aes_256_ctr());
-        } else {
-          DECRYPT_INIT(ctx_, EVP_aes_256_ctr());
-        }
-      }
-    }
-  }
-
-  EVP_CIPHER_CTX* get() { return ctx_; }
-
-  ~EvpCipher() {
-    if (nullptr != ctx_) {
-      EVP_CIPHER_CTX_free(ctx_);
-    }
-  }
-
- private:
-  EVP_CIPHER_CTX* ctx_;
-};
-
-int gcm_encrypt(const uint8_t* plaintext, int plaintext_len, uint8_t* key, int key_len,
-                uint8_t* aad, int aad_len, uint8_t* ciphertext) {
-  int len;
-  int ciphertext_len;
-
-  uint8_t tag[gcmTagLen];
-  memset(tag, 0, gcmTagLen);
-  uint8_t iv[gcmIvLen];
-  memset(iv, 0, gcmIvLen);
-
-  // Random IV
-  RAND_load_file("/dev/urandom", rndMaxBytes);
-  RAND_bytes(iv, sizeof(iv));
-
-  // Init cipher context
-  EvpCipher cipher(aesGcm, key_len, encryptType);
-
-  // Setting key and IV
-  if (1 != EVP_EncryptInit_ex(cipher.get(), nullptr, nullptr, key, iv)) {
-    throw ParquetException("Couldn't set key and IV");
-  }
-
-  // Setting additional authenticated data
-  if ((nullptr != aad) &&
-      (1 != EVP_EncryptUpdate(cipher.get(), nullptr, &len, aad, aad_len))) {
-    throw ParquetException("Couldn't set AAD");
-  }
-
-  // Encryption
-  if (1 != EVP_EncryptUpdate(cipher.get(), ciphertext + gcmIvLen, &len, plaintext,
-                             plaintext_len)) {
-    throw ParquetException("Failed encryption update");
-  }
-
-  ciphertext_len = len;
-
-  // Finalization
-  if (1 != EVP_EncryptFinal_ex(cipher.get(), ciphertext + gcmIvLen + len, &len)) {
-    throw ParquetException("Failed encryption finalization");
-  }
-
-  ciphertext_len += len;
-
-  // Getting the tag
-  if (1 != EVP_CIPHER_CTX_ctrl(cipher.get(), EVP_CTRL_GCM_GET_TAG, gcmTagLen, tag)) {
-    throw ParquetException("Couldn't get AES-GCM tag");
-  }
-
-  // Copying the IV and tag to ciphertext
-  std::copy(iv, iv + gcmIvLen, ciphertext);
-  std::copy(tag, tag + gcmTagLen, ciphertext + gcmIvLen + ciphertext_len);
-
-  return gcmIvLen + ciphertext_len + gcmTagLen;
-}
-
-int ctr_encrypt(const uint8_t* plaintext, int plaintext_len, uint8_t* key, int key_len,
-                uint8_t* ciphertext) {
-  int len;
-  int ciphertext_len;
-
-  uint8_t iv[ctrIvLen];
-  memset(iv, 0, ctrIvLen);
-
-  // Random IV
-  RAND_load_file("/dev/urandom", rndMaxBytes);
-  RAND_bytes(iv, sizeof(iv));
-
-  // Init cipher context
-  EvpCipher cipher(aesCtr, key_len, encryptType);
-
-  // Setting key and IV
-  if (1 != EVP_EncryptInit_ex(cipher.get(), nullptr, nullptr, key, iv)) {
-    throw ParquetException("Couldn't set key and IV");
-  }
-
-  // Encryption
-  if (1 != EVP_EncryptUpdate(cipher.get(), ciphertext + ctrIvLen, &len, plaintext,
-                             plaintext_len)) {
-    throw ParquetException("Failed encryption update");
-  }
-
-  ciphertext_len = len;
-
-  // Finalization
-  if (1 != EVP_EncryptFinal_ex(cipher.get(), ciphertext + ctrIvLen + len, &len)) {
-    throw ParquetException("Failed encryption finalization");
-  }
-
-  ciphertext_len += len;
-
-  // Copying the IV ciphertext
-  std::copy(iv, iv + ctrIvLen, ciphertext);
-
-  return ctrIvLen + ciphertext_len;
-}
-
-int Encrypt(Encryption::type alg_id, bool metadata, const uint8_t* plaintext,
-            int plaintext_len, uint8_t* key, int key_len, uint8_t* aad, int aad_len,
-            uint8_t* ciphertext) {
-  if (Encryption::AES_GCM_V1 != alg_id && Encryption::AES_GCM_CTR_V1 != alg_id) {
-    std::stringstream ss;
-    ss << "Crypto algorithm " << alg_id << " is not supported";
-    throw ParquetException(ss.str());
-  }
-
-  if (metadata || (Encryption::AES_GCM_V1 == alg_id)) {
-    return gcm_encrypt(plaintext, plaintext_len, key, key_len, aad, aad_len, ciphertext);
-  }
-
-  // Data (page) encryption with AES_GCM_CTR_V1
-  return ctr_encrypt(plaintext, plaintext_len, key, key_len, ciphertext);
-}
-
-int Encrypt(std::shared_ptr<EncryptionProperties> encryption_props, bool metadata,
-            const uint8_t* plaintext, int plaintext_len, uint8_t* ciphertext) {
-  return Encrypt(encryption_props->algorithm(), metadata, plaintext, plaintext_len,
-                 encryption_props->key_bytes(), encryption_props->key_length(),
-                 encryption_props->aad_bytes(), encryption_props->aad_length(),
-                 ciphertext);
-}
-
-int gcm_decrypt(const uint8_t* ciphertext, int ciphertext_len, uint8_t* key, int key_len,
-                uint8_t* aad, int aad_len, uint8_t* plaintext) {
-  int len;
-  int plaintext_len;
-
-  uint8_t tag[gcmTagLen];
-  memset(tag, 0, gcmTagLen);
-  uint8_t iv[gcmIvLen];
-  memset(iv, 0, gcmIvLen);
-
-  // Extracting IV and tag
-  std::copy(ciphertext, ciphertext + gcmIvLen, iv);
-  std::copy(ciphertext + ciphertext_len - gcmTagLen, ciphertext + ciphertext_len, tag);
-
-  // Init cipher context
-  EvpCipher cipher(aesGcm, key_len, decryptType);
-
-  // Setting key and IV
-  if (1 != EVP_DecryptInit_ex(cipher.get(), nullptr, nullptr, key, iv)) {
-    throw ParquetException("Couldn't set key and IV");
-  }
-
-  // Setting additional authenticated data
-  if ((nullptr != aad) &&
-      (1 != EVP_DecryptUpdate(cipher.get(), nullptr, &len, aad, aad_len))) {
-    throw ParquetException("Couldn't set AAD");
-  }
-
-  // Decryption
-  if (!EVP_DecryptUpdate(cipher.get(), plaintext, &len, ciphertext + gcmIvLen,
-                         ciphertext_len - gcmIvLen - gcmTagLen)) {
-    throw ParquetException("Failed decryption update");
-  }
-
-  plaintext_len = len;
-
-  // Checking the tag (authentication)
-  if (!EVP_CIPHER_CTX_ctrl(cipher.get(), EVP_CTRL_GCM_SET_TAG, gcmTagLen, tag)) {
-    throw ParquetException("Failed authentication");
-  }
-
-  // Finalization
-  if (1 != EVP_DecryptFinal_ex(cipher.get(), plaintext + len, &len)) {
-    throw ParquetException("Failed decryption finalization");
-  }
-
-  plaintext_len += len;
-  return plaintext_len;
-}
-
-int ctr_decrypt(const uint8_t* ciphertext, int ciphertext_len, uint8_t* key, int key_len,
-                uint8_t* plaintext) {
-  int len;
-  int plaintext_len;
-
-  uint8_t iv[ctrIvLen];
-  memset(iv, 0, ctrIvLen);
-
-  // Extracting IV and tag
-  std::copy(ciphertext, ciphertext + ctrIvLen, iv);
-
-  // Init cipher context
-  EvpCipher cipher(aesCtr, key_len, decryptType);
-
-  // Setting key and IV
-  if (1 != EVP_DecryptInit_ex(cipher.get(), nullptr, nullptr, key, iv)) {
-    throw ParquetException("Couldn't set key and IV");
-  }
-
-  // Decryption
-  if (!EVP_DecryptUpdate(cipher.get(), plaintext, &len, ciphertext + ctrIvLen,
-                         ciphertext_len - ctrIvLen)) {
-    throw ParquetException("Failed decryption update");
-  }
-
-  plaintext_len = len;
-
-  // Finalization
-  if (1 != EVP_DecryptFinal_ex(cipher.get(), plaintext + len, &len)) {
-    throw ParquetException("Failed decryption finalization");
-  }
-
-  plaintext_len += len;
-  return plaintext_len;
-}
-
-int Decrypt(Encryption::type alg_id, bool metadata, const uint8_t* ciphertext,
-            int ciphertext_len, uint8_t* key, int key_len, uint8_t* aad, int aad_len,
-            uint8_t* plaintext) {
-  if (Encryption::AES_GCM_V1 != alg_id && Encryption::AES_GCM_CTR_V1 != alg_id) {
-    std::stringstream ss;
-    ss << "Crypto algorithm " << alg_id << " is not supported";
-    throw ParquetException(ss.str());
-  }
-
-  if (metadata || (Encryption::AES_GCM_V1 == alg_id)) {
-    return gcm_decrypt(ciphertext, ciphertext_len, key, key_len, aad, aad_len, plaintext);
-  }
-
-  // Data (page) decryption with AES_GCM_CTR_V1
-  return ctr_decrypt(ciphertext, ciphertext_len, key, key_len, plaintext);
-}
-
-int Decrypt(std::shared_ptr<EncryptionProperties> encryption_props, bool metadata,
-            const uint8_t* ciphertext, int ciphertext_len, uint8_t* plaintext) {
-  return Decrypt(encryption_props->algorithm(), metadata, ciphertext, ciphertext_len,
-                 encryption_props->key_bytes(), encryption_props->key_length(),
-                 encryption_props->aad_bytes(), encryption_props->aad_length(),
-                 plaintext);
-}
-
-}  // namespace parquet_encryption
diff --git a/src/parquet/util/crypto.h b/src/parquet/util/crypto.h
deleted file mode 100644
index d3beb10..0000000
--- a/src/parquet/util/crypto.h
+++ /dev/null
@@ -1,44 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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.
-
-#ifndef PARQUET_UTIL_CRYPTO_H
-#define PARQUET_UTIL_CRYPTO_H
-
-#include "parquet/properties.h"
-#include "parquet/types.h"
-
-using parquet::Encryption;
-using parquet::EncryptionProperties;
-
-namespace parquet_encryption {
-
-int Encrypt(Encryption::type alg_id, bool metadata, const uint8_t* plaintext,
-            int plaintext_len, uint8_t* key, int key_len, uint8_t* aad, int aad_len,
-            uint8_t* ciphertext);
-
-int Encrypt(std::shared_ptr<EncryptionProperties> encryption_props, bool metadata,
-            const uint8_t* plaintext, int plaintext_len, uint8_t* ciphertext);
-
-int Decrypt(Encryption::type alg_id, bool metadata, const uint8_t* ciphertext,
-            int ciphertext_len, uint8_t* key, int key_len, uint8_t* aad, int aad_len,
-            uint8_t* plaintext);
-
-int Decrypt(std::shared_ptr<EncryptionProperties> encryption_props, bool metadata,
-            const uint8_t* ciphertext, int ciphertext_len, uint8_t* plaintext);
-}  // namespace parquet_encryption
-
-#endif  // PARQUET_UTIL_CRYPTO_H
diff --git a/src/parquet/util/logging.h b/src/parquet/util/logging.h
deleted file mode 100644
index e2c7abb..0000000
--- a/src/parquet/util/logging.h
+++ /dev/null
@@ -1,23 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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.
-
-#ifndef PARQUET_UTIL_LOGGING_H
-#define PARQUET_UTIL_LOGGING_H
-
-#include "arrow/util/logging.h"
-
-#endif  // PARQUET_UTIL_LOGGING_H
diff --git a/src/parquet/util/macros.h b/src/parquet/util/macros.h
deleted file mode 100644
index c28b2fa..0000000
--- a/src/parquet/util/macros.h
+++ /dev/null
@@ -1,86 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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.
-
-#ifndef PARQUET_UTIL_MACROS_H
-#define PARQUET_UTIL_MACROS_H
-
-// Useful macros from elsewhere
-
-// From Google gutil
-#ifndef DISALLOW_COPY_AND_ASSIGN
-#define DISALLOW_COPY_AND_ASSIGN(TypeName) \
-  TypeName(const TypeName&) = delete;      \
-  void operator=(const TypeName&) = delete
-#endif
-
-#if defined(__GNUC__)
-#define PARQUET_PREDICT_FALSE(x) (__builtin_expect(x, 0))
-#define PARQUET_PREDICT_TRUE(x) (__builtin_expect(!!(x), 1))
-#define PARQUET_NORETURN __attribute__((noreturn))
-#define PARQUET_PREFETCH(addr) __builtin_prefetch(addr)
-#elif defined(_MSC_VER)
-#define PARQUET_NORETURN __declspec(noreturn)
-#define PARQUET_PREDICT_FALSE(x) x
-#define PARQUET_PREDICT_TRUE(x) x
-#define PARQUET_PREFETCH(addr)
-#else
-#define PARQUET_NORETURN
-#define PARQUET_PREDICT_FALSE(x) x
-#define PARQUET_PREDICT_TRUE(x) x
-#define PARQUET_PREFETCH(addr)
-#endif
-
-// ----------------------------------------------------------------------
-// From googletest
-
-// When you need to test the private or protected members of a class,
-// use the FRIEND_TEST macro to declare your tests as friends of the
-// class.  For example:
-//
-// class MyClass {
-//  private:
-//   void MyMethod();
-//   FRIEND_TEST(MyClassTest, MyMethod);
-// };
-//
-// class MyClassTest : public testing::Test {
-//   // ...
-// };
-//
-// TEST_F(MyClassTest, MyMethod) {
-//   // Can call MyClass::MyMethod() here.
-// }
-
-#define FRIEND_TEST(test_case_name, test_name) \
-  friend class test_case_name##_##test_name##_Test
-
-// clang-format off
-// [[deprecated]] is only available in C++14, use this for the time being
-// This macro takes an optional deprecation message
-#if __cplusplus <= 201103L
-# ifdef __GNUC__
-#  define PARQUET_DEPRECATED(...) __attribute__((deprecated(__VA_ARGS__)))
-# elif defined(_MSC_VER)
-#  define PARQUET_DEPRECATED(...) __declspec(deprecated(__VA_ARGS__))
-# else
-#  define PARQUET_DEPRECATED(...)
-# endif
-#else
-#  define PARQUET_DEPRECATED(...) [[deprecated(__VA_ARGS__)]]
-#endif
-
-#endif  // PARQUET_UTIL_MACROS_H
diff --git a/src/parquet/util/memory-test.cc b/src/parquet/util/memory-test.cc
deleted file mode 100644
index bfd685d..0000000
--- a/src/parquet/util/memory-test.cc
+++ /dev/null
@@ -1,362 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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.
-
-#include <cstdint>
-#include <cstdio>
-#include <memory>
-#include <string>
-#include <vector>
-
-#include <gtest/gtest.h>
-
-#include "parquet/exception.h"
-#include "parquet/util/memory.h"
-#include "parquet/util/test-common.h"
-
-using arrow::default_memory_pool;
-using arrow::MemoryPool;
-
-namespace parquet {
-
-class TestBuffer : public ::testing::Test {};
-
-// Utility class to call private functions on MemPool.
-class ChunkedAllocatorTest {
- public:
-  static bool CheckIntegrity(ChunkedAllocator* pool, bool current_chunk_empty) {
-    return pool->CheckIntegrity(current_chunk_empty);
-  }
-
-  static const int INITIAL_CHUNK_SIZE = ChunkedAllocator::INITIAL_CHUNK_SIZE;
-  static const int MAX_CHUNK_SIZE = ChunkedAllocator::MAX_CHUNK_SIZE;
-};
-
-const int ChunkedAllocatorTest::INITIAL_CHUNK_SIZE;
-const int ChunkedAllocatorTest::MAX_CHUNK_SIZE;
-
-TEST(ChunkedAllocatorTest, Basic) {
-  ChunkedAllocator p;
-  ChunkedAllocator p2;
-  ChunkedAllocator p3;
-
-  for (int iter = 0; iter < 2; ++iter) {
-    // allocate a total of 24K in 32-byte pieces (for which we only request 25 bytes)
-    for (int i = 0; i < 768; ++i) {
-      // pads to 32 bytes
-      p.Allocate(25);
-    }
-    // we handed back 24K
-    EXPECT_EQ(24 * 1024, p.total_allocated_bytes());
-    // .. and allocated 28K of chunks (4, 8, 16)
-    EXPECT_EQ(28 * 1024, p.GetTotalChunkSizes());
-
-    // we're passing on the first two chunks, containing 12K of data; we're left with
-    // one chunk of 16K containing 12K of data
-    p2.AcquireData(&p, true);
-    EXPECT_EQ(12 * 1024, p.total_allocated_bytes());
-    EXPECT_EQ(16 * 1024, p.GetTotalChunkSizes());
-
-    // we allocate 8K, for which there isn't enough room in the current chunk,
-    // so another one is allocated (32K)
-    p.Allocate(8 * 1024);
-    EXPECT_EQ((16 + 32) * 1024, p.GetTotalChunkSizes());
-
-    // we allocate 65K, which doesn't fit into the current chunk or the default
-    // size of the next allocated chunk (64K)
-    p.Allocate(65 * 1024);
-    EXPECT_EQ((12 + 8 + 65) * 1024, p.total_allocated_bytes());
-    if (iter == 0) {
-      EXPECT_EQ((12 + 8 + 65) * 1024, p.peak_allocated_bytes());
-    } else {
-      EXPECT_EQ((1 + 120 + 33) * 1024, p.peak_allocated_bytes());
-    }
-    EXPECT_EQ((16 + 32 + 65) * 1024, p.GetTotalChunkSizes());
-
-    // Clear() resets allocated data, but doesn't remove any chunks
-    p.Clear();
-    EXPECT_EQ(0, p.total_allocated_bytes());
-    if (iter == 0) {
-      EXPECT_EQ((12 + 8 + 65) * 1024, p.peak_allocated_bytes());
-    } else {
-      EXPECT_EQ((1 + 120 + 33) * 1024, p.peak_allocated_bytes());
-    }
-    EXPECT_EQ((16 + 32 + 65) * 1024, p.GetTotalChunkSizes());
-
-    // next allocation reuses existing chunks
-    p.Allocate(1024);
-    EXPECT_EQ(1024, p.total_allocated_bytes());
-    if (iter == 0) {
-      EXPECT_EQ((12 + 8 + 65) * 1024, p.peak_allocated_bytes());
-    } else {
-      EXPECT_EQ((1 + 120 + 33) * 1024, p.peak_allocated_bytes());
-    }
-    EXPECT_EQ((16 + 32 + 65) * 1024, p.GetTotalChunkSizes());
-
-    // ... unless it doesn't fit into any available chunk
-    p.Allocate(120 * 1024);
-    EXPECT_EQ((1 + 120) * 1024, p.total_allocated_bytes());
-    if (iter == 0) {
-      EXPECT_EQ((1 + 120) * 1024, p.peak_allocated_bytes());
-    } else {
-      EXPECT_EQ((1 + 120 + 33) * 1024, p.peak_allocated_bytes());
-    }
-    EXPECT_EQ((130 + 16 + 32 + 65) * 1024, p.GetTotalChunkSizes());
-
-    // ... Try another chunk that fits into an existing chunk
-    p.Allocate(33 * 1024);
-    EXPECT_EQ((1 + 120 + 33) * 1024, p.total_allocated_bytes());
-    EXPECT_EQ((130 + 16 + 32 + 65) * 1024, p.GetTotalChunkSizes());
-
-    // we're releasing 3 chunks, which get added to p2
-    p2.AcquireData(&p, false);
-    EXPECT_EQ(0, p.total_allocated_bytes());
-    EXPECT_EQ((1 + 120 + 33) * 1024, p.peak_allocated_bytes());
-    EXPECT_EQ(0, p.GetTotalChunkSizes());
-
-    p3.AcquireData(&p2, true);  // we're keeping the 65k chunk
-    EXPECT_EQ(33 * 1024, p2.total_allocated_bytes());
-    EXPECT_EQ(65 * 1024, p2.GetTotalChunkSizes());
-
-    p.FreeAll();
-    p2.FreeAll();
-    p3.FreeAll();
-  }
-}
-
-// Test that we can keep an allocated chunk and a free chunk.
-// This case verifies that when chunks are acquired by another memory pool the
-// remaining chunks are consistent if there were more than one used chunk and some
-// free chunks.
-TEST(ChunkedAllocatorTest, Keep) {
-  ChunkedAllocator p;
-  p.Allocate(4 * 1024);
-  p.Allocate(8 * 1024);
-  p.Allocate(16 * 1024);
-  EXPECT_EQ((4 + 8 + 16) * 1024, p.total_allocated_bytes());
-  EXPECT_EQ((4 + 8 + 16) * 1024, p.GetTotalChunkSizes());
-  p.Clear();
-  EXPECT_EQ(0, p.total_allocated_bytes());
-  EXPECT_EQ((4 + 8 + 16) * 1024, p.GetTotalChunkSizes());
-  p.Allocate(1 * 1024);
-  p.Allocate(4 * 1024);
-  EXPECT_EQ((1 + 4) * 1024, p.total_allocated_bytes());
-  EXPECT_EQ((4 + 8 + 16) * 1024, p.GetTotalChunkSizes());
-
-  ChunkedAllocator p2;
-  p2.AcquireData(&p, true);
-  EXPECT_EQ(4 * 1024, p.total_allocated_bytes());
-  EXPECT_EQ((8 + 16) * 1024, p.GetTotalChunkSizes());
-  EXPECT_EQ(1 * 1024, p2.total_allocated_bytes());
-  EXPECT_EQ(4 * 1024, p2.GetTotalChunkSizes());
-
-  p.FreeAll();
-  p2.FreeAll();
-}
-
-// Tests that we can return partial allocations.
-TEST(ChunkedAllocatorTest, ReturnPartial) {
-  ChunkedAllocator p;
-  uint8_t* ptr = p.Allocate(1024);
-  EXPECT_EQ(1024, p.total_allocated_bytes());
-  memset(ptr, 0, 1024);
-  p.ReturnPartialAllocation(1024);
-
-  uint8_t* ptr2 = p.Allocate(1024);
-  EXPECT_EQ(1024, p.total_allocated_bytes());
-  EXPECT_TRUE(ptr == ptr2);
-  p.ReturnPartialAllocation(1016);
-
-  ptr2 = p.Allocate(1016);
-  EXPECT_EQ(1024, p.total_allocated_bytes());
-  EXPECT_TRUE(ptr2 == ptr + 8);
-  p.ReturnPartialAllocation(512);
-  memset(ptr2, 1, 1016 - 512);
-
-  uint8_t* ptr3 = p.Allocate(512);
-  EXPECT_EQ(1024, p.total_allocated_bytes());
-  EXPECT_TRUE(ptr3 == ptr + 512);
-  memset(ptr3, 2, 512);
-
-  for (int i = 0; i < 8; ++i) {
-    EXPECT_EQ(0, ptr[i]);
-  }
-  for (int i = 8; i < 512; ++i) {
-    EXPECT_EQ(1, ptr[i]);
-  }
-  for (int i = 512; i < 1024; ++i) {
-    EXPECT_EQ(2, ptr[i]);
-  }
-
-  p.FreeAll();
-}
-
-// Test that the ChunkedAllocator overhead is bounded when we make allocations of
-// INITIAL_CHUNK_SIZE.
-TEST(ChunkedAllocatorTest, MemoryOverhead) {
-  ChunkedAllocator p;
-  const int alloc_size = ChunkedAllocatorTest::INITIAL_CHUNK_SIZE;
-  const int num_allocs = 1000;
-  int64_t total_allocated = 0;
-
-  for (int i = 0; i < num_allocs; ++i) {
-    uint8_t* mem = p.Allocate(alloc_size);
-    ASSERT_TRUE(mem != nullptr);
-    total_allocated += alloc_size;
-
-    int64_t wasted_memory = p.GetTotalChunkSizes() - total_allocated;
-    // The initial chunk fits evenly into MAX_CHUNK_SIZE, so should have at most
-    // one empty chunk at the end.
-    EXPECT_LE(wasted_memory, ChunkedAllocatorTest::MAX_CHUNK_SIZE);
-    // The chunk doubling algorithm should not allocate chunks larger than the total
-    // amount of memory already allocated.
-    EXPECT_LE(wasted_memory, total_allocated);
-  }
-
-  p.FreeAll();
-}
-
-// Test that the ChunkedAllocator overhead is bounded when we make alternating
-// large and small allocations.
-TEST(ChunkedAllocatorTest, FragmentationOverhead) {
-  ChunkedAllocator p;
-  const int num_allocs = 100;
-  int64_t total_allocated = 0;
-
-  for (int i = 0; i < num_allocs; ++i) {
-    int alloc_size = i % 2 == 0 ? 1 : ChunkedAllocatorTest::MAX_CHUNK_SIZE;
-    uint8_t* mem = p.Allocate(alloc_size);
-    ASSERT_TRUE(mem != nullptr);
-    total_allocated += alloc_size;
-
-    int64_t wasted_memory = p.GetTotalChunkSizes() - total_allocated;
-    // Fragmentation should not waste more than half of each completed chunk.
-    EXPECT_LE(wasted_memory, total_allocated + ChunkedAllocatorTest::MAX_CHUNK_SIZE);
-  }
-
-  p.FreeAll();
-}
-
-TEST(TestBufferedInputStream, Basics) {
-  int64_t source_size = 256;
-  int64_t stream_offset = 10;
-  int64_t stream_size = source_size - stream_offset;
-  int64_t chunk_size = 50;
-  std::shared_ptr<ResizableBuffer> buf =
-      AllocateBuffer(default_memory_pool(), source_size);
-  ASSERT_EQ(source_size, buf->size());
-  for (int i = 0; i < source_size; i++) {
-    buf->mutable_data()[i] = static_cast<uint8_t>(i);
-  }
-
-  auto wrapper =
-      std::make_shared<ArrowInputFile>(std::make_shared<::arrow::io::BufferReader>(buf));
-
-  std::unique_ptr<BufferedInputStream> stream(new BufferedInputStream(
-      default_memory_pool(), chunk_size, wrapper.get(), stream_offset, stream_size));
-
-  const uint8_t* output;
-  int64_t bytes_read;
-
-  // source is at offset 10
-  output = stream->Peek(10, &bytes_read);
-  ASSERT_EQ(10, bytes_read);
-  for (int i = 0; i < 10; i++) {
-    ASSERT_EQ(10 + i, output[i]) << i;
-  }
-  output = stream->Read(10, &bytes_read);
-  ASSERT_EQ(10, bytes_read);
-  for (int i = 0; i < 10; i++) {
-    ASSERT_EQ(10 + i, output[i]) << i;
-  }
-  output = stream->Read(10, &bytes_read);
-  ASSERT_EQ(10, bytes_read);
-  for (int i = 0; i < 10; i++) {
-    ASSERT_EQ(20 + i, output[i]) << i;
-  }
-  stream->Advance(5);
-  stream->Advance(5);
-  // source is at offset 40
-  // read across buffer boundary. buffer size is 50
-  output = stream->Read(20, &bytes_read);
-  ASSERT_EQ(20, bytes_read);
-  for (int i = 0; i < 20; i++) {
-    ASSERT_EQ(40 + i, output[i]) << i;
-  }
-  // read more than original chunk_size
-  output = stream->Read(60, &bytes_read);
-  ASSERT_EQ(60, bytes_read);
-  for (int i = 0; i < 60; i++) {
-    ASSERT_EQ(60 + i, output[i]) << i;
-  }
-
-  stream->Advance(120);
-  // source is at offset 240
-  // read outside of source boundary. source size is 256
-  output = stream->Read(30, &bytes_read);
-  ASSERT_EQ(16, bytes_read);
-  for (int i = 0; i < 16; i++) {
-    ASSERT_EQ(240 + i, output[i]) << i;
-  }
-}
-
-TEST(TestArrowInputFile, ReadAt) {
-  std::string data = "this is the data";
-  auto data_buffer = reinterpret_cast<const uint8_t*>(data.c_str());
-
-  auto file = std::make_shared<::arrow::io::BufferReader>(data_buffer, data.size());
-  auto source = std::make_shared<ArrowInputFile>(file);
-
-  ASSERT_EQ(0, source->Tell());
-
-  uint8_t buffer[50];
-
-  ASSERT_NO_THROW(source->ReadAt(0, 4, buffer));
-  ASSERT_EQ(0, std::memcmp(buffer, "this", 4));
-
-  // Note: it's undefined (and possibly platform-dependent) whether ArrowInputFile
-  // updates the file position after ReadAt().
-}
-
-TEST(TestArrowInputFile, Read) {
-  std::string data = "this is the data";
-  auto data_buffer = reinterpret_cast<const uint8_t*>(data.c_str());
-
-  auto file = std::make_shared<::arrow::io::BufferReader>(data_buffer, data.size());
-  auto source = std::make_shared<ArrowInputFile>(file);
-
-  ASSERT_EQ(0, source->Tell());
-
-  std::shared_ptr<Buffer> pq_buffer, expected_buffer;
-
-  ASSERT_NO_THROW(pq_buffer = source->Read(4));
-  expected_buffer = std::make_shared<Buffer>(data_buffer, 4);
-  ASSERT_TRUE(expected_buffer->Equals(*pq_buffer.get()));
-
-  ASSERT_NO_THROW(pq_buffer = source->Read(7));
-  expected_buffer = std::make_shared<Buffer>(data_buffer + 4, 7);
-  ASSERT_TRUE(expected_buffer->Equals(*pq_buffer.get()));
-
-  ASSERT_EQ(11, source->Tell());
-
-  ASSERT_NO_THROW(pq_buffer = source->Read(8));
-  expected_buffer = std::make_shared<Buffer>(data_buffer + 11, 5);
-  ASSERT_TRUE(expected_buffer->Equals(*pq_buffer.get()));
-
-  ASSERT_EQ(16, source->Tell());
-}
-
-}  // namespace parquet
diff --git a/src/parquet/util/memory.cc b/src/parquet/util/memory.cc
deleted file mode 100644
index d9caf6e..0000000
--- a/src/parquet/util/memory.cc
+++ /dev/null
@@ -1,502 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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.
-
-#include "parquet/util/memory.h"
-
-#include <algorithm>
-#include <cstdint>
-#include <cstdio>
-#include <string>
-#include <utility>
-
-#include "arrow/status.h"
-#include "arrow/util/bit-util.h"
-
-#include "parquet/exception.h"
-#include "parquet/types.h"
-#include "parquet/util/logging.h"
-
-using arrow::MemoryPool;
-
-namespace parquet {
-
-template <class T>
-Vector<T>::Vector(int64_t size, MemoryPool* pool)
-    : buffer_(AllocateBuffer(pool, size * sizeof(T))), size_(size), capacity_(size) {
-  if (size > 0) {
-    data_ = reinterpret_cast<T*>(buffer_->mutable_data());
-  } else {
-    data_ = nullptr;
-  }
-}
-
-template <class T>
-void Vector<T>::Reserve(int64_t new_capacity) {
-  if (new_capacity > capacity_) {
-    PARQUET_THROW_NOT_OK(buffer_->Resize(new_capacity * sizeof(T)));
-    data_ = reinterpret_cast<T*>(buffer_->mutable_data());
-    capacity_ = new_capacity;
-  }
-}
-
-template <class T>
-void Vector<T>::Resize(int64_t new_size) {
-  Reserve(new_size);
-  size_ = new_size;
-}
-
-template <class T>
-void Vector<T>::Assign(int64_t size, const T val) {
-  Resize(size);
-  for (int64_t i = 0; i < size_; i++) {
-    data_[i] = val;
-  }
-}
-
-template <class T>
-void Vector<T>::Swap(Vector<T>& v) {
-  buffer_.swap(v.buffer_);
-  std::swap(size_, v.size_);
-  std::swap(capacity_, v.capacity_);
-  std::swap(data_, v.data_);
-}
-
-template class Vector<int32_t>;
-template class Vector<int64_t>;
-template class Vector<bool>;
-template class Vector<float>;
-template class Vector<double>;
-template class Vector<Int96>;
-template class Vector<ByteArray>;
-template class Vector<FixedLenByteArray>;
-
-const int ChunkedAllocator::INITIAL_CHUNK_SIZE;
-const int ChunkedAllocator::MAX_CHUNK_SIZE;
-
-ChunkedAllocator::ChunkedAllocator(MemoryPool* pool)
-    : current_chunk_idx_(-1),
-      next_chunk_size_(INITIAL_CHUNK_SIZE),
-      total_allocated_bytes_(0),
-      peak_allocated_bytes_(0),
-      total_reserved_bytes_(0),
-      pool_(pool) {}
-
-ChunkedAllocator::ChunkInfo::ChunkInfo(int64_t size, uint8_t* buf)
-    : data(buf), size(size), allocated_bytes(0) {}
-
-ChunkedAllocator::~ChunkedAllocator() {
-  int64_t total_bytes_released = 0;
-  for (size_t i = 0; i < chunks_.size(); ++i) {
-    total_bytes_released += chunks_[i].size;
-    pool_->Free(chunks_[i].data, chunks_[i].size);
-  }
-
-  DCHECK(chunks_.empty()) << "Must call FreeAll() or AcquireData() for this pool";
-}
-
-void ChunkedAllocator::ReturnPartialAllocation(int byte_size) {
-  DCHECK_GE(byte_size, 0);
-  DCHECK(current_chunk_idx_ != -1);
-  ChunkInfo& info = chunks_[current_chunk_idx_];
-  DCHECK_GE(info.allocated_bytes, byte_size);
-  info.allocated_bytes -= byte_size;
-  total_allocated_bytes_ -= byte_size;
-}
-
-template <bool CHECK_LIMIT_FIRST>
-uint8_t* ChunkedAllocator::Allocate(int size) {
-  if (size == 0) {
-    return nullptr;
-  }
-
-  int64_t num_bytes = ::arrow::BitUtil::RoundUp(size, 8);
-  if (current_chunk_idx_ == -1 ||
-      num_bytes + chunks_[current_chunk_idx_].allocated_bytes >
-          chunks_[current_chunk_idx_].size) {
-    // If we couldn't allocate a new chunk, return nullptr.
-    if (ARROW_PREDICT_FALSE(!FindChunk(num_bytes))) {
-      return nullptr;
-    }
-  }
-  ChunkInfo& info = chunks_[current_chunk_idx_];
-  uint8_t* result = info.data + info.allocated_bytes;
-  DCHECK_LE(info.allocated_bytes + num_bytes, info.size);
-  info.allocated_bytes += num_bytes;
-  total_allocated_bytes_ += num_bytes;
-  DCHECK_LE(current_chunk_idx_, static_cast<int>(chunks_.size()) - 1);
-  peak_allocated_bytes_ = std::max(total_allocated_bytes_, peak_allocated_bytes_);
-  return result;
-}
-
-uint8_t* ChunkedAllocator::Allocate(int size) { return Allocate<false>(size); }
-
-void ChunkedAllocator::Clear() {
-  current_chunk_idx_ = -1;
-  for (auto chunk = chunks_.begin(); chunk != chunks_.end(); ++chunk) {
-    chunk->allocated_bytes = 0;
-  }
-  total_allocated_bytes_ = 0;
-  DCHECK(CheckIntegrity(false));
-}
-
-void ChunkedAllocator::FreeAll() {
-  int64_t total_bytes_released = 0;
-  for (size_t i = 0; i < chunks_.size(); ++i) {
-    total_bytes_released += chunks_[i].size;
-    pool_->Free(chunks_[i].data, chunks_[i].size);
-  }
-  chunks_.clear();
-  next_chunk_size_ = INITIAL_CHUNK_SIZE;
-  current_chunk_idx_ = -1;
-  total_allocated_bytes_ = 0;
-  total_reserved_bytes_ = 0;
-}
-
-bool ChunkedAllocator::FindChunk(int64_t min_size) {
-  // Try to allocate from a free chunk. The first free chunk, if any, will be immediately
-  // after the current chunk.
-  int first_free_idx = current_chunk_idx_ + 1;
-  // (cast size() to signed int in order to avoid everything else being cast to
-  // unsigned long, in particular -1)
-  while (++current_chunk_idx_ < static_cast<int>(chunks_.size())) {
-    // we found a free chunk
-    DCHECK_EQ(chunks_[current_chunk_idx_].allocated_bytes, 0);
-
-    if (chunks_[current_chunk_idx_].size >= min_size) {
-      // This chunk is big enough.  Move it before the other free chunks.
-      if (current_chunk_idx_ != first_free_idx) {
-        std::swap(chunks_[current_chunk_idx_], chunks_[first_free_idx]);
-        current_chunk_idx_ = first_free_idx;
-      }
-      break;
-    }
-  }
-
-  if (current_chunk_idx_ == static_cast<int>(chunks_.size())) {
-    // need to allocate new chunk.
-    int64_t chunk_size;
-    DCHECK_GE(next_chunk_size_, INITIAL_CHUNK_SIZE);
-    DCHECK_LE(next_chunk_size_, MAX_CHUNK_SIZE);
-
-    chunk_size = std::max<int64_t>(min_size, next_chunk_size_);
-
-    // Allocate a new chunk. Return early if malloc fails.
-    uint8_t* buf = nullptr;
-    PARQUET_THROW_NOT_OK(pool_->Allocate(chunk_size, &buf));
-    if (ARROW_PREDICT_FALSE(buf == nullptr)) {
-      DCHECK_EQ(current_chunk_idx_, static_cast<int>(chunks_.size()));
-      current_chunk_idx_ = static_cast<int>(chunks_.size()) - 1;
-      return false;
-    }
-
-    // If there are no free chunks put it at the end, otherwise before the first free.
-    if (first_free_idx == static_cast<int>(chunks_.size())) {
-      chunks_.push_back(ChunkInfo(chunk_size, buf));
-    } else {
-      current_chunk_idx_ = first_free_idx;
-      auto insert_chunk = chunks_.begin() + current_chunk_idx_;
-      chunks_.insert(insert_chunk, ChunkInfo(chunk_size, buf));
-    }
-    total_reserved_bytes_ += chunk_size;
-    // Don't increment the chunk size until the allocation succeeds: if an attempted
-    // large allocation fails we don't want to increase the chunk size further.
-    next_chunk_size_ =
-        static_cast<int>(std::min<int64_t>(chunk_size * 2, MAX_CHUNK_SIZE));
-  }
-
-  DCHECK_LT(current_chunk_idx_, static_cast<int>(chunks_.size()));
-  DCHECK(CheckIntegrity(true));
-  return true;
-}
-
-void ChunkedAllocator::AcquireData(ChunkedAllocator* src, bool keep_current) {
-  DCHECK(src->CheckIntegrity(false));
-  int num_acquired_chunks;
-  if (keep_current) {
-    num_acquired_chunks = src->current_chunk_idx_;
-  } else if (src->GetFreeOffset() == 0) {
-    // nothing in the last chunk
-    num_acquired_chunks = src->current_chunk_idx_;
-  } else {
-    num_acquired_chunks = src->current_chunk_idx_ + 1;
-  }
-
-  if (num_acquired_chunks <= 0) {
-    if (!keep_current) src->FreeAll();
-    return;
-  }
-
-  auto end_chunk = src->chunks_.begin() + num_acquired_chunks;
-  int64_t total_transfered_bytes = 0;
-  for (auto i = src->chunks_.begin(); i != end_chunk; ++i) {
-    total_transfered_bytes += i->size;
-  }
-  src->total_reserved_bytes_ -= total_transfered_bytes;
-  total_reserved_bytes_ += total_transfered_bytes;
-
-  // insert new chunks after current_chunk_idx_
-  auto insert_chunk = chunks_.begin() + (current_chunk_idx_ + 1);
-  chunks_.insert(insert_chunk, src->chunks_.begin(), end_chunk);
-  src->chunks_.erase(src->chunks_.begin(), end_chunk);
-  current_chunk_idx_ += num_acquired_chunks;
-
-  if (keep_current) {
-    src->current_chunk_idx_ = 0;
-    DCHECK(src->chunks_.size() == 1 || src->chunks_[1].allocated_bytes == 0);
-    total_allocated_bytes_ += src->total_allocated_bytes_ - src->GetFreeOffset();
-    src->total_allocated_bytes_ = src->GetFreeOffset();
-  } else {
-    src->current_chunk_idx_ = -1;
-    total_allocated_bytes_ += src->total_allocated_bytes_;
-    src->total_allocated_bytes_ = 0;
-  }
-  peak_allocated_bytes_ = std::max(total_allocated_bytes_, peak_allocated_bytes_);
-
-  if (!keep_current) src->FreeAll();
-  DCHECK(CheckIntegrity(false));
-}
-
-std::string ChunkedAllocator::DebugString() {
-  std::stringstream out;
-  char str[16];
-  out << "ChunkedAllocator(#chunks=" << chunks_.size() << " [";
-  for (size_t i = 0; i < chunks_.size(); ++i) {
-    sprintf(str, "0x%zx=", reinterpret_cast<size_t>(chunks_[i].data));  // NOLINT
-    out << (i > 0 ? " " : "") << str << chunks_[i].size << "/"
-        << chunks_[i].allocated_bytes;
-  }
-  out << "] current_chunk=" << current_chunk_idx_
-      << " total_sizes=" << GetTotalChunkSizes()
-      << " total_alloc=" << total_allocated_bytes_ << ")";
-  return out.str();
-}
-
-int64_t ChunkedAllocator::GetTotalChunkSizes() const {
-  int64_t result = 0;
-  for (size_t i = 0; i < chunks_.size(); ++i) {
-    result += chunks_[i].size;
-  }
-  return result;
-}
-
-bool ChunkedAllocator::CheckIntegrity(bool current_chunk_empty) {
-  // check that current_chunk_idx_ points to the last chunk with allocated data
-  DCHECK_LT(current_chunk_idx_, static_cast<int>(chunks_.size()));
-  int64_t total_allocated = 0;
-  for (int i = 0; i < static_cast<int>(chunks_.size()); ++i) {
-    DCHECK_GT(chunks_[i].size, 0);
-    if (i < current_chunk_idx_) {
-      DCHECK_GT(chunks_[i].allocated_bytes, 0);
-    } else if (i == current_chunk_idx_) {
-      if (current_chunk_empty) {
-        DCHECK_EQ(chunks_[i].allocated_bytes, 0);
-      } else {
-        DCHECK_GT(chunks_[i].allocated_bytes, 0);
-      }
-    } else {
-      DCHECK_EQ(chunks_[i].allocated_bytes, 0);
-    }
-    total_allocated += chunks_[i].allocated_bytes;
-  }
-  DCHECK_EQ(total_allocated, total_allocated_bytes_);
-  return true;
-}
-
-// ----------------------------------------------------------------------
-// Arrow IO wrappers
-
-void ArrowFileMethods::Close() {
-  // Closing the file is the responsibility of the owner of the handle
-  return;
-}
-
-// Return the current position in the output stream relative to the start
-int64_t ArrowFileMethods::Tell() {
-  int64_t position = 0;
-  PARQUET_THROW_NOT_OK(file_interface()->Tell(&position));
-  return position;
-}
-
-ArrowInputFile::ArrowInputFile(
-    const std::shared_ptr<::arrow::io::ReadableFileInterface>& file)
-    : file_(file) {}
-
-::arrow::io::FileInterface* ArrowInputFile::file_interface() { return file_.get(); }
-
-int64_t ArrowInputFile::Size() const {
-  int64_t size;
-  PARQUET_THROW_NOT_OK(file_->GetSize(&size));
-  return size;
-}
-
-// Returns bytes read
-int64_t ArrowInputFile::Read(int64_t nbytes, uint8_t* out) {
-  int64_t bytes_read = 0;
-  PARQUET_THROW_NOT_OK(file_->Read(nbytes, &bytes_read, out));
-  return bytes_read;
-}
-
-std::shared_ptr<Buffer> ArrowInputFile::Read(int64_t nbytes) {
-  std::shared_ptr<Buffer> out;
-  PARQUET_THROW_NOT_OK(file_->Read(nbytes, &out));
-  return out;
-}
-
-std::shared_ptr<Buffer> ArrowInputFile::ReadAt(int64_t position, int64_t nbytes) {
-  std::shared_ptr<Buffer> out;
-  PARQUET_THROW_NOT_OK(file_->ReadAt(position, nbytes, &out));
-  return out;
-}
-
-int64_t ArrowInputFile::ReadAt(int64_t position, int64_t nbytes, uint8_t* out) {
-  int64_t bytes_read = 0;
-  PARQUET_THROW_NOT_OK(file_->ReadAt(position, nbytes, &bytes_read, out));
-  return bytes_read;
-}
-
-ArrowOutputStream::ArrowOutputStream(
-    const std::shared_ptr<::arrow::io::OutputStream> file)
-    : file_(file) {}
-
-::arrow::io::FileInterface* ArrowOutputStream::file_interface() { return file_.get(); }
-
-// Copy bytes into the output stream
-void ArrowOutputStream::Write(const uint8_t* data, int64_t length) {
-  PARQUET_THROW_NOT_OK(file_->Write(data, length));
-}
-
-// ----------------------------------------------------------------------
-// InMemoryInputStream
-
-InMemoryInputStream::InMemoryInputStream(const std::shared_ptr<Buffer>& buffer)
-    : buffer_(buffer), offset_(0) {
-  len_ = buffer_->size();
-}
-
-InMemoryInputStream::InMemoryInputStream(RandomAccessSource* source, int64_t start,
-                                         int64_t num_bytes)
-    : offset_(0) {
-  buffer_ = source->ReadAt(start, num_bytes);
-  if (buffer_->size() < num_bytes) {
-    throw ParquetException("Unable to read column chunk data");
-  }
-  len_ = buffer_->size();
-}
-
-const uint8_t* InMemoryInputStream::Peek(int64_t num_to_peek, int64_t* num_bytes) {
-  *num_bytes = std::min(static_cast<int64_t>(num_to_peek), len_ - offset_);
-  return buffer_->data() + offset_;
-}
-
-const uint8_t* InMemoryInputStream::Read(int64_t num_to_read, int64_t* num_bytes) {
-  const uint8_t* result = Peek(num_to_read, num_bytes);
-  offset_ += *num_bytes;
-  return result;
-}
-
-void InMemoryInputStream::Advance(int64_t num_bytes) { offset_ += num_bytes; }
-
-// ----------------------------------------------------------------------
-// In-memory output stream
-
-InMemoryOutputStream::InMemoryOutputStream(MemoryPool* pool, int64_t initial_capacity)
-    : size_(0), capacity_(initial_capacity) {
-  if (initial_capacity == 0) {
-    initial_capacity = kInMemoryDefaultCapacity;
-  }
-  buffer_ = AllocateBuffer(pool, initial_capacity);
-}
-
-InMemoryOutputStream::~InMemoryOutputStream() {}
-
-uint8_t* InMemoryOutputStream::Head() { return buffer_->mutable_data() + size_; }
-
-void InMemoryOutputStream::Write(const uint8_t* data, int64_t length) {
-  if (size_ + length > capacity_) {
-    int64_t new_capacity = capacity_ * 2;
-    while (new_capacity < size_ + length) {
-      new_capacity *= 2;
-    }
-    PARQUET_THROW_NOT_OK(buffer_->Resize(new_capacity));
-    capacity_ = new_capacity;
-  }
-  memcpy(Head(), data, length);
-  size_ += length;
-}
-
-int64_t InMemoryOutputStream::Tell() { return size_; }
-
-std::shared_ptr<Buffer> InMemoryOutputStream::GetBuffer() {
-  PARQUET_THROW_NOT_OK(buffer_->Resize(size_));
-  std::shared_ptr<Buffer> result = buffer_;
-  buffer_ = nullptr;
-  return result;
-}
-
-// ----------------------------------------------------------------------
-// BufferedInputStream
-
-BufferedInputStream::BufferedInputStream(MemoryPool* pool, int64_t buffer_size,
-                                         RandomAccessSource* source, int64_t start,
-                                         int64_t num_bytes)
-    : source_(source), stream_offset_(start), stream_end_(start + num_bytes) {
-  buffer_ = AllocateBuffer(pool, buffer_size);
-  buffer_size_ = buffer_->size();
-  // Required to force a lazy read
-  buffer_offset_ = buffer_size_;
-}
-
-const uint8_t* BufferedInputStream::Peek(int64_t num_to_peek, int64_t* num_bytes) {
-  *num_bytes = std::min(num_to_peek, stream_end_ - stream_offset_);
-  // increase the buffer size if needed
-  if (*num_bytes > buffer_size_) {
-    PARQUET_THROW_NOT_OK(buffer_->Resize(*num_bytes));
-    buffer_size_ = buffer_->size();
-    DCHECK(buffer_size_ >= *num_bytes);
-  }
-  // Read more data when buffer has insufficient left or when resized
-  if (*num_bytes > (buffer_size_ - buffer_offset_)) {
-    buffer_size_ = std::min(buffer_size_, stream_end_ - stream_offset_);
-    int64_t bytes_read =
-        source_->ReadAt(stream_offset_, buffer_size_, buffer_->mutable_data());
-    if (bytes_read < *num_bytes) {
-      throw ParquetException("Failed reading column data from source");
-    }
-    buffer_offset_ = 0;
-  }
-  return buffer_->data() + buffer_offset_;
-}
-
-const uint8_t* BufferedInputStream::Read(int64_t num_to_read, int64_t* num_bytes) {
-  const uint8_t* result = Peek(num_to_read, num_bytes);
-  stream_offset_ += *num_bytes;
-  buffer_offset_ += *num_bytes;
-  return result;
-}
-
-void BufferedInputStream::Advance(int64_t num_bytes) {
-  stream_offset_ += num_bytes;
-  buffer_offset_ += num_bytes;
-}
-
-std::shared_ptr<ResizableBuffer> AllocateBuffer(MemoryPool* pool, int64_t size) {
-  std::shared_ptr<ResizableBuffer> result;
-  PARQUET_THROW_NOT_OK(arrow::AllocateResizableBuffer(pool, size, &result));
-  return result;
-}
-
-}  // namespace parquet
diff --git a/src/parquet/util/memory.h b/src/parquet/util/memory.h
deleted file mode 100644
index 088f86f..0000000
--- a/src/parquet/util/memory.h
+++ /dev/null
@@ -1,445 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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.
-
-#ifndef PARQUET_UTIL_MEMORY_H
-#define PARQUET_UTIL_MEMORY_H
-
-#include <atomic>
-#include <cstdint>
-#include <cstdlib>
-#include <cstring>
-#include <memory>
-#include <string>
-#include <vector>
-
-#include "arrow/buffer.h"
-#include "arrow/io/interfaces.h"
-#include "arrow/io/memory.h"
-#include "arrow/memory_pool.h"
-#include "arrow/status.h"
-#include "arrow/util/compression.h"
-
-#include "parquet/exception.h"
-#include "parquet/types.h"
-#include "parquet/util/macros.h"
-#include "parquet/util/visibility.h"
-
-namespace parquet {
-
-static inline std::unique_ptr<::arrow::Codec> GetCodecFromArrow(Compression::type codec) {
-  std::unique_ptr<::arrow::Codec> result;
-  switch (codec) {
-    case Compression::UNCOMPRESSED:
-      break;
-    case Compression::SNAPPY:
-      PARQUET_THROW_NOT_OK(::arrow::Codec::Create(::arrow::Compression::SNAPPY, &result));
-      break;
-    case Compression::GZIP:
-      PARQUET_THROW_NOT_OK(::arrow::Codec::Create(::arrow::Compression::GZIP, &result));
-      break;
-    case Compression::LZO:
-      PARQUET_THROW_NOT_OK(::arrow::Codec::Create(::arrow::Compression::LZO, &result));
-      break;
-    case Compression::BROTLI:
-      PARQUET_THROW_NOT_OK(::arrow::Codec::Create(::arrow::Compression::BROTLI, &result));
-      break;
-    case Compression::LZ4:
-      PARQUET_THROW_NOT_OK(::arrow::Codec::Create(::arrow::Compression::LZ4, &result));
-      break;
-    case Compression::ZSTD:
-      PARQUET_THROW_NOT_OK(::arrow::Codec::Create(::arrow::Compression::ZSTD, &result));
-      break;
-    default:
-      break;
-  }
-  return result;
-}
-
-static constexpr int64_t kInMemoryDefaultCapacity = 1024;
-
-using Buffer = ::arrow::Buffer;
-using MutableBuffer = ::arrow::MutableBuffer;
-using ResizableBuffer = ::arrow::ResizableBuffer;
-using ResizableBuffer = ::arrow::ResizableBuffer;
-
-template <class T>
-class PARQUET_EXPORT Vector {
- public:
-  explicit Vector(int64_t size, ::arrow::MemoryPool* pool);
-  void Resize(int64_t new_size);
-  void Reserve(int64_t new_capacity);
-  void Assign(int64_t size, const T val);
-  void Swap(Vector<T>& v);
-  inline T& operator[](int64_t i) const { return data_[i]; }
-
-  const T* data() const { return data_; }
-
- private:
-  std::shared_ptr<ResizableBuffer> buffer_;
-  int64_t size_;
-  int64_t capacity_;
-  T* data_;
-
-  DISALLOW_COPY_AND_ASSIGN(Vector);
-};
-
-/// A ChunkedAllocator maintains a list of memory chunks from which it
-/// allocates memory in response to Allocate() calls; Chunks stay around for
-/// the lifetime of the allocator or until they are passed on to another
-/// allocator.
-//
-/// An Allocate() call will attempt to allocate memory from the chunk that was most
-/// recently added; if that chunk doesn't have enough memory to
-/// satisfy the allocation request, the free chunks are searched for one that is
-/// big enough otherwise a new chunk is added to the list.
-/// The current_chunk_idx_ always points to the last chunk with allocated memory.
-/// In order to keep allocation overhead low, chunk sizes double with each new one
-/// added, until they hit a maximum size.
-//
-///     Example:
-///     ChunkedAllocator* p = new ChunkedAllocator();
-///     for (int i = 0; i < 1024; ++i) {
-/// returns 8-byte aligned memory (effectively 24 bytes):
-///       .. = p->Allocate(17);
-///     }
-/// at this point, 17K have been handed out in response to Allocate() calls and
-/// 28K of chunks have been allocated (chunk sizes: 4K, 8K, 16K)
-/// We track total and peak allocated bytes. At this point they would be the same:
-/// 28k bytes.  A call to Clear will return the allocated memory so
-/// total_allocate_bytes_
-/// becomes 0 while peak_allocate_bytes_ remains at 28k.
-///     p->Clear();
-/// the entire 1st chunk is returned:
-///     .. = p->Allocate(4 * 1024);
-/// 4K of the 2nd chunk are returned:
-///     .. = p->Allocate(4 * 1024);
-/// a new 20K chunk is created
-///     .. = p->Allocate(20 * 1024);
-//
-///      ChunkedAllocator* p2 = new ChunkedAllocator();
-/// the new ChunkedAllocator receives all chunks containing data from p
-///      p2->AcquireData(p, false);
-/// At this point p.total_allocated_bytes_ would be 0 while p.peak_allocated_bytes_
-/// remains unchanged.
-/// The one remaining (empty) chunk is released:
-///    delete p;
-
-class PARQUET_EXPORT ChunkedAllocator {
- public:
-  explicit ChunkedAllocator(::arrow::MemoryPool* pool = ::arrow::default_memory_pool());
-
-  /// Frees all chunks of memory and subtracts the total allocated bytes
-  /// from the registered limits.
-  ~ChunkedAllocator();
-
-  /// Allocates 8-byte aligned section of memory of 'size' bytes at the end
-  /// of the the current chunk. Creates a new chunk if there aren't any chunks
-  /// with enough capacity.
-  uint8_t* Allocate(int size);
-
-  /// Returns 'byte_size' to the current chunk back to the mem pool. This can
-  /// only be used to return either all or part of the previous allocation returned
-  /// by Allocate().
-  void ReturnPartialAllocation(int byte_size);
-
-  /// Makes all allocated chunks available for re-use, but doesn't delete any chunks.
-  void Clear();
-
-  /// Deletes all allocated chunks. FreeAll() or AcquireData() must be called for
-  /// each mem pool
-  void FreeAll();
-
-  /// Absorb all chunks that hold data from src. If keep_current is true, let src hold on
-  /// to its last allocated chunk that contains data.
-  /// All offsets handed out by calls to GetCurrentOffset() for 'src' become invalid.
-  void AcquireData(ChunkedAllocator* src, bool keep_current);
-
-  std::string DebugString();
-
-  int64_t total_allocated_bytes() const { return total_allocated_bytes_; }
-  int64_t peak_allocated_bytes() const { return peak_allocated_bytes_; }
-  int64_t total_reserved_bytes() const { return total_reserved_bytes_; }
-
-  /// Return sum of chunk_sizes_.
-  int64_t GetTotalChunkSizes() const;
-
- private:
-  friend class ChunkedAllocatorTest;
-  static const int INITIAL_CHUNK_SIZE = 4 * 1024;
-
-  /// The maximum size of chunk that should be allocated. Allocations larger than this
-  /// size will get their own individual chunk.
-  static const int MAX_CHUNK_SIZE = 1024 * 1024;
-
-  struct ChunkInfo {
-    uint8_t* data;  // Owned by the ChunkInfo.
-    int64_t size;   // in bytes
-
-    /// bytes allocated via Allocate() in this chunk
-    int64_t allocated_bytes;
-
-    explicit ChunkInfo(int64_t size, uint8_t* buf);
-
-    ChunkInfo() : data(nullptr), size(0), allocated_bytes(0) {}
-  };
-
-  /// chunk from which we served the last Allocate() call;
-  /// always points to the last chunk that contains allocated data;
-  /// chunks 0..current_chunk_idx_ are guaranteed to contain data
-  /// (chunks_[i].allocated_bytes > 0 for i: 0..current_chunk_idx_);
-  /// -1 if no chunks present
-  int current_chunk_idx_;
-
-  /// The size of the next chunk to allocate.
-  int64_t next_chunk_size_;
-
-  /// sum of allocated_bytes_
-  int64_t total_allocated_bytes_;
-
-  /// Maximum number of bytes allocated from this pool at one time.
-  int64_t peak_allocated_bytes_;
-
-  /// sum of all bytes allocated in chunks_
-  int64_t total_reserved_bytes_;
-
-  std::vector<ChunkInfo> chunks_;
-
-  ::arrow::MemoryPool* pool_;
-
-  /// Find or allocated a chunk with at least min_size spare capacity and update
-  /// current_chunk_idx_. Also updates chunks_, chunk_sizes_ and allocated_bytes_
-  /// if a new chunk needs to be created.
-  bool FindChunk(int64_t min_size);
-
-  /// Check integrity of the supporting data structures; always returns true but DCHECKs
-  /// all invariants.
-  /// If 'current_chunk_empty' is false, checks that the current chunk contains data.
-  bool CheckIntegrity(bool current_chunk_empty);
-
-  /// Return offset to unoccpied space in current chunk.
-  int GetFreeOffset() const {
-    if (current_chunk_idx_ == -1) return 0;
-    return static_cast<int>(chunks_[current_chunk_idx_].allocated_bytes);
-  }
-
-  template <bool CHECK_LIMIT_FIRST>
-  uint8_t* Allocate(int size);
-};
-
-// File input and output interfaces that translate arrow::Status to exceptions
-
-class PARQUET_EXPORT FileInterface {
- public:
-  virtual ~FileInterface() = default;
-
-  // Close the file
-  virtual void Close() = 0;
-
-  // Return the current position in the file relative to the start
-  virtual int64_t Tell() = 0;
-};
-
-/// It is the responsibility of implementations to mind threadsafety of shared
-/// resources
-class PARQUET_EXPORT RandomAccessSource : virtual public FileInterface {
- public:
-  virtual ~RandomAccessSource() = default;
-
-  virtual int64_t Size() const = 0;
-
-  // Returns bytes read
-  virtual int64_t Read(int64_t nbytes, uint8_t* out) = 0;
-
-  virtual std::shared_ptr<Buffer> Read(int64_t nbytes) = 0;
-
-  virtual std::shared_ptr<Buffer> ReadAt(int64_t position, int64_t nbytes) = 0;
-
-  /// Returns bytes read
-  virtual int64_t ReadAt(int64_t position, int64_t nbytes, uint8_t* out) = 0;
-};
-
-class PARQUET_EXPORT OutputStream : virtual public FileInterface {
- public:
-  virtual ~OutputStream() = default;
-
-  // Copy bytes into the output stream
-  virtual void Write(const uint8_t* data, int64_t length) = 0;
-};
-
-class PARQUET_EXPORT ArrowFileMethods : virtual public FileInterface {
- public:
-  // No-op. Closing the file is the responsibility of the owner of the handle
-  void Close() override;
-
-  int64_t Tell() override;
-
- protected:
-  virtual ::arrow::io::FileInterface* file_interface() = 0;
-};
-
-/// This interface depends on the threadsafety of the underlying Arrow file interface
-class PARQUET_EXPORT ArrowInputFile : public ArrowFileMethods, public RandomAccessSource {
- public:
-  explicit ArrowInputFile(
-      const std::shared_ptr<::arrow::io::ReadableFileInterface>& file);
-
-  int64_t Size() const override;
-
-  // Returns bytes read
-  int64_t Read(int64_t nbytes, uint8_t* out) override;
-
-  std::shared_ptr<Buffer> Read(int64_t nbytes) override;
-
-  std::shared_ptr<Buffer> ReadAt(int64_t position, int64_t nbytes) override;
-
-  /// Returns bytes read
-  int64_t ReadAt(int64_t position, int64_t nbytes, uint8_t* out) override;
-
-  std::shared_ptr<::arrow::io::ReadableFileInterface> file() const { return file_; }
-
-  // Diamond inheritance
-  using ArrowFileMethods::Close;
-  using ArrowFileMethods::Tell;
-
- private:
-  ::arrow::io::FileInterface* file_interface() override;
-  std::shared_ptr<::arrow::io::ReadableFileInterface> file_;
-};
-
-class PARQUET_EXPORT ArrowOutputStream : public ArrowFileMethods, public OutputStream {
- public:
-  explicit ArrowOutputStream(const std::shared_ptr<::arrow::io::OutputStream> file);
-
-  // Copy bytes into the output stream
-  void Write(const uint8_t* data, int64_t length) override;
-
-  std::shared_ptr<::arrow::io::OutputStream> file() { return file_; }
-
-  // Diamond inheritance
-  using ArrowFileMethods::Close;
-  using ArrowFileMethods::Tell;
-
- private:
-  ::arrow::io::FileInterface* file_interface() override;
-  std::shared_ptr<::arrow::io::OutputStream> file_;
-};
-
-class PARQUET_EXPORT InMemoryOutputStream : public OutputStream {
- public:
-  explicit InMemoryOutputStream(
-      ::arrow::MemoryPool* pool = ::arrow::default_memory_pool(),
-      int64_t initial_capacity = kInMemoryDefaultCapacity);
-
-  virtual ~InMemoryOutputStream();
-
-  // Close is currently a no-op with the in-memory stream
-  virtual void Close() {}
-
-  virtual int64_t Tell();
-
-  virtual void Write(const uint8_t* data, int64_t length);
-
-  // Clears the stream
-  void Clear() { size_ = 0; }
-
-  // Get pointer to the underlying buffer
-  const Buffer& GetBufferRef() const { return *buffer_; }
-
-  // Return complete stream as Buffer
-  std::shared_ptr<Buffer> GetBuffer();
-
- private:
-  // Mutable pointer to the current write position in the stream
-  uint8_t* Head();
-
-  std::shared_ptr<ResizableBuffer> buffer_;
-  int64_t size_;
-  int64_t capacity_;
-
-  DISALLOW_COPY_AND_ASSIGN(InMemoryOutputStream);
-};
-
-// ----------------------------------------------------------------------
-// Streaming input interfaces
-
-// Interface for the column reader to get the bytes. The interface is a stream
-// interface, meaning the bytes in order and once a byte is read, it does not
-// need to be read again.
-class InputStream {
- public:
-  // Returns the next 'num_to_peek' without advancing the current position.
-  // *num_bytes will contain the number of bytes returned which can only be
-  // less than num_to_peek at end of stream cases.
-  // Since the position is not advanced, calls to this function are idempotent.
-  // The buffer returned to the caller is still owned by the input stream and must
-  // stay valid until the next call to Peek() or Read().
-  virtual const uint8_t* Peek(int64_t num_to_peek, int64_t* num_bytes) = 0;
-
-  // Identical to Peek(), except the current position in the stream is advanced by
-  // *num_bytes.
-  virtual const uint8_t* Read(int64_t num_to_read, int64_t* num_bytes) = 0;
-
-  // Advance the stream without reading
-  virtual void Advance(int64_t num_bytes) = 0;
-
-  virtual ~InputStream() {}
-
- protected:
-  InputStream() {}
-};
-
-// Implementation of an InputStream when all the bytes are in memory.
-class PARQUET_EXPORT InMemoryInputStream : public InputStream {
- public:
-  InMemoryInputStream(RandomAccessSource* source, int64_t start, int64_t end);
-  explicit InMemoryInputStream(const std::shared_ptr<Buffer>& buffer);
-  virtual const uint8_t* Peek(int64_t num_to_peek, int64_t* num_bytes);
-  virtual const uint8_t* Read(int64_t num_to_read, int64_t* num_bytes);
-
-  virtual void Advance(int64_t num_bytes);
-
- private:
-  std::shared_ptr<Buffer> buffer_;
-  int64_t len_;
-  int64_t offset_;
-};
-
-// Implementation of an InputStream when only some of the bytes are in memory.
-class PARQUET_EXPORT BufferedInputStream : public InputStream {
- public:
-  BufferedInputStream(::arrow::MemoryPool* pool, int64_t buffer_size,
-                      RandomAccessSource* source, int64_t start, int64_t end);
-  virtual const uint8_t* Peek(int64_t num_to_peek, int64_t* num_bytes);
-  virtual const uint8_t* Read(int64_t num_to_read, int64_t* num_bytes);
-
-  virtual void Advance(int64_t num_bytes);
-
- private:
-  std::shared_ptr<ResizableBuffer> buffer_;
-  RandomAccessSource* source_;
-  int64_t stream_offset_;
-  int64_t stream_end_;
-  int64_t buffer_offset_;
-  int64_t buffer_size_;
-};
-
-std::shared_ptr<ResizableBuffer> PARQUET_EXPORT AllocateBuffer(
-    ::arrow::MemoryPool* pool = ::arrow::default_memory_pool(), int64_t size = 0);
-
-}  // namespace parquet
-
-#endif  // PARQUET_UTIL_MEMORY_H
diff --git a/src/parquet/util/schema-util.h b/src/parquet/util/schema-util.h
deleted file mode 100644
index 1c66f67..0000000
--- a/src/parquet/util/schema-util.h
+++ /dev/null
@@ -1,87 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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.
-
-#ifndef PARQUET_SCHEMA_UTIL_H
-#define PARQUET_SCHEMA_UTIL_H
-
-#include <string>
-#include <unordered_set>
-#include <vector>
-
-#include "parquet/exception.h"
-#include "parquet/schema.h"
-#include "parquet/types.h"
-
-using parquet::LogicalType;
-using parquet::ParquetException;
-using parquet::SchemaDescriptor;
-using parquet::schema::GroupNode;
-using parquet::schema::Node;
-using parquet::schema::NodePtr;
-
-inline bool str_endswith_tuple(const std::string& str) {
-  if (str.size() >= 6) {
-    return str.substr(str.size() - 6, 6) == "_tuple";
-  }
-  return false;
-}
-
-// Special case mentioned in the format spec:
-//   If the name is array or ends in _tuple, this should be a list of struct
-//   even for single child elements.
-inline bool HasStructListName(const GroupNode& node) {
-  return (node.name() == "array" || str_endswith_tuple(node.name()));
-}
-
-// TODO(itaiin): This aux. function is to be deleted once repeated structs are supported
-inline bool IsSimpleStruct(const Node* node) {
-  if (!node->is_group()) return false;
-  if (node->is_repeated()) return false;
-  if (node->logical_type() == LogicalType::LIST) return false;
-  // Special case mentioned in the format spec:
-  //   If the name is array or ends in _tuple, this should be a list of struct
-  //   even for single child elements.
-  auto group = static_cast<const GroupNode*>(node);
-  if (group->field_count() == 1 && HasStructListName(*group)) return false;
-
-  return true;
-}
-
-// Coalesce a list of schema fields indices which are the roots of the
-// columns referred by a list of column indices
-inline bool ColumnIndicesToFieldIndices(const SchemaDescriptor& descr,
-                                        const std::vector<int>& column_indices,
-                                        std::vector<int>* out) {
-  const GroupNode* group = descr.group_node();
-  std::unordered_set<int> already_added;
-  out->clear();
-  for (auto& column_idx : column_indices) {
-    auto field_node = descr.GetColumnRoot(column_idx);
-    auto field_idx = group->FieldIndex(*field_node);
-    if (field_idx < 0) {
-      return false;
-    }
-    auto insertion = already_added.insert(field_idx);
-    if (insertion.second) {
-      out->push_back(field_idx);
-    }
-  }
-
-  return true;
-}
-
-#endif  // PARQUET_SCHEMA_UTIL_H
diff --git a/src/parquet/util/stopwatch.h b/src/parquet/util/stopwatch.h
deleted file mode 100644
index 68cf792..0000000
--- a/src/parquet/util/stopwatch.h
+++ /dev/null
@@ -1,52 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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.
-
-#ifndef PARQUET_UTIL_STOPWATCH_H
-#define PARQUET_UTIL_STOPWATCH_H
-
-#include <stdio.h>
-#ifndef _MSC_VER
-#include <sys/time.h>
-#endif
-
-#include <ctime>
-#include <iostream>
-
-namespace parquet {
-
-class StopWatch {
- public:
-  StopWatch() {}
-
-  void Start() { gettimeofday(&start_time, 0); }
-
-  // Returns time in nanoseconds.
-  uint64_t Stop() {
-    struct timeval t_time;
-    gettimeofday(&t_time, 0);
-
-    return (1000L * 1000L * 1000L * (t_time.tv_sec - start_time.tv_sec) +
-            (t_time.tv_usec - start_time.tv_usec));
-  }
-
- private:
-  struct timeval start_time;
-};
-
-}  // namespace parquet
-
-#endif
diff --git a/src/parquet/util/test-common.h b/src/parquet/util/test-common.h
deleted file mode 100644
index 4e95870..0000000
--- a/src/parquet/util/test-common.h
+++ /dev/null
@@ -1,208 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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.
-
-#ifndef PARQUET_UTIL_TEST_COMMON_H
-#define PARQUET_UTIL_TEST_COMMON_H
-
-#include <chrono>
-#include <iostream>
-#include <limits>
-#include <random>
-#include <vector>
-
-#include "parquet/exception.h"
-#include "parquet/types.h"
-
-using std::vector;
-
-namespace parquet {
-
-namespace test {
-
-typedef ::testing::Types<BooleanType, Int32Type, Int64Type, Int96Type, FloatType,
-                         DoubleType, ByteArrayType, FLBAType>
-    ParquetTypes;
-
-class ParquetTestException : public parquet::ParquetException {
-  using ParquetException::ParquetException;
-};
-
-const char* get_data_dir() {
-  const auto result = std::getenv("PARQUET_TEST_DATA");
-  if (!result || !result[0]) {
-    throw ParquetTestException(
-        "Please point the PARQUET_TEST_DATA environment "
-        "variable to the test data directory");
-  }
-  return result;
-}
-
-template <typename T>
-static inline void assert_vector_equal(const vector<T>& left, const vector<T>& right) {
-  ASSERT_EQ(left.size(), right.size());
-
-  for (size_t i = 0; i < left.size(); ++i) {
-    ASSERT_EQ(left[i], right[i]) << i;
-  }
-}
-
-template <typename T>
-static inline bool vector_equal(const vector<T>& left, const vector<T>& right) {
-  if (left.size() != right.size()) {
-    return false;
-  }
-
-  for (size_t i = 0; i < left.size(); ++i) {
-    if (left[i] != right[i]) {
-      std::cerr << "index " << i << " left was " << left[i] << " right was " << right[i]
-                << std::endl;
-      return false;
-    }
-  }
-
-  return true;
-}
-
-template <typename T>
-static vector<T> slice(const vector<T>& values, int start, int end) {
-  if (end < start) {
-    return vector<T>(0);
-  }
-
-  vector<T> out(end - start);
-  for (int i = start; i < end; ++i) {
-    out[i - start] = values[i];
-  }
-  return out;
-}
-
-static inline vector<bool> flip_coins_seed(int n, double p, uint32_t seed) {
-  std::mt19937 gen(seed);
-  std::bernoulli_distribution d(p);
-
-  vector<bool> draws;
-  for (int i = 0; i < n; ++i) {
-    draws.push_back(d(gen));
-  }
-  return draws;
-}
-
-static inline vector<bool> flip_coins(int n, double p) {
-  uint64_t seed = std::chrono::high_resolution_clock::now().time_since_epoch().count();
-  std::mt19937 gen(static_cast<uint32_t>(seed));
-
-  std::bernoulli_distribution d(p);
-
-  vector<bool> draws;
-  for (int i = 0; i < n; ++i) {
-    draws.push_back(d(gen));
-  }
-  return draws;
-}
-
-void random_bytes(int n, uint32_t seed, std::vector<uint8_t>* out) {
-  std::mt19937 gen(seed);
-  std::uniform_int_distribution<int> d(0, 255);
-
-  for (int i = 0; i < n; ++i) {
-    out->push_back(static_cast<uint8_t>(d(gen) & 0xFF));
-  }
-}
-
-void random_bools(int n, double p, uint32_t seed, bool* out) {
-  std::mt19937 gen(seed);
-  std::bernoulli_distribution d(p);
-  for (int i = 0; i < n; ++i) {
-    out[i] = d(gen);
-  }
-}
-
-template <typename T>
-void random_numbers(int n, uint32_t seed, T min_value, T max_value, T* out) {
-  std::mt19937 gen(seed);
-  std::uniform_int_distribution<T> d(min_value, max_value);
-  for (int i = 0; i < n; ++i) {
-    out[i] = d(gen);
-  }
-}
-
-template <>
-void random_numbers(int n, uint32_t seed, float min_value, float max_value, float* out) {
-  std::mt19937 gen(seed);
-  std::uniform_real_distribution<float> d(min_value, max_value);
-  for (int i = 0; i < n; ++i) {
-    out[i] = d(gen);
-  }
-}
-
-template <>
-void random_numbers(int n, uint32_t seed, double min_value, double max_value,
-                    double* out) {
-  std::mt19937 gen(seed);
-  std::uniform_real_distribution<double> d(min_value, max_value);
-  for (int i = 0; i < n; ++i) {
-    out[i] = d(gen);
-  }
-}
-
-void random_Int96_numbers(int n, uint32_t seed, int32_t min_value, int32_t max_value,
-                          Int96* out) {
-  std::mt19937 gen(seed);
-  std::uniform_int_distribution<int32_t> d(min_value, max_value);
-  for (int i = 0; i < n; ++i) {
-    out[i].value[0] = d(gen);
-    out[i].value[1] = d(gen);
-    out[i].value[2] = d(gen);
-  }
-}
-
-void random_fixed_byte_array(int n, uint32_t seed, uint8_t* buf, int len, FLBA* out) {
-  std::mt19937 gen(seed);
-  std::uniform_int_distribution<int> d(0, 255);
-  for (int i = 0; i < n; ++i) {
-    out[i].ptr = buf;
-    for (int j = 0; j < len; ++j) {
-      buf[j] = static_cast<uint8_t>(d(gen) & 0xFF);
-    }
-    buf += len;
-  }
-}
-
-void random_byte_array(int n, uint32_t seed, uint8_t* buf, ByteArray* out, int min_size,
-                       int max_size) {
-  std::mt19937 gen(seed);
-  std::uniform_int_distribution<int> d1(min_size, max_size);
-  std::uniform_int_distribution<int> d2(0, 255);
-  for (int i = 0; i < n; ++i) {
-    int len = d1(gen);
-    out[i].len = len;
-    out[i].ptr = buf;
-    for (int j = 0; j < len; ++j) {
-      buf[j] = static_cast<uint8_t>(d2(gen) & 0xFF);
-    }
-    buf += len;
-  }
-}
-
-void random_byte_array(int n, uint32_t seed, uint8_t* buf, ByteArray* out, int max_size) {
-  random_byte_array(n, seed, buf, out, 0, max_size);
-}
-
-}  // namespace test
-}  // namespace parquet
-
-#endif  // PARQUET_UTIL_TEST_COMMON_H
diff --git a/src/parquet/util/visibility.h b/src/parquet/util/visibility.h
deleted file mode 100644
index 984fac2..0000000
--- a/src/parquet/util/visibility.h
+++ /dev/null
@@ -1,62 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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.
-
-#ifndef PARQUET_UTIL_VISIBILITY_H
-#define PARQUET_UTIL_VISIBILITY_H
-
-#if defined(_WIN32) || defined(__CYGWIN__)
-#ifdef _MSC_VER
-#pragma warning(push)
-// Disable warning for STL types usage in DLL interface
-// https://web.archive.org/web/20130317015847/http://connect.microsoft.com/VisualStudio/feedback/details/696593/vc-10-vs-2010-basic-string-exports
-#pragma warning(disable : 4275 4251)
-// Disable diamond inheritance warnings
-#pragma warning(disable : 4250)
-// Disable macro redefinition warnings
-#pragma warning(disable : 4005)
-// Disable extern before exported template warnings
-#pragma warning(disable : 4910)
-#endif
-#define PARQUET_EXPORT __declspec(dllexport)
-#define PARQUET_NO_EXPORT
-#else  // Not Windows
-#ifndef PARQUET_EXPORT
-#define PARQUET_EXPORT __attribute__((visibility("default")))
-#endif
-#ifndef PARQUET_NO_EXPORT
-#define PARQUET_NO_EXPORT __attribute__((visibility("hidden")))
-#endif
-#endif  // Non-Windows
-
-// gcc and clang disagree about how to handle template visibility when you have
-// explicit specializations https://llvm.org/bugs/show_bug.cgi?id=24815
-
-#if defined(__clang__)
-#define PARQUET_EXTERN_TEMPLATE extern template class PARQUET_EXPORT
-#else
-#define PARQUET_EXTERN_TEMPLATE extern template class
-#endif
-
-// This is a complicated topic, some reading on it:
-// http://www.codesynthesis.com/~boris/blog/2010/01/18/dll-export-cxx-templates/
-#ifdef _MSC_VER
-#define PARQUET_TEMPLATE_EXPORT PARQUET_EXPORT
-#else
-#define PARQUET_TEMPLATE_EXPORT
-#endif
-
-#endif  // PARQUET_UTIL_VISIBILITY_H
diff --git a/src/parquet/util/windows_compatibility.h b/src/parquet/util/windows_compatibility.h
deleted file mode 100644
index 899590a..0000000
--- a/src/parquet/util/windows_compatibility.h
+++ /dev/null
@@ -1,37 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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.
-
-#ifndef PARQUET_UTIL_WINDOWS_COMPATIBILITY
-#define PARQUET_UTIL_WINDOWS_COMPATIBILITY
-
-#ifdef _WIN32
-
-// Windows defines min and max macros that mess up std::min/max
-#ifndef NOMINMAX
-#define NOMINMAX
-#endif
-
-#include <windows.h>
-#include <winsock2.h>
-
-#ifdef OPTIONAL
-#undef OPTIONAL
-#endif
-
-#endif  // _WIN32
-
-#endif  // PARQUET_UTIL_WINDOWS_COMPATIBILITY
diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt
deleted file mode 100644
index 0705c83..0000000
--- a/tools/CMakeLists.txt
+++ /dev/null
@@ -1,31 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you 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.
-
-if (PARQUET_BUILD_EXECUTABLES)
-  set(EXECUTABLE_TOOLS
-    parquet-dump-schema
-    parquet_reader
-    parquet-scan)
-
-  foreach(TOOL ${EXECUTABLE_TOOLS})
-    add_executable(${TOOL} "${TOOL}.cc")
-    target_link_libraries(${TOOL} parquet_static)
-    # Avoid unsetting RPATH when installing
-    set_target_properties(${TOOL} PROPERTIES INSTALL_RPATH_USE_LINK_PATH TRUE)
-    install(TARGETS ${TOOL} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
-  endforeach(TOOL)
-endif()
diff --git a/tools/parquet-dump-schema.cc b/tools/parquet-dump-schema.cc
deleted file mode 100644
index 1e0239b..0000000
--- a/tools/parquet-dump-schema.cc
+++ /dev/null
@@ -1,36 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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.
-
-#include <iostream>
-
-#include "parquet/api/reader.h"
-#include "parquet/api/schema.h"
-
-int main(int argc, char** argv) {
-  std::string filename = argv[1];
-
-  try {
-    std::unique_ptr<parquet::ParquetFileReader> reader =
-        parquet::ParquetFileReader::OpenFile(filename);
-    PrintSchema(reader->metadata()->schema()->schema_root().get(), std::cout);
-  } catch (const std::exception& e) {
-    std::cerr << "Parquet error: " << e.what() << std::endl;
-    return -1;
-  }
-
-  return 0;
-}
diff --git a/tools/parquet-scan.cc b/tools/parquet-scan.cc
deleted file mode 100644
index ab9363b..0000000
--- a/tools/parquet-scan.cc
+++ /dev/null
@@ -1,78 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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.
-
-#include <ctime>
-#include <iostream>
-#include <list>
-#include <memory>
-
-#include "parquet/api/reader.h"
-
-int main(int argc, char** argv) {
-  if (argc > 4 || argc < 1) {
-    std::cerr << "Usage: parquet-scan [--batch-size=] [--columns=...] <file>"
-              << std::endl;
-    return -1;
-  }
-
-  std::string filename;
-
-  // Read command-line options
-  int batch_size = 256;
-  const std::string COLUMNS_PREFIX = "--columns=";
-  const std::string BATCH_SIZE_PREFIX = "--batch-size=";
-  std::vector<int> columns;
-  int num_columns = 0;
-
-  char *param, *value;
-  for (int i = 1; i < argc; i++) {
-    if ((param = std::strstr(argv[i], COLUMNS_PREFIX.c_str()))) {
-      value = std::strtok(param + COLUMNS_PREFIX.length(), ",");
-      while (value) {
-        columns.push_back(std::atoi(value));
-        value = std::strtok(nullptr, ",");
-        num_columns++;
-      }
-    } else if ((param = std::strstr(argv[i], BATCH_SIZE_PREFIX.c_str()))) {
-      value = std::strtok(param + BATCH_SIZE_PREFIX.length(), " ");
-      if (value) {
-        batch_size = std::atoi(value);
-      }
-    } else {
-      filename = argv[i];
-    }
-  }
-
-  try {
-    double total_time;
-    std::clock_t start_time = std::clock();
-    std::unique_ptr<parquet::ParquetFileReader> reader =
-        parquet::ParquetFileReader::OpenFile(filename);
-
-    int64_t total_rows = parquet::ScanFileContents(columns, batch_size, reader.get());
-
-    total_time = static_cast<double>(std::clock() - start_time) /
-      static_cast<double>(CLOCKS_PER_SEC);
-    std::cout << total_rows << " rows scanned in " << total_time << " seconds."
-              << std::endl;
-  } catch (const std::exception& e) {
-    std::cerr << "Parquet error: " << e.what() << std::endl;
-    return -1;
-  }
-
-  return 0;
-}
diff --git a/tools/parquet_reader.cc b/tools/parquet_reader.cc
deleted file mode 100644
index 34bdfc1..0000000
--- a/tools/parquet_reader.cc
+++ /dev/null
@@ -1,79 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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.
-
-#include <iostream>
-#include <list>
-#include <memory>
-
-#include "parquet/api/reader.h"
-
-int main(int argc, char** argv) {
-  if (argc > 5 || argc < 2) {
-    std::cerr << "Usage: parquet_reader [--only-metadata] [--no-memory-map] [--json]"
-                 "[--print-key-value-metadata] [--columns=...] <file>"
-              << std::endl;
-    return -1;
-  }
-
-  std::string filename;
-  bool print_values = true;
-  bool print_key_value_metadata = false;
-  bool memory_map = true;
-  bool format_json = false;
-
-  // Read command-line options
-  const std::string COLUMNS_PREFIX = "--columns=";
-  std::list<int> columns;
-
-  char *param, *value;
-  for (int i = 1; i < argc; i++) {
-    if ((param = std::strstr(argv[i], "--only-metadata"))) {
-      print_values = false;
-    } else if ((param = std::strstr(argv[i], "--print-key-value-metadata"))) {
-      print_key_value_metadata = true;
-    } else if ((param = std::strstr(argv[i], "--no-memory-map"))) {
-      memory_map = false;
-    } else if ((param = std::strstr(argv[i], "--json"))) {
-      format_json = true;
-    } else if ((param = std::strstr(argv[i], COLUMNS_PREFIX.c_str()))) {
-      value = std::strtok(param + COLUMNS_PREFIX.length(), ",");
-      while (value) {
-        columns.push_back(std::atoi(value));
-        value = std::strtok(nullptr, ",");
-      }
-    } else {
-      filename = argv[i];
-    }
-  }
-
-  try {
-    std::unique_ptr<parquet::ParquetFileReader> reader =
-        parquet::ParquetFileReader::OpenFile(filename, memory_map);
-    parquet::ParquetFilePrinter printer(reader.get());
-    if (format_json) {
-      printer.JSONPrint(std::cout, columns, filename.c_str());
-    } else {
-      printer.DebugPrint(std::cout, columns, print_values,
-        print_key_value_metadata, filename.c_str());
-    }
-  } catch (const std::exception& e) {
-    std::cerr << "Parquet error: " << e.what() << std::endl;
-    return -1;
-  }
-
-  return 0;
-}
