helix-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From hu...@apache.org
Subject [helix] branch master updated: Add metrics-common, zookeeper-api, helix-common modules (#684)
Date Tue, 11 Feb 2020 21:59:06 GMT
This is an automated email from the ASF dual-hosted git repository.

hulee pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/helix.git


The following commit(s) were added to refs/heads/master by this push:
     new b227b3b  Add metrics-common, zookeeper-api, helix-common modules (#684)
b227b3b is described below

commit b227b3b72b3ed0e347464f8d8e5279365a6e5acb
Author: Hunter Lee <hulee@linkedin.com>
AuthorDate: Tue Feb 11 13:58:57 2020 -0800

    Add metrics-common, zookeeper-api, helix-common modules (#684)
    
    We want to create a new module called zookeeper-api in order to decouple Helix's ZooKeeper APIs from helix-core. The goal is to enable non-Helix applications to use Helix's ZooKeeper APIs. This change also allows for better modularity and separation of concerns.
---
 bump-up.command                                    |   35 +
 helix-admin-webapp/pom.xml                         |    3 +
 .../org/apache/helix/webapp/HelixAdminWebApp.java  |    2 +-
 .../resources/ClusterRepresentationUtil.java       |    4 +-
 .../helix/webapp/resources/ClusterResource.java    |    4 +-
 .../helix/webapp/resources/ClustersResource.java   |    4 +-
 .../helix/webapp/resources/ConfigResource.java     |    4 +-
 .../helix/webapp/resources/ConstraintResource.java |    4 +-
 .../helix/webapp/resources/ControllerResource.java |    4 +-
 .../resources/ControllerStatusUpdateResource.java  |    2 +-
 .../webapp/resources/CurrentStateResource.java     |    2 +-
 .../webapp/resources/CurrentStatesResource.java    |    2 +-
 .../helix/webapp/resources/ErrorResource.java      |    2 +-
 .../helix/webapp/resources/ErrorsResource.java     |    2 +-
 .../webapp/resources/ExternalViewResource.java     |    2 +-
 .../helix/webapp/resources/IdealStateResource.java |    4 +-
 .../helix/webapp/resources/InstanceResource.java   |    2 +-
 .../helix/webapp/resources/InstancesResource.java  |    4 +-
 .../helix/webapp/resources/JobQueueResource.java   |    4 +-
 .../helix/webapp/resources/JobQueuesResource.java  |    4 +-
 .../apache/helix/webapp/resources/JobResource.java |    4 +-
 .../helix/webapp/resources/JsonParameters.java     |    2 +-
 .../webapp/resources/ResourceGroupResource.java    |    2 +-
 .../webapp/resources/ResourceGroupsResource.java   |    4 +-
 .../helix/webapp/resources/ResourceUtil.java       |    2 +-
 .../webapp/resources/SchedulerTasksResource.java   |    2 +-
 .../helix/webapp/resources/StateModelResource.java |    4 +-
 .../webapp/resources/StateModelsResource.java      |    4 +-
 .../webapp/resources/StatusUpdateResource.java     |    2 +-
 .../webapp/resources/StatusUpdatesResource.java    |    2 +-
 .../helix/webapp/resources/WorkflowsResource.java  |    4 +-
 .../helix/webapp/resources/ZkChildResource.java    |    4 +-
 .../helix/webapp/resources/ZkPathResource.java     |    4 +-
 .../org/apache/helix/webapp/AdminTestBase.java     |    4 +-
 .../org/apache/helix/webapp/AdminTestHelper.java   |    2 +-
 .../helix/webapp/TestClusterManagementWebapp.java  |    2 +-
 .../apache/helix/webapp/TestDisableResource.java   |    2 +-
 .../helix/webapp/TestHelixAdminScenariosRest.java  |    2 +-
 .../helix/webapp/TestResetPartitionState.java      |    2 +-
 .../webapp/resources/TestJobQueuesResource.java    |    2 +-
 helix-common/LICENSE                               |  270 +++
 helix-common/NOTICE                                |   37 +
 .../helix-common-0.9.2-SNAPSHOT.ivy                |   38 +-
 {helix-admin-webapp => helix-common}/pom.xml       |   78 +-
 helix-common/src/assemble/assembly.xml             |   60 +
 .../main/java/org/apache/helix/HelixException.java |    0
 .../java/org/apache/helix/SystemPropertyKeys.java  |   21 +-
 .../src/main/java/org/apache/helix/ZNRecord.java   |   30 +-
 .../main/java/org/apache/helix/ZNRecordDelta.java  |   11 +-
 .../zk/serializer/JacksonPayloadSerializer.java    |   11 +-
 .../manager/zk/serializer/PayloadSerializer.java   |   11 +-
 helix-common/src/test/conf/testng.xml              |   27 +
 helix-common/src/test/resources/log4j.properties   |   41 +
 helix-core/helix-core-0.9.2-SNAPSHOT.ivy           |    5 +-
 helix-core/pom.xml                                 |   11 +-
 .../java/org/apache/helix/BaseDataAccessor.java    |    6 +-
 .../main/java/org/apache/helix/ConfigAccessor.java |    5 +-
 .../main/java/org/apache/helix/GroupCommit.java    |   14 +-
 .../java/org/apache/helix/HelixDataAccessor.java   |   11 +-
 .../main/java/org/apache/helix/HelixManager.java   |    2 +
 .../main/java/org/apache/helix/HelixProperty.java  |   20 +-
 .../org/apache/helix/LiveInstanceInfoProvider.java |    3 +
 .../java/org/apache/helix/SystemPropertyKeys.java  |   19 +
 .../java/org/apache/helix/ZNRecordAssembler.java   |   29 +-
 .../java/org/apache/helix/ZNRecordBucketizer.java  |   97 +-
 .../java/org/apache/helix/ZNRecordUpdater.java     |   20 +-
 .../apache/helix/api/config/RebalanceConfig.java   |    2 +-
 .../api/config/StateTransitionTimeoutConfig.java   |    2 +-
 .../org/apache/helix/api/listeners/PreFetch.java   |    5 +-
 .../apache/helix/common/DedupEventProcessor.java   |    2 +-
 .../apache/helix/common/caches/TaskDataCache.java  |    2 +-
 .../helix/controller/ExternalViewGenerator.java    |    2 +-
 .../helix/controller/GenericHelixController.java   |    2 +-
 .../helix/controller/HelixControllerMain.java      |    2 +-
 .../helix/controller/HierarchicalDataHolder.java   |    2 +-
 .../changedetector/ResourceChangeSnapshot.java     |    2 +-
 .../ResourceControllerDataProvider.java            |    2 +-
 .../WorkflowControllerDataProvider.java            |    2 +-
 .../controller/rebalancer/AbstractRebalancer.java  |    2 +-
 .../controller/rebalancer/AutoRebalancer.java      |    2 +-
 .../rebalancer/DelayedAutoRebalancer.java          |    2 +-
 .../dataprovider/ZkBasedCapacityProvider.java      |    2 +-
 .../ZkBasedPartitionWeightProvider.java            |    2 +-
 .../AbstractEvenDistributionRebalanceStrategy.java |    2 +-
 .../rebalancer/strategy/AutoRebalanceStrategy.java |    2 +-
 .../strategy/ConstraintRebalanceStrategy.java      |    2 +-
 .../strategy/CrushRebalanceStrategy.java           |    2 +-
 .../strategy/MultiRoundCrushRebalanceStrategy.java |    2 +-
 .../rebalancer/strategy/RebalanceStrategy.java     |    2 +-
 .../rebalancer/waged/AssignmentMetadataStore.java  |   15 +-
 .../helix/controller/stages/ClusterDataCache.java  |    2 +-
 .../stages/ExternalViewComputeStage.java           |    7 +-
 .../controller/stages/PersistAssignmentStage.java  |    4 +-
 .../controller/strategy/AutoRebalanceStrategy.java |    2 +-
 .../org/apache/helix/examples/ExampleHelper.java   |    8 +-
 .../helix/examples/IdealStateBuilderExample.java   |    5 +-
 .../apache/helix/examples/IdealStateExample.java   |    5 +-
 .../java/org/apache/helix/examples/Quickstart.java |    7 +-
 .../examples/WeightAwareRebalanceUtilExample.java  |   22 +-
 .../ParticipantHealthReportCollector.java          |    2 +-
 .../ParticipantHealthReportCollectorImpl.java      |    2 +-
 .../apache/helix/manager/zk/BasicZkSerializer.java |   26 +-
 .../helix/manager/zk/ByteArraySerializer.java      |    5 +-
 .../apache/helix/manager/zk/CallbackHandler.java   |   10 +-
 .../helix/manager/zk/ChainedPathZkSerializer.java  |    5 +-
 .../helix/manager/zk/ControllerManagerHelper.java  |    2 +-
 .../helix/manager/zk/CurStateCarryOverUpdater.java |    4 +-
 .../zk/DefaultSchedulerMessageHandlerFactory.java  |    2 +-
 .../manager/zk/DistributedLeaderElection.java      |    2 +-
 .../apache/helix/manager/zk/HelixGroupCommit.java  |    6 +-
 .../helix/manager/zk/ParticipantManager.java       |   11 +-
 .../helix/manager/zk/PathBasedZkSerializer.java    |   28 +-
 .../apache/helix/manager/zk/WriteThroughCache.java |    2 +-
 .../helix/manager/zk/ZKExceptionHandler.java       |    2 +-
 .../org/apache/helix/manager/zk/ZKHelixAdmin.java  |   42 +-
 .../helix/manager/zk/ZKHelixDataAccessor.java      |   12 +-
 .../apache/helix/manager/zk/ZKHelixManager.java    |   14 +-
 .../java/org/apache/helix/manager/zk/ZKUtil.java   |    8 +-
 .../manager/zk/ZNRecordJacksonSerializer.java      |   45 +-
 .../helix/manager/zk/ZNRecordSerializer.java       |  116 +-
 .../manager/zk/ZNRecordStreamingSerializer.java    |  293 +--
 .../apache/helix/manager/zk/ZkAsyncCallbacks.java  |  176 +-
 .../helix/manager/zk/ZkBaseDataAccessor.java       |   93 +-
 .../helix/manager/zk/ZkBucketDataAccessor.java     |   14 +-
 .../helix/manager/zk/ZkCacheBaseDataAccessor.java  |   22 +-
 .../helix/manager/zk/ZkCacheEventThread.java       |    2 +-
 .../apache/helix/manager/zk/ZkCallbackCache.java   |    6 +-
 .../java/org/apache/helix/manager/zk/ZkClient.java |   15 +-
 .../manager/zk/ZkSessionMismatchedException.java   |   18 -
 .../zk/client/DedicatedZkClientFactory.java        |   50 +-
 .../helix/manager/zk/client/HelixZkClient.java     |  441 +---
 .../manager/zk/client/HelixZkClientFactory.java    |   46 -
 .../helix/manager/zk/client/SharedZkClient.java    |  109 +-
 .../manager/zk/client/SharedZkClientFactory.java   |  102 +-
 .../manager/zk/client/ZkConnectionManager.java     |  120 +-
 .../manager/zk/zookeeper/IZkStateListener.java     |   43 +-
 .../helix/manager/zk/zookeeper/ZkClient.java       | 2149 +-------------------
 .../helix/manager/zk/zookeeper/ZkConnection.java   |  174 +-
 .../org/apache/helix/messaging/ZNRecordRow.java    |    2 +-
 .../handling/HelixStateTransitionHandler.java      |    8 +-
 .../java/org/apache/helix/model/AlertHistory.java  |    2 +-
 .../java/org/apache/helix/model/AlertStatus.java   |    2 +-
 .../main/java/org/apache/helix/model/Alerts.java   |    2 +-
 .../java/org/apache/helix/model/ClusterConfig.java |    2 +-
 .../org/apache/helix/model/ClusterConstraints.java |    2 +-
 .../org/apache/helix/model/ControllerHistory.java  |    2 +-
 .../java/org/apache/helix/model/CurrentState.java  |    2 +-
 .../main/java/org/apache/helix/model/Error.java    |    2 +-
 .../java/org/apache/helix/model/ExternalView.java  |    2 +-
 .../java/org/apache/helix/model/HealthStat.java    |    2 +-
 .../java/org/apache/helix/model/IdealState.java    |    2 +-
 .../org/apache/helix/model/InstanceConfig.java     |    2 +-
 .../org/apache/helix/model/LeaderStandbySMD.java   |    2 +-
 .../java/org/apache/helix/model/LiveInstance.java  |    2 +-
 .../org/apache/helix/model/MaintenanceSignal.java  |    2 +-
 .../org/apache/helix/model/MasterSlaveSMD.java     |    2 +-
 .../main/java/org/apache/helix/model/Message.java  |    2 +-
 .../org/apache/helix/model/OnlineOfflineSMD.java   |    2 +-
 .../org/apache/helix/model/ParticipantHistory.java |    2 +-
 .../java/org/apache/helix/model/PauseSignal.java   |    2 +-
 .../org/apache/helix/model/PersistentStats.java    |    2 +-
 .../java/org/apache/helix/model/RESTConfig.java    |    2 +-
 .../org/apache/helix/model/ResourceAssignment.java |    2 +-
 .../org/apache/helix/model/ResourceConfig.java     |    2 +-
 .../org/apache/helix/model/ScheduledTaskSMD.java   |    2 +-
 .../apache/helix/model/StateModelDefinition.java   |    3 +-
 .../java/org/apache/helix/model/StatusUpdate.java  |    2 +-
 .../org/apache/helix/model/StorageSchemataSMD.java |    2 +-
 .../main/java/org/apache/helix/model/TaskSMD.java  |    2 +-
 .../helix/model/builder/IdealStateBuilder.java     |    2 +-
 .../helix/monitoring/ZKPathDataDumpTask.java       |    2 +-
 .../helix/monitoring/mbeans/ZkClientMonitor.java   |  231 +--
 .../monitoring/mbeans/ZkClientPathMonitor.java     |  228 +--
 .../helix/participant/HelixCustomCodeRunner.java   |   26 +-
 .../statemachine/ScheduledTaskStateModel.java      |    2 +-
 .../apache/helix/store/PropertyJsonSerializer.java |    2 +-
 .../apache/helix/store/ZNRecordJsonSerializer.java |    2 +-
 .../helix/store/zk/AutoFallbackPropertyStore.java  |    2 +-
 .../helix/store/zk/ZkHelixPropertyStore.java       |    3 +-
 .../helix/task/DeprecatedTaskRebalancer.java       |    4 +-
 .../java/org/apache/helix/task/JobContext.java     |    2 +-
 .../java/org/apache/helix/task/JobDispatcher.java  |    2 +-
 .../java/org/apache/helix/task/TaskDriver.java     |    6 +-
 .../main/java/org/apache/helix/task/TaskUtil.java  |    4 +-
 .../org/apache/helix/task/WorkflowContext.java     |    2 +-
 .../org/apache/helix/task/WorkflowDispatcher.java  |    2 +-
 .../helix/tools/ClusterExternalViewVerifier.java   |    2 +-
 .../helix/tools/ClusterLiveNodesVerifier.java      |    2 +-
 .../java/org/apache/helix/tools/ClusterSetup.java  |    8 +-
 .../apache/helix/tools/ClusterStateVerifier.java   |   14 +-
 .../org/apache/helix/tools/ClusterVerifier.java    |    8 +-
 .../BestPossibleExternalViewVerifier.java          |    4 +-
 .../ClusterVerifiers/ClusterLiveNodesVerifier.java |    2 +-
 .../StrictMatchExternalViewVerifier.java           |    4 +-
 .../ClusterVerifiers/ZkHelixClusterVerifier.java   |   10 +-
 .../helix/tools/DefaultIdealStateCalculator.java   |    2 +-
 .../tools/IdealCalculatorByConsistentHashing.java  |    2 +-
 .../helix/tools/IdealStateCalculatorByRush.java    |    2 +-
 .../tools/IdealStateCalculatorByShuffling.java     |    2 +-
 .../java/org/apache/helix/tools/MessagePoster.java |    6 +-
 .../helix/tools/StateModelConfigGenerator.java     |    2 +-
 .../java/org/apache/helix/tools/TestExecutor.java  |   10 +-
 .../java/org/apache/helix/tools/TestTrigger.java   |    2 +-
 .../java/org/apache/helix/tools/ZnodeOpArg.java    |    2 +-
 .../java/org/apache/helix/tools/ZnodeValue.java    |    2 +-
 .../tools/commandtools/CurrentStateCleanUp.java    |    4 +-
 .../tools/commandtools/IntegrationTestUtil.java    |    6 +-
 .../helix/tools/commandtools/LocalZKServer.java    |    7 +-
 .../apache/helix/tools/commandtools/ZKDumper.java  |    7 +-
 .../apache/helix/tools/commandtools/ZkCopy.java    |    4 +-
 .../tools/commandtools/ZkLogCSVFormatter.java      |    2 +-
 .../helix/util/ExponentialBackoffStrategy.java     |   52 +-
 .../org/apache/helix/util/GZipCompressionUtil.java |   56 +-
 .../org/apache/helix/util/StatusUpdateUtil.java    |    2 +-
 .../helix/util/WeightAwareRebalanceUtil.java       |    2 +-
 .../java/org/apache/helix/util/ZKClientPool.java   |    2 +-
 .../java/org/apache/helix/util/ZNRecordUtil.java   |    5 +-
 .../test/java/org/apache/helix/MockAccessor.java   |   37 +-
 .../TestEspressoStorageClusterIdealState.java      |   16 +-
 .../java/org/apache/helix/TestGroupCommit.java     |    4 +-
 .../src/test/java/org/apache/helix/TestHelper.java |   94 +-
 .../apache/helix/TestHierarchicalDataStore.java    |    4 +-
 .../org/apache/helix/TestShuffledIdealState.java   |   49 +-
 .../apache/helix/TestZKRoutingInfoProvider.java    |    2 +
 .../test/java/org/apache/helix/TestZkBasis.java    |    8 +-
 .../test/java/org/apache/helix/ZkTestHelper.java   |   28 +-
 .../java/org/apache/helix/common/ZkTestBase.java   |   14 +-
 .../common/caches/TestCurrentStateSnapshot.java    |    2 +-
 .../changedetector/TestResourceChangeDetector.java |    7 +-
 .../rebalancer/TestAutoRebalanceStrategy.java      |    2 +-
 ...stAutoRebalanceStrategyImbalanceAssignment.java |    2 +-
 .../rebalancer/TestZeroReplicaAvoidance.java       |    2 +-
 .../helix/controller/stages/BaseStageTest.java     |    2 +-
 .../controller/stages/DummyClusterManager.java     |    2 +-
 .../TestBestPossibleCalcStageCompatibility.java    |    2 +-
 .../stages/TestCompatibilityCheckStage.java        |    2 +-
 .../stages/TestCurrentStateComputationStage.java   |    2 +-
 .../stages/TestMessageThrottleStage.java           |    2 +-
 .../stages/TestResourceComputationStage.java       |    2 +-
 .../helix/controller/stages/TestTaskStage.java     |    2 +-
 .../TestAddStateModelFactoryAfterConnect.java      |    2 +-
 .../helix/integration/TestBucketizedResource.java  |    2 +-
 .../integration/TestCarryOverBadCurState.java      |    2 +-
 .../helix/integration/TestCleanupExternalView.java |    2 +-
 .../TestCorrectnessOnConnectivityLoss.java         |    2 +-
 .../org/apache/helix/integration/TestDisable.java  |    2 +-
 .../integration/TestDisableCustomCodeRunner.java   |    2 +-
 .../helix/integration/TestDisableExternalView.java |    2 +-
 .../helix/integration/TestDisableResource.java     |    2 +-
 .../helix/integration/TestDistributedCMMain.java   |    2 +-
 .../TestDistributedClusterController.java          |    2 +-
 .../org/apache/helix/integration/TestDriver.java   |    6 +-
 .../helix/integration/TestEnableCompression.java   |    6 +-
 .../integration/TestEntropyFreeNodeBounce.java     |    4 +-
 .../helix/integration/TestExternalViewUpdates.java |    2 +-
 .../TestNoThrottleDisabledPartitions.java          |    2 +-
 .../apache/helix/integration/TestNullReplica.java  |    2 +-
 .../TestPartitionLevelTransitionConstraint.java    |    2 +-
 .../integration/TestPersistAssignmentStage.java    |    2 +-
 .../integration/TestPreferenceListAsQueue.java     |    4 +-
 .../helix/integration/TestRenamePartition.java     |    2 +-
 .../helix/integration/TestResetPartitionState.java |    2 +-
 .../integration/TestResourceGroupEndtoEnd.java     |    2 +-
 .../TestResourceWithSamePartitionKey.java          |    2 +-
 .../integration/TestSyncSessionToController.java   |    2 +-
 .../integration/TestWeightBasedRebalanceUtil.java  |    2 +-
 .../integration/TestZkCallbackHandlerLeak.java     |    6 +-
 .../helix/integration/TestZkConnectionLost.java    |    6 +-
 .../TestControllerDataProviderSelectiveUpdate.java |    2 +-
 .../controller/TestControllerLeadershipChange.java |    2 +-
 .../controller/TestControllerLiveLock.java         |    2 +-
 .../manager/ClusterControllerManager.java          |    2 +-
 .../manager/ClusterDistributedController.java      |    2 +-
 .../manager/MockParticipantManager.java            |    2 +-
 .../manager/TestConsecutiveZkSessionExpiry.java    |    2 +-
 .../integration/manager/TestHelixDataAccessor.java |    2 +-
 .../manager/TestParticipantManager.java            |    2 +-
 .../helix/integration/manager/ZkTestManager.java   |    2 +-
 .../integration/messaging/TestBatchMessage.java    |    4 +-
 .../messaging/TestBatchMessageWrapper.java         |    2 +-
 .../integration/messaging/TestMessageThrottle.java |    4 +-
 .../messaging/TestMessageThrottle2.java            |    2 +-
 .../messaging/TestSchedulerMessage.java            |    2 +-
 .../messaging/TestSchedulerMessage2.java           |    2 +-
 .../messaging/TestSchedulerMsgContraints.java      |    2 +-
 .../messaging/TestSchedulerMsgUsingQueue.java      |    2 +-
 .../TestStateTransitionTimeoutWithResource.java    |    2 +-
 .../rebalancer/TestAutoIsWithEmptyMap.java         |    2 +-
 .../integration/rebalancer/TestAutoRebalance.java  |    6 +-
 .../TestAutoRebalancePartitionLimit.java           |    6 +-
 .../TestCustomizedIdealStateRebalancer.java        |    6 +-
 .../rebalancer/TestFullAutoNodeTagging.java        |    8 +-
 .../helix/integration/task/TaskTestUtil.java       |    2 +-
 .../helix/integration/task/TestTaskStopQueue.java  |    2 +-
 .../task/TestWorkflowContextWithoutConfig.java     |    2 +-
 .../manager/zk/TestAddBuiltInStateModelDef.java    |    2 +-
 .../helix/manager/zk/TestHandleNewSession.java     |   40 +-
 .../apache/helix/manager/zk/TestRawZkClient.java   |  159 +-
 .../manager/zk/TestWtCacheAsyncOpMultiThread.java  |    6 +-
 .../manager/zk/TestWtCacheAsyncOpSingleThread.java |    6 +-
 .../manager/zk/TestWtCacheSyncOpSingleThread.java  |    4 +-
 .../org/apache/helix/manager/zk/TestZKUtil.java    |    4 +-
 .../org/apache/helix/manager/zk/TestZKWatch.java   |    4 +-
 .../helix/manager/zk/TestZNRecordSerializer.java   |    4 +-
 .../helix/manager/zk/TestZNRecordSizeLimit.java    |    6 +-
 .../zk/TestZNRecordStreamingSerializer.java        |    2 +-
 .../helix/manager/zk/TestZkBaseDataAccessor.java   |   10 +-
 .../helix/manager/zk/TestZkBucketDataAccessor.java |   10 +-
 .../manager/zk/TestZkCacheAsyncOpSingleThread.java |   10 +-
 .../manager/zk/TestZkCacheSyncOpSingleThread.java  |    8 +-
 .../helix/manager/zk/TestZkClusterManager.java     |    2 +-
 .../apache/helix/manager/zk/TestZkFlapping.java    |    2 +
 .../apache/helix/manager/zk/TestZkHelixAdmin.java  |    2 +-
 .../apache/helix/manager/zk/TestZkReconnect.java   |    4 +-
 .../helix/manager/zk/client/TestHelixZkClient.java |   27 +-
 .../serializer/TestJacksonPayloadSerializer.java   |    2 +-
 .../messaging/TestDefaultMessagingService.java     |    2 +-
 .../apache/helix/mock/MockBaseDataAccessor.java    |    8 +-
 .../java/org/apache/helix/mock/MockHelixAdmin.java |    2 +-
 .../java/org/apache/helix/mock/MockManager.java    |    2 +-
 .../java/org/apache/helix/mock/MockZkClient.java   |    4 +-
 .../apache/helix/mock/MockZkHelixDataAccessor.java |    2 +-
 .../helix/mock/controller/MockController.java      |    6 +-
 .../participant/StoreAccessDiffNodeTransition.java |    7 +-
 .../participant/StoreAccessOneNodeTransition.java  |    7 +-
 .../helix/mock/spectator/MockSpectatorProcess.java |    9 +-
 .../org/apache/helix/model/TestClusterConfig.java  |    2 +-
 .../org/apache/helix/model/TestConstraint.java     |    2 +-
 .../org/apache/helix/model/TestInstanceConfig.java |    2 +-
 .../org/apache/helix/model/TestResourceConfig.java |    2 +-
 .../apache/helix/model/TestStateModelValidity.java |    2 +-
 .../helix/model/TestStateTransitionProperty.java   |    2 +-
 .../helix/monitoring/TestZKPathDataDumpTask.java   |    2 +-
 .../mbeans/TestClusterStatusMonitor.java           |    2 +-
 .../monitoring/mbeans/TestResourceMonitor.java     |    2 +-
 .../helix/participant/MockZKHelixManager.java      |    4 +-
 .../participant/TestDistControllerStateModel.java  |    2 +-
 .../TestDistControllerStateModelFactory.java       |    2 +-
 .../helix/spectator/TestRoutingDataCache.java      |    2 +-
 .../org/apache/helix/store/TestJsonComparator.java |    2 +-
 .../store/zk/TestAutoFallbackPropertyStore.java    |    4 +-
 .../helix/store/zk/TestZkHelixPropertyStore.java   |    8 +-
 .../zk/TestZkManagerWithAutoFallbackStore.java     |    2 +-
 .../helix/task/TestAssignableInstanceManager.java  |    2 +-
 .../org/apache/helix/tools/TestClusterSetup.java   |    2 +-
 .../org/apache/helix/tools/TestHelixAdminCli.java  |    2 +-
 .../java/org/apache/helix/tools/TestZkCopy.java    |    2 +-
 .../apache/helix/util/TestPropertyKeyGetPath.java  |    2 +-
 .../org/apache/helix/util/TestZKClientPool.java    |    8 +-
 helix-rest/pom.xml                                 |    2 +
 .../rest/common/HelixDataAccessorWrapper.java      |    2 +-
 .../apache/helix/rest/server/ServerContext.java    |   12 +-
 .../rest/server/json/instance/InstanceInfo.java    |    2 +-
 .../resources/helix/AbstractHelixResource.java     |    6 +-
 .../server/resources/helix/ClusterAccessor.java    |    4 +-
 .../rest/server/resources/helix/JobAccessor.java   |    4 +-
 .../resources/helix/PerInstanceAccessor.java       |    2 +-
 .../resources/helix/PropertyStoreAccessor.java     |    2 +-
 .../server/resources/helix/ResourceAccessor.java   |    4 +-
 .../rest/server/resources/helix/TaskAccessor.java  |    2 +-
 .../server/resources/helix/WorkflowAccessor.java   |    4 +-
 .../resources/zookeeper/ZooKeeperAccessor.java     |    6 +-
 .../rest/common/TestHelixDataAccessorWrapper.java  |    2 +-
 .../helix/rest/server/AbstractTestClass.java       |    8 +-
 .../helix/rest/server/TestClusterAccessor.java     |    2 +-
 .../helix/rest/server/TestPerInstanceAccessor.java |    2 +-
 .../rest/server/TestPropertyStoreAccessor.java     |    6 +-
 .../helix/rest/server/TestResourceAccessor.java    |    2 +-
 .../helix/rest/server/TestZooKeeperAccessor.java   |    4 +-
 metrics-common/LICENSE                             |  270 +++
 metrics-common/NOTICE                              |   37 +
 .../metrics-common-0.9.2-SNAPSHOT.ivy              |   36 +-
 {helix-admin-webapp => metrics-common}/pom.xml     |   74 +-
 metrics-common/src/assemble/assembly.xml           |   60 +
 .../helix/monitoring/SensorNameProvider.java       |    0
 .../helix/monitoring/mbeans/MBeanRegistrar.java    |    1 +
 .../monitoring/mbeans/MonitorDomainNames.java      |   14 +-
 .../mbeans/dynamicMBeans/DynamicMBeanProvider.java |  260 +++
 .../mbeans/dynamicMBeans/DynamicMetric.java        |    5 +-
 .../dynamicMBeans/HistogramDynamicMetric.java      |    1 +
 .../mbeans/dynamicMBeans/SimpleDynamicMetric.java  |   60 +
 .../mbeans/exception/MetricException.java          |   18 +-
 metrics-common/src/test/conf/testng.xml            |   27 +
 metrics-common/src/test/resources/log4j.properties |   41 +
 pom.xml                                            |   11 +-
 .../apache/helix/lockmanager/LockManagerDemo.java  |    7 +-
 .../apache/helix/recipes/rabbitmq/Consumer.java    |    2 +-
 .../recipes/rabbitmq/SetupConsumerCluster.java     |    2 +-
 recipes/rsync-replicated-file-system/pom.xml       |    5 -
 .../java/org/apache/helix/filestore/FileStore.java |    2 +-
 .../helix/filestore/FileStoreStateModel.java       |    4 +-
 .../apache/helix/filestore/IntegrationTest.java    |    8 +-
 .../org/apache/helix/filestore/Replicator.java     |    2 +-
 .../org/apache/helix/filestore/SetupCluster.java   |    2 +-
 .../helix/servicediscovery/ServiceDiscovery.java   |    2 +-
 .../apache/helix/taskexecution/TaskCluster.java    |    2 +-
 .../helix/taskexecution/TaskExecutionDemo.java     |    7 +-
 .../org/apache/helix/taskexecution/Worker.java     |    2 +-
 zookeeper-api/LICENSE                              |  270 +++
 zookeeper-api/NOTICE                               |   37 +
 {helix-admin-webapp => zookeeper-api}/pom.xml      |   89 +-
 zookeeper-api/src/assemble/assembly.xml            |   60 +
 zookeeper-api/src/main/config/log4j.properties     |   32 +
 .../helix/zookeeper/api/client/HelixZkClient.java  |    8 +-
 .../zookeeper/api/client/RealmAwareZkClient.java   |  123 +-
 .../api/factory/RealmAwareZkClientFactory.java     |    5 +-
 .../helix/zookeeper/datamodel}/ZNRecord.java       |   14 +-
 .../zookeeper/datamodel}/ZNRecordAssembler.java    |    3 +-
 .../zookeeper/datamodel}/ZNRecordBucketizer.java   |    3 +-
 .../helix/zookeeper/datamodel}/ZNRecordDelta.java  |    2 +-
 .../zookeeper/datamodel}/ZNRecordUpdater.java      |    5 +-
 .../serializer/JacksonPayloadSerializer.java       |    8 +-
 .../datamodel}/serializer/PayloadSerializer.java   |    2 +-
 .../serializer}/ZNRecordJacksonSerializer.java     |   18 +-
 .../datamodel/serializer}/ZNRecordSerializer.java  |   17 +-
 .../serializer}/ZNRecordStreamingSerializer.java   |   27 +-
 .../zookeeper/exception/ZkClientException.java     |   14 +-
 .../zookeeper/impl/client/FederatedZkClient.java   |  363 ++++
 .../zookeeper/impl}/client/SharedZkClient.java     |   57 +-
 .../helix/zookeeper/impl/client}/ZkClient.java     |   59 +-
 .../impl/factory/DedicatedZkClientFactory.java     |   57 +
 .../impl/factory/HelixZkClientFactory.java         |   68 +
 .../impl/factory}/SharedZkClientFactory.java       |   46 +-
 .../impl/factory}/ZkConnectionManager.java         |   55 +-
 .../helix/zookeeper}/util/GZipCompressionUtil.java |    5 +-
 .../helix/zookeeper/zkclient/DataUpdater.java      |   34 +
 .../helix/zookeeper/zkclient/ExceptionUtil.java    |   52 +
 .../zookeeper/zkclient/IDefaultNameSpace.java      |   27 +
 .../helix/zookeeper/zkclient/IZkChildListener.java |   41 +
 .../helix/zookeeper/zkclient/IZkConnection.java    |   60 +
 .../helix/zookeeper/zkclient/IZkDataListener.java  |   30 +
 .../zookeeper/zkclient}/IZkStateListener.java      |    2 +-
 .../helix/zookeeper/zkclient/NetworkUtil.java      |  122 ++
 .../apache/helix/zookeeper/zkclient}/ZkClient.java |  171 +-
 .../helix/zookeeper/zkclient}/ZkConnection.java    |    6 +-
 .../helix/zookeeper/zkclient}/ZkEventThread.java   |    5 +-
 .../apache/helix/zookeeper/zkclient/ZkLock.java    |   56 +
 .../apache/helix/zookeeper/zkclient/ZkServer.java  |  175 ++
 .../zookeeper/zkclient/annotation}/PreFetch.java   |    2 +-
 .../zkclient/callback}/ZkAsyncCallbacks.java       |   11 +-
 .../zkclient/deprecated/IZkStateListener.java      |   53 +
 .../zkclient/exception/ZkBadVersionException.java  |   39 +
 .../zookeeper/zkclient/exception/ZkException.java  |   71 +
 .../zkclient/exception/ZkInterruptedException.java |   26 +
 .../zkclient/exception/ZkMarshallingError.java     |   37 +
 .../zkclient/exception/ZkNoNodeException.java      |   39 +
 .../zkclient/exception/ZkNodeExistsException.java  |   39 +
 .../exception/ZkSessionMismatchedException.java    |   22 +-
 .../zkclient/exception/ZkTimeoutException.java     |   37 +
 .../zkclient/metric}/ZkClientMonitor.java          |   15 +-
 .../zkclient/metric}/ZkClientPathMonitor.java      |    4 +-
 .../zkclient/serialize}/BasicZkSerializer.java     |    4 +-
 .../serialize/BytesPushThroughSerializer.java      |   36 +
 .../zkclient/serialize}/PathBasedZkSerializer.java |    5 +-
 .../zkclient/serialize/SerializableSerializer.java |   55 +
 .../serialize/TcclAwareObjectIputStream.java       |   82 +
 .../zookeeper/zkclient/serialize/ZkSerializer.java |   33 +
 .../zkclient}/util/ExponentialBackoffStrategy.java |   22 +-
 zookeeper-api/src/test/conf/testng.xml             |   27 +
 zookeeper-api/src/test/resources/log4j.properties  |   41 +
 .../zookeeper-api-0.9.2-SNAPSHOT.ivy               |   39 +-
 461 files changed, 5144 insertions(+), 5925 deletions(-)

diff --git a/bump-up.command b/bump-up.command
index d67616c..b59f314 100755
--- a/bump-up.command
+++ b/bump-up.command
@@ -41,6 +41,40 @@ sed -i "s/${version}/${new_version}/g" pom.xml
 # git diff pom.xml
 grep -C 1 "$new_version" pom.xml
 
+echo "bump up helix-common/pom.xml"
+sed -i "s/${version}/${new_version}/g" helix-common/pom.xml
+grep -C 1 "$new_version" helix-common/pom.xml
+# git diff helix-common/pom.xml
+
+ivy_file="helix-common-"$version".ivy"
+new_ivy_file="helix-common-"$new_version".ivy"
+# echo "$ivy_file"
+if [ -f helix-common/$ivy_file ]; then
+  echo "bump up helix-common/$ivy_file"
+  git mv "helix-common/$ivy_file" "helix-common/$new_ivy_file"
+  sed -i "s/${version}/${new_version}/g" "helix-common/$new_ivy_file"
+  grep -C 1 "$new_version" "helix-common/$new_ivy_file"
+else
+  echo "helix-common/$ivy_file not exist"
+fi
+
+echo "bump up zookeeper-api/pom.xml"
+sed -i "s/${version}/${new_version}/g" zookeeper-api/pom.xml
+grep -C 1 "$new_version" zookeeper-api/pom.xml
+# git diff zookeeper-api/pom.xml
+
+ivy_file="zookeeper-api-"$version".ivy"
+new_ivy_file="zookeeper-api-"$new_version".ivy"
+# echo "$ivy_file"
+if [ -f zookeeper-api/$ivy_file ]; then
+  echo "bump up zookeeper-api/$ivy_file"
+  git mv "zookeeper-api/$ivy_file" "zookeeper-api/$new_ivy_file"
+  sed -i "s/${version}/${new_version}/g" "zookeeper-api/$new_ivy_file"
+  grep -C 1 "$new_version" "zookeeper-api/$new_ivy_file"
+else
+  echo "zookeeper-api/$ivy_file not exist"
+fi
+
 echo "bump up helix-core/pom.xml"
 sed -i "s/${version}/${new_version}/g" helix-core/pom.xml
 grep -C 1 "$new_version" helix-core/pom.xml
@@ -109,6 +143,7 @@ else
   echo "helix-agent/$ivy_file not exist"
 fi
 
+
 for POM in helix-agent/pom.xml recipes/task-execution/pom.xml recipes/pom.xml recipes/distributed-lock-manager/pom.xml recipes/rsync-replicated-file-system/pom.xml recipes/rabbitmq-consumer-group/pom.xml recipes/service-discovery/pom.xml
 do
   echo "bump up $POM"
diff --git a/helix-admin-webapp/pom.xml b/helix-admin-webapp/pom.xml
index 87e7d8e..bd89133 100644
--- a/helix-admin-webapp/pom.xml
+++ b/helix-admin-webapp/pom.xml
@@ -34,8 +34,11 @@ under the License.
       org.apache.helix*,
       org.codehaus.jackson*,
       org.apache.commons.cli*,
+      org.apache.commons.cli;version="[1.2,2)",
+      org.apache.commons.io*;version="[1.4,2)",
       org.restlet*,
       org.slf4j*;version="[1.6,2)",
+      org.apache.zookeeper*;version="[3.4,4)",
       *
     </osgi.import>
     <osgi.export>org.apache.helix.webapp*;version="${project.version};-noimport:=true</osgi.export>
diff --git a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/HelixAdminWebApp.java b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/HelixAdminWebApp.java
index 9785537..a68c85d 100644
--- a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/HelixAdminWebApp.java
+++ b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/HelixAdminWebApp.java
@@ -21,7 +21,7 @@ package org.apache.helix.webapp;
 
 import org.apache.helix.manager.zk.ByteArraySerializer;
 import org.apache.helix.manager.zk.ZNRecordSerializer;
-import org.apache.helix.manager.zk.ZkClient;
+import org.apache.helix.zookeeper.impl.client.ZkClient;
 import org.apache.helix.webapp.resources.ResourceUtil;
 import org.restlet.Component;
 import org.restlet.Context;
diff --git a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ClusterRepresentationUtil.java b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ClusterRepresentationUtil.java
index 2710684..3adc6af 100644
--- a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ClusterRepresentationUtil.java
+++ b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ClusterRepresentationUtil.java
@@ -34,11 +34,11 @@ import org.apache.helix.PropertyKey;
 import org.apache.helix.PropertyKey.Builder;
 import org.apache.helix.PropertyPathBuilder;
 import org.apache.helix.PropertyType;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
 import org.apache.helix.manager.zk.ZKHelixDataAccessor;
 import org.apache.helix.manager.zk.ZNRecordSerializer;
 import org.apache.helix.manager.zk.ZkBaseDataAccessor;
-import org.apache.helix.manager.zk.ZkClient;
+import org.apache.helix.zookeeper.impl.client.ZkClient;
 import org.apache.helix.model.LiveInstance.LiveInstanceProperty;
 import org.codehaus.jackson.JsonGenerationException;
 import org.codehaus.jackson.JsonParseException;
diff --git a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ClusterResource.java b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ClusterResource.java
index e168903..f4d1de3 100644
--- a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ClusterResource.java
+++ b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ClusterResource.java
@@ -25,8 +25,8 @@ import java.util.List;
 import org.apache.helix.HelixDataAccessor;
 import org.apache.helix.HelixException;
 import org.apache.helix.PropertyKey.Builder;
-import org.apache.helix.ZNRecord;
-import org.apache.helix.manager.zk.ZkClient;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
+import org.apache.helix.zookeeper.impl.client.ZkClient;
 import org.apache.helix.model.LiveInstance;
 import org.apache.helix.tools.ClusterSetup;
 import org.codehaus.jackson.JsonGenerationException;
diff --git a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ClustersResource.java b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ClustersResource.java
index fe6a6d5..05a2e8f 100644
--- a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ClustersResource.java
+++ b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ClustersResource.java
@@ -23,8 +23,8 @@ import java.io.IOException;
 import java.util.List;
 
 import org.apache.helix.HelixException;
-import org.apache.helix.ZNRecord;
-import org.apache.helix.manager.zk.ZkClient;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
+import org.apache.helix.zookeeper.impl.client.ZkClient;
 import org.apache.helix.tools.ClusterSetup;
 import org.codehaus.jackson.JsonGenerationException;
 import org.codehaus.jackson.map.JsonMappingException;
diff --git a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ConfigResource.java b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ConfigResource.java
index c7a58b5..65f468d 100644
--- a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ConfigResource.java
+++ b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ConfigResource.java
@@ -25,8 +25,8 @@ import java.util.Map;
 
 import org.apache.helix.HelixAdmin;
 import org.apache.helix.HelixException;
-import org.apache.helix.ZNRecord;
-import org.apache.helix.manager.zk.ZkClient;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
+import org.apache.helix.zookeeper.impl.client.ZkClient;
 import org.apache.helix.model.HelixConfigScope;
 import org.apache.helix.model.HelixConfigScope.ConfigScopeProperty;
 import org.apache.helix.model.builder.HelixConfigScopeBuilder;
diff --git a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ConstraintResource.java b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ConstraintResource.java
index dc16c18..56fc1cf 100644
--- a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ConstraintResource.java
+++ b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ConstraintResource.java
@@ -22,9 +22,9 @@ package org.apache.helix.webapp.resources;
 import java.util.Map;
 
 import org.apache.helix.HelixAdmin;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
 import org.apache.helix.manager.zk.ZKHelixAdmin;
-import org.apache.helix.manager.zk.ZkClient;
+import org.apache.helix.zookeeper.impl.client.ZkClient;
 import org.apache.helix.model.ClusterConstraints.ConstraintType;
 import org.apache.helix.tools.ClusterSetup;
 import org.restlet.data.MediaType;
diff --git a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ControllerResource.java b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ControllerResource.java
index fede1b6..2004992 100644
--- a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ControllerResource.java
+++ b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ControllerResource.java
@@ -30,10 +30,10 @@ import org.apache.helix.HelixException;
 import org.apache.helix.PropertyKey;
 import org.apache.helix.PropertyKey.Builder;
 import org.apache.helix.PropertyType;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
 import org.apache.helix.manager.zk.ZKHelixDataAccessor;
 import org.apache.helix.manager.zk.ZkBaseDataAccessor;
-import org.apache.helix.manager.zk.ZkClient;
+import org.apache.helix.zookeeper.impl.client.ZkClient;
 import org.apache.helix.model.LiveInstance;
 import org.apache.helix.tools.ClusterSetup;
 import org.apache.helix.util.StatusUpdateUtil.Level;
diff --git a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ControllerStatusUpdateResource.java b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ControllerStatusUpdateResource.java
index 6a6a7b7..54875c1 100644
--- a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ControllerStatusUpdateResource.java
+++ b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ControllerStatusUpdateResource.java
@@ -23,7 +23,7 @@ import java.io.IOException;
 
 import org.apache.helix.PropertyKey;
 import org.apache.helix.PropertyKey.Builder;
-import org.apache.helix.manager.zk.ZkClient;
+import org.apache.helix.zookeeper.impl.client.ZkClient;
 import org.apache.helix.webapp.RestAdminApplication;
 import org.codehaus.jackson.JsonGenerationException;
 import org.codehaus.jackson.map.JsonMappingException;
diff --git a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/CurrentStateResource.java b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/CurrentStateResource.java
index 424ce92..6a84ddd 100644
--- a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/CurrentStateResource.java
+++ b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/CurrentStateResource.java
@@ -23,7 +23,7 @@ import java.io.IOException;
 
 import org.apache.helix.PropertyKey;
 import org.apache.helix.PropertyKey.Builder;
-import org.apache.helix.manager.zk.ZkClient;
+import org.apache.helix.zookeeper.impl.client.ZkClient;
 import org.apache.helix.webapp.RestAdminApplication;
 import org.codehaus.jackson.JsonGenerationException;
 import org.codehaus.jackson.map.JsonMappingException;
diff --git a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/CurrentStatesResource.java b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/CurrentStatesResource.java
index 02582a3..5787075 100644
--- a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/CurrentStatesResource.java
+++ b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/CurrentStatesResource.java
@@ -22,7 +22,7 @@ package org.apache.helix.webapp.resources;
 import java.io.IOException;
 
 import org.apache.helix.PropertyType;
-import org.apache.helix.manager.zk.ZkClient;
+import org.apache.helix.zookeeper.impl.client.ZkClient;
 import org.apache.helix.webapp.RestAdminApplication;
 import org.codehaus.jackson.JsonGenerationException;
 import org.codehaus.jackson.map.JsonMappingException;
diff --git a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ErrorResource.java b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ErrorResource.java
index 0c12705..5952bc2 100644
--- a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ErrorResource.java
+++ b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ErrorResource.java
@@ -23,7 +23,7 @@ import java.io.IOException;
 
 import org.apache.helix.PropertyKey;
 import org.apache.helix.PropertyKey.Builder;
-import org.apache.helix.manager.zk.ZkClient;
+import org.apache.helix.zookeeper.impl.client.ZkClient;
 import org.apache.helix.webapp.RestAdminApplication;
 import org.codehaus.jackson.JsonGenerationException;
 import org.codehaus.jackson.map.JsonMappingException;
diff --git a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ErrorsResource.java b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ErrorsResource.java
index 671c528..efb3d97 100644
--- a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ErrorsResource.java
+++ b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ErrorsResource.java
@@ -22,7 +22,7 @@ package org.apache.helix.webapp.resources;
 import java.io.IOException;
 
 import org.apache.helix.PropertyType;
-import org.apache.helix.manager.zk.ZkClient;
+import org.apache.helix.zookeeper.impl.client.ZkClient;
 import org.apache.helix.webapp.RestAdminApplication;
 import org.codehaus.jackson.JsonGenerationException;
 import org.codehaus.jackson.map.JsonMappingException;
diff --git a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ExternalViewResource.java b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ExternalViewResource.java
index 801a86f..48d0967 100644
--- a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ExternalViewResource.java
+++ b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ExternalViewResource.java
@@ -23,7 +23,7 @@ import java.io.IOException;
 
 import org.apache.helix.PropertyKey;
 import org.apache.helix.PropertyKey.Builder;
-import org.apache.helix.manager.zk.ZkClient;
+import org.apache.helix.zookeeper.impl.client.ZkClient;
 import org.codehaus.jackson.JsonGenerationException;
 import org.codehaus.jackson.map.JsonMappingException;
 import org.restlet.data.MediaType;
diff --git a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/IdealStateResource.java b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/IdealStateResource.java
index b927a35..ae1a0ab 100644
--- a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/IdealStateResource.java
+++ b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/IdealStateResource.java
@@ -26,8 +26,8 @@ import org.apache.helix.HelixDataAccessor;
 import org.apache.helix.HelixException;
 import org.apache.helix.PropertyKey;
 import org.apache.helix.PropertyKey.Builder;
-import org.apache.helix.ZNRecord;
-import org.apache.helix.manager.zk.ZkClient;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
+import org.apache.helix.zookeeper.impl.client.ZkClient;
 import org.apache.helix.model.IdealState;
 import org.apache.helix.tools.ClusterSetup;
 import org.codehaus.jackson.JsonGenerationException;
diff --git a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/InstanceResource.java b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/InstanceResource.java
index 23d6303..f251cbb 100644
--- a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/InstanceResource.java
+++ b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/InstanceResource.java
@@ -25,7 +25,7 @@ import java.util.Arrays;
 import org.apache.helix.HelixException;
 import org.apache.helix.PropertyKey;
 import org.apache.helix.PropertyKey.Builder;
-import org.apache.helix.manager.zk.ZkClient;
+import org.apache.helix.zookeeper.impl.client.ZkClient;
 import org.apache.helix.tools.ClusterSetup;
 import org.codehaus.jackson.JsonGenerationException;
 import org.codehaus.jackson.map.JsonMappingException;
diff --git a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/InstancesResource.java b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/InstancesResource.java
index 5909d72..9c03400 100644
--- a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/InstancesResource.java
+++ b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/InstancesResource.java
@@ -28,8 +28,8 @@ import java.util.TreeMap;
 import com.google.common.collect.Lists;
 import org.apache.helix.HelixDataAccessor;
 import org.apache.helix.HelixException;
-import org.apache.helix.ZNRecord;
-import org.apache.helix.manager.zk.ZkClient;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
+import org.apache.helix.zookeeper.impl.client.ZkClient;
 import org.apache.helix.model.InstanceConfig;
 import org.apache.helix.model.LiveInstance;
 import org.apache.helix.tools.ClusterSetup;
diff --git a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/JobQueueResource.java b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/JobQueueResource.java
index 10c603d..bacd0ea 100644
--- a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/JobQueueResource.java
+++ b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/JobQueueResource.java
@@ -24,8 +24,8 @@ import java.util.Map;
 import org.apache.helix.HelixDataAccessor;
 import org.apache.helix.HelixException;
 import org.apache.helix.PropertyKey;
-import org.apache.helix.ZNRecord;
-import org.apache.helix.manager.zk.ZkClient;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
+import org.apache.helix.zookeeper.impl.client.ZkClient;
 import org.apache.helix.model.ResourceConfig;
 import org.apache.helix.task.JobConfig;
 import org.apache.helix.task.TaskDriver;
diff --git a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/JobQueuesResource.java b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/JobQueuesResource.java
index 2937026..debdb49 100644
--- a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/JobQueuesResource.java
+++ b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/JobQueuesResource.java
@@ -29,8 +29,8 @@ import org.apache.helix.HelixDataAccessor;
 import org.apache.helix.HelixException;
 import org.apache.helix.HelixProperty;
 import org.apache.helix.PropertyKey;
-import org.apache.helix.ZNRecord;
-import org.apache.helix.manager.zk.ZkClient;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
+import org.apache.helix.zookeeper.impl.client.ZkClient;
 import org.apache.helix.task.JobQueue;
 import org.apache.helix.task.TaskDriver;
 import org.apache.helix.task.Workflow;
diff --git a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/JobResource.java b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/JobResource.java
index 8389e5d..aab37ed 100644
--- a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/JobResource.java
+++ b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/JobResource.java
@@ -22,8 +22,8 @@ package org.apache.helix.webapp.resources;
 import org.apache.helix.HelixDataAccessor;
 import org.apache.helix.HelixProperty;
 import org.apache.helix.PropertyKey;
-import org.apache.helix.ZNRecord;
-import org.apache.helix.manager.zk.ZkClient;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
+import org.apache.helix.zookeeper.impl.client.ZkClient;
 import org.apache.helix.task.JobContext;
 import org.apache.helix.task.TaskDriver;
 import org.apache.helix.task.TaskUtil;
diff --git a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/JsonParameters.java b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/JsonParameters.java
index 41d9a77..69e4de0 100644
--- a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/JsonParameters.java
+++ b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/JsonParameters.java
@@ -29,7 +29,7 @@ import java.util.Set;
 import java.util.TreeMap;
 
 import org.apache.helix.HelixException;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
 import org.apache.helix.tools.ClusterSetup;
 import org.codehaus.jackson.map.ObjectMapper;
 import org.restlet.data.Form;
diff --git a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ResourceGroupResource.java b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ResourceGroupResource.java
index a8c7634..860199e 100644
--- a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ResourceGroupResource.java
+++ b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ResourceGroupResource.java
@@ -25,7 +25,7 @@ import java.util.Arrays;
 import org.apache.helix.HelixException;
 import org.apache.helix.PropertyKey;
 import org.apache.helix.PropertyKey.Builder;
-import org.apache.helix.manager.zk.ZkClient;
+import org.apache.helix.zookeeper.impl.client.ZkClient;
 import org.apache.helix.tools.ClusterSetup;
 import org.codehaus.jackson.JsonGenerationException;
 import org.codehaus.jackson.map.JsonMappingException;
diff --git a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ResourceGroupsResource.java b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ResourceGroupsResource.java
index 75f8fb5..d974987 100644
--- a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ResourceGroupsResource.java
+++ b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ResourceGroupsResource.java
@@ -27,8 +27,8 @@ import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
 import org.apache.helix.HelixException;
 import org.apache.helix.PropertyKey;
-import org.apache.helix.ZNRecord;
-import org.apache.helix.manager.zk.ZkClient;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
+import org.apache.helix.zookeeper.impl.client.ZkClient;
 import org.apache.helix.model.IdealState;
 import org.apache.helix.model.IdealState.RebalanceMode;
 import org.apache.helix.tools.ClusterSetup;
diff --git a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ResourceUtil.java b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ResourceUtil.java
index 78a760a..053b542 100644
--- a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ResourceUtil.java
+++ b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ResourceUtil.java
@@ -30,7 +30,7 @@ import org.apache.helix.BaseDataAccessor;
 import org.apache.helix.HelixException;
 import org.apache.helix.PropertyKey;
 import org.apache.helix.manager.zk.ZkBaseDataAccessor;
-import org.apache.helix.manager.zk.ZkClient;
+import org.apache.helix.zookeeper.impl.client.ZkClient;
 import org.apache.helix.webapp.RestAdminApplication;
 import org.codehaus.jackson.JsonGenerationException;
 import org.codehaus.jackson.map.JsonMappingException;
diff --git a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/SchedulerTasksResource.java b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/SchedulerTasksResource.java
index 9e4b849..d38c8e4 100644
--- a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/SchedulerTasksResource.java
+++ b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/SchedulerTasksResource.java
@@ -31,7 +31,7 @@ import org.apache.helix.HelixException;
 import org.apache.helix.InstanceType;
 import org.apache.helix.PropertyPathBuilder;
 import org.apache.helix.manager.zk.DefaultSchedulerMessageHandlerFactory;
-import org.apache.helix.manager.zk.ZkClient;
+import org.apache.helix.zookeeper.impl.client.ZkClient;
 import org.apache.helix.model.LiveInstance;
 import org.apache.helix.model.Message;
 import org.apache.helix.model.Message.MessageType;
diff --git a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/StateModelResource.java b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/StateModelResource.java
index efb5776..ea451eb 100644
--- a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/StateModelResource.java
+++ b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/StateModelResource.java
@@ -25,8 +25,8 @@ import org.apache.helix.HelixDataAccessor;
 import org.apache.helix.HelixException;
 import org.apache.helix.PropertyKey;
 import org.apache.helix.PropertyKey.Builder;
-import org.apache.helix.ZNRecord;
-import org.apache.helix.manager.zk.ZkClient;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
+import org.apache.helix.zookeeper.impl.client.ZkClient;
 import org.apache.helix.model.StateModelDefinition;
 import org.apache.helix.tools.ClusterSetup;
 import org.apache.helix.webapp.RestAdminApplication;
diff --git a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/StateModelsResource.java b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/StateModelsResource.java
index 326fa54..5340067 100644
--- a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/StateModelsResource.java
+++ b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/StateModelsResource.java
@@ -24,8 +24,8 @@ import java.util.List;
 
 import org.apache.helix.HelixDataAccessor;
 import org.apache.helix.HelixException;
-import org.apache.helix.ZNRecord;
-import org.apache.helix.manager.zk.ZkClient;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
+import org.apache.helix.zookeeper.impl.client.ZkClient;
 import org.apache.helix.model.StateModelDefinition;
 import org.apache.helix.tools.ClusterSetup;
 import org.apache.helix.webapp.RestAdminApplication;
diff --git a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/StatusUpdateResource.java b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/StatusUpdateResource.java
index 2d81a22..2e9aafe 100644
--- a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/StatusUpdateResource.java
+++ b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/StatusUpdateResource.java
@@ -23,7 +23,7 @@ import java.io.IOException;
 
 import org.apache.helix.PropertyKey;
 import org.apache.helix.PropertyKey.Builder;
-import org.apache.helix.manager.zk.ZkClient;
+import org.apache.helix.zookeeper.impl.client.ZkClient;
 import org.apache.helix.webapp.RestAdminApplication;
 import org.codehaus.jackson.JsonGenerationException;
 import org.codehaus.jackson.map.JsonMappingException;
diff --git a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/StatusUpdatesResource.java b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/StatusUpdatesResource.java
index 0838a85..4867365 100644
--- a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/StatusUpdatesResource.java
+++ b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/StatusUpdatesResource.java
@@ -22,7 +22,7 @@ package org.apache.helix.webapp.resources;
 import java.io.IOException;
 
 import org.apache.helix.PropertyType;
-import org.apache.helix.manager.zk.ZkClient;
+import org.apache.helix.zookeeper.impl.client.ZkClient;
 import org.apache.helix.webapp.RestAdminApplication;
 import org.codehaus.jackson.JsonGenerationException;
 import org.codehaus.jackson.map.JsonMappingException;
diff --git a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/WorkflowsResource.java b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/WorkflowsResource.java
index a695c36..658e98d 100644
--- a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/WorkflowsResource.java
+++ b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/WorkflowsResource.java
@@ -32,8 +32,8 @@ import org.apache.helix.HelixManagerFactory;
 import org.apache.helix.HelixProperty;
 import org.apache.helix.InstanceType;
 import org.apache.helix.PropertyKey;
-import org.apache.helix.ZNRecord;
-import org.apache.helix.manager.zk.ZkClient;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
+import org.apache.helix.zookeeper.impl.client.ZkClient;
 import org.apache.helix.task.TaskDriver;
 import org.apache.helix.task.Workflow;
 import org.apache.helix.task.WorkflowConfig;
diff --git a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ZkChildResource.java b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ZkChildResource.java
index d321e38..2c81de2 100644
--- a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ZkChildResource.java
+++ b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ZkChildResource.java
@@ -21,8 +21,8 @@ package org.apache.helix.webapp.resources;
 
 import java.util.List;
 
-import org.apache.helix.ZNRecord;
-import org.apache.helix.manager.zk.ZkClient;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
+import org.apache.helix.zookeeper.impl.client.ZkClient;
 import org.apache.helix.webapp.RestAdminApplication;
 import org.apache.zookeeper.data.Stat;
 import org.restlet.data.MediaType;
diff --git a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ZkPathResource.java b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ZkPathResource.java
index 3e49284..99294e4 100644
--- a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ZkPathResource.java
+++ b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ZkPathResource.java
@@ -23,8 +23,8 @@ import java.util.Date;
 import java.util.List;
 
 import org.apache.helix.HelixException;
-import org.apache.helix.ZNRecord;
-import org.apache.helix.manager.zk.ZkClient;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
+import org.apache.helix.zookeeper.impl.client.ZkClient;
 import org.apache.helix.webapp.RestAdminApplication;
 import org.apache.zookeeper.data.Stat;
 import org.restlet.data.MediaType;
diff --git a/helix-admin-webapp/src/test/java/org/apache/helix/webapp/AdminTestBase.java b/helix-admin-webapp/src/test/java/org/apache/helix/webapp/AdminTestBase.java
index 0037a5b..6af49de 100644
--- a/helix-admin-webapp/src/test/java/org/apache/helix/webapp/AdminTestBase.java
+++ b/helix-admin-webapp/src/test/java/org/apache/helix/webapp/AdminTestBase.java
@@ -21,13 +21,13 @@ package org.apache.helix.webapp;
 
 import java.util.logging.Level;
 
-import org.I0Itec.zkclient.ZkServer;
 import org.apache.helix.TestHelper;
 import org.apache.helix.manager.zk.ZNRecordSerializer;
-import org.apache.helix.manager.zk.ZkClient;
+import org.apache.helix.zookeeper.impl.client.ZkClient;
 import org.apache.helix.tools.ClusterSetup;
 import org.apache.helix.util.ZKClientPool;
 import org.apache.helix.webapp.AdminTestHelper.AdminThread;
+import org.apache.helix.zookeeper.zkclient.ZkServer;
 import org.restlet.Client;
 import org.restlet.data.Protocol;
 import org.slf4j.Logger;
diff --git a/helix-admin-webapp/src/test/java/org/apache/helix/webapp/AdminTestHelper.java b/helix-admin-webapp/src/test/java/org/apache/helix/webapp/AdminTestHelper.java
index f5f05c9..acc15ef 100644
--- a/helix-admin-webapp/src/test/java/org/apache/helix/webapp/AdminTestHelper.java
+++ b/helix-admin-webapp/src/test/java/org/apache/helix/webapp/AdminTestHelper.java
@@ -24,7 +24,7 @@ import java.io.StringReader;
 import java.io.StringWriter;
 import java.util.concurrent.CountDownLatch;
 
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
 import org.codehaus.jackson.map.ObjectMapper;
 import org.restlet.Client;
 import org.restlet.Request;
diff --git a/helix-admin-webapp/src/test/java/org/apache/helix/webapp/TestClusterManagementWebapp.java b/helix-admin-webapp/src/test/java/org/apache/helix/webapp/TestClusterManagementWebapp.java
index 486af07..0e45ac3 100644
--- a/helix-admin-webapp/src/test/java/org/apache/helix/webapp/TestClusterManagementWebapp.java
+++ b/helix-admin-webapp/src/test/java/org/apache/helix/webapp/TestClusterManagementWebapp.java
@@ -27,7 +27,7 @@ import java.util.List;
 import java.util.Map;
 
 import org.apache.helix.PropertyPathBuilder;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
 import org.apache.helix.model.InstanceConfig.InstanceConfigProperty;
 import org.apache.helix.tools.ClusterSetup;
 import org.apache.helix.webapp.resources.ClusterRepresentationUtil;
diff --git a/helix-admin-webapp/src/test/java/org/apache/helix/webapp/TestDisableResource.java b/helix-admin-webapp/src/test/java/org/apache/helix/webapp/TestDisableResource.java
index 9800179..e85fa87 100644
--- a/helix-admin-webapp/src/test/java/org/apache/helix/webapp/TestDisableResource.java
+++ b/helix-admin-webapp/src/test/java/org/apache/helix/webapp/TestDisableResource.java
@@ -27,7 +27,7 @@ import org.apache.helix.BaseDataAccessor;
 import org.apache.helix.HelixDataAccessor;
 import org.apache.helix.PropertyKey;
 import org.apache.helix.TestHelper;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
 import org.apache.helix.manager.zk.ZKHelixDataAccessor;
 import org.apache.helix.manager.zk.ZkBaseDataAccessor;
 import org.apache.helix.model.IdealState;
diff --git a/helix-admin-webapp/src/test/java/org/apache/helix/webapp/TestHelixAdminScenariosRest.java b/helix-admin-webapp/src/test/java/org/apache/helix/webapp/TestHelixAdminScenariosRest.java
index 0b49096..e78e074 100644
--- a/helix-admin-webapp/src/test/java/org/apache/helix/webapp/TestHelixAdminScenariosRest.java
+++ b/helix-admin-webapp/src/test/java/org/apache/helix/webapp/TestHelixAdminScenariosRest.java
@@ -30,7 +30,7 @@ import java.util.Map;
 
 import org.apache.helix.HelixAdmin;
 import org.apache.helix.HelixDataAccessor;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
 import org.apache.helix.integration.manager.ClusterControllerManager;
 import org.apache.helix.integration.manager.ClusterDistributedController;
 import org.apache.helix.integration.manager.MockParticipantManager;
diff --git a/helix-admin-webapp/src/test/java/org/apache/helix/webapp/TestResetPartitionState.java b/helix-admin-webapp/src/test/java/org/apache/helix/webapp/TestResetPartitionState.java
index 8d994e8..42bcbad 100644
--- a/helix-admin-webapp/src/test/java/org/apache/helix/webapp/TestResetPartitionState.java
+++ b/helix-admin-webapp/src/test/java/org/apache/helix/webapp/TestResetPartitionState.java
@@ -28,7 +28,7 @@ import java.util.concurrent.atomic.AtomicInteger;
 import org.apache.helix.NotificationContext;
 import org.apache.helix.PropertyKey.Builder;
 import org.apache.helix.TestHelper;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
 import org.apache.helix.integration.manager.ClusterControllerManager;
 import org.apache.helix.integration.manager.MockParticipantManager;
 import org.apache.helix.manager.zk.ZKHelixDataAccessor;
diff --git a/helix-admin-webapp/src/test/java/org/apache/helix/webapp/resources/TestJobQueuesResource.java b/helix-admin-webapp/src/test/java/org/apache/helix/webapp/resources/TestJobQueuesResource.java
index 6d5d5e2..ca34d52 100644
--- a/helix-admin-webapp/src/test/java/org/apache/helix/webapp/resources/TestJobQueuesResource.java
+++ b/helix-admin-webapp/src/test/java/org/apache/helix/webapp/resources/TestJobQueuesResource.java
@@ -25,7 +25,7 @@ import java.util.Map;
 
 import com.google.common.collect.Lists;
 import org.apache.helix.TestHelper;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
 import org.apache.helix.integration.manager.ClusterControllerManager;
 import org.apache.helix.integration.manager.MockParticipantManager;
 import org.apache.helix.integration.task.MockTask;
diff --git a/helix-common/LICENSE b/helix-common/LICENSE
new file mode 100644
index 0000000..d78ae52
--- /dev/null
+++ b/helix-common/LICENSE
@@ -0,0 +1,270 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   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.
+
+
+
+For xstream:
+
+Copyright (c) 2003-2006, Joe Walnes
+Copyright (c) 2006-2009, 2011 XStream Committers
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this list of
+conditions and the following disclaimer.
+
+2. 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.
+
+3. Neither the name of XStream 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.
+
+for jline:
+
+Copyright (c) 2002-2006, Marc Prud'hommeaux <mwp1@cornell.edu>
+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 JLine 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.
\ No newline at end of file
diff --git a/helix-common/NOTICE b/helix-common/NOTICE
new file mode 100644
index 0000000..ff5a745
--- /dev/null
+++ b/helix-common/NOTICE
@@ -0,0 +1,37 @@
+Apache Helix
+Copyright 2014 The Apache Software Foundation
+
+
+I. Included Software
+
+This product includes software developed at
+The Apache Software Foundation (http://www.apache.org/).
+Licensed under the Apache License 2.0.
+
+This product includes software developed at
+Codehaus (http://www.codehaus.org/).
+Licensed under the BSD License.
+
+This product includes software developed at
+jline (http://jline.sourceforge.net/).
+Licensed under the BSD License.
+
+This product includes software developed at
+restlet (http://www.restlet.org/about/legal).
+Licensed under the Apache License 2.0.
+
+This product includes software developed at
+Google (http://www.google.com/).
+Licensed under the Apache License 2.0.
+
+This product includes software developed at
+snakeyaml (http://www.snakeyaml.org/).
+Licensed under the Apache License 2.0.
+
+This product includes software developed at
+zkclient (https://github.com/sgroschupf/zkclient).
+Licensed under the Apache License 2.0.
+
+II. License Summary
+- Apache License 2.0
+- BSD License
\ No newline at end of file
diff --git a/helix-core/helix-core-0.9.2-SNAPSHOT.ivy b/helix-common/helix-common-0.9.2-SNAPSHOT.ivy
similarity index 54%
copy from helix-core/helix-core-0.9.2-SNAPSHOT.ivy
copy to helix-common/helix-common-0.9.2-SNAPSHOT.ivy
index 07dd266..e1aa2f5 100644
--- a/helix-core/helix-core-0.9.2-SNAPSHOT.ivy
+++ b/helix-common/helix-common-0.9.2-SNAPSHOT.ivy
@@ -17,34 +17,25 @@ KIND, either express or implied.  See the License for the
 specific language governing permissions and limitations
 under the License.
 -->
-<ivy-module version="1.0" xmlns:m="http://ant.apache.org/ivy/maven">
+<ivy-module version="1.0">
 	<info organisation="org.apache.helix"
-		module="helix-core"
+		module="helix-common"
 		revision="0.9.2-SNAPSHOT"
-		status="release"
-		publication="2011111505113547"
-	>
-	<description homepage="http://maven.apache.org" />
-	</info>
-
+		status="integration"
+		publication="20170128141623"
+	/>
 	<configurations>
 		<conf name="default" visibility="public" description="runtime dependencies and master artifact can be used with this conf" extends="runtime,master"/>
 		<conf name="master" visibility="public" description="contains only the artifact published by this module itself, with no transitive dependencies"/>
 		<conf name="compile" visibility="public" description="this is the default scope, used if none is specified. Compile dependencies are available in all classpaths."/>
 		<conf name="provided" visibility="public" description="this is much like compile, but indicates you expect the JDK or a container to provide it. It is only available on the compilation classpath, and is not transitive."/>
 		<conf name="runtime" visibility="public" description="this scope indicates that the dependency is not required for compilation, but is for execution. It is in the runtime and test classpaths, but not the compile classpath." extends="compile"/>
-		<conf name="test" visibility="private" description="this scope indicates that the dependency is not required for normal use of the application, and is only available for the test compilation and execution phases." extends="runtime"/>
+		<conf name="test" visibility="private" description="this scope indicates that the dependency is not required for normal use of the application, and is only available for the test compilation and execution phases."/>
 		<conf name="system" visibility="public" description="this scope is similar to provided except that you have to provide the JAR which contains it explicitly. The artifact is always available and is not looked up in a repository."/>
-		<conf name="sources" visibility="public" description="this configuration contains the source artifact of this module, if any."/>
-		<conf name="javadoc" visibility="public" description="this configuration contains the javadoc artifact of this module, if any."/>
-		<conf name="optional" visibility="public" description="contains all optional dependencies"/>
 	</configurations>
-
 	<publications>
-		<artifact name="helix-core" type="jar" ext="jar" conf="master"/>
-    <artifact name="helix-core" type="jar" ext="jar" conf="sources" m:classifier="sources"/>
+		<artifact name="helix-common" type="jar" ext="jar" conf="master"/>
 	</publications>
-
 	<dependencies>
 	  <dependency org="org.slf4j" name="slf4j-api" rev="1.7.25" force="true" conf="compile->compile(*),master(*);runtime->runtime(*)">
         <artifact name="slf4j-api" ext="jar"/>
@@ -52,18 +43,9 @@ under the License.
     <dependency org="org.slf4j" name="slf4j-log4j12" rev="1.7.14" force="true" conf="compile->compile(*),master(*);runtime->runtime(*)">
         <artifact name="slf4j-log4j12" ext="jar"/>
     </dependency>
-    <dependency org="org.apache.zookeeper" name="zookeeper" rev="3.4.13" conf="compile->compile(default);runtime->runtime(default);default->default"/>
-    <dependency org="org.codehaus.jackson" name="jackson-core-asl" rev="1.8.5" conf="compile->compile(default);runtime->runtime(default);default->default"/>
-    <dependency org="org.codehaus.jackson" name="jackson-mapper-asl" rev="1.8.5" conf="compile->compile(default);runtime->runtime(default);default->default"/>
-    <dependency org="commons-io" name="commons-io" rev="1.4" conf="compile->compile(default);runtime->runtime(default);default->default"/>
-    <dependency org="commons-cli" name="commons-cli" rev="1.2" conf="compile->compile(default);runtime->runtime(default);default->default"/>
-    <dependency org="org.apache.commons" name="commons-math" rev="2.1" conf="compile->compile(default);runtime->runtime(default);default->default"/>
-    <dependency org="org.apache.commons" name="commons-math3" rev="3.6.1" conf="compile->compile(default);runtime->runtime(default);default->default"/>
-    <dependency org="com.101tec" name="zkclient" rev="0.5" conf="compile->compile(default);runtime->runtime(default);default->default"/>
-    <dependency org="com.google.guava" name="guava" rev="15.0" conf="compile->compile(default);runtime->runtime(default);default->default"/>
     <dependency org="org.yaml" name="snakeyaml" rev="1.12" conf="compile->compile(default);runtime->runtime(default);default->default"/>
-    <dependency org="commons-logging" name="commons-logging-api" rev="1.1" conf="compile->compile(*),master(*);runtime->runtime(*)"/>
-    <dependency org="io.dropwizard.metrics" name="metrics-core" rev="3.2.3" conf="compile->compile(default);runtime->runtime(default);default->default"/>
+		<dependency org="org.codehaus.jackson" name="jackson-core-asl" rev="1.8.5" force="true" conf="compile->compile(*),master(*);runtime->runtime(*)"/>
+		<dependency org="org.codehaus.jackson" name="jackson-mapper-asl" rev="1.8.5" force="true" conf="compile->compile(*),master(*);runtime->runtime(*)"/>
+		<dependency org="commons-cli" name="commons-cli" rev="1.2" force="true" conf="compile->compile(*),master(*);runtime->runtime(*)"/>
 	</dependencies>
 </ivy-module>
-
diff --git a/helix-admin-webapp/pom.xml b/helix-common/pom.xml
similarity index 58%
copy from helix-admin-webapp/pom.xml
copy to helix-common/pom.xml
index 87e7d8e..64a5f88 100644
--- a/helix-admin-webapp/pom.xml
+++ b/helix-common/pom.xml
@@ -25,24 +25,31 @@ under the License.
   </parent>
   <modelVersion>4.0.0</modelVersion>
 
-  <artifactId>helix-admin-webapp</artifactId>
+  <artifactId>helix-common</artifactId>
   <packaging>bundle</packaging>
-  <name>Apache Helix :: Admin Webapp</name>
+  <name>Apache Helix :: Helix Common</name>
 
   <properties>
     <osgi.import>
-      org.apache.helix*,
       org.codehaus.jackson*,
-      org.apache.commons.cli*,
-      org.restlet*,
       org.slf4j*;version="[1.6,2)",
       *
     </osgi.import>
-    <osgi.export>org.apache.helix.webapp*;version="${project.version};-noimport:=true</osgi.export>
+    <osgi.export>org.apache.helix*;version="${project.version};-noimport:=true</osgi.export>
   </properties>
 
   <dependencies>
     <dependency>
+      <groupId>org.apache.helix</groupId>
+      <artifactId>metrics-common</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.helix</groupId>
+      <artifactId>zookeeper-api</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
       <groupId>org.slf4j</groupId>
       <artifactId>slf4j-api</artifactId>
       <version>1.7.25</version>
@@ -53,52 +60,10 @@ under the License.
       <version>1.7.14</version>
     </dependency>
     <dependency>
-      <groupId>org.apache.helix</groupId>
-      <artifactId>helix-core</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.restlet.jse</groupId>
-      <artifactId>org.restlet</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.restlet.jse</groupId>
-      <artifactId>org.restlet.ext.jetty</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.eclipse.jetty</groupId>
-      <artifactId>jetty-server</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>com.thoughtworks.xstream</groupId>
-      <artifactId>xstream</artifactId>
-      <version>1.3.1</version>
-    </dependency>
-    <dependency>
-      <groupId>org.codehaus.jackson</groupId>
-      <artifactId>jackson-core-asl</artifactId>
-      <version>1.8.5</version>
-    </dependency>
-    <dependency>
-      <groupId>org.codehaus.jackson</groupId>
-      <artifactId>jackson-mapper-asl</artifactId>
-      <version>1.8.5</version>
-    </dependency>
-    <dependency>
-      <groupId>commons-cli</groupId>
-      <artifactId>commons-cli</artifactId>
-      <version>1.2</version>
-    </dependency>
-    <dependency>
       <groupId>org.testng</groupId>
       <artifactId>testng</artifactId>
       <scope>test</scope>
     </dependency>
-    <dependency>
-      <groupId>org.apache.helix</groupId>
-      <artifactId>helix-core</artifactId>
-      <type>test-jar</type>
-      <scope>test</scope>
-    </dependency>
   </dependencies>
   <build>
     <resources>
@@ -111,23 +76,6 @@ under the License.
     </resources>
     <plugins>
       <plugin>
-        <groupId>org.codehaus.mojo</groupId>
-        <artifactId>appassembler-maven-plugin</artifactId>
-        <configuration>
-          <platforms>
-            <platform>windows</platform>
-            <platform>unix</platform>
-          </platforms>
-          <programs>
-            <program>
-              <mainClass>org.apache.helix.webapp.RestAdminApplication</mainClass>
-              <name>run-rest-admin</name>
-            </program>
-          </programs>
-        </configuration>
-
-      </plugin>
-      <plugin>
         <groupId>org.apache.maven.plugins</groupId>
         <artifactId>maven-assembly-plugin</artifactId>
         <configuration>
diff --git a/helix-common/src/assemble/assembly.xml b/helix-common/src/assemble/assembly.xml
new file mode 100644
index 0000000..79e2f5c
--- /dev/null
+++ b/helix-common/src/assemble/assembly.xml
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+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.
+-->
+<assembly>
+  <id>pkg</id>
+  <formats>
+    <format>tar</format>
+  </formats>
+  <fileSets>
+    <fileSet>
+      <directory>target/helix-common-pkg/bin</directory>
+      <outputDirectory>bin</outputDirectory>
+      <lineEnding>unix</lineEnding>
+      <fileMode>0755</fileMode>
+      <directoryMode>0755</directoryMode>
+    </fileSet>
+    <fileSet>
+      <directory>target/helix-common-pkg/repo/</directory>
+      <outputDirectory>repo</outputDirectory>
+      <fileMode>0755</fileMode>
+      <directoryMode>0755</directoryMode>
+      <excludes>
+        <exclude>**/*.xml</exclude>
+      </excludes>
+    </fileSet>
+   <fileSet>
+      <directory>target/helix-common-pkg/conf</directory>
+      <outputDirectory>conf</outputDirectory>
+      <lineEnding>unix</lineEnding>
+      <fileMode>0755</fileMode>
+      <directoryMode>0755</directoryMode>
+    </fileSet>
+    <fileSet>
+      <directory>${project.basedir}</directory>
+      <outputDirectory>/</outputDirectory>
+      <includes>
+        <include>LICENSE</include>
+        <include>NOTICE</include>
+        <include>DISCLAIMER</include>
+      </includes>
+      <fileMode>0755</fileMode>
+    </fileSet>
+  </fileSets>
+</assembly>
diff --git a/helix-core/src/main/java/org/apache/helix/HelixException.java b/helix-common/src/main/java/org/apache/helix/HelixException.java
similarity index 100%
copy from helix-core/src/main/java/org/apache/helix/HelixException.java
copy to helix-common/src/main/java/org/apache/helix/HelixException.java
diff --git a/helix-core/src/main/java/org/apache/helix/SystemPropertyKeys.java b/helix-common/src/main/java/org/apache/helix/SystemPropertyKeys.java
similarity index 67%
copy from helix-core/src/main/java/org/apache/helix/SystemPropertyKeys.java
copy to helix-common/src/main/java/org/apache/helix/SystemPropertyKeys.java
index d316986..bcb8405 100644
--- a/helix-core/src/main/java/org/apache/helix/SystemPropertyKeys.java
+++ b/helix-common/src/main/java/org/apache/helix/SystemPropertyKeys.java
@@ -1,13 +1,30 @@
 package org.apache.helix;
 
+/*
+ * 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.
+ */
+
 public class SystemPropertyKeys {
   // Task Driver
   public static final String TASK_CONFIG_LIMITATION = "helixTask.configsLimitation";
 
   // ZKHelixManager
   public static final String CLUSTER_MANAGER_VERSION = "cluster-manager-version.properties";
-  // soft constraints weight definitions
-  public static final String SOFT_CONSTRAINT_WEIGHTS = "soft-constraint-weight.properties";
 
   public static final String FLAPPING_TIME_WINDOW = "helixmanager.flappingTimeWindow";
 
diff --git a/helix-core/src/main/java/org/apache/helix/HelixException.java b/helix-common/src/main/java/org/apache/helix/ZNRecord.java
similarity index 52%
copy from helix-core/src/main/java/org/apache/helix/HelixException.java
copy to helix-common/src/main/java/org/apache/helix/ZNRecord.java
index 26585ed..a8018fd 100644
--- a/helix-core/src/main/java/org/apache/helix/HelixException.java
+++ b/helix-common/src/main/java/org/apache/helix/ZNRecord.java
@@ -19,22 +19,30 @@ package org.apache.helix;
  * under the License.
  */
 
-/**
- * Base class for an exception thrown by Helix due to inconsistencies caught by Helix itself.
- */
-public class HelixException extends RuntimeException {
+import org.codehaus.jackson.annotate.JsonIgnoreProperties;
+import org.codehaus.jackson.map.annotate.JsonSerialize;
+import org.codehaus.jackson.map.annotate.JsonSerialize.Inclusion;
 
-  private static final long serialVersionUID = 6558251214364526257L;
 
-  public HelixException(String message) {
-    super(message);
+/**
+ * Deprecated; please use ZNRecord in zookeeper-api instead.
+ *
+ * Generic Record Format to store data at a Node This can be used to store
+ * simpleFields mapFields listFields
+ */
+@Deprecated
+@JsonIgnoreProperties(ignoreUnknown = true)
+@JsonSerialize(include = Inclusion.NON_NULL)
+public class ZNRecord extends org.apache.helix.zookeeper.datamodel.ZNRecord {
+  public ZNRecord(String id) {
+    super(id);
   }
 
-  public HelixException(Throwable cause) {
-    super(cause);
+  public ZNRecord(org.apache.helix.zookeeper.datamodel.ZNRecord record) {
+    super(record);
   }
 
-  public HelixException(String message, Throwable cause) {
-    super(message, cause);
+  public ZNRecord(org.apache.helix.zookeeper.datamodel.ZNRecord record, String id) {
+    super(record, id);
   }
 }
diff --git a/helix-core/src/main/java/org/apache/helix/monitoring/SensorNameProvider.java b/helix-common/src/main/java/org/apache/helix/ZNRecordDelta.java
similarity index 78%
copy from helix-core/src/main/java/org/apache/helix/monitoring/SensorNameProvider.java
copy to helix-common/src/main/java/org/apache/helix/ZNRecordDelta.java
index 718bac5..2529d94 100644
--- a/helix-core/src/main/java/org/apache/helix/monitoring/SensorNameProvider.java
+++ b/helix-common/src/main/java/org/apache/helix/ZNRecordDelta.java
@@ -1,4 +1,4 @@
-package org.apache.helix.monitoring;
+package org.apache.helix;
 
 /*
  * Licensed to the Apache Software Foundation (ASF) under one
@@ -19,6 +19,11 @@ package org.apache.helix.monitoring;
  * under the License.
  */
 
-public interface SensorNameProvider {
-  String getSensorName();
+/**
+ * Deprecated; please use ZNRecordDelta in zookeeper-api instead.
+ *
+ * A ZNRecord container that specifies how it should be merged with another ZNRecord
+ */
+@Deprecated
+public class ZNRecordDelta {
 }
diff --git a/helix-core/src/main/java/org/apache/helix/monitoring/SensorNameProvider.java b/helix-common/src/main/java/org/apache/helix/manager/zk/serializer/JacksonPayloadSerializer.java
similarity index 70%
copy from helix-core/src/main/java/org/apache/helix/monitoring/SensorNameProvider.java
copy to helix-common/src/main/java/org/apache/helix/manager/zk/serializer/JacksonPayloadSerializer.java
index 718bac5..651836b 100644
--- a/helix-core/src/main/java/org/apache/helix/monitoring/SensorNameProvider.java
+++ b/helix-common/src/main/java/org/apache/helix/manager/zk/serializer/JacksonPayloadSerializer.java
@@ -1,4 +1,4 @@
-package org.apache.helix.monitoring;
+package org.apache.helix.manager.zk.serializer;
 
 /*
  * Licensed to the Apache Software Foundation (ASF) under one
@@ -19,6 +19,11 @@ package org.apache.helix.monitoring;
  * under the License.
  */
 
-public interface SensorNameProvider {
-  String getSensorName();
+/**
+ * Deprecated; please use JacksonPayloadSerializer in zookeeper-api instead.
+ *
+ * Serializes and deserializes data of a generic type using Jackson
+ */
+@Deprecated
+public class JacksonPayloadSerializer extends org.apache.helix.zookeeper.datamodel.serializer.JacksonPayloadSerializer {
 }
diff --git a/helix-core/src/main/java/org/apache/helix/monitoring/SensorNameProvider.java b/helix-common/src/main/java/org/apache/helix/manager/zk/serializer/PayloadSerializer.java
similarity index 70%
copy from helix-core/src/main/java/org/apache/helix/monitoring/SensorNameProvider.java
copy to helix-common/src/main/java/org/apache/helix/manager/zk/serializer/PayloadSerializer.java
index 718bac5..a26e7fb 100644
--- a/helix-core/src/main/java/org/apache/helix/monitoring/SensorNameProvider.java
+++ b/helix-common/src/main/java/org/apache/helix/manager/zk/serializer/PayloadSerializer.java
@@ -1,4 +1,4 @@
-package org.apache.helix.monitoring;
+package org.apache.helix.manager.zk.serializer;
 
 /*
  * Licensed to the Apache Software Foundation (ASF) under one
@@ -19,6 +19,11 @@ package org.apache.helix.monitoring;
  * under the License.
  */
 
-public interface SensorNameProvider {
-  String getSensorName();
+/**
+ * Deprecated; please use PayloadSerializer in zookeeper-api instead.
+ *
+ * Interface for converting back and forth between raw bytes and generic objects
+ */
+@Deprecated
+public interface PayloadSerializer extends org.apache.helix.zookeeper.datamodel.serializer.PayloadSerializer {
 }
diff --git a/helix-common/src/test/conf/testng.xml b/helix-common/src/test/conf/testng.xml
new file mode 100644
index 0000000..46911d2
--- /dev/null
+++ b/helix-common/src/test/conf/testng.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+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.
+-->
+<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
+<suite name="Suite" parallel="false">
+  <test name="Test" preserve-order="true">
+    <packages>
+      <package name="org.apache.helix.helix.common.*"/>
+    </packages>
+  </test>
+</suite>
diff --git a/helix-common/src/test/resources/log4j.properties b/helix-common/src/test/resources/log4j.properties
new file mode 100644
index 0000000..24b6d10
--- /dev/null
+++ b/helix-common/src/test/resources/log4j.properties
@@ -0,0 +1,41 @@
+#
+# 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 root logger level to DEBUG and its only appender to R.
+log4j.rootLogger=ERROR, C
+
+# A1 is set to be a ConsoleAppender.
+log4j.appender.C=org.apache.log4j.ConsoleAppender
+log4j.appender.C.layout=org.apache.log4j.PatternLayout
+log4j.appender.C.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n
+
+log4j.appender.R=org.apache.log4j.RollingFileAppender
+log4j.appender.R.layout=org.apache.log4j.PatternLayout
+log4j.appender.R.layout.ConversionPattern=%5p [%C:%M] (%F:%L) - %m%n
+log4j.appender.R.File=target/ClusterManagerLogs/log.txt
+
+log4j.appender.STATUSDUMP=org.apache.log4j.RollingFileAppender
+log4j.appender.STATUSDUMP.layout=org.apache.log4j.SimpleLayout
+log4j.appender.STATUSDUMP.File=target/ClusterManagerLogs/statusUpdates.log
+
+log4j.logger.org.I0Itec=ERROR
+log4j.logger.org.apache=ERROR
+log4j.logger.com.noelios=ERROR
+log4j.logger.org.restlet=ERROR
+
+log4j.logger.org.apache.helix.monitoring.ZKPathDataDumpTask=ERROR,STATUSDUMP
diff --git a/helix-core/helix-core-0.9.2-SNAPSHOT.ivy b/helix-core/helix-core-0.9.2-SNAPSHOT.ivy
index 07dd266..6a1cdee 100644
--- a/helix-core/helix-core-0.9.2-SNAPSHOT.ivy
+++ b/helix-core/helix-core-0.9.2-SNAPSHOT.ivy
@@ -57,9 +57,8 @@ under the License.
     <dependency org="org.codehaus.jackson" name="jackson-mapper-asl" rev="1.8.5" conf="compile->compile(default);runtime->runtime(default);default->default"/>
     <dependency org="commons-io" name="commons-io" rev="1.4" conf="compile->compile(default);runtime->runtime(default);default->default"/>
     <dependency org="commons-cli" name="commons-cli" rev="1.2" conf="compile->compile(default);runtime->runtime(default);default->default"/>
-    <dependency org="org.apache.commons" name="commons-math" rev="2.1" conf="compile->compile(default);runtime->runtime(default);default->default"/>
-    <dependency org="org.apache.commons" name="commons-math3" rev="3.6.1" conf="compile->compile(default);runtime->runtime(default);default->default"/>
-    <dependency org="com.101tec" name="zkclient" rev="0.5" conf="compile->compile(default);runtime->runtime(default);default->default"/>
+    <dependency org="commons-math" name="commons-math" rev="2.1" conf="compile->compile(default);runtime->runtime(default);default->default"/>
+    <dependency org="commons-math" name="commons-math3" rev="3.6.1" conf="compile->compile(default);runtime->runtime(default);default->default"/>
     <dependency org="com.google.guava" name="guava" rev="15.0" conf="compile->compile(default);runtime->runtime(default);default->default"/>
     <dependency org="org.yaml" name="snakeyaml" rev="1.12" conf="compile->compile(default);runtime->runtime(default);default->default"/>
     <dependency org="commons-logging" name="commons-logging-api" rev="1.1" conf="compile->compile(*),master(*);runtime->runtime(*)"/>
diff --git a/helix-core/pom.xml b/helix-core/pom.xml
index 1077cc0..18113e1 100644
--- a/helix-core/pom.xml
+++ b/helix-core/pom.xml
@@ -34,7 +34,6 @@ under the License.
     <osgi.import>
       javax.management*,
       javax.xml.bind*,
-      org.I0Itec.zkclient*,
       org.apache.commons.cli*;version="[1.2,2)",
       org.apache.commons.io*;version="[1.4,2)",
       org.apache.commons.math*;version="[2.1,4)",
@@ -55,6 +54,11 @@ under the License.
 
   <dependencies>
     <dependency>
+      <groupId>org.apache.helix</groupId>
+      <artifactId>helix-common</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
       <groupId>org.slf4j</groupId>
       <artifactId>slf4j-api</artifactId>
       <version>1.7.25</version>
@@ -114,11 +118,6 @@ under the License.
       <version>1.2</version>
     </dependency>
     <dependency>
-      <groupId>com.101tec</groupId>
-      <artifactId>zkclient</artifactId>
-      <version>0.5</version>
-    </dependency>
-    <dependency>
       <groupId>org.testng</groupId>
       <artifactId>testng</artifactId>
       <scope>test</scope>
diff --git a/helix-core/src/main/java/org/apache/helix/BaseDataAccessor.java b/helix-core/src/main/java/org/apache/helix/BaseDataAccessor.java
index 34a20ea..ba64664 100644
--- a/helix-core/src/main/java/org/apache/helix/BaseDataAccessor.java
+++ b/helix-core/src/main/java/org/apache/helix/BaseDataAccessor.java
@@ -21,9 +21,9 @@ package org.apache.helix;
 
 import java.util.List;
 
-import org.I0Itec.zkclient.DataUpdater;
-import org.I0Itec.zkclient.IZkChildListener;
-import org.I0Itec.zkclient.IZkDataListener;
+import org.apache.helix.zookeeper.zkclient.DataUpdater;
+import org.apache.helix.zookeeper.zkclient.IZkChildListener;
+import org.apache.helix.zookeeper.zkclient.IZkDataListener;
 import org.apache.zookeeper.data.Stat;
 
 
diff --git a/helix-core/src/main/java/org/apache/helix/ConfigAccessor.java b/helix-core/src/main/java/org/apache/helix/ConfigAccessor.java
index 018743d..b5f06ef 100644
--- a/helix-core/src/main/java/org/apache/helix/ConfigAccessor.java
+++ b/helix-core/src/main/java/org/apache/helix/ConfigAccessor.java
@@ -29,8 +29,6 @@ import java.util.TreeMap;
 
 import org.apache.helix.manager.zk.ZKUtil;
 import org.apache.helix.manager.zk.ZNRecordSerializer;
-import org.apache.helix.manager.zk.client.HelixZkClient;
-import org.apache.helix.manager.zk.client.SharedZkClientFactory;
 import org.apache.helix.model.ClusterConfig;
 import org.apache.helix.model.ConfigScope;
 import org.apache.helix.model.HelixConfigScope;
@@ -40,6 +38,9 @@ import org.apache.helix.model.RESTConfig;
 import org.apache.helix.model.ResourceConfig;
 import org.apache.helix.model.builder.HelixConfigScopeBuilder;
 import org.apache.helix.util.StringTemplate;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
+import org.apache.helix.zookeeper.api.client.HelixZkClient;
+import org.apache.helix.zookeeper.impl.factory.SharedZkClientFactory;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
diff --git a/helix-core/src/main/java/org/apache/helix/GroupCommit.java b/helix-core/src/main/java/org/apache/helix/GroupCommit.java
index b23fc2e..7146e37 100644
--- a/helix-core/src/main/java/org/apache/helix/GroupCommit.java
+++ b/helix-core/src/main/java/org/apache/helix/GroupCommit.java
@@ -25,11 +25,13 @@ import java.util.concurrent.ConcurrentLinkedQueue;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicReference;
 
-import org.I0Itec.zkclient.exception.ZkNoNodeException;
+import org.apache.helix.zookeeper.zkclient.exception.ZkNoNodeException;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 // TODO: move to mananger.zk
+
 /**
  * Support committing updates to data such that they are ordered for each key
  */
@@ -94,8 +96,9 @@ public class GroupCommit {
       if (queue._running.compareAndSet(null, Thread.currentThread())) {
         ArrayList<Entry> processed = new ArrayList<>();
         try {
-          if (queue._pending.peek() == null)
+          if (queue._pending.peek() == null) {
             return true;
+          }
 
           // remove from queue
           Entry first = queue._pending.poll();
@@ -123,8 +126,9 @@ public class GroupCommit {
           Iterator<Entry> it = queue._pending.iterator();
           while (it.hasNext()) {
             Entry ent = it.next();
-            if (!ent._key.equals(mergedKey))
+            if (!ent._key.equals(mergedKey)) {
               continue;
+            }
             processed.add(ent);
             merged.merge(ent._record);
             // System.out.println("After merging:" + merged);
@@ -162,7 +166,8 @@ public class GroupCommit {
           try {
             entry.wait(10);
           } catch (InterruptedException e) {
-            LOG.error("Interrupted while committing change, key: " + key + ", record: " + record, e);
+            LOG.error("Interrupted while committing change, key: " + key + ", record: " + record,
+                e);
             // Restore interrupt status
             Thread.currentThread().interrupt();
             return false;
@@ -172,5 +177,4 @@ public class GroupCommit {
     }
     return success;
   }
-
 }
diff --git a/helix-core/src/main/java/org/apache/helix/HelixDataAccessor.java b/helix-core/src/main/java/org/apache/helix/HelixDataAccessor.java
index d8dde1e..2a763df 100644
--- a/helix-core/src/main/java/org/apache/helix/HelixDataAccessor.java
+++ b/helix-core/src/main/java/org/apache/helix/HelixDataAccessor.java
@@ -22,12 +22,14 @@ package org.apache.helix;
 import java.util.List;
 import java.util.Map;
 
-import org.I0Itec.zkclient.DataUpdater;
 import org.apache.helix.model.LiveInstance;
 import org.apache.helix.model.MaintenanceSignal;
 import org.apache.helix.model.Message;
 import org.apache.helix.model.PauseSignal;
 import org.apache.helix.model.StateModelDefinition;
+import org.apache.helix.zookeeper.zkclient.DataUpdater;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
+
 
 /**
  * Interface used to interact with Helix Data Types like IdealState, Config,
@@ -36,9 +38,13 @@ import org.apache.helix.model.StateModelDefinition;
  */
 public interface HelixDataAccessor {
   boolean createStateModelDef(StateModelDefinition stateModelDef);
+
   boolean createControllerMessage(Message message);
+
   boolean createControllerLeader(LiveInstance leader);
+
   boolean createPause(PauseSignal pauseSignal);
+
   boolean createMaintenance(MaintenanceSignal maintenanceSignal);
 
   /**
@@ -67,7 +73,8 @@ public interface HelixDataAccessor {
    * @param value
    * @return true if the update was successful
    */
-  <T extends HelixProperty> boolean updateProperty(PropertyKey key, DataUpdater<ZNRecord> updater, T value);
+  <T extends HelixProperty> boolean updateProperty(PropertyKey key, DataUpdater<ZNRecord> updater,
+      T value);
 
   /**
    * Return the property value, it must be refer to a single Helix Property. i.e
diff --git a/helix-core/src/main/java/org/apache/helix/HelixManager.java b/helix-core/src/main/java/org/apache/helix/HelixManager.java
index 67d77ec..2191153 100644
--- a/helix-core/src/main/java/org/apache/helix/HelixManager.java
+++ b/helix-core/src/main/java/org/apache/helix/HelixManager.java
@@ -43,6 +43,8 @@ import org.apache.helix.participant.HelixStateMachineEngine;
 import org.apache.helix.participant.StateMachineEngine;
 import org.apache.helix.spectator.RoutingTableProvider;
 import org.apache.helix.store.zk.ZkHelixPropertyStore;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
+
 
 /**
  * Class that represents the Helix Agent.
diff --git a/helix-core/src/main/java/org/apache/helix/HelixProperty.java b/helix-core/src/main/java/org/apache/helix/HelixProperty.java
index 540e4c6..a9db500 100644
--- a/helix-core/src/main/java/org/apache/helix/HelixProperty.java
+++ b/helix-core/src/main/java/org/apache/helix/HelixProperty.java
@@ -27,7 +27,9 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
-import org.I0Itec.zkclient.serialize.ZkSerializer;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecordDelta;
+import org.apache.helix.zookeeper.zkclient.serialize.ZkSerializer;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -39,8 +41,7 @@ public class HelixProperty {
   private static Logger LOG = LoggerFactory.getLogger(HelixProperty.class);
 
   public enum HelixPropertyAttribute {
-    BUCKET_SIZE,
-    BATCH_MESSAGE_MODE
+    BUCKET_SIZE, BATCH_MESSAGE_MODE
   }
 
   protected final ZNRecord _record;
@@ -172,7 +173,8 @@ public class HelixProperty {
    */
   public HelixProperty(ZNRecord record, String id) {
     _record = new ZNRecord(record, id);
-    _stat = new Stat(_record.getVersion(), _record.getCreationTime(), _record.getModifiedTime(), _record.getEphemeralOwner());
+    _stat = new Stat(_record.getVersion(), _record.getCreationTime(), _record.getModifiedTime(),
+        _record.getEphemeralOwner());
   }
 
   /**
@@ -201,7 +203,7 @@ public class HelixProperty {
 
   @Override
   public String toString() {
-    return "ZnRecord=" + _record.toString() + ", Stat=" + _stat.toString() ;
+    return "ZnRecord=" + _record.toString() + ", Stat=" + _stat.toString();
   }
 
   /**
@@ -226,8 +228,9 @@ public class HelixProperty {
    * @param bucketSize the bucket size (will default to 0 if negative)
    */
   public void setBucketSize(int bucketSize) {
-    if (bucketSize <= 0)
+    if (bucketSize <= 0) {
       bucketSize = 0;
+    }
 
     _record.setSimpleField(HelixPropertyAttribute.BUCKET_SIZE.toString(), "" + bucketSize);
   }
@@ -238,7 +241,8 @@ public class HelixProperty {
    * @param record the ZNRecord describing the property
    * @return typed instance corresponding to the record, or null if conversion fails
    */
-  public static <T extends HelixProperty> T convertToTypedInstance(Class<T> clazz, ZNRecord record) {
+  public static <T extends HelixProperty> T convertToTypedInstance(Class<T> clazz,
+      ZNRecord record) {
     if (record == null) {
       return null;
     }
@@ -302,7 +306,7 @@ public class HelixProperty {
       return Collections.emptyList();
     }
 
-    List<ZNRecord> records = new ArrayList<ZNRecord>();
+    List<ZNRecord> records = new ArrayList<>();
     for (T typedInstance : typedInstances) {
       records.add(typedInstance.getRecord());
     }
diff --git a/helix-core/src/main/java/org/apache/helix/LiveInstanceInfoProvider.java b/helix-core/src/main/java/org/apache/helix/LiveInstanceInfoProvider.java
index 91d6194..827d434 100644
--- a/helix-core/src/main/java/org/apache/helix/LiveInstanceInfoProvider.java
+++ b/helix-core/src/main/java/org/apache/helix/LiveInstanceInfoProvider.java
@@ -19,6 +19,9 @@ package org.apache.helix;
  * under the License.
  */
 
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
+
+
 /**
  * Interface to provide additional information about a live instance at creation time
  */
diff --git a/helix-core/src/main/java/org/apache/helix/SystemPropertyKeys.java b/helix-core/src/main/java/org/apache/helix/SystemPropertyKeys.java
index d316986..2d824cb 100644
--- a/helix-core/src/main/java/org/apache/helix/SystemPropertyKeys.java
+++ b/helix-core/src/main/java/org/apache/helix/SystemPropertyKeys.java
@@ -1,5 +1,24 @@
 package org.apache.helix;
 
+/*
+ * 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.
+ */
+
 public class SystemPropertyKeys {
   // Task Driver
   public static final String TASK_CONFIG_LIMITATION = "helixTask.configsLimitation";
diff --git a/helix-core/src/main/java/org/apache/helix/ZNRecordAssembler.java b/helix-core/src/main/java/org/apache/helix/ZNRecordAssembler.java
index 87231cd..8028007 100644
--- a/helix-core/src/main/java/org/apache/helix/ZNRecordAssembler.java
+++ b/helix-core/src/main/java/org/apache/helix/ZNRecordAssembler.java
@@ -19,33 +19,10 @@ package org.apache.helix;
  * under the License.
  */
 
-import java.util.List;
-
 /**
+ * Deprecated - use ZNRecordAssembler in zookeeper-api instead.
  * Constructs ZNRecords from collections of ZNRecords
  */
-public class ZNRecordAssembler {
-  /**
-   * Merge a list of ZNRecords into a single ZNRecord
-   * @param records
-   * @return {@link ZNRecord}
-   */
-  public ZNRecord assemble(List<ZNRecord> records) {
-    ZNRecord assembledRecord = null;
-    if (records != null && records.size() > 0) {
-      for (ZNRecord record : records) {
-        if (record == null) {
-          continue;
-        }
-
-        if (assembledRecord == null) {
-          assembledRecord = new ZNRecord(record.getId());
-        }
-
-        assembledRecord.merge(record);
-      }
-    }
-    return assembledRecord;
-  }
-
+@Deprecated
+public class ZNRecordAssembler extends org.apache.helix.zookeeper.datamodel.ZNRecordAssembler {
 }
diff --git a/helix-core/src/main/java/org/apache/helix/ZNRecordBucketizer.java b/helix-core/src/main/java/org/apache/helix/ZNRecordBucketizer.java
index 79b56cb..a490572 100644
--- a/helix-core/src/main/java/org/apache/helix/ZNRecordBucketizer.java
+++ b/helix-core/src/main/java/org/apache/helix/ZNRecordBucketizer.java
@@ -19,106 +19,17 @@ package org.apache.helix;
  * under the License.
  */
 
-import java.util.HashMap;
-import java.util.Map;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
 /**
+ * Deprecated - use ZNRecordBucketizer in zookeeper-api instead.
  * Operations to divide a ZNRecord into specified buckets
  */
-public class ZNRecordBucketizer {
-  private static Logger LOG = LoggerFactory.getLogger(ZNRecordBucketizer.class);
-  final int _bucketSize;
-
+@Deprecated
+public class ZNRecordBucketizer extends org.apache.helix.zookeeper.datamodel.ZNRecordBucketizer {
   /**
    * Instantiate a bucketizer with the number of buckets
    * @param bucketSize
    */
   public ZNRecordBucketizer(int bucketSize) {
-    if (bucketSize <= 0) {
-      LOG.debug("bucketSize <= 0 (was " + bucketSize
-          + "). Set to 0 to use non-bucketized HelixProperty.");
-      bucketSize = 0;
-    }
-
-    _bucketSize = bucketSize;
-  }
-
-  /**
-   * Calculate bucketName in form of "resourceName_p{startPartition}-p{endPartition}
-   * @param partitionName
-   * @return the bucket name
-   */
-  public String getBucketName(String key) {
-    if (_bucketSize == 0) {
-      // no bucketize
-      return null;
-    }
-
-    int idx = key.lastIndexOf('_');
-    if (idx < 0) {
-      throw new IllegalArgumentException("Could NOT find partition# in " + key
-          + ". partitionName should be in format of resourceName_partition#");
-    }
-
-    try {
-      int partitionNb = Integer.parseInt(key.substring(idx + 1));
-      int bucketNb = partitionNb / _bucketSize;
-      int startPartition = bucketNb * _bucketSize;
-      int endPartition = bucketNb * _bucketSize + (_bucketSize - 1);
-      return key.substring(0, idx) + "_p" + startPartition + "-p" + endPartition;
-    } catch (NumberFormatException e) {
-      throw new IllegalArgumentException("Could NOT parse partition# (" + key.substring(idx + 1)
-          + ") in " + key);
-    }
-  }
-
-  /**
-   * Bucketize a ZNRecord
-   * @param record
-   * @return A map of bucket names to bucketized records
-   */
-  public Map<String, ZNRecord> bucketize(ZNRecord record) {
-    Map<String, ZNRecord> map = new HashMap<String, ZNRecord>();
-    if (_bucketSize == 0) {
-      map.put(record.getId(), record);
-      return map;
-    }
-
-    // bucketize list field
-    for (String partitionName : record.getListFields().keySet()) {
-      String bucketName = getBucketName(partitionName);
-      if (bucketName != null) {
-        if (!map.containsKey(bucketName)) {
-          map.put(bucketName, new ZNRecord(bucketName));
-        }
-        ZNRecord bucketizedRecord = map.get(bucketName);
-        bucketizedRecord.setListField(partitionName, record.getListField(partitionName));
-      } else {
-        LOG.error("Can't bucketize " + partitionName + " in list field");
-      }
-    }
-
-    // bucketize map field
-    for (String partitionName : record.getMapFields().keySet()) {
-      String bucketName = getBucketName(partitionName);
-      if (bucketName != null) {
-        if (!map.containsKey(bucketName)) {
-          map.put(bucketName, new ZNRecord(bucketName));
-        }
-        ZNRecord bucketizedRecord = map.get(bucketName);
-        bucketizedRecord.setMapField(partitionName, record.getMapField(partitionName));
-      } else {
-        LOG.error("Can't bucketize " + partitionName + " in map field");
-      }
-    }
-
-    // copy all simple fields
-    for (ZNRecord bucketizedRecord : map.values()) {
-      bucketizedRecord.setSimpleFields(record.getSimpleFields());
-    }
-    return map;
+    super(bucketSize);
   }
 }
diff --git a/helix-core/src/main/java/org/apache/helix/ZNRecordUpdater.java b/helix-core/src/main/java/org/apache/helix/ZNRecordUpdater.java
index 6b74dd1..bedb0e4 100644
--- a/helix-core/src/main/java/org/apache/helix/ZNRecordUpdater.java
+++ b/helix-core/src/main/java/org/apache/helix/ZNRecordUpdater.java
@@ -19,28 +19,20 @@ package org.apache.helix;
  * under the License.
  */
 
-import org.I0Itec.zkclient.DataUpdater;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
+
 
 /**
+ * Deprecated - Use ZNRecordUpdater in zookeeper-api intstead.
  * Class that specifies how a ZNRecord should be updated with another ZNRecord
  */
-public class ZNRecordUpdater implements DataUpdater<ZNRecord> {
-  final ZNRecord _record;
-
+@Deprecated
+public class ZNRecordUpdater extends org.apache.helix.zookeeper.datamodel.ZNRecordUpdater {
   /**
    * Initialize with the record that will be updated
    * @param record
    */
   public ZNRecordUpdater(ZNRecord record) {
-    _record = record;
-  }
-
-  @Override
-  public ZNRecord update(ZNRecord current) {
-    if (current != null) {
-      current.merge(_record);
-      return current;
-    }
-    return _record;
+    super(record);
   }
 }
diff --git a/helix-core/src/main/java/org/apache/helix/api/config/RebalanceConfig.java b/helix-core/src/main/java/org/apache/helix/api/config/RebalanceConfig.java
index 3750554..8ea1c22 100644
--- a/helix-core/src/main/java/org/apache/helix/api/config/RebalanceConfig.java
+++ b/helix-core/src/main/java/org/apache/helix/api/config/RebalanceConfig.java
@@ -22,7 +22,7 @@ package org.apache.helix.api.config;
 import java.util.HashMap;
 import java.util.Map;
 
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
 import org.apache.helix.controller.rebalancer.Rebalancer;
 import org.apache.helix.task.TaskRebalancer;
 import org.slf4j.Logger;
diff --git a/helix-core/src/main/java/org/apache/helix/api/config/StateTransitionTimeoutConfig.java b/helix-core/src/main/java/org/apache/helix/api/config/StateTransitionTimeoutConfig.java
index d39f466..b846b00 100644
--- a/helix-core/src/main/java/org/apache/helix/api/config/StateTransitionTimeoutConfig.java
+++ b/helix-core/src/main/java/org/apache/helix/api/config/StateTransitionTimeoutConfig.java
@@ -22,7 +22,7 @@ package org.apache.helix.api.config;
 import java.util.HashMap;
 import java.util.Map;
 
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
 
 public class StateTransitionTimeoutConfig {
   public enum StateTransitionTimeoutProperty {
diff --git a/helix-core/src/main/java/org/apache/helix/api/listeners/PreFetch.java b/helix-core/src/main/java/org/apache/helix/api/listeners/PreFetch.java
index b601680..594f533 100644
--- a/helix-core/src/main/java/org/apache/helix/api/listeners/PreFetch.java
+++ b/helix-core/src/main/java/org/apache/helix/api/listeners/PreFetch.java
@@ -22,7 +22,10 @@ package org.apache.helix.api.listeners;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 
-
+/**
+ * This annotation has been deprecated. Use PreFetch in zookeeper-api module instead.
+ */
+@Deprecated
 @Retention(RetentionPolicy.RUNTIME)
 public @interface PreFetch {
   boolean enabled() default true;
diff --git a/helix-core/src/main/java/org/apache/helix/common/DedupEventProcessor.java b/helix-core/src/main/java/org/apache/helix/common/DedupEventProcessor.java
index c26ecd8..c761a30 100644
--- a/helix-core/src/main/java/org/apache/helix/common/DedupEventProcessor.java
+++ b/helix-core/src/main/java/org/apache/helix/common/DedupEventProcessor.java
@@ -1,6 +1,6 @@
 package org.apache.helix.common;
 
-import org.I0Itec.zkclient.exception.ZkInterruptedException;
+import org.apache.helix.zookeeper.zkclient.exception.ZkInterruptedException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
diff --git a/helix-core/src/main/java/org/apache/helix/common/caches/TaskDataCache.java b/helix-core/src/main/java/org/apache/helix/common/caches/TaskDataCache.java
index 58c1220..b16e484 100644
--- a/helix-core/src/main/java/org/apache/helix/common/caches/TaskDataCache.java
+++ b/helix-core/src/main/java/org/apache/helix/common/caches/TaskDataCache.java
@@ -30,7 +30,7 @@ import java.util.concurrent.ConcurrentHashMap;
 import org.apache.helix.AccessOption;
 import org.apache.helix.HelixDataAccessor;
 import org.apache.helix.PropertyType;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
 import org.apache.helix.common.controllers.ControlContextProvider;
 import org.apache.helix.controller.LogUtil;
 import org.apache.helix.model.ResourceAssignment;
diff --git a/helix-core/src/main/java/org/apache/helix/controller/ExternalViewGenerator.java b/helix-core/src/main/java/org/apache/helix/controller/ExternalViewGenerator.java
index ab25118..2533b97 100644
--- a/helix-core/src/main/java/org/apache/helix/controller/ExternalViewGenerator.java
+++ b/helix-core/src/main/java/org/apache/helix/controller/ExternalViewGenerator.java
@@ -27,7 +27,7 @@ import java.util.Set;
 import java.util.TreeMap;
 import java.util.TreeSet;
 
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
 import org.apache.helix.model.CurrentState.CurrentStateProperty;
 import org.apache.helix.model.Message;
 import org.slf4j.Logger;
diff --git a/helix-core/src/main/java/org/apache/helix/controller/GenericHelixController.java b/helix-core/src/main/java/org/apache/helix/controller/GenericHelixController.java
index e47c420..8f7da2d 100644
--- a/helix-core/src/main/java/org/apache/helix/controller/GenericHelixController.java
+++ b/helix-core/src/main/java/org/apache/helix/controller/GenericHelixController.java
@@ -38,7 +38,6 @@ import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicReference;
 
 import com.google.common.collect.Sets;
-import org.I0Itec.zkclient.exception.ZkInterruptedException;
 import org.apache.helix.HelixDataAccessor;
 import org.apache.helix.HelixManager;
 import org.apache.helix.NotificationContext;
@@ -99,6 +98,7 @@ import org.apache.helix.model.PauseSignal;
 import org.apache.helix.model.ResourceConfig;
 import org.apache.helix.monitoring.mbeans.ClusterEventMonitor;
 import org.apache.helix.monitoring.mbeans.ClusterStatusMonitor;
+import org.apache.helix.zookeeper.zkclient.exception.ZkInterruptedException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
diff --git a/helix-core/src/main/java/org/apache/helix/controller/HelixControllerMain.java b/helix-core/src/main/java/org/apache/helix/controller/HelixControllerMain.java
index d8e5a3f..d446fec 100644
--- a/helix-core/src/main/java/org/apache/helix/controller/HelixControllerMain.java
+++ b/helix-core/src/main/java/org/apache/helix/controller/HelixControllerMain.java
@@ -35,7 +35,6 @@ package org.apache.helix.controller;
 
 import java.util.Arrays;
 
-import org.I0Itec.zkclient.exception.ZkInterruptedException;
 import org.apache.commons.cli.CommandLine;
 import org.apache.commons.cli.CommandLineParser;
 import org.apache.commons.cli.GnuParser;
@@ -50,6 +49,7 @@ import org.apache.helix.InstanceType;
 import org.apache.helix.manager.zk.HelixManagerShutdownHook;
 import org.apache.helix.participant.DistClusterControllerStateModelFactory;
 import org.apache.helix.participant.StateMachineEngine;
+import org.apache.helix.zookeeper.zkclient.exception.ZkInterruptedException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
diff --git a/helix-core/src/main/java/org/apache/helix/controller/HierarchicalDataHolder.java b/helix-core/src/main/java/org/apache/helix/controller/HierarchicalDataHolder.java
index 27ecc40..a6e71ee 100644
--- a/helix-core/src/main/java/org/apache/helix/controller/HierarchicalDataHolder.java
+++ b/helix-core/src/main/java/org/apache/helix/controller/HierarchicalDataHolder.java
@@ -26,7 +26,7 @@ import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.atomic.AtomicLong;
 import java.util.concurrent.atomic.AtomicReference;
 
-import org.apache.helix.manager.zk.client.HelixZkClient;
+import org.apache.helix.zookeeper.api.client.HelixZkClient;
 import org.apache.zookeeper.data.Stat;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
diff --git a/helix-core/src/main/java/org/apache/helix/controller/changedetector/ResourceChangeSnapshot.java b/helix-core/src/main/java/org/apache/helix/controller/changedetector/ResourceChangeSnapshot.java
index fc8c5c4..4d31ad4 100644
--- a/helix-core/src/main/java/org/apache/helix/controller/changedetector/ResourceChangeSnapshot.java
+++ b/helix-core/src/main/java/org/apache/helix/controller/changedetector/ResourceChangeSnapshot.java
@@ -27,7 +27,7 @@ import java.util.Set;
 import java.util.stream.Collectors;
 
 import org.apache.helix.HelixConstants;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
 import org.apache.helix.controller.dataproviders.ResourceControllerDataProvider;
 import org.apache.helix.model.ClusterConfig;
 import org.apache.helix.model.IdealState;
diff --git a/helix-core/src/main/java/org/apache/helix/controller/dataproviders/ResourceControllerDataProvider.java b/helix-core/src/main/java/org/apache/helix/controller/dataproviders/ResourceControllerDataProvider.java
index 1631d50..74a93c7 100644
--- a/helix-core/src/main/java/org/apache/helix/controller/dataproviders/ResourceControllerDataProvider.java
+++ b/helix-core/src/main/java/org/apache/helix/controller/dataproviders/ResourceControllerDataProvider.java
@@ -29,7 +29,7 @@ import java.util.concurrent.ConcurrentHashMap;
 import org.apache.helix.HelixConstants;
 import org.apache.helix.HelixDataAccessor;
 import org.apache.helix.PropertyKey;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
 import org.apache.helix.common.caches.AbstractDataCache;
 import org.apache.helix.common.caches.PropertyCache;
 import org.apache.helix.controller.LogUtil;
diff --git a/helix-core/src/main/java/org/apache/helix/controller/dataproviders/WorkflowControllerDataProvider.java b/helix-core/src/main/java/org/apache/helix/controller/dataproviders/WorkflowControllerDataProvider.java
index 714b659..20308a4 100644
--- a/helix-core/src/main/java/org/apache/helix/controller/dataproviders/WorkflowControllerDataProvider.java
+++ b/helix-core/src/main/java/org/apache/helix/controller/dataproviders/WorkflowControllerDataProvider.java
@@ -26,7 +26,7 @@ import java.util.Set;
 
 import org.apache.helix.HelixConstants;
 import org.apache.helix.HelixDataAccessor;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
 import org.apache.helix.common.caches.AbstractDataCache;
 import org.apache.helix.common.caches.TaskDataCache;
 import org.apache.helix.controller.LogUtil;
diff --git a/helix-core/src/main/java/org/apache/helix/controller/rebalancer/AbstractRebalancer.java b/helix-core/src/main/java/org/apache/helix/controller/rebalancer/AbstractRebalancer.java
index 4a6eff8..17343e6 100644
--- a/helix-core/src/main/java/org/apache/helix/controller/rebalancer/AbstractRebalancer.java
+++ b/helix-core/src/main/java/org/apache/helix/controller/rebalancer/AbstractRebalancer.java
@@ -32,7 +32,7 @@ import java.util.Set;
 import org.apache.helix.HelixDefinedState;
 import org.apache.helix.HelixException;
 import org.apache.helix.HelixManager;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
 import org.apache.helix.controller.dataproviders.BaseControllerDataProvider;
 import org.apache.helix.controller.dataproviders.ResourceControllerDataProvider;
 import org.apache.helix.controller.rebalancer.internal.MappingCalculator;
diff --git a/helix-core/src/main/java/org/apache/helix/controller/rebalancer/AutoRebalancer.java b/helix-core/src/main/java/org/apache/helix/controller/rebalancer/AutoRebalancer.java
index c0b6f26..f74f1eb 100644
--- a/helix-core/src/main/java/org/apache/helix/controller/rebalancer/AutoRebalancer.java
+++ b/helix-core/src/main/java/org/apache/helix/controller/rebalancer/AutoRebalancer.java
@@ -28,7 +28,7 @@ import java.util.Map;
 import java.util.Set;
 
 import org.apache.helix.HelixException;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
 import org.apache.helix.controller.dataproviders.ResourceControllerDataProvider;
 import org.apache.helix.controller.stages.CurrentStateOutput;
 import org.apache.helix.model.IdealState;
diff --git a/helix-core/src/main/java/org/apache/helix/controller/rebalancer/DelayedAutoRebalancer.java b/helix-core/src/main/java/org/apache/helix/controller/rebalancer/DelayedAutoRebalancer.java
index 63870ec..448cc73 100644
--- a/helix-core/src/main/java/org/apache/helix/controller/rebalancer/DelayedAutoRebalancer.java
+++ b/helix-core/src/main/java/org/apache/helix/controller/rebalancer/DelayedAutoRebalancer.java
@@ -30,7 +30,7 @@ import java.util.Map;
 import java.util.Set;
 
 import org.apache.helix.HelixDefinedState;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
 import org.apache.helix.api.config.StateTransitionThrottleConfig;
 import org.apache.helix.controller.dataproviders.ResourceControllerDataProvider;
 import org.apache.helix.controller.rebalancer.util.DelayedRebalanceUtil;
diff --git a/helix-core/src/main/java/org/apache/helix/controller/rebalancer/constraint/dataprovider/ZkBasedCapacityProvider.java b/helix-core/src/main/java/org/apache/helix/controller/rebalancer/constraint/dataprovider/ZkBasedCapacityProvider.java
index b4fefb3..f2ba28c 100644
--- a/helix-core/src/main/java/org/apache/helix/controller/rebalancer/constraint/dataprovider/ZkBasedCapacityProvider.java
+++ b/helix-core/src/main/java/org/apache/helix/controller/rebalancer/constraint/dataprovider/ZkBasedCapacityProvider.java
@@ -26,7 +26,7 @@ import org.apache.helix.AccessOption;
 import org.apache.helix.HelixException;
 import org.apache.helix.HelixProperty;
 import org.apache.helix.PropertyPathBuilder;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
 import org.apache.helix.api.rebalancer.constraint.dataprovider.CapacityProvider;
 import org.apache.helix.manager.zk.ZNRecordSerializer;
 import org.apache.helix.store.zk.ZkHelixPropertyStore;
diff --git a/helix-core/src/main/java/org/apache/helix/controller/rebalancer/constraint/dataprovider/ZkBasedPartitionWeightProvider.java b/helix-core/src/main/java/org/apache/helix/controller/rebalancer/constraint/dataprovider/ZkBasedPartitionWeightProvider.java
index 8325682..bea711f 100644
--- a/helix-core/src/main/java/org/apache/helix/controller/rebalancer/constraint/dataprovider/ZkBasedPartitionWeightProvider.java
+++ b/helix-core/src/main/java/org/apache/helix/controller/rebalancer/constraint/dataprovider/ZkBasedPartitionWeightProvider.java
@@ -26,7 +26,7 @@ import org.apache.helix.AccessOption;
 import org.apache.helix.HelixException;
 import org.apache.helix.HelixProperty;
 import org.apache.helix.PropertyPathBuilder;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
 import org.apache.helix.api.rebalancer.constraint.dataprovider.PartitionWeightProvider;
 import org.apache.helix.manager.zk.ZNRecordSerializer;
 import org.apache.helix.store.zk.ZkHelixPropertyStore;
diff --git a/helix-core/src/main/java/org/apache/helix/controller/rebalancer/strategy/AbstractEvenDistributionRebalanceStrategy.java b/helix-core/src/main/java/org/apache/helix/controller/rebalancer/strategy/AbstractEvenDistributionRebalanceStrategy.java
index 267ac1a..71daaad 100644
--- a/helix-core/src/main/java/org/apache/helix/controller/rebalancer/strategy/AbstractEvenDistributionRebalanceStrategy.java
+++ b/helix-core/src/main/java/org/apache/helix/controller/rebalancer/strategy/AbstractEvenDistributionRebalanceStrategy.java
@@ -32,7 +32,7 @@ import java.util.concurrent.ExecutionException;
 import java.util.stream.Collectors;
 
 import org.apache.helix.HelixException;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
 import org.apache.helix.controller.LogUtil;
 import org.apache.helix.controller.dataproviders.ResourceControllerDataProvider;
 import org.apache.helix.controller.rebalancer.strategy.crushMapping.CardDealingAdjustmentAlgorithmV2;
diff --git a/helix-core/src/main/java/org/apache/helix/controller/rebalancer/strategy/AutoRebalanceStrategy.java b/helix-core/src/main/java/org/apache/helix/controller/rebalancer/strategy/AutoRebalanceStrategy.java
index bd7e46a..0bdaed8 100644
--- a/helix-core/src/main/java/org/apache/helix/controller/rebalancer/strategy/AutoRebalanceStrategy.java
+++ b/helix-core/src/main/java/org/apache/helix/controller/rebalancer/strategy/AutoRebalanceStrategy.java
@@ -34,7 +34,7 @@ import java.util.TreeMap;
 import java.util.TreeSet;
 
 import org.apache.helix.HelixManager;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
 import org.apache.helix.controller.dataproviders.ResourceControllerDataProvider;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
diff --git a/helix-core/src/main/java/org/apache/helix/controller/rebalancer/strategy/ConstraintRebalanceStrategy.java b/helix-core/src/main/java/org/apache/helix/controller/rebalancer/strategy/ConstraintRebalanceStrategy.java
index 4d8b41f..a555d34 100644
--- a/helix-core/src/main/java/org/apache/helix/controller/rebalancer/strategy/ConstraintRebalanceStrategy.java
+++ b/helix-core/src/main/java/org/apache/helix/controller/rebalancer/strategy/ConstraintRebalanceStrategy.java
@@ -28,7 +28,7 @@ import java.util.Map;
 import java.util.Random;
 
 import org.apache.helix.HelixException;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
 import org.apache.helix.api.rebalancer.constraint.AbstractRebalanceHardConstraint;
 import org.apache.helix.api.rebalancer.constraint.AbstractRebalanceSoftConstraint;
 import org.apache.helix.api.rebalancer.constraint.dataprovider.CapacityProvider;
diff --git a/helix-core/src/main/java/org/apache/helix/controller/rebalancer/strategy/CrushRebalanceStrategy.java b/helix-core/src/main/java/org/apache/helix/controller/rebalancer/strategy/CrushRebalanceStrategy.java
index 4c1d972..5db5b2a 100644
--- a/helix-core/src/main/java/org/apache/helix/controller/rebalancer/strategy/CrushRebalanceStrategy.java
+++ b/helix-core/src/main/java/org/apache/helix/controller/rebalancer/strategy/CrushRebalanceStrategy.java
@@ -30,7 +30,7 @@ import java.util.Set;
 import com.google.common.base.Predicate;
 import com.google.common.base.Predicates;
 import org.apache.helix.HelixException;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
 import org.apache.helix.controller.LogUtil;
 import org.apache.helix.controller.dataproviders.ResourceControllerDataProvider;
 import org.apache.helix.controller.rebalancer.strategy.crushMapping.CRUSHPlacementAlgorithm;
diff --git a/helix-core/src/main/java/org/apache/helix/controller/rebalancer/strategy/MultiRoundCrushRebalanceStrategy.java b/helix-core/src/main/java/org/apache/helix/controller/rebalancer/strategy/MultiRoundCrushRebalanceStrategy.java
index 04b084b..847109c 100644
--- a/helix-core/src/main/java/org/apache/helix/controller/rebalancer/strategy/MultiRoundCrushRebalanceStrategy.java
+++ b/helix-core/src/main/java/org/apache/helix/controller/rebalancer/strategy/MultiRoundCrushRebalanceStrategy.java
@@ -31,7 +31,7 @@ import java.util.Set;
 import com.google.common.base.Predicate;
 import com.google.common.base.Predicates;
 import org.apache.helix.HelixException;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
 import org.apache.helix.controller.LogUtil;
 import org.apache.helix.controller.dataproviders.ResourceControllerDataProvider;
 import org.apache.helix.controller.rebalancer.strategy.crushMapping.CRUSHPlacementAlgorithm;
diff --git a/helix-core/src/main/java/org/apache/helix/controller/rebalancer/strategy/RebalanceStrategy.java b/helix-core/src/main/java/org/apache/helix/controller/rebalancer/strategy/RebalanceStrategy.java
index 223cf8e..4c885cf 100644
--- a/helix-core/src/main/java/org/apache/helix/controller/rebalancer/strategy/RebalanceStrategy.java
+++ b/helix-core/src/main/java/org/apache/helix/controller/rebalancer/strategy/RebalanceStrategy.java
@@ -23,7 +23,7 @@ import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
 import org.apache.helix.controller.dataproviders.BaseControllerDataProvider;
 
 /**
diff --git a/helix-core/src/main/java/org/apache/helix/controller/rebalancer/waged/AssignmentMetadataStore.java b/helix-core/src/main/java/org/apache/helix/controller/rebalancer/waged/AssignmentMetadataStore.java
index afd0187..381b612 100644
--- a/helix-core/src/main/java/org/apache/helix/controller/rebalancer/waged/AssignmentMetadataStore.java
+++ b/helix-core/src/main/java/org/apache/helix/controller/rebalancer/waged/AssignmentMetadataStore.java
@@ -24,16 +24,15 @@ import java.util.Collections;
 import java.util.HashMap;
 import java.util.Map;
 
-import org.I0Itec.zkclient.exception.ZkNoNodeException;
-import org.I0Itec.zkclient.serialize.ZkSerializer;
 import org.apache.helix.BucketDataAccessor;
 import org.apache.helix.HelixException;
 import org.apache.helix.HelixProperty;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
 import org.apache.helix.manager.zk.ZNRecordJacksonSerializer;
 import org.apache.helix.manager.zk.ZkBucketDataAccessor;
 import org.apache.helix.model.ResourceAssignment;
-
+import org.apache.helix.zookeeper.zkclient.exception.ZkNoNodeException;
+import org.apache.helix.zookeeper.zkclient.serialize.ZkSerializer;
 
 /**
  * A placeholder before we have the real assignment metadata store.
@@ -178,8 +177,8 @@ public class AssignmentMetadataStore {
     HelixProperty property = new HelixProperty(name);
     // Add each resource's assignment as a simple field in one ZNRecord
     // Node that don't use Arrays.toString() for the record converting. The deserialize will fail.
-    assignmentMap.forEach((resource, assignment) -> property.getRecord()
-        .setSimpleField(resource, new String(SERIALIZER.serialize(assignment.getRecord()))));
+    assignmentMap.forEach((resource, assignment) -> property.getRecord().setSimpleField(resource,
+        new String(SERIALIZER.serialize(assignment.getRecord()))));
     return property;
   }
 
@@ -192,8 +191,8 @@ public class AssignmentMetadataStore {
     Map<String, ResourceAssignment> assignmentMap = new HashMap<>();
     // Convert each resource's assignment String into a ResourceAssignment object and put it in a
     // map
-    property.getRecord().getSimpleFields().forEach((resource, assignmentStr) -> assignmentMap
-        .put(resource,
+    property.getRecord().getSimpleFields()
+        .forEach((resource, assignmentStr) -> assignmentMap.put(resource,
             new ResourceAssignment((ZNRecord) SERIALIZER.deserialize(assignmentStr.getBytes()))));
     return assignmentMap;
   }
diff --git a/helix-core/src/main/java/org/apache/helix/controller/stages/ClusterDataCache.java b/helix-core/src/main/java/org/apache/helix/controller/stages/ClusterDataCache.java
index 0f321e1..c64dc94 100644
--- a/helix-core/src/main/java/org/apache/helix/controller/stages/ClusterDataCache.java
+++ b/helix-core/src/main/java/org/apache/helix/controller/stages/ClusterDataCache.java
@@ -25,7 +25,7 @@ import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
 
 import org.apache.helix.HelixDataAccessor;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
 import org.apache.helix.common.caches.CurrentStateCache;
 import org.apache.helix.common.caches.IdealStateCache;
 import org.apache.helix.common.caches.InstanceMessagesCache;
diff --git a/helix-core/src/main/java/org/apache/helix/controller/stages/ExternalViewComputeStage.java b/helix-core/src/main/java/org/apache/helix/controller/stages/ExternalViewComputeStage.java
index 0580485..ed5cbc3 100644
--- a/helix-core/src/main/java/org/apache/helix/controller/stages/ExternalViewComputeStage.java
+++ b/helix-core/src/main/java/org/apache/helix/controller/stages/ExternalViewComputeStage.java
@@ -35,9 +35,6 @@ import org.apache.helix.HelixException;
 import org.apache.helix.HelixManager;
 import org.apache.helix.PropertyKey;
 import org.apache.helix.PropertyKey.Builder;
-import org.apache.helix.ZNRecord;
-import org.apache.helix.ZNRecordDelta;
-import org.apache.helix.ZNRecordDelta.MergeOperation;
 import org.apache.helix.controller.LogUtil;
 import org.apache.helix.controller.dataproviders.ResourceControllerDataProvider;
 import org.apache.helix.controller.pipeline.AbstractAsyncBaseStage;
@@ -54,6 +51,8 @@ import org.apache.helix.model.ResourceConfig;
 import org.apache.helix.model.StateModelDefinition;
 import org.apache.helix.model.StatusUpdate;
 import org.apache.helix.monitoring.mbeans.ClusterStatusMonitor;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecordDelta;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -316,7 +315,7 @@ public class ExternalViewComputeStage extends AbstractAsyncBaseStage {
     }
 
     if (finishedTasks.getListFields().size() > 0) {
-      ZNRecordDelta znDelta = new ZNRecordDelta(finishedTasks, MergeOperation.SUBTRACT);
+      ZNRecordDelta znDelta = new ZNRecordDelta(finishedTasks, ZNRecordDelta.MergeOperation.SUBTRACT);
       List<ZNRecordDelta> deltaList = new LinkedList<ZNRecordDelta>();
       deltaList.add(znDelta);
       IdealState delta = new IdealState(taskQueueIdealState.getResourceName());
diff --git a/helix-core/src/main/java/org/apache/helix/controller/stages/PersistAssignmentStage.java b/helix-core/src/main/java/org/apache/helix/controller/stages/PersistAssignmentStage.java
index d33cdfc..4959646 100644
--- a/helix-core/src/main/java/org/apache/helix/controller/stages/PersistAssignmentStage.java
+++ b/helix-core/src/main/java/org/apache/helix/controller/stages/PersistAssignmentStage.java
@@ -26,12 +26,11 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
-import org.I0Itec.zkclient.DataUpdater;
 import org.apache.helix.HelixDataAccessor;
 import org.apache.helix.HelixException;
 import org.apache.helix.HelixManager;
 import org.apache.helix.PropertyKey;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
 import org.apache.helix.controller.LogUtil;
 import org.apache.helix.controller.common.PartitionStateMap;
 import org.apache.helix.controller.dataproviders.ResourceControllerDataProvider;
@@ -43,6 +42,7 @@ import org.apache.helix.model.IdealState;
 import org.apache.helix.model.MasterSlaveSMD;
 import org.apache.helix.model.Partition;
 import org.apache.helix.model.Resource;
+import org.apache.helix.zookeeper.zkclient.DataUpdater;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
diff --git a/helix-core/src/main/java/org/apache/helix/controller/strategy/AutoRebalanceStrategy.java b/helix-core/src/main/java/org/apache/helix/controller/strategy/AutoRebalanceStrategy.java
index 270e6de..1c325e1 100644
--- a/helix-core/src/main/java/org/apache/helix/controller/strategy/AutoRebalanceStrategy.java
+++ b/helix-core/src/main/java/org/apache/helix/controller/strategy/AutoRebalanceStrategy.java
@@ -33,7 +33,7 @@ import java.util.TreeMap;
 import java.util.TreeSet;
 
 import org.apache.helix.HelixManager;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
diff --git a/helix-core/src/main/java/org/apache/helix/examples/ExampleHelper.java b/helix-core/src/main/java/org/apache/helix/examples/ExampleHelper.java
index 44ee1e5..c1e87b0 100644
--- a/helix-core/src/main/java/org/apache/helix/examples/ExampleHelper.java
+++ b/helix-core/src/main/java/org/apache/helix/examples/ExampleHelper.java
@@ -22,9 +22,11 @@ package org.apache.helix.examples;
 import java.io.File;
 import java.io.IOException;
 
-import org.I0Itec.zkclient.IDefaultNameSpace;
-import org.I0Itec.zkclient.ZkServer;
 import org.apache.commons.io.FileUtils;
+import org.apache.helix.zookeeper.zkclient.IDefaultNameSpace;
+import org.apache.helix.zookeeper.zkclient.ZkClient;
+import org.apache.helix.zookeeper.zkclient.ZkServer;
+
 
 public class ExampleHelper {
 
@@ -45,7 +47,7 @@ public class ExampleHelper {
 
     IDefaultNameSpace defaultNameSpace = new IDefaultNameSpace() {
       @Override
-      public void createDefaultNameSpace(org.I0Itec.zkclient.ZkClient zkClient) {
+      public void createDefaultNameSpace(ZkClient zkClient) {
         // do nothing
       }
     };
diff --git a/helix-core/src/main/java/org/apache/helix/examples/IdealStateBuilderExample.java b/helix-core/src/main/java/org/apache/helix/examples/IdealStateBuilderExample.java
index 71e6662..f413c46 100644
--- a/helix-core/src/main/java/org/apache/helix/examples/IdealStateBuilderExample.java
+++ b/helix-core/src/main/java/org/apache/helix/examples/IdealStateBuilderExample.java
@@ -22,8 +22,6 @@ package org.apache.helix.examples;
 import org.apache.helix.controller.HelixControllerMain;
 import org.apache.helix.manager.zk.ZKHelixAdmin;
 import org.apache.helix.manager.zk.ZNRecordSerializer;
-import org.apache.helix.manager.zk.client.HelixZkClient;
-import org.apache.helix.manager.zk.client.SharedZkClientFactory;
 import org.apache.helix.model.IdealState;
 import org.apache.helix.model.IdealState.RebalanceMode;
 import org.apache.helix.model.InstanceConfig;
@@ -32,6 +30,9 @@ import org.apache.helix.model.builder.CustomModeISBuilder;
 import org.apache.helix.model.builder.FullAutoModeISBuilder;
 import org.apache.helix.model.builder.SemiAutoModeISBuilder;
 import org.apache.helix.tools.StateModelConfigGenerator;
+import org.apache.helix.zookeeper.api.client.HelixZkClient;
+import org.apache.helix.zookeeper.impl.factory.SharedZkClientFactory;
+
 
 public class IdealStateBuilderExample {
 
diff --git a/helix-core/src/main/java/org/apache/helix/examples/IdealStateExample.java b/helix-core/src/main/java/org/apache/helix/examples/IdealStateExample.java
index 723cbbe..988eaa7 100644
--- a/helix-core/src/main/java/org/apache/helix/examples/IdealStateExample.java
+++ b/helix-core/src/main/java/org/apache/helix/examples/IdealStateExample.java
@@ -22,12 +22,13 @@ package org.apache.helix.examples;
 import org.apache.helix.controller.HelixControllerMain;
 import org.apache.helix.manager.zk.ZKHelixAdmin;
 import org.apache.helix.manager.zk.ZNRecordSerializer;
-import org.apache.helix.manager.zk.client.HelixZkClient;
-import org.apache.helix.manager.zk.client.SharedZkClientFactory;
 import org.apache.helix.model.IdealState.RebalanceMode;
 import org.apache.helix.model.InstanceConfig;
 import org.apache.helix.model.StateModelDefinition;
 import org.apache.helix.tools.StateModelConfigGenerator;
+import org.apache.helix.zookeeper.api.client.HelixZkClient;
+import org.apache.helix.zookeeper.impl.factory.SharedZkClientFactory;
+
 
 /**
  * Ideal state json format file used in this example for CUSTOMIZED ideal state mode
diff --git a/helix-core/src/main/java/org/apache/helix/examples/Quickstart.java b/helix-core/src/main/java/org/apache/helix/examples/Quickstart.java
index 6773848..854b649 100644
--- a/helix-core/src/main/java/org/apache/helix/examples/Quickstart.java
+++ b/helix-core/src/main/java/org/apache/helix/examples/Quickstart.java
@@ -25,9 +25,6 @@ import java.util.List;
 import java.util.Map;
 import java.util.TreeSet;
 
-import org.I0Itec.zkclient.IDefaultNameSpace;
-import org.I0Itec.zkclient.ZkClient;
-import org.I0Itec.zkclient.ZkServer;
 import org.apache.helix.HelixAdmin;
 import org.apache.helix.HelixManager;
 import org.apache.helix.HelixManagerFactory;
@@ -38,6 +35,10 @@ import org.apache.helix.model.ExternalView;
 import org.apache.helix.model.InstanceConfig;
 import org.apache.helix.model.StateModelDefinition;
 import org.apache.helix.participant.StateMachineEngine;
+import org.apache.helix.zookeeper.zkclient.IDefaultNameSpace;
+import org.apache.helix.zookeeper.zkclient.ZkClient;
+import org.apache.helix.zookeeper.zkclient.ZkServer;
+
 
 public class Quickstart {
 
diff --git a/helix-core/src/main/java/org/apache/helix/examples/WeightAwareRebalanceUtilExample.java b/helix-core/src/main/java/org/apache/helix/examples/WeightAwareRebalanceUtilExample.java
index 13d22ba..a9a4cc4 100644
--- a/helix-core/src/main/java/org/apache/helix/examples/WeightAwareRebalanceUtilExample.java
+++ b/helix-core/src/main/java/org/apache/helix/examples/WeightAwareRebalanceUtilExample.java
@@ -1,12 +1,30 @@
 package org.apache.helix.examples;
 
+/*
+ * 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 java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
-import org.I0Itec.zkclient.ZkServer;
 import org.apache.helix.HelixAdmin;
 import org.apache.helix.api.rebalancer.constraint.AbstractRebalanceHardConstraint;
 import org.apache.helix.api.rebalancer.constraint.AbstractRebalanceSoftConstraint;
@@ -22,6 +40,8 @@ import org.apache.helix.model.ClusterConfig;
 import org.apache.helix.model.InstanceConfig;
 import org.apache.helix.model.ResourceConfig;
 import org.apache.helix.util.WeightAwareRebalanceUtil;
+import org.apache.helix.zookeeper.zkclient.ZkServer;
+
 
 public class WeightAwareRebalanceUtilExample {
   private static String ZK_ADDRESS = "localhost:2199";
diff --git a/helix-core/src/main/java/org/apache/helix/healthcheck/ParticipantHealthReportCollector.java b/helix-core/src/main/java/org/apache/helix/healthcheck/ParticipantHealthReportCollector.java
index 5ba6cb4..1e92e2a 100644
--- a/helix-core/src/main/java/org/apache/helix/healthcheck/ParticipantHealthReportCollector.java
+++ b/helix-core/src/main/java/org/apache/helix/healthcheck/ParticipantHealthReportCollector.java
@@ -19,7 +19,7 @@ package org.apache.helix.healthcheck;
  * under the License.
  */
 
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
 
 public interface ParticipantHealthReportCollector {
   void addHealthReportProvider(HealthReportProvider provider);
diff --git a/helix-core/src/main/java/org/apache/helix/healthcheck/ParticipantHealthReportCollectorImpl.java b/helix-core/src/main/java/org/apache/helix/healthcheck/ParticipantHealthReportCollectorImpl.java
index 2ca9dd2..ca08653 100644
--- a/helix-core/src/main/java/org/apache/helix/healthcheck/ParticipantHealthReportCollectorImpl.java
+++ b/helix-core/src/main/java/org/apache/helix/healthcheck/ParticipantHealthReportCollectorImpl.java
@@ -25,7 +25,7 @@ import java.util.Map;
 import org.apache.helix.HelixDataAccessor;
 import org.apache.helix.HelixManager;
 import org.apache.helix.PropertyKey.Builder;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
 import org.apache.helix.model.HealthStat;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
diff --git a/helix-core/src/main/java/org/apache/helix/manager/zk/BasicZkSerializer.java b/helix-core/src/main/java/org/apache/helix/manager/zk/BasicZkSerializer.java
index df165b1..99612a0 100644
--- a/helix-core/src/main/java/org/apache/helix/manager/zk/BasicZkSerializer.java
+++ b/helix-core/src/main/java/org/apache/helix/manager/zk/BasicZkSerializer.java
@@ -19,25 +19,17 @@ package org.apache.helix.manager.zk;
  * under the License.
  */
 
-import org.I0Itec.zkclient.serialize.ZkSerializer;
+import org.apache.helix.zookeeper.zkclient.serialize.ZkSerializer;
+
 
 /**
- * Basic path based serializer which ignores the path and delegates
- * serialization into a regular {@link ZkSerializer}
+ * Use BasicZkSerializer in zookeeper-api module instead.
  */
-public class BasicZkSerializer implements PathBasedZkSerializer {
-  private final ZkSerializer _delegate;
-
-  public BasicZkSerializer(ZkSerializer delegate) {
-    _delegate = delegate;
-  }
-
-  public byte[] serialize(Object data, String path) {
-    return _delegate.serialize(data);
-  }
-
-  @Override
-  public Object deserialize(byte[] bytes, String path) {
-    return _delegate.deserialize(bytes);
+@Deprecated
+public class BasicZkSerializer
+    extends org.apache.helix.zookeeper.zkclient.serialize.BasicZkSerializer {
+  public BasicZkSerializer(
+      ZkSerializer delegate) {
+    super(delegate);
   }
 }
diff --git a/helix-core/src/main/java/org/apache/helix/manager/zk/ByteArraySerializer.java b/helix-core/src/main/java/org/apache/helix/manager/zk/ByteArraySerializer.java
index d054011..a1889ea 100644
--- a/helix-core/src/main/java/org/apache/helix/manager/zk/ByteArraySerializer.java
+++ b/helix-core/src/main/java/org/apache/helix/manager/zk/ByteArraySerializer.java
@@ -19,8 +19,9 @@ package org.apache.helix.manager.zk;
  * under the License.
  */
 
-import org.I0Itec.zkclient.exception.ZkMarshallingError;
-import org.I0Itec.zkclient.serialize.ZkSerializer;
+import org.apache.helix.zookeeper.zkclient.exception.ZkMarshallingError;
+import org.apache.helix.zookeeper.zkclient.serialize.ZkSerializer;
+
 
 public class ByteArraySerializer implements ZkSerializer {
   @Override
diff --git a/helix-core/src/main/java/org/apache/helix/manager/zk/CallbackHandler.java b/helix-core/src/main/java/org/apache/helix/manager/zk/CallbackHandler.java
index 0f03ee4..82c9b29 100644
--- a/helix-core/src/main/java/org/apache/helix/manager/zk/CallbackHandler.java
+++ b/helix-core/src/main/java/org/apache/helix/manager/zk/CallbackHandler.java
@@ -29,9 +29,6 @@ import java.util.Map;
 import java.util.Set;
 import java.util.concurrent.atomic.AtomicLong;
 
-import org.I0Itec.zkclient.IZkChildListener;
-import org.I0Itec.zkclient.IZkDataListener;
-import org.I0Itec.zkclient.exception.ZkNoNodeException;
 import org.apache.helix.BaseDataAccessor;
 import org.apache.helix.HelixConstants.ChangeType;
 import org.apache.helix.HelixDataAccessor;
@@ -43,7 +40,6 @@ import org.apache.helix.NotificationContext.Type;
 import org.apache.helix.PropertyKey;
 import org.apache.helix.PropertyPathConfig;
 import org.apache.helix.SystemPropertyKeys;
-import org.apache.helix.ZNRecord;
 import org.apache.helix.api.listeners.BatchMode;
 import org.apache.helix.api.listeners.ClusterConfigChangeListener;
 import org.apache.helix.api.listeners.ConfigChangeListener;
@@ -58,7 +54,6 @@ import org.apache.helix.api.listeners.PreFetch;
 import org.apache.helix.api.listeners.ResourceConfigChangeListener;
 import org.apache.helix.api.listeners.ScopedConfigChangeListener;
 import org.apache.helix.common.DedupEventProcessor;
-import org.apache.helix.manager.zk.client.HelixZkClient;
 import org.apache.helix.model.ClusterConfig;
 import org.apache.helix.model.CurrentState;
 import org.apache.helix.model.ExternalView;
@@ -68,6 +63,11 @@ import org.apache.helix.model.LiveInstance;
 import org.apache.helix.model.Message;
 import org.apache.helix.model.ResourceConfig;
 import org.apache.helix.monitoring.mbeans.HelixCallbackMonitor;
+import org.apache.helix.zookeeper.api.client.HelixZkClient;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
+import org.apache.helix.zookeeper.zkclient.IZkChildListener;
+import org.apache.helix.zookeeper.zkclient.IZkDataListener;
+import org.apache.helix.zookeeper.zkclient.exception.ZkNoNodeException;
 import org.apache.zookeeper.Watcher.Event.EventType;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
diff --git a/helix-core/src/main/java/org/apache/helix/manager/zk/ChainedPathZkSerializer.java b/helix-core/src/main/java/org/apache/helix/manager/zk/ChainedPathZkSerializer.java
index 6975ea1..bb815c1 100644
--- a/helix-core/src/main/java/org/apache/helix/manager/zk/ChainedPathZkSerializer.java
+++ b/helix-core/src/main/java/org/apache/helix/manager/zk/ChainedPathZkSerializer.java
@@ -23,8 +23,9 @@ import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 
-import org.I0Itec.zkclient.exception.ZkMarshallingError;
-import org.I0Itec.zkclient.serialize.ZkSerializer;
+import org.apache.helix.zookeeper.zkclient.exception.ZkMarshallingError;
+import org.apache.helix.zookeeper.zkclient.serialize.ZkSerializer;
+
 
 public class ChainedPathZkSerializer implements PathBasedZkSerializer {
 
diff --git a/helix-core/src/main/java/org/apache/helix/manager/zk/ControllerManagerHelper.java b/helix-core/src/main/java/org/apache/helix/manager/zk/ControllerManagerHelper.java
index eeb2242..3b25f0f 100644
--- a/helix-core/src/main/java/org/apache/helix/manager/zk/ControllerManagerHelper.java
+++ b/helix-core/src/main/java/org/apache/helix/manager/zk/ControllerManagerHelper.java
@@ -21,13 +21,13 @@ package org.apache.helix.manager.zk;
 
 import java.util.List;
 
-import org.I0Itec.zkclient.exception.ZkInterruptedException;
 import org.apache.helix.HelixManager;
 import org.apache.helix.HelixTimerTask;
 import org.apache.helix.PropertyKey;
 import org.apache.helix.controller.GenericHelixController;
 import org.apache.helix.messaging.DefaultMessagingService;
 import org.apache.helix.messaging.handling.MultiTypeMessageHandlerFactory;
+import org.apache.helix.zookeeper.zkclient.exception.ZkInterruptedException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
diff --git a/helix-core/src/main/java/org/apache/helix/manager/zk/CurStateCarryOverUpdater.java b/helix-core/src/main/java/org/apache/helix/manager/zk/CurStateCarryOverUpdater.java
index f52a669..8fff9d2 100644
--- a/helix-core/src/main/java/org/apache/helix/manager/zk/CurStateCarryOverUpdater.java
+++ b/helix-core/src/main/java/org/apache/helix/manager/zk/CurStateCarryOverUpdater.java
@@ -19,11 +19,11 @@ package org.apache.helix.manager.zk;
  * under the License.
  */
 
-import org.I0Itec.zkclient.DataUpdater;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
 import org.apache.helix.model.CurrentState;
 import org.apache.helix.task.TaskConstants;
 import org.apache.helix.task.TaskPartitionState;
+import org.apache.helix.zookeeper.zkclient.DataUpdater;
 
 
 /**
diff --git a/helix-core/src/main/java/org/apache/helix/manager/zk/DefaultSchedulerMessageHandlerFactory.java b/helix-core/src/main/java/org/apache/helix/manager/zk/DefaultSchedulerMessageHandlerFactory.java
index 93819f9..defdd6b 100644
--- a/helix-core/src/main/java/org/apache/helix/manager/zk/DefaultSchedulerMessageHandlerFactory.java
+++ b/helix-core/src/main/java/org/apache/helix/manager/zk/DefaultSchedulerMessageHandlerFactory.java
@@ -36,7 +36,7 @@ import org.apache.helix.HelixManager;
 import org.apache.helix.InstanceType;
 import org.apache.helix.NotificationContext;
 import org.apache.helix.PropertyKey.Builder;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
 import org.apache.helix.messaging.AsyncCallback;
 import org.apache.helix.messaging.handling.HelixTaskResult;
 import org.apache.helix.messaging.handling.MessageHandler;
diff --git a/helix-core/src/main/java/org/apache/helix/manager/zk/DistributedLeaderElection.java b/helix-core/src/main/java/org/apache/helix/manager/zk/DistributedLeaderElection.java
index 0a9d72d..ed9027b 100644
--- a/helix-core/src/main/java/org/apache/helix/manager/zk/DistributedLeaderElection.java
+++ b/helix-core/src/main/java/org/apache/helix/manager/zk/DistributedLeaderElection.java
@@ -32,7 +32,7 @@ import org.apache.helix.NotificationContext;
 import org.apache.helix.PropertyKey;
 import org.apache.helix.PropertyKey.Builder;
 import org.apache.helix.PropertyType;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
 import org.apache.helix.api.listeners.ControllerChangeListener;
 import org.apache.helix.controller.GenericHelixController;
 import org.apache.helix.model.ControllerHistory;
diff --git a/helix-core/src/main/java/org/apache/helix/manager/zk/HelixGroupCommit.java b/helix-core/src/main/java/org/apache/helix/manager/zk/HelixGroupCommit.java
index 9cada74..79f1a51 100644
--- a/helix-core/src/main/java/org/apache/helix/manager/zk/HelixGroupCommit.java
+++ b/helix-core/src/main/java/org/apache/helix/manager/zk/HelixGroupCommit.java
@@ -25,9 +25,9 @@ import java.util.concurrent.ConcurrentLinkedQueue;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicReference;
 
-import org.I0Itec.zkclient.DataUpdater;
-import org.I0Itec.zkclient.exception.ZkBadVersionException;
-import org.I0Itec.zkclient.exception.ZkNoNodeException;
+import org.apache.helix.zookeeper.zkclient.DataUpdater;
+import org.apache.helix.zookeeper.zkclient.exception.ZkBadVersionException;
+import org.apache.helix.zookeeper.zkclient.exception.ZkNoNodeException;
 import org.apache.zookeeper.data.Stat;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
diff --git a/helix-core/src/main/java/org/apache/helix/manager/zk/ParticipantManager.java b/helix-core/src/main/java/org/apache/helix/manager/zk/ParticipantManager.java
index 7af69c6..411d937 100644
--- a/helix-core/src/main/java/org/apache/helix/manager/zk/ParticipantManager.java
+++ b/helix-core/src/main/java/org/apache/helix/manager/zk/ParticipantManager.java
@@ -25,8 +25,6 @@ import java.util.List;
 import java.util.Map;
 import java.util.concurrent.TimeUnit;
 
-import org.I0Itec.zkclient.DataUpdater;
-import org.I0Itec.zkclient.exception.ZkNodeExistsException;
 import org.apache.helix.AccessOption;
 import org.apache.helix.BaseDataAccessor;
 import org.apache.helix.ConfigAccessor;
@@ -37,9 +35,6 @@ import org.apache.helix.InstanceType;
 import org.apache.helix.LiveInstanceInfoProvider;
 import org.apache.helix.PreConnectCallback;
 import org.apache.helix.PropertyKey;
-import org.apache.helix.ZNRecord;
-import org.apache.helix.ZNRecordBucketizer;
-import org.apache.helix.manager.zk.client.HelixZkClient;
 import org.apache.helix.messaging.DefaultMessagingService;
 import org.apache.helix.model.CurrentState;
 import org.apache.helix.model.HelixConfigScope;
@@ -51,6 +46,12 @@ import org.apache.helix.model.StateModelDefinition;
 import org.apache.helix.model.builder.HelixConfigScopeBuilder;
 import org.apache.helix.participant.StateMachineEngine;
 import org.apache.helix.participant.statemachine.ScheduledTaskStateModelFactory;
+import org.apache.helix.zookeeper.api.client.HelixZkClient;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecordBucketizer;
+import org.apache.helix.zookeeper.zkclient.DataUpdater;
+import org.apache.helix.zookeeper.zkclient.exception.ZkNodeExistsException;
+import org.apache.helix.zookeeper.zkclient.exception.ZkSessionMismatchedException;
 import org.apache.zookeeper.data.Stat;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
diff --git a/helix-core/src/main/java/org/apache/helix/manager/zk/PathBasedZkSerializer.java b/helix-core/src/main/java/org/apache/helix/manager/zk/PathBasedZkSerializer.java
index c717298..a248fb8 100644
--- a/helix-core/src/main/java/org/apache/helix/manager/zk/PathBasedZkSerializer.java
+++ b/helix-core/src/main/java/org/apache/helix/manager/zk/PathBasedZkSerializer.java
@@ -19,26 +19,10 @@ package org.apache.helix.manager.zk;
  * under the License.
  */
 
-import org.I0Itec.zkclient.exception.ZkMarshallingError;
-
-public interface PathBasedZkSerializer {
-
-  /**
-   * Serialize data differently according to different paths
-   * @param data
-   * @param path
-   * @return
-   * @throws ZkMarshallingError
-   */
-  public byte[] serialize(Object data, String path) throws ZkMarshallingError;
-
-  /**
-   * Deserialize data differently according to different paths
-   * @param bytes
-   * @param path
-   * @return
-   * @throws ZkMarshallingError
-   */
-  public Object deserialize(byte[] bytes, String path) throws ZkMarshallingError;
-
+/**
+ * Use PathBasedZkSerializer in zookeeper-api module instead.
+ */
+@Deprecated
+public interface PathBasedZkSerializer
+    extends org.apache.helix.zookeeper.zkclient.serialize.PathBasedZkSerializer {
 }
diff --git a/helix-core/src/main/java/org/apache/helix/manager/zk/WriteThroughCache.java b/helix-core/src/main/java/org/apache/helix/manager/zk/WriteThroughCache.java
index 82e9b21..1dd84f7 100644
--- a/helix-core/src/main/java/org/apache/helix/manager/zk/WriteThroughCache.java
+++ b/helix-core/src/main/java/org/apache/helix/manager/zk/WriteThroughCache.java
@@ -21,11 +21,11 @@ package org.apache.helix.manager.zk;
 
 import java.util.List;
 
-import org.I0Itec.zkclient.exception.ZkNoNodeException;
 import org.apache.helix.AccessOption;
 import org.apache.helix.BaseDataAccessor;
 import org.apache.helix.store.zk.ZNode;
 import org.apache.helix.util.HelixUtil;
+import org.apache.helix.zookeeper.zkclient.exception.ZkNoNodeException;
 import org.apache.zookeeper.data.Stat;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
diff --git a/helix-core/src/main/java/org/apache/helix/manager/zk/ZKExceptionHandler.java b/helix-core/src/main/java/org/apache/helix/manager/zk/ZKExceptionHandler.java
index 3746e31..1f9e73d 100644
--- a/helix-core/src/main/java/org/apache/helix/manager/zk/ZKExceptionHandler.java
+++ b/helix-core/src/main/java/org/apache/helix/manager/zk/ZKExceptionHandler.java
@@ -19,7 +19,7 @@ package org.apache.helix.manager.zk;
  * under the License.
  */
 
-import org.I0Itec.zkclient.exception.ZkInterruptedException;
+import org.apache.helix.zookeeper.zkclient.exception.ZkInterruptedException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
diff --git a/helix-core/src/main/java/org/apache/helix/manager/zk/ZKHelixAdmin.java b/helix-core/src/main/java/org/apache/helix/manager/zk/ZKHelixAdmin.java
index 61e75b3..77d8103 100644
--- a/helix-core/src/main/java/org/apache/helix/manager/zk/ZKHelixAdmin.java
+++ b/helix-core/src/main/java/org/apache/helix/manager/zk/ZKHelixAdmin.java
@@ -37,9 +37,6 @@ import java.util.TreeMap;
 import java.util.UUID;
 import java.util.concurrent.TimeUnit;
 
-import org.I0Itec.zkclient.DataUpdater;
-import org.I0Itec.zkclient.exception.ZkException;
-import org.I0Itec.zkclient.exception.ZkNoNodeException;
 import org.apache.helix.AccessOption;
 import org.apache.helix.BaseDataAccessor;
 import org.apache.helix.ConfigAccessor;
@@ -53,16 +50,11 @@ import org.apache.helix.PropertyKey;
 import org.apache.helix.PropertyKey.Builder;
 import org.apache.helix.PropertyPathBuilder;
 import org.apache.helix.PropertyType;
-import org.apache.helix.ZNRecord;
 import org.apache.helix.controller.rebalancer.DelayedAutoRebalancer;
 import org.apache.helix.controller.rebalancer.strategy.CrushEdRebalanceStrategy;
 import org.apache.helix.controller.rebalancer.strategy.RebalanceStrategy;
 import org.apache.helix.controller.rebalancer.util.WagedValidationUtil;
 import org.apache.helix.controller.rebalancer.waged.WagedRebalancer;
-import org.apache.helix.controller.rebalancer.waged.model.AssignableNode;
-import org.apache.helix.controller.rebalancer.waged.model.AssignableReplica;
-import org.apache.helix.manager.zk.client.HelixZkClient;
-import org.apache.helix.manager.zk.client.SharedZkClientFactory;
 import org.apache.helix.model.ClusterConfig;
 import org.apache.helix.model.ClusterConstraints;
 import org.apache.helix.model.ClusterConstraints.ConstraintType;
@@ -85,6 +77,12 @@ import org.apache.helix.model.StateModelDefinition;
 import org.apache.helix.tools.DefaultIdealStateCalculator;
 import org.apache.helix.util.HelixUtil;
 import org.apache.helix.util.RebalanceUtil;
+import org.apache.helix.zookeeper.api.client.HelixZkClient;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
+import org.apache.helix.zookeeper.impl.factory.SharedZkClientFactory;
+import org.apache.helix.zookeeper.zkclient.DataUpdater;
+import org.apache.helix.zookeeper.zkclient.exception.ZkException;
+import org.apache.helix.zookeeper.zkclient.exception.ZkNoNodeException;
 import org.apache.zookeeper.KeeperException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -491,22 +489,20 @@ public class ZKHelixAdmin implements HelixAdmin {
 
     // Record a MaintenanceSignal history
     if (!accessor.getBaseDataAccessor()
-        .update(keyBuilder.controllerLeaderHistory().getPath(), new DataUpdater<ZNRecord>() {
-          @Override
-          public ZNRecord update(ZNRecord oldRecord) {
-            try {
-              if (oldRecord == null) {
-                oldRecord = new ZNRecord(PropertyType.HISTORY.toString());
+        .update(keyBuilder.controllerLeaderHistory().getPath(),
+            (DataUpdater<ZNRecord>) oldRecord -> {
+              try {
+                if (oldRecord == null) {
+                  oldRecord = new ZNRecord(PropertyType.HISTORY.toString());
+                }
+                return new ControllerHistory(oldRecord)
+                    .updateMaintenanceHistory(enabled, reason, currentTime, internalReason,
+                        customFields, triggeringEntity);
+              } catch (IOException e) {
+                logger.error("Failed to update maintenance history! Exception: {}", e);
+                return oldRecord;
               }
-              return new ControllerHistory(oldRecord)
-                  .updateMaintenanceHistory(enabled, reason, currentTime, internalReason,
-                      customFields, triggeringEntity);
-            } catch (IOException e) {
-              logger.error("Failed to update maintenance history! Exception: {}", e);
-              return oldRecord;
-            }
-          }
-        }, AccessOption.PERSISTENT)) {
+            }, AccessOption.PERSISTENT)) {
       logger.error("Failed to write maintenance history to ZK!");
     }
   }
diff --git a/helix-core/src/main/java/org/apache/helix/manager/zk/ZKHelixDataAccessor.java b/helix-core/src/main/java/org/apache/helix/manager/zk/ZKHelixDataAccessor.java
index 8d3eafa..9f9ddc9 100644
--- a/helix-core/src/main/java/org/apache/helix/manager/zk/ZKHelixDataAccessor.java
+++ b/helix-core/src/main/java/org/apache/helix/manager/zk/ZKHelixDataAccessor.java
@@ -25,8 +25,6 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
-import org.I0Itec.zkclient.DataUpdater;
-import org.I0Itec.zkclient.exception.ZkNoNodeException;
 import org.apache.helix.AccessOption;
 import org.apache.helix.BaseDataAccessor;
 import org.apache.helix.GroupCommit;
@@ -37,16 +35,18 @@ import org.apache.helix.PropertyKey;
 import org.apache.helix.PropertyKey.Builder;
 import org.apache.helix.PropertyPathBuilder;
 import org.apache.helix.PropertyType;
-import org.apache.helix.ZNRecord;
-import org.apache.helix.ZNRecordAssembler;
-import org.apache.helix.ZNRecordBucketizer;
-import org.apache.helix.ZNRecordUpdater;
 import org.apache.helix.api.exceptions.HelixMetaDataAccessException;
 import org.apache.helix.model.LiveInstance;
 import org.apache.helix.model.MaintenanceSignal;
 import org.apache.helix.model.Message;
 import org.apache.helix.model.PauseSignal;
 import org.apache.helix.model.StateModelDefinition;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecordAssembler;
+import org.apache.helix.zookeeper.datamodel.ZNRecordBucketizer;
+import org.apache.helix.zookeeper.datamodel.ZNRecordUpdater;
+import org.apache.helix.zookeeper.zkclient.DataUpdater;
+import org.apache.helix.zookeeper.zkclient.exception.ZkNoNodeException;
 import org.apache.zookeeper.data.Stat;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
diff --git a/helix-core/src/main/java/org/apache/helix/manager/zk/ZKHelixManager.java b/helix-core/src/main/java/org/apache/helix/manager/zk/ZKHelixManager.java
index ef0308e..b4368f9 100644
--- a/helix-core/src/main/java/org/apache/helix/manager/zk/ZKHelixManager.java
+++ b/helix-core/src/main/java/org/apache/helix/manager/zk/ZKHelixManager.java
@@ -31,7 +31,7 @@ import java.util.concurrent.TimeUnit;
 import javax.management.JMException;
 
 import com.google.common.collect.Sets;
-import org.I0Itec.zkclient.exception.ZkInterruptedException;
+
 import org.apache.helix.BaseDataAccessor;
 import org.apache.helix.ClusterMessagingService;
 import org.apache.helix.ConfigAccessor;
@@ -50,7 +50,6 @@ import org.apache.helix.PropertyKey.Builder;
 import org.apache.helix.PropertyPathBuilder;
 import org.apache.helix.PropertyType;
 import org.apache.helix.SystemPropertyKeys;
-import org.apache.helix.ZNRecord;
 import org.apache.helix.api.listeners.ClusterConfigChangeListener;
 import org.apache.helix.api.listeners.ConfigChangeListener;
 import org.apache.helix.api.listeners.ControllerChangeListener;
@@ -67,10 +66,6 @@ import org.apache.helix.controller.pipeline.Pipeline;
 import org.apache.helix.healthcheck.ParticipantHealthReportCollector;
 import org.apache.helix.healthcheck.ParticipantHealthReportCollectorImpl;
 import org.apache.helix.healthcheck.ParticipantHealthReportTask;
-import org.apache.helix.manager.zk.client.DedicatedZkClientFactory;
-import org.apache.helix.manager.zk.client.HelixZkClient;
-import org.apache.helix.manager.zk.client.SharedZkClientFactory;
-import org.apache.helix.manager.zk.zookeeper.IZkStateListener;
 import org.apache.helix.messaging.DefaultMessagingService;
 import org.apache.helix.model.BuiltInStateModelDefinitions;
 import org.apache.helix.model.HelixConfigScope.ConfigScopeProperty;
@@ -83,6 +78,13 @@ import org.apache.helix.participant.StateMachineEngine;
 import org.apache.helix.store.zk.AutoFallbackPropertyStore;
 import org.apache.helix.store.zk.ZkHelixPropertyStore;
 import org.apache.helix.util.HelixUtil;
+import org.apache.helix.zookeeper.api.client.HelixZkClient;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
+import org.apache.helix.zookeeper.impl.factory.DedicatedZkClientFactory;
+import org.apache.helix.zookeeper.impl.factory.SharedZkClientFactory;
+import org.apache.helix.zookeeper.zkclient.IZkStateListener;
+import org.apache.helix.zookeeper.zkclient.exception.ZkInterruptedException;
+import org.apache.helix.zookeeper.zkclient.serialize.PathBasedZkSerializer;
 import org.apache.zookeeper.Watcher.Event.EventType;
 import org.apache.zookeeper.Watcher.Event.KeeperState;
 import org.slf4j.Logger;
diff --git a/helix-core/src/main/java/org/apache/helix/manager/zk/ZKUtil.java b/helix-core/src/main/java/org/apache/helix/manager/zk/ZKUtil.java
index 821af52..126ae38 100644
--- a/helix-core/src/main/java/org/apache/helix/manager/zk/ZKUtil.java
+++ b/helix-core/src/main/java/org/apache/helix/manager/zk/ZKUtil.java
@@ -23,14 +23,14 @@ import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 
-import org.I0Itec.zkclient.DataUpdater;
 import org.apache.helix.BaseDataAccessor;
 import org.apache.helix.HelixException;
 import org.apache.helix.InstanceType;
 import org.apache.helix.PropertyPathBuilder;
-import org.apache.helix.ZNRecord;
-import org.apache.helix.manager.zk.client.DedicatedZkClientFactory;
-import org.apache.helix.manager.zk.client.HelixZkClient;
+import org.apache.helix.zookeeper.api.client.HelixZkClient;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
+import org.apache.helix.zookeeper.impl.factory.DedicatedZkClientFactory;
+import org.apache.helix.zookeeper.zkclient.DataUpdater;
 import org.apache.zookeeper.CreateMode;
 import org.apache.zookeeper.data.Stat;
 import org.slf4j.Logger;
diff --git a/helix-core/src/main/java/org/apache/helix/manager/zk/ZNRecordJacksonSerializer.java b/helix-core/src/main/java/org/apache/helix/manager/zk/ZNRecordJacksonSerializer.java
index b375e80..4f139ce 100644
--- a/helix-core/src/main/java/org/apache/helix/manager/zk/ZNRecordJacksonSerializer.java
+++ b/helix-core/src/main/java/org/apache/helix/manager/zk/ZNRecordJacksonSerializer.java
@@ -19,49 +19,12 @@ package org.apache.helix.manager.zk;
  * under the License.
  */
 
-import java.io.IOException;
-import org.I0Itec.zkclient.exception.ZkMarshallingError;
-import org.I0Itec.zkclient.serialize.ZkSerializer;
-import org.apache.helix.HelixException;
-import org.apache.helix.ZNRecord;
-import org.codehaus.jackson.map.ObjectMapper;
-
 /**
+ * Use ZNRecordJacksonSerializer in zookeeper-api instead.
+ *
  * ZNRecordJacksonSerializer serializes ZNRecord objects into a byte array using Jackson. Note that
  * this serializer doesn't check for the size of the resulting binary.
  */
-public class ZNRecordJacksonSerializer implements ZkSerializer {
-  private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
-
-  @Override
-  public byte[] serialize(Object record) throws ZkMarshallingError {
-    if (!(record instanceof ZNRecord)) {
-      // null is NOT an instance of any class
-      throw new HelixException("Input object is not of type ZNRecord (was " + record + ")");
-    }
-    ZNRecord znRecord = (ZNRecord) record;
-
-    try {
-      return OBJECT_MAPPER.writeValueAsBytes(znRecord);
-    } catch (IOException e) {
-      throw new HelixException(
-          String.format("Exception during serialization. ZNRecord id: %s", znRecord.getId()), e);
-    }
-  }
-
-  @Override
-  public Object deserialize(byte[] bytes) throws ZkMarshallingError {
-    if (bytes == null || bytes.length == 0) {
-      // reading a parent/null node
-      return null;
-    }
-
-    ZNRecord record;
-    try {
-      record = OBJECT_MAPPER.readValue(bytes, ZNRecord.class);
-    } catch (IOException e) {
-      throw new HelixException("Exception during deserialization!", e);
-    }
-    return record;
-  }
+@Deprecated
+public class ZNRecordJacksonSerializer extends org.apache.helix.zookeeper.datamodel.serializer.ZNRecordJacksonSerializer {
 }
diff --git a/helix-core/src/main/java/org/apache/helix/manager/zk/ZNRecordSerializer.java b/helix-core/src/main/java/org/apache/helix/manager/zk/ZNRecordSerializer.java
index df9acaa..ba1892f 100644
--- a/helix-core/src/main/java/org/apache/helix/manager/zk/ZNRecordSerializer.java
+++ b/helix-core/src/main/java/org/apache/helix/manager/zk/ZNRecordSerializer.java
@@ -19,115 +19,9 @@ package org.apache.helix.manager.zk;
  * under the License.
  */
 
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.util.List;
-import java.util.Map;
-
-import org.I0Itec.zkclient.serialize.ZkSerializer;
-import org.apache.helix.HelixException;
-import org.apache.helix.ZNRecord;
-import org.apache.helix.util.GZipCompressionUtil;
-import org.codehaus.jackson.map.DeserializationConfig;
-import org.codehaus.jackson.map.ObjectMapper;
-import org.codehaus.jackson.map.SerializationConfig;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class ZNRecordSerializer implements ZkSerializer {
-  private static Logger logger = LoggerFactory.getLogger(ZNRecordSerializer.class);
-
-  private static int getListFieldBound(ZNRecord record) {
-    int max = Integer.MAX_VALUE;
-    if (record.getSimpleFields().containsKey(ZNRecord.LIST_FIELD_BOUND)) {
-      String maxStr = record.getSimpleField(ZNRecord.LIST_FIELD_BOUND);
-      try {
-        max = Integer.parseInt(maxStr);
-      } catch (Exception e) {
-        logger.error("IllegalNumberFormat for list field bound: " + maxStr);
-      }
-    }
-    return max;
-  }
-
-  @Override
-  public byte[] serialize(Object data) {
-    if (!(data instanceof ZNRecord)) {
-      // null is NOT an instance of any class
-      logger.error("Input object must be of type ZNRecord but it is " + data
-          + ". Will not write to zk");
-      throw new HelixException("Input object is not of type ZNRecord (was " + data + ")");
-    }
-
-    ZNRecord record = (ZNRecord) data;
-
-    // apply retention policy
-    int max = getListFieldBound(record);
-    if (max < Integer.MAX_VALUE) {
-      Map<String, List<String>> listMap = record.getListFields();
-      for (String key : listMap.keySet()) {
-        List<String> list = listMap.get(key);
-        if (list.size() > max) {
-          listMap.put(key, list.subList(0, max));
-        }
-      }
-    }
-
-    // do serialization
-    ObjectMapper mapper = new ObjectMapper();
-    SerializationConfig serializationConfig = mapper.getSerializationConfig();
-    serializationConfig.set(SerializationConfig.Feature.INDENT_OUTPUT, true);
-    serializationConfig.set(SerializationConfig.Feature.AUTO_DETECT_FIELDS, true);
-    serializationConfig.set(SerializationConfig.Feature.CAN_OVERRIDE_ACCESS_MODIFIERS, true);
-    ByteArrayOutputStream baos = new ByteArrayOutputStream();
-    byte[] serializedBytes;
-    try {
-      mapper.writeValue(baos, data);
-      serializedBytes = baos.toByteArray();
-      // apply compression if needed
-      if (record.getBooleanField("enableCompression", false) || serializedBytes.length > ZNRecord.SIZE_LIMIT) {
-        serializedBytes = GZipCompressionUtil.compress(serializedBytes);
-      }
-    } catch (Exception e) {
-      logger.error("Exception during data serialization. Will not write to zk. Data (first 1k): "
-          + new String(baos.toByteArray()).substring(0, 1024), e);
-      throw new HelixException(e);
-    }
-    if (serializedBytes.length > ZNRecord.SIZE_LIMIT) {
-      logger.error("Data size larger than 1M, ZNRecord.id: " + record.getId()
-          + ". Will not write to zk. Data (first 1k): "
-          + new String(serializedBytes).substring(0, 1024));
-      throw new HelixException("Data size larger than 1M, ZNRecord.id: " + record.getId());
-    }
-    return serializedBytes;
-  }
-
-  @Override
-  public Object deserialize(byte[] bytes) {
-    if (bytes == null || bytes.length == 0) {
-      // reading a parent/null node
-      return null;
-    }
-
-    ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
-
-    ObjectMapper mapper = new ObjectMapper();
-    DeserializationConfig deserializationConfig = mapper.getDeserializationConfig();
-    deserializationConfig.set(DeserializationConfig.Feature.AUTO_DETECT_FIELDS, true);
-    deserializationConfig.set(DeserializationConfig.Feature.AUTO_DETECT_SETTERS, true);
-    deserializationConfig.set(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, true);
-    try {
-      //decompress the data if its already compressed
-      if (GZipCompressionUtil.isCompressed(bytes)) {
-        byte[] uncompressedBytes = GZipCompressionUtil.uncompress(bais);
-        bais = new ByteArrayInputStream(uncompressedBytes);
-      }
-      ZNRecord zn = mapper.readValue(bais, ZNRecord.class);
-
-      return zn;
-    } catch (Exception e) {
-      logger.error("Exception during deserialization of bytes: " + new String(bytes), e);
-      return null;
-    }
-  }
+/**
+ * Use ZNRecordSerializer in zookeeper-api instead.
+ */
+@Deprecated
+public class ZNRecordSerializer extends org.apache.helix.zookeeper.datamodel.serializer.ZNRecordSerializer {
 }
diff --git a/helix-core/src/main/java/org/apache/helix/manager/zk/ZNRecordStreamingSerializer.java b/helix-core/src/main/java/org/apache/helix/manager/zk/ZNRecordStreamingSerializer.java
index 769baa0..bd18eff 100644
--- a/helix-core/src/main/java/org/apache/helix/manager/zk/ZNRecordStreamingSerializer.java
+++ b/helix-core/src/main/java/org/apache/helix/manager/zk/ZNRecordStreamingSerializer.java
@@ -19,292 +19,9 @@ package org.apache.helix.manager.zk;
  * under the License.
  */
 
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.TreeMap;
-
-import com.google.common.collect.Maps;
-import org.I0Itec.zkclient.exception.ZkMarshallingError;
-import org.I0Itec.zkclient.serialize.ZkSerializer;
-import org.apache.commons.codec.binary.Base64;
-import org.apache.helix.HelixException;
-import org.apache.helix.ZNRecord;
-import org.apache.helix.util.GZipCompressionUtil;
-import org.codehaus.jackson.JsonFactory;
-import org.codehaus.jackson.JsonGenerator;
-import org.codehaus.jackson.JsonParser;
-import org.codehaus.jackson.JsonToken;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class ZNRecordStreamingSerializer implements ZkSerializer {
-  private static Logger LOG = LoggerFactory.getLogger(ZNRecordStreamingSerializer.class);
-
-  private static int getListFieldBound(ZNRecord record) {
-    int max = Integer.MAX_VALUE;
-    if (record.getSimpleFields().containsKey(ZNRecord.LIST_FIELD_BOUND)) {
-      String maxStr = record.getSimpleField(ZNRecord.LIST_FIELD_BOUND);
-      try {
-        max = Integer.parseInt(maxStr);
-      } catch (Exception e) {
-        LOG.error("IllegalNumberFormat for list field bound: " + maxStr);
-      }
-    }
-    return max;
-  }
-
-  @Override
-  public byte[] serialize(Object data) throws ZkMarshallingError {
-    if (!(data instanceof ZNRecord)) {
-      // null is NOT an instance of any class
-      LOG.error("Input object must be of type ZNRecord but it is " + data
-          + ". Will not write to zk");
-      throw new HelixException("Input object is not of type ZNRecord (was " + data + ")");
-    }
-
-    // apply retention policy on list field
-    ZNRecord record = (ZNRecord) data;
-    int max = getListFieldBound(record);
-    if (max < Integer.MAX_VALUE) {
-      Map<String, List<String>> listMap = record.getListFields();
-      for (String key : listMap.keySet()) {
-        List<String> list = listMap.get(key);
-        if (list.size() > max) {
-          listMap.put(key, list.subList(0, max));
-        }
-      }
-    }
-    ByteArrayOutputStream baos = new ByteArrayOutputStream();
-    byte[] serializedBytes = null;
-    try {
-      JsonFactory f = new JsonFactory();
-      JsonGenerator g = f.createJsonGenerator(baos);
-
-      g.writeStartObject();
-
-      // write id field
-      g.writeRaw("\n  ");
-      g.writeStringField("id", record.getId());
-
-      // write simepleFields
-      g.writeRaw("\n  ");
-      g.writeObjectFieldStart("simpleFields");
-      for (String key : record.getSimpleFields().keySet()) {
-        g.writeRaw("\n    ");
-        g.writeStringField(key, record.getSimpleField(key));
-      }
-      g.writeRaw("\n  ");
-      g.writeEndObject(); // for simpleFields
-
-      // write listFields
-      g.writeRaw("\n  ");
-      g.writeObjectFieldStart("listFields");
-      for (String key : record.getListFields().keySet()) {
-        // g.writeStringField(key, record.getListField(key).toString());
-
-        // g.writeObjectFieldStart(key);
-        g.writeRaw("\n    ");
-        g.writeArrayFieldStart(key);
-        List<String> list = record.getListField(key);
-        for (String listValue : list) {
-          g.writeString(listValue);
-        }
-        // g.writeEndObject();
-        g.writeEndArray();
-
-      }
-      g.writeRaw("\n  ");
-      g.writeEndObject(); // for listFields
-
-      // write mapFields
-      g.writeRaw("\n  ");
-      g.writeObjectFieldStart("mapFields");
-      for (String key : record.getMapFields().keySet()) {
-        // g.writeStringField(key, record.getMapField(key).toString());
-        g.writeRaw("\n    ");
-        g.writeObjectFieldStart(key);
-        Map<String, String> map = record.getMapField(key);
-        for (String mapKey : map.keySet()) {
-          g.writeRaw("\n      ");
-          g.writeStringField(mapKey, map.get(mapKey));
-        }
-        g.writeRaw("\n    ");
-        g.writeEndObject();
-
-      }
-      g.writeRaw("\n  ");
-      g.writeEndObject(); // for mapFields
-
-      byte[] rawPayload = record.getRawPayload();
-      if (rawPayload != null && rawPayload.length > 0) {
-        // write rawPayload
-        g.writeRaw("\n  ");
-        g.writeStringField("rawPayload", new String(Base64.encodeBase64(rawPayload), "UTF-8"));
-      }
-
-      g.writeRaw("\n");
-      g.writeEndObject(); // for whole znrecord
-
-      // important: will force flushing of output, close underlying output
-      // stream
-      g.close();
-      serializedBytes = baos.toByteArray();
-      // apply compression if needed
-      if (record.getBooleanField("enableCompression", false) || serializedBytes.length > ZNRecord.SIZE_LIMIT) {
-        serializedBytes = GZipCompressionUtil.compress(serializedBytes);
-      }
-    } catch (Exception e) {
-      LOG.error("Exception during data serialization. Will not write to zk. Data (first 1k): "
-          + new String(baos.toByteArray()).substring(0, 1024), e);
-      throw new HelixException(e);
-    }
-    // check size
-    if (serializedBytes.length > ZNRecord.SIZE_LIMIT) {
-      LOG.error("Data size larger than 1M, ZNRecord.id: " + record.getId()
-          + ". Will not write to zk. Data (first 1k): "
-          + new String(serializedBytes).substring(0, 1024));
-      throw new HelixException("Data size larger than 1M, ZNRecord.id: " + record.getId());
-    }
-
-    return serializedBytes;
-  }
-
-  @Override
-  public Object deserialize(byte[] bytes) throws ZkMarshallingError {
-    if (bytes == null || bytes.length == 0) {
-      LOG.error("ZNode is empty.");
-      return null;
-    }
-
-    ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
-
-    ZNRecord record = null;
-    String id = null;
-    Map<String, String> simpleFields = Maps.newHashMap();
-    Map<String, List<String>> listFields = Maps.newHashMap();
-    Map<String, Map<String, String>> mapFields = Maps.newHashMap();
-    byte[] rawPayload = null;
-
-    try {
-      // decompress the data if its already compressed
-      if (GZipCompressionUtil.isCompressed(bytes)) {
-        byte[] uncompressedBytes = GZipCompressionUtil.uncompress(bais);
-        bais = new ByteArrayInputStream(uncompressedBytes);
-      }
-      JsonFactory f = new JsonFactory();
-      JsonParser jp = f.createJsonParser(bais);
-
-      jp.nextToken(); // will return JsonToken.START_OBJECT (verify?)
-      while (jp.nextToken() != JsonToken.END_OBJECT) {
-        String fieldname = jp.getCurrentName();
-        jp.nextToken(); // move to value, or START_OBJECT/START_ARRAY
-        if ("id".equals(fieldname)) {
-          // contains an object
-          id = jp.getText();
-        } else if ("simpleFields".equals(fieldname)) {
-          while (jp.nextToken() != JsonToken.END_OBJECT) {
-            String key = jp.getCurrentName();
-            jp.nextToken(); // move to value
-            simpleFields.put(key, jp.getText());
-          }
-        } else if ("mapFields".equals(fieldname)) {
-          // user.setVerified(jp.getCurrentToken() == JsonToken.VALUE_TRUE);
-          while (jp.nextToken() != JsonToken.END_OBJECT) {
-            String key = jp.getCurrentName();
-            mapFields.put(key, new TreeMap<String, String>());
-            jp.nextToken(); // move to value
-
-            while (jp.nextToken() != JsonToken.END_OBJECT) {
-              String mapKey = jp.getCurrentName();
-              jp.nextToken(); // move to value
-              mapFields.get(key).put(mapKey, jp.getText());
-            }
-          }
-
-        } else if ("listFields".equals(fieldname)) {
-          // user.setUserImage(jp.getBinaryValue());
-          while (jp.nextToken() != JsonToken.END_OBJECT) {
-            String key = jp.getCurrentName();
-            listFields.put(key, new ArrayList<String>());
-            jp.nextToken(); // move to value
-            while (jp.nextToken() != JsonToken.END_ARRAY) {
-              listFields.get(key).add(jp.getText());
-            }
-
-          }
-
-        } else if ("rawPayload".equals(fieldname)) {
-          rawPayload = Base64.decodeBase64(jp.getText());
-        } else {
-          throw new IllegalStateException("Unrecognized field '" + fieldname + "'!");
-        }
-      }
-      jp.close(); // ensure resources get cleaned up timely and properly
-
-      if (id == null) {
-        throw new IllegalStateException("ZNRecord id field is required!");
-      }
-      record = new ZNRecord(id);
-      record.setSimpleFields(simpleFields);
-      record.setListFields(listFields);
-      record.setMapFields(mapFields);
-      record.setRawPayload(rawPayload);
-    } catch (Exception e) {
-      LOG.error("Exception during deserialization of bytes: " + new String(bytes), e);
-    }
-    return record;
-  }
-
-  public static void main(String[] args) {
-    ZNRecord record = new ZNRecord("record");
-    final int recordSize = 10;
-    for (int i = 0; i < recordSize; i++) {
-      record.setSimpleField("" + i, "" + i);
-      record.setListField("" + i, new ArrayList<String>());
-      for (int j = 0; j < recordSize; j++) {
-        record.getListField("" + i).add("" + j);
-      }
-
-      record.setMapField("" + i, new TreeMap<String, String>());
-      for (int j = 0; j < recordSize; j++) {
-        record.getMapField("" + i).put("" + j, "" + j);
-      }
-    }
-
-    ZNRecordStreamingSerializer serializer = new ZNRecordStreamingSerializer();
-    byte[] bytes = serializer.serialize(record);
-    System.out.println(new String(bytes));
-    ZNRecord record2 = (ZNRecord) serializer.deserialize(bytes);
-    System.out.println(record2);
-
-    long start = System.currentTimeMillis();
-    for (int i = 0; i < 100; i++) {
-      bytes = serializer.serialize(record);
-      // System.out.println(new String(bytes));
-      record2 = (ZNRecord) serializer.deserialize(bytes);
-      // System.out.println(record2);
-    }
-    long end = System.currentTimeMillis();
-    System.out.println("ZNRecordStreamingSerializer time used: " + (end - start));
-
-    ZNRecordSerializer serializer2 = new ZNRecordSerializer();
-    bytes = serializer2.serialize(record);
-    // System.out.println(new String(bytes));
-    record2 = (ZNRecord) serializer2.deserialize(bytes);
-    // System.out.println(record2);
-
-    start = System.currentTimeMillis();
-    for (int i = 0; i < 100; i++) {
-      bytes = serializer2.serialize(record);
-      // System.out.println(new String(bytes));
-      record2 = (ZNRecord) serializer2.deserialize(bytes);
-      // System.out.println(record2);
-    }
-    end = System.currentTimeMillis();
-    System.out.println("ZNRecordSerializer time used: " + (end - start));
-
-  }
+/**
+ * Use ZNRecordStreamingSerializer in zookeeper-api module instead.
+ */
+@Deprecated
+public class ZNRecordStreamingSerializer extends org.apache.helix.zookeeper.datamodel.serializer.ZNRecordStreamingSerializer {
 }
diff --git a/helix-core/src/main/java/org/apache/helix/manager/zk/ZkAsyncCallbacks.java b/helix-core/src/main/java/org/apache/helix/manager/zk/ZkAsyncCallbacks.java
index 6b51b47..566a6e0 100644
--- a/helix-core/src/main/java/org/apache/helix/manager/zk/ZkAsyncCallbacks.java
+++ b/helix-core/src/main/java/org/apache/helix/manager/zk/ZkAsyncCallbacks.java
@@ -19,174 +19,10 @@ package org.apache.helix.manager.zk;
  * under the License.
  */
 
-import java.util.concurrent.atomic.AtomicBoolean;
-
-import org.apache.helix.monitoring.mbeans.ZkClientMonitor;
-import org.apache.zookeeper.AsyncCallback.DataCallback;
-import org.apache.zookeeper.AsyncCallback.StatCallback;
-import org.apache.zookeeper.AsyncCallback.StringCallback;
-import org.apache.zookeeper.AsyncCallback.VoidCallback;
-import org.apache.zookeeper.KeeperException.Code;
-import org.apache.zookeeper.data.Stat;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class ZkAsyncCallbacks {
-  private static Logger LOG = LoggerFactory.getLogger(ZkAsyncCallbacks.class);
-
-  public static class GetDataCallbackHandler extends DefaultCallback implements DataCallback {
-    byte[] _data;
-    Stat _stat;
-
-    @Override
-    public void handle() {
-      // TODO Auto-generated method stub
-    }
-
-    @Override
-    public void processResult(int rc, String path, Object ctx, byte[] data, Stat stat) {
-      if (rc == 0) {
-        _data = data;
-        _stat = stat;
-        // update ctx with data size
-        if (_data != null && ctx != null && ctx instanceof ZkAsyncCallContext) {
-          ZkAsyncCallContext zkCtx = (ZkAsyncCallContext) ctx;
-          zkCtx._bytes = _data.length;
-        }
-      }
-      callback(rc, path, ctx);
-    }
-  }
-
-  public static class SetDataCallbackHandler extends DefaultCallback implements StatCallback {
-    Stat _stat;
-
-    @Override
-    public void handle() {
-      // TODO Auto-generated method stub
-    }
-
-    @Override
-    public void processResult(int rc, String path, Object ctx, Stat stat) {
-      if (rc == 0) {
-        _stat = stat;
-      }
-      callback(rc, path, ctx);
-    }
-
-    public Stat getStat() {
-      return _stat;
-    }
-  }
-
-  public static class ExistsCallbackHandler extends DefaultCallback implements StatCallback {
-    Stat _stat;
-
-    @Override
-    public void handle() {
-      // TODO Auto-generated method stub
-    }
-
-    @Override
-    public void processResult(int rc, String path, Object ctx, Stat stat) {
-      if (rc == 0) {
-        _stat = stat;
-      }
-      callback(rc, path, ctx);
-    }
-  }
-
-  public static class CreateCallbackHandler extends DefaultCallback implements StringCallback {
-    @Override
-    public void processResult(int rc, String path, Object ctx, String name) {
-      callback(rc, path, ctx);
-    }
-
-    @Override
-    public void handle() {
-      // TODO Auto-generated method stub
-    }
-  }
-
-  public static class DeleteCallbackHandler extends DefaultCallback implements VoidCallback {
-    @Override
-    public void processResult(int rc, String path, Object ctx) {
-      callback(rc, path, ctx);
-    }
-
-    @Override
-    public void handle() {
-      // TODO Auto-generated method stub
-    }
-  }
-
-  /**
-   * Default callback for zookeeper async api
-   */
-  public static abstract class DefaultCallback {
-    AtomicBoolean _lock = new AtomicBoolean(false);
-    int _rc = -1;
-
-    public void callback(int rc, String path, Object ctx) {
-      if (rc != 0 && LOG.isDebugEnabled()) {
-        LOG.debug(this + ", rc:" + Code.get(rc) + ", path: " + path);
-      }
-
-      if (ctx != null && ctx instanceof ZkAsyncCallContext) {
-        ZkAsyncCallContext zkCtx = (ZkAsyncCallContext) ctx;
-        if (zkCtx._monitor != null) {
-          if (zkCtx._isRead) {
-            zkCtx._monitor.record(path, zkCtx._bytes, zkCtx._startTimeMilliSec,
-                ZkClientMonitor.AccessType.READ);
-          } else {
-            zkCtx._monitor.record(path, zkCtx._bytes, zkCtx._startTimeMilliSec,
-                ZkClientMonitor.AccessType.WRITE);
-          }
-        }
-      }
-
-      _rc = rc;
-      handle();
-
-      synchronized (_lock) {
-        _lock.set(true);
-        _lock.notify();
-      }
-    }
-
-    public boolean waitForSuccess() {
-      try {
-        synchronized (_lock) {
-          while (!_lock.get()) {
-            _lock.wait();
-          }
-        }
-      } catch (InterruptedException e) {
-        LOG.error("Interrupted waiting for success", e);
-      }
-      return true;
-    }
-
-    public int getRc() {
-      return _rc;
-    }
-
-    abstract public void handle();
-  }
-
-  public static class ZkAsyncCallContext {
-    private long _startTimeMilliSec;
-    private int _bytes;
-    private ZkClientMonitor _monitor;
-    private boolean _isRead;
-
-    public ZkAsyncCallContext(final ZkClientMonitor monitor, long startTimeMilliSec, int bytes,
-        boolean isRead) {
-      _monitor = monitor;
-      _startTimeMilliSec = startTimeMilliSec;
-      _bytes = bytes;
-      _isRead = isRead;
-    }
-  }
-
+/**
+ * This class has been deprecated. Please use ZkAsyncCallbacks in zookeeper-api module instead.
+ */
+@Deprecated
+public class ZkAsyncCallbacks
+    extends org.apache.helix.zookeeper.zkclient.callback.ZkAsyncCallbacks {
 }
diff --git a/helix-core/src/main/java/org/apache/helix/manager/zk/ZkBaseDataAccessor.java b/helix-core/src/main/java/org/apache/helix/manager/zk/ZkBaseDataAccessor.java
index c1abccb..bc84a1d 100644
--- a/helix-core/src/main/java/org/apache/helix/manager/zk/ZkBaseDataAccessor.java
+++ b/helix-core/src/main/java/org/apache/helix/manager/zk/ZkBaseDataAccessor.java
@@ -27,28 +27,25 @@ import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 
-import org.I0Itec.zkclient.DataUpdater;
-import org.I0Itec.zkclient.IZkChildListener;
-import org.I0Itec.zkclient.IZkDataListener;
-import org.I0Itec.zkclient.exception.ZkBadVersionException;
-import org.I0Itec.zkclient.exception.ZkException;
-import org.I0Itec.zkclient.exception.ZkNoNodeException;
-import org.I0Itec.zkclient.exception.ZkNodeExistsException;
-import org.I0Itec.zkclient.serialize.ZkSerializer;
 import org.apache.helix.AccessOption;
 import org.apache.helix.BaseDataAccessor;
 import org.apache.helix.HelixException;
 import org.apache.helix.api.exceptions.HelixMetaDataAccessException;
-import org.apache.helix.manager.zk.ZkAsyncCallbacks.CreateCallbackHandler;
-import org.apache.helix.manager.zk.ZkAsyncCallbacks.DeleteCallbackHandler;
-import org.apache.helix.manager.zk.ZkAsyncCallbacks.ExistsCallbackHandler;
-import org.apache.helix.manager.zk.ZkAsyncCallbacks.GetDataCallbackHandler;
-import org.apache.helix.manager.zk.ZkAsyncCallbacks.SetDataCallbackHandler;
-import org.apache.helix.manager.zk.client.DedicatedZkClientFactory;
-import org.apache.helix.manager.zk.client.HelixZkClient;
-import org.apache.helix.manager.zk.client.SharedZkClientFactory;
 import org.apache.helix.store.zk.ZNode;
 import org.apache.helix.util.HelixUtil;
+import org.apache.helix.zookeeper.api.client.HelixZkClient;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
+import org.apache.helix.zookeeper.impl.factory.DedicatedZkClientFactory;
+import org.apache.helix.zookeeper.impl.factory.SharedZkClientFactory;
+import org.apache.helix.zookeeper.zkclient.DataUpdater;
+import org.apache.helix.zookeeper.zkclient.IZkChildListener;
+import org.apache.helix.zookeeper.zkclient.IZkDataListener;
+import org.apache.helix.zookeeper.zkclient.callback.ZkAsyncCallbacks;
+import org.apache.helix.zookeeper.zkclient.exception.ZkBadVersionException;
+import org.apache.helix.zookeeper.zkclient.exception.ZkException;
+import org.apache.helix.zookeeper.zkclient.exception.ZkNoNodeException;
+import org.apache.helix.zookeeper.zkclient.exception.ZkNodeExistsException;
+import org.apache.helix.zookeeper.zkclient.serialize.ZkSerializer;
 import org.apache.zookeeper.CreateMode;
 import org.apache.zookeeper.KeeperException.Code;
 import org.apache.zookeeper.data.Stat;
@@ -143,7 +140,7 @@ public class ZkBaseDataAccessor<T> implements BaseDataAccessor<T> {
   }
 
   /**
-   * Creates a ZkBaseDataAccessor with {@link org.apache.helix.ZNRecord} as the data model.
+   * Creates a ZkBaseDataAccessor with {@link ZNRecord} as the data model.
    * Uses a shared ZkConnection resource.
    * Does NOT support ephemeral node creation, callbacks, or session management.
    * Uses {@link ZNRecordSerializer} serializer
@@ -154,7 +151,7 @@ public class ZkBaseDataAccessor<T> implements BaseDataAccessor<T> {
   }
 
   /**
-   * Creates a ZkBaseDataAccessor with {@link org.apache.helix.ZNRecord} as the data model.
+   * Creates a ZkBaseDataAccessor with {@link ZNRecord} as the data model.
    * If DEDICATED, it will use a dedicated ZkConnection, which allows ephemeral
    * node creation, callbacks, and session management.
    * If SHARED, it will use a shared ZkConnection, which only allows simple
@@ -492,13 +489,13 @@ public class ZkBaseDataAccessor<T> implements BaseDataAccessor<T> {
 
     try {
       // issue asyn get requests
-      GetDataCallbackHandler[] cbList = new GetDataCallbackHandler[paths.size()];
+      ZkAsyncCallbacks.GetDataCallbackHandler[] cbList = new ZkAsyncCallbacks.GetDataCallbackHandler[paths.size()];
       for (int i = 0; i < paths.size(); i++) {
         if (!needRead[i])
           continue;
 
         String path = paths.get(i);
-        cbList[i] = new GetDataCallbackHandler();
+        cbList[i] = new ZkAsyncCallbacks.GetDataCallbackHandler();
         _zkClient.asyncGetData(path, cbList[i]);
       }
 
@@ -507,7 +504,7 @@ public class ZkBaseDataAccessor<T> implements BaseDataAccessor<T> {
         if (!needRead[i])
           continue;
 
-        GetDataCallbackHandler cb = cbList[i];
+        ZkAsyncCallbacks.GetDataCallbackHandler cb = cbList[i];
         cb.waitForSuccess();
       }
 
@@ -518,7 +515,7 @@ public class ZkBaseDataAccessor<T> implements BaseDataAccessor<T> {
         if (!needRead[i])
           continue;
 
-        GetDataCallbackHandler cb = cbList[i];
+        ZkAsyncCallbacks.GetDataCallbackHandler cb = cbList[i];
         if (Code.get(cb.getRc()) == Code.OK) {
           @SuppressWarnings("unchecked")
           T record = (T) _zkClient.deserialize(cb._data, paths.get(i));
@@ -684,7 +681,7 @@ public class ZkBaseDataAccessor<T> implements BaseDataAccessor<T> {
   /**
    * async create. give up on error other than NONODE
    */
-  CreateCallbackHandler[] create(List<String> paths, List<T> records, boolean[] needCreate,
+  ZkAsyncCallbacks.CreateCallbackHandler[] create(List<String> paths, List<T> records, boolean[] needCreate,
       List<List<String>> pathsCreated, int options) {
     if ((records != null && records.size() != paths.size()) || needCreate.length != paths.size()
         || (pathsCreated != null && pathsCreated.size() != paths.size())) {
@@ -692,7 +689,7 @@ public class ZkBaseDataAccessor<T> implements BaseDataAccessor<T> {
           "paths, records, needCreate, and pathsCreated should be of same size");
     }
 
-    CreateCallbackHandler[] cbList = new CreateCallbackHandler[paths.size()];
+    ZkAsyncCallbacks.CreateCallbackHandler[] cbList = new ZkAsyncCallbacks.CreateCallbackHandler[paths.size()];
 
     CreateMode mode = AccessOption.getMode(options);
     if (mode == null) {
@@ -710,7 +707,7 @@ public class ZkBaseDataAccessor<T> implements BaseDataAccessor<T> {
 
         String path = paths.get(i);
         T record = records == null ? null : records.get(i);
-        cbList[i] = new CreateCallbackHandler();
+        cbList[i] = new ZkAsyncCallbacks.CreateCallbackHandler();
         _zkClient.asyncCreate(path, record, mode, cbList[i]);
       }
 
@@ -721,7 +718,7 @@ public class ZkBaseDataAccessor<T> implements BaseDataAccessor<T> {
         if (!needCreate[i])
           continue;
 
-        CreateCallbackHandler cb = cbList[i];
+        ZkAsyncCallbacks.CreateCallbackHandler cb = cbList[i];
         cb.waitForSuccess();
         String path = paths.get(i);
 
@@ -747,10 +744,10 @@ public class ZkBaseDataAccessor<T> implements BaseDataAccessor<T> {
       if (failOnNoNode) {
         boolean[] needCreateParent = Arrays.copyOf(needCreate, needCreate.length);
 
-        CreateCallbackHandler[] parentCbList =
+        ZkAsyncCallbacks.CreateCallbackHandler[] parentCbList =
             create(parentPaths, null, needCreateParent, pathsCreated, AccessOption.PERSISTENT);
         for (int i = 0; i < parentCbList.length; i++) {
-          CreateCallbackHandler parentCb = parentCbList[i];
+          ZkAsyncCallbacks.CreateCallbackHandler parentCb = parentCbList[i];
           if (parentCb == null)
             continue;
 
@@ -790,10 +787,10 @@ public class ZkBaseDataAccessor<T> implements BaseDataAccessor<T> {
     long startT = System.nanoTime();
     try {
 
-      CreateCallbackHandler[] cbList = create(paths, records, needCreate, pathsCreated, options);
+      ZkAsyncCallbacks.CreateCallbackHandler[] cbList = create(paths, records, needCreate, pathsCreated, options);
 
       for (int i = 0; i < cbList.length; i++) {
-        CreateCallbackHandler cb = cbList[i];
+        ZkAsyncCallbacks.CreateCallbackHandler cb = cbList[i];
         success[i] = (Code.get(cb.getRc()) == Code.OK);
       }
 
@@ -840,8 +837,8 @@ public class ZkBaseDataAccessor<T> implements BaseDataAccessor<T> {
     }
 
     List<Stat> setStats = new ArrayList<>(Collections.<Stat> nCopies(paths.size(), null));
-    SetDataCallbackHandler[] cbList = new SetDataCallbackHandler[paths.size()];
-    CreateCallbackHandler[] createCbList = null;
+    ZkAsyncCallbacks.SetDataCallbackHandler[] cbList = new ZkAsyncCallbacks.SetDataCallbackHandler[paths.size()];
+    ZkAsyncCallbacks.CreateCallbackHandler[] createCbList = null;
     boolean[] needSet = new boolean[paths.size()];
     Arrays.fill(needSet, true);
 
@@ -858,7 +855,7 @@ public class ZkBaseDataAccessor<T> implements BaseDataAccessor<T> {
 
           String path = paths.get(i);
           T record = records.get(i);
-          cbList[i] = new SetDataCallbackHandler();
+          cbList[i] = new ZkAsyncCallbacks.SetDataCallbackHandler();
           _zkClient.asyncSetData(path, record, -1, cbList[i]);
 
         }
@@ -866,7 +863,7 @@ public class ZkBaseDataAccessor<T> implements BaseDataAccessor<T> {
         boolean failOnNoNode = false;
 
         for (int i = 0; i < cbList.length; i++) {
-          SetDataCallbackHandler cb = cbList[i];
+          ZkAsyncCallbacks.SetDataCallbackHandler cb = cbList[i];
           cb.waitForSuccess();
           Code rc = Code.get(cb.getRc());
           switch (rc) {
@@ -890,7 +887,7 @@ public class ZkBaseDataAccessor<T> implements BaseDataAccessor<T> {
           boolean[] needCreate = Arrays.copyOf(needSet, needSet.length);
           createCbList = create(paths, records, needCreate, pathsCreated, options);
           for (int i = 0; i < createCbList.length; i++) {
-            CreateCallbackHandler createCb = createCbList[i];
+            ZkAsyncCallbacks.CreateCallbackHandler createCb = createCbList[i];
             if (createCb == null) {
               continue;
             }
@@ -916,13 +913,13 @@ public class ZkBaseDataAccessor<T> implements BaseDataAccessor<T> {
 
       // construct return results
       for (int i = 0; i < cbList.length; i++) {
-        SetDataCallbackHandler cb = cbList[i];
+        ZkAsyncCallbacks.SetDataCallbackHandler cb = cbList[i];
 
         Code rc = Code.get(cb.getRc());
         if (rc == Code.OK) {
           success[i] = true;
         } else if (rc == Code.NONODE) {
-          CreateCallbackHandler createCb = createCbList[i];
+          ZkAsyncCallbacks.CreateCallbackHandler createCb = createCbList[i];
           if (Code.get(createCb.getRc()) == Code.OK) {
             success[i] = true;
           }
@@ -986,8 +983,8 @@ public class ZkBaseDataAccessor<T> implements BaseDataAccessor<T> {
       return updateData;
     }
 
-    SetDataCallbackHandler[] cbList = new SetDataCallbackHandler[paths.size()];
-    CreateCallbackHandler[] createCbList = null;
+    ZkAsyncCallbacks.SetDataCallbackHandler[] cbList = new ZkAsyncCallbacks.SetDataCallbackHandler[paths.size()];
+    ZkAsyncCallbacks.CreateCallbackHandler[] createCbList = null;
     boolean[] needUpdate = new boolean[paths.size()];
     Arrays.fill(needUpdate, true);
 
@@ -1026,7 +1023,7 @@ public class ZkBaseDataAccessor<T> implements BaseDataAccessor<T> {
             failOnNoNode = true;
             needCreate[i] = true;
           } else {
-            cbList[i] = new SetDataCallbackHandler();
+            cbList[i] = new ZkAsyncCallbacks.SetDataCallbackHandler();
             _zkClient.asyncSetData(path, newData, curStat.getVersion(), cbList[i]);
           }
         }
@@ -1035,7 +1032,7 @@ public class ZkBaseDataAccessor<T> implements BaseDataAccessor<T> {
         boolean failOnBadVersion = false;
 
         for (int i = 0; i < paths.size(); i++) {
-          SetDataCallbackHandler cb = cbList[i];
+          ZkAsyncCallbacks.SetDataCallbackHandler cb = cbList[i];
           if (cb == null)
             continue;
 
@@ -1066,7 +1063,7 @@ public class ZkBaseDataAccessor<T> implements BaseDataAccessor<T> {
         if (failOnNoNode) {
           createCbList = create(paths, newDataList, needCreate, pathsCreated, options);
           for (int i = 0; i < paths.size(); i++) {
-            CreateCallbackHandler createCb = createCbList[i];
+            ZkAsyncCallbacks.CreateCallbackHandler createCb = createCbList[i];
             if (createCb == null) {
               continue;
             }
@@ -1141,15 +1138,15 @@ public class ZkBaseDataAccessor<T> implements BaseDataAccessor<T> {
     long startT = System.nanoTime();
 
     try {
-      ExistsCallbackHandler[] cbList = new ExistsCallbackHandler[paths.size()];
+      ZkAsyncCallbacks.ExistsCallbackHandler[] cbList = new ZkAsyncCallbacks.ExistsCallbackHandler[paths.size()];
       for (int i = 0; i < paths.size(); i++) {
         String path = paths.get(i);
-        cbList[i] = new ExistsCallbackHandler();
+        cbList[i] = new ZkAsyncCallbacks.ExistsCallbackHandler();
         _zkClient.asyncExists(path, cbList[i]);
       }
 
       for (int i = 0; i < cbList.length; i++) {
-        ExistsCallbackHandler cb = cbList[i];
+        ZkAsyncCallbacks.ExistsCallbackHandler cb = cbList[i];
         cb.waitForSuccess();
         stats[i] = cb._stat;
       }
@@ -1175,19 +1172,19 @@ public class ZkBaseDataAccessor<T> implements BaseDataAccessor<T> {
 
     boolean[] success = new boolean[paths.size()];
 
-    DeleteCallbackHandler[] cbList = new DeleteCallbackHandler[paths.size()];
+    ZkAsyncCallbacks.DeleteCallbackHandler[] cbList = new ZkAsyncCallbacks.DeleteCallbackHandler[paths.size()];
 
     long startT = System.nanoTime();
 
     try {
       for (int i = 0; i < paths.size(); i++) {
         String path = paths.get(i);
-        cbList[i] = new DeleteCallbackHandler();
+        cbList[i] = new ZkAsyncCallbacks.DeleteCallbackHandler();
         _zkClient.asyncDelete(path, cbList[i]);
       }
 
       for (int i = 0; i < cbList.length; i++) {
-        DeleteCallbackHandler cb = cbList[i];
+        ZkAsyncCallbacks.DeleteCallbackHandler cb = cbList[i];
         cb.waitForSuccess();
         success[i] = (cb.getRc() == 0);
       }
diff --git a/helix-core/src/main/java/org/apache/helix/manager/zk/ZkBucketDataAccessor.java b/helix-core/src/main/java/org/apache/helix/manager/zk/ZkBucketDataAccessor.java
index bc13471..ffed9f3 100644
--- a/helix-core/src/main/java/org/apache/helix/manager/zk/ZkBucketDataAccessor.java
+++ b/helix-core/src/main/java/org/apache/helix/manager/zk/ZkBucketDataAccessor.java
@@ -30,18 +30,18 @@ import java.util.TimerTask;
 import java.util.concurrent.Executors;
 import java.util.concurrent.ScheduledExecutorService;
 import java.util.concurrent.TimeUnit;
-import org.I0Itec.zkclient.DataUpdater;
-import org.I0Itec.zkclient.exception.ZkMarshallingError;
-import org.I0Itec.zkclient.exception.ZkNoNodeException;
-import org.I0Itec.zkclient.serialize.ZkSerializer;
 import org.apache.helix.AccessOption;
 import org.apache.helix.BucketDataAccessor;
 import org.apache.helix.HelixException;
 import org.apache.helix.HelixProperty;
-import org.apache.helix.ZNRecord;
-import org.apache.helix.manager.zk.client.DedicatedZkClientFactory;
-import org.apache.helix.manager.zk.client.HelixZkClient;
 import org.apache.helix.util.GZipCompressionUtil;
+import org.apache.helix.zookeeper.api.client.HelixZkClient;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
+import org.apache.helix.zookeeper.impl.factory.DedicatedZkClientFactory;
+import org.apache.helix.zookeeper.zkclient.DataUpdater;
+import org.apache.helix.zookeeper.zkclient.exception.ZkMarshallingError;
+import org.apache.helix.zookeeper.zkclient.exception.ZkNoNodeException;
+import org.apache.helix.zookeeper.zkclient.serialize.ZkSerializer;
 import org.codehaus.jackson.map.ObjectMapper;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
diff --git a/helix-core/src/main/java/org/apache/helix/manager/zk/ZkCacheBaseDataAccessor.java b/helix-core/src/main/java/org/apache/helix/manager/zk/ZkCacheBaseDataAccessor.java
index b230827..6d2c5cf 100644
--- a/helix-core/src/main/java/org/apache/helix/manager/zk/ZkCacheBaseDataAccessor.java
+++ b/helix-core/src/main/java/org/apache/helix/manager/zk/ZkCacheBaseDataAccessor.java
@@ -29,22 +29,22 @@ import java.util.TreeMap;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.locks.ReentrantLock;
 
-import org.I0Itec.zkclient.DataUpdater;
-import org.I0Itec.zkclient.IZkChildListener;
-import org.I0Itec.zkclient.IZkDataListener;
-import org.I0Itec.zkclient.exception.ZkNoNodeException;
-import org.I0Itec.zkclient.serialize.ZkSerializer;
 import org.apache.helix.AccessOption;
 import org.apache.helix.HelixException;
-import org.apache.helix.manager.zk.ZkAsyncCallbacks.CreateCallbackHandler;
 import org.apache.helix.manager.zk.ZkBaseDataAccessor.RetCode;
-import org.apache.helix.manager.zk.client.DedicatedZkClientFactory;
-import org.apache.helix.manager.zk.client.HelixZkClient;
-import org.apache.helix.manager.zk.client.SharedZkClientFactory;
 import org.apache.helix.store.HelixPropertyListener;
 import org.apache.helix.store.HelixPropertyStore;
 import org.apache.helix.store.zk.ZNode;
 import org.apache.helix.util.PathUtils;
+import org.apache.helix.zookeeper.api.client.HelixZkClient;
+import org.apache.helix.zookeeper.impl.factory.DedicatedZkClientFactory;
+import org.apache.helix.zookeeper.impl.factory.SharedZkClientFactory;
+import org.apache.helix.zookeeper.zkclient.DataUpdater;
+import org.apache.helix.zookeeper.zkclient.IZkChildListener;
+import org.apache.helix.zookeeper.zkclient.IZkDataListener;
+import org.apache.helix.zookeeper.zkclient.callback.ZkAsyncCallbacks;
+import org.apache.helix.zookeeper.zkclient.exception.ZkNoNodeException;
+import org.apache.helix.zookeeper.zkclient.serialize.ZkSerializer;
 import org.apache.zookeeper.KeeperException.Code;
 import org.apache.zookeeper.data.Stat;
 import org.apache.zookeeper.server.DataTree;
@@ -451,12 +451,12 @@ public class ZkCacheBaseDataAccessor<T> implements HelixPropertyStore<T> {
         Arrays.fill(needCreate, true);
         List<List<String>> pathsCreatedList =
             new ArrayList<List<String>>(Collections.<List<String>>nCopies(size, null));
-        CreateCallbackHandler[] createCbList =
+        ZkAsyncCallbacks.CreateCallbackHandler[] createCbList =
             _baseAccessor.create(serverPaths, records, needCreate, pathsCreatedList, options);
 
         boolean[] success = new boolean[size];
         for (int i = 0; i < size; i++) {
-          CreateCallbackHandler cb = createCbList[i];
+          ZkAsyncCallbacks.CreateCallbackHandler cb = createCbList[i];
           success[i] = (Code.get(cb.getRc()) == Code.OK);
 
           updateCache(cache, pathsCreatedList.get(i), success[i], serverPaths.get(i),
diff --git a/helix-core/src/main/java/org/apache/helix/manager/zk/ZkCacheEventThread.java b/helix-core/src/main/java/org/apache/helix/manager/zk/ZkCacheEventThread.java
index 9c208d3..5dc1ebb 100644
--- a/helix-core/src/main/java/org/apache/helix/manager/zk/ZkCacheEventThread.java
+++ b/helix-core/src/main/java/org/apache/helix/manager/zk/ZkCacheEventThread.java
@@ -23,7 +23,7 @@ import java.util.concurrent.BlockingQueue;
 import java.util.concurrent.LinkedBlockingQueue;
 import java.util.concurrent.atomic.AtomicInteger;
 
-import org.I0Itec.zkclient.exception.ZkInterruptedException;
+import org.apache.helix.zookeeper.zkclient.exception.ZkInterruptedException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
diff --git a/helix-core/src/main/java/org/apache/helix/manager/zk/ZkCallbackCache.java b/helix-core/src/main/java/org/apache/helix/manager/zk/ZkCallbackCache.java
index 49037eb..4b08d27 100644
--- a/helix-core/src/main/java/org/apache/helix/manager/zk/ZkCallbackCache.java
+++ b/helix-core/src/main/java/org/apache/helix/manager/zk/ZkCallbackCache.java
@@ -25,9 +25,6 @@ import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.CopyOnWriteArraySet;
 
-import org.I0Itec.zkclient.IZkChildListener;
-import org.I0Itec.zkclient.IZkDataListener;
-import org.I0Itec.zkclient.exception.ZkNoNodeException;
 import org.apache.helix.AccessOption;
 import org.apache.helix.BaseDataAccessor;
 import org.apache.helix.manager.zk.ZkCacheEventThread.ZkCacheEvent;
@@ -35,6 +32,9 @@ import org.apache.helix.manager.zk.zookeeper.IZkStateListener;
 import org.apache.helix.store.HelixPropertyListener;
 import org.apache.helix.store.zk.ZNode;
 import org.apache.helix.util.HelixUtil;
+import org.apache.helix.zookeeper.zkclient.IZkChildListener;
+import org.apache.helix.zookeeper.zkclient.IZkDataListener;
+import org.apache.helix.zookeeper.zkclient.exception.ZkNoNodeException;
 import org.apache.zookeeper.Watcher.Event.EventType;
 import org.apache.zookeeper.Watcher.Event.KeeperState;
 import org.apache.zookeeper.data.Stat;
diff --git a/helix-core/src/main/java/org/apache/helix/manager/zk/ZkClient.java b/helix-core/src/main/java/org/apache/helix/manager/zk/ZkClient.java
index 55c7048..4e38f26 100644
--- a/helix-core/src/main/java/org/apache/helix/manager/zk/ZkClient.java
+++ b/helix-core/src/main/java/org/apache/helix/manager/zk/ZkClient.java
@@ -19,12 +19,14 @@ package org.apache.helix.manager.zk;
  * under the License.
  */
 
-import org.I0Itec.zkclient.IZkConnection;
-import org.I0Itec.zkclient.serialize.SerializableSerializer;
-import org.I0Itec.zkclient.serialize.ZkSerializer;
 import org.apache.helix.HelixException;
-import org.apache.helix.manager.zk.client.HelixZkClient;
-import org.apache.helix.manager.zk.zookeeper.ZkConnection;
+import org.apache.helix.zookeeper.api.client.HelixZkClient;
+import org.apache.helix.zookeeper.zkclient.IZkConnection;
+import org.apache.helix.zookeeper.zkclient.ZkConnection;
+import org.apache.helix.zookeeper.zkclient.serialize.BasicZkSerializer;
+import org.apache.helix.zookeeper.zkclient.serialize.PathBasedZkSerializer;
+import org.apache.helix.zookeeper.zkclient.serialize.SerializableSerializer;
+import org.apache.helix.zookeeper.zkclient.serialize.ZkSerializer;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -189,7 +191,8 @@ public class ZkClient extends org.apache.helix.manager.zk.zookeeper.ZkClient imp
       return this;
     }
 
-    public Builder setZkSerializer(PathBasedZkSerializer zkSerializer) {
+    public Builder setZkSerializer(
+        PathBasedZkSerializer zkSerializer) {
       this._zkSerializer = zkSerializer;
       return this;
     }
diff --git a/helix-core/src/main/java/org/apache/helix/manager/zk/ZkSessionMismatchedException.java b/helix-core/src/main/java/org/apache/helix/manager/zk/ZkSessionMismatchedException.java
deleted file mode 100644
index e336bb6..0000000
--- a/helix-core/src/main/java/org/apache/helix/manager/zk/ZkSessionMismatchedException.java
+++ /dev/null
@@ -1,18 +0,0 @@
-package org.apache.helix.manager.zk;
-
-import org.I0Itec.zkclient.exception.ZkException;
-import org.apache.zookeeper.KeeperException;
-
-
-/**
- * Exception thrown when an action is taken by an expected zk session which
- * does not match the actual zk session.
- */
-public class ZkSessionMismatchedException extends ZkException {
-
-    private static final long serialVersionUID = 1L;
-
-    public ZkSessionMismatchedException(String message) {
-        super(message);
-    }
-}
diff --git a/helix-core/src/main/java/org/apache/helix/manager/zk/client/DedicatedZkClientFactory.java b/helix-core/src/main/java/org/apache/helix/manager/zk/client/DedicatedZkClientFactory.java
index edeb978..c82c1fc 100644
--- a/helix-core/src/main/java/org/apache/helix/manager/zk/client/DedicatedZkClientFactory.java
+++ b/helix-core/src/main/java/org/apache/helix/manager/zk/client/DedicatedZkClientFactory.java
@@ -1,35 +1,29 @@
 package org.apache.helix.manager.zk.client;
 
-import org.apache.helix.manager.zk.ZkClient;
+/*
+ * 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.
+ */
 
 /**
+ * Deprecated; please use DedicatedZkClientFactory in zookeeper-api instead.
+ *
  * Singleton factory that build dedicated clients using the raw ZkClient.
  */
-public class DedicatedZkClientFactory extends HelixZkClientFactory {
-
-  protected DedicatedZkClientFactory() {}
-
-  private static class SingletonHelper{
-    private static final DedicatedZkClientFactory INSTANCE = new DedicatedZkClientFactory();
-  }
-
-  public static DedicatedZkClientFactory getInstance(){
-    return SingletonHelper.INSTANCE;
-  }
-
-  /**
-   * Build a Dedicated ZkClient based on connection config and client config
-   *
-   * @param connectionConfig
-   * @param clientConfig
-   * @return
-   */
-  @Override
-  public HelixZkClient buildZkClient(HelixZkClient.ZkConnectionConfig connectionConfig,
-      HelixZkClient.ZkClientConfig clientConfig) {
-    return new ZkClient(createZkConnection(connectionConfig),
-        (int) clientConfig.getConnectInitTimeout(), clientConfig.getOperationRetryTimeout(),
-        clientConfig.getZkSerializer(), clientConfig.getMonitorType(), clientConfig.getMonitorKey(),
-        clientConfig.getMonitorInstanceName(), clientConfig.isMonitorRootPathOnly());
-  }
+@Deprecated
+public class DedicatedZkClientFactory extends org.apache.helix.zookeeper.impl.factory.DedicatedZkClientFactory {
 }
diff --git a/helix-core/src/main/java/org/apache/helix/manager/zk/client/HelixZkClient.java b/helix-core/src/main/java/org/apache/helix/manager/zk/client/HelixZkClient.java
index 5f58b69..a2aa114 100644
--- a/helix-core/src/main/java/org/apache/helix/manager/zk/client/HelixZkClient.java
+++ b/helix-core/src/main/java/org/apache/helix/manager/zk/client/HelixZkClient.java
@@ -1,442 +1,9 @@
 package org.apache.helix.manager.zk.client;
 
-import java.util.List;
-import java.util.concurrent.TimeUnit;
-
-import org.I0Itec.zkclient.DataUpdater;
-import org.I0Itec.zkclient.IZkChildListener;
-import org.I0Itec.zkclient.IZkDataListener;
-import org.I0Itec.zkclient.exception.ZkTimeoutException;
-import org.I0Itec.zkclient.serialize.SerializableSerializer;
-import org.I0Itec.zkclient.serialize.ZkSerializer;
-import org.apache.helix.manager.zk.BasicZkSerializer;
-import org.apache.helix.manager.zk.PathBasedZkSerializer;
-import org.apache.helix.manager.zk.ZkAsyncCallbacks;
-import org.apache.helix.manager.zk.zookeeper.IZkStateListener;
-import org.apache.zookeeper.CreateMode;
-import org.apache.zookeeper.Op;
-import org.apache.zookeeper.OpResult;
-import org.apache.zookeeper.Watcher.Event.KeeperState;
-import org.apache.zookeeper.data.ACL;
-import org.apache.zookeeper.data.Stat;
-
 /**
- * Helix ZkClient interface.
+ * NOTE: this interface has been deprecated. Please use HelixZkClient or RealmAwareZkClient in zookeeper-api instead.
+ * HelixZkClient interface.
  */
-public interface HelixZkClient {
-  int DEFAULT_OPERATION_TIMEOUT = Integer.MAX_VALUE;
-  int DEFAULT_CONNECTION_TIMEOUT = 60 * 1000;
-  int DEFAULT_SESSION_TIMEOUT = 30 * 1000;
-
-  // listener subscription
-  List<String> subscribeChildChanges(String path, IZkChildListener listener);
-
-  void unsubscribeChildChanges(String path, IZkChildListener listener);
-
-  void subscribeDataChanges(String path, IZkDataListener listener);
-
-  void unsubscribeDataChanges(String path, IZkDataListener listener);
-
-  /*
-   * This is for backwards compatibility.
-   *
-   * TODO: remove below default implementation when getting rid of I0Itec in the new zk client.
-   */
-  default void subscribeStateChanges(final IZkStateListener listener) {
-    subscribeStateChanges(new I0ItecIZkStateListenerHelixImpl(listener));
-  }
-
-  /*
-   * This is for backwards compatibility.
-   *
-   * TODO: remove below default implementation when getting rid of I0Itec in the new zk client.
-   */
-  default void unsubscribeStateChanges(IZkStateListener listener) {
-    unsubscribeStateChanges(new I0ItecIZkStateListenerHelixImpl(listener));
-  }
-
-  /**
-   * Subscribes state changes for a {@link org.I0Itec.zkclient.IZkStateListener} listener.
-   *
-   * @deprecated
-   * This is deprecated. It is kept for backwards compatibility. Please use
-   * {@link #subscribeStateChanges(org.apache.helix.manager.zk.zookeeper.IZkStateListener)}.
-   *
-   * @param listener {@link org.I0Itec.zkclient.IZkStateListener} listener
-   */
-  @Deprecated
-  void subscribeStateChanges(final org.I0Itec.zkclient.IZkStateListener listener);
-
-  /**
-   * Unsubscribes state changes for a {@link org.I0Itec.zkclient.IZkStateListener} listener.
-   *
-   * @deprecated
-   * This is deprecated. It is kept for backwards compatibility. Please use
-   * {@link #unsubscribeStateChanges(org.apache.helix.manager.zk.zookeeper.IZkStateListener)}.
-   *
-   * @param listener {@link org.I0Itec.zkclient.IZkStateListener} listener
-   */
-  @Deprecated
-  void unsubscribeStateChanges(org.I0Itec.zkclient.IZkStateListener listener);
-
-  void unsubscribeAll();
-
-  // data access
-  void createPersistent(String path);
-
-  void createPersistent(String path, boolean createParents);
-
-  void createPersistent(String path, boolean createParents, List<ACL> acl);
-
-  void createPersistent(String path, Object data);
-
-  void createPersistent(String path, Object data, List<ACL> acl);
-
-  String createPersistentSequential(String path, Object data);
-
-  String createPersistentSequential(String path, Object data, List<ACL> acl);
-
-  void createEphemeral(final String path);
-
-  void createEphemeral(final String path, final String sessionId);
-
-  void createEphemeral(final String path, final List<ACL> acl);
-
-  void createEphemeral(final String path, final List<ACL> acl, final String sessionId);
-
-  String create(final String path, Object data, final CreateMode mode);
-
-  String create(final String path, Object datat, final List<ACL> acl, final CreateMode mode);
-
-  void createEphemeral(final String path, final Object data);
-
-  void createEphemeral(final String path, final Object data, final String sessionId);
-
-  void createEphemeral(final String path, final Object data, final List<ACL> acl);
-
-  void createEphemeral(final String path, final Object data, final List<ACL> acl,
-      final String sessionId);
-
-  String createEphemeralSequential(final String path, final Object data);
-
-  String createEphemeralSequential(final String path, final Object data, final List<ACL> acl);
-
-  String createEphemeralSequential(final String path, final Object data, final String sessionId);
-
-  String createEphemeralSequential(final String path, final Object data, final List<ACL> acl,
-      final String sessionId);
-
-  List<String> getChildren(String path);
-
-  int countChildren(String path);
-
-  boolean exists(final String path);
-
-  Stat getStat(final String path);
-
-  boolean waitUntilExists(String path, TimeUnit timeUnit, long time);
-
-  void deleteRecursively(String path);
-
-  boolean delete(final String path);
-
-  <T extends Object> T readData(String path);
-
-  <T extends Object> T readData(String path, boolean returnNullIfPathNotExists);
-
-  <T extends Object> T readData(String path, Stat stat);
-
-  <T extends Object> T readData(final String path, final Stat stat, final boolean watch);
-
-  <T extends Object> T readDataAndStat(String path, Stat stat, boolean returnNullIfPathNotExists);
-
-  void writeData(String path, Object object);
-
-  <T extends Object> void updateDataSerialized(String path, DataUpdater<T> updater);
-
-  void writeData(final String path, Object datat, final int expectedVersion);
-
-  Stat writeDataReturnStat(final String path, Object datat, final int expectedVersion);
-
-  Stat writeDataGetStat(final String path, Object datat, final int expectedVersion);
-
-  void asyncCreate(final String path, Object datat, final CreateMode mode,
-      final ZkAsyncCallbacks.CreateCallbackHandler cb);
-
-  void asyncSetData(final String path, Object datat, final int version,
-      final ZkAsyncCallbacks.SetDataCallbackHandler cb);
-
-  void asyncGetData(final String path, final ZkAsyncCallbacks.GetDataCallbackHandler cb);
-
-  void asyncExists(final String path, final ZkAsyncCallbacks.ExistsCallbackHandler cb);
-
-  void asyncDelete(final String path, final ZkAsyncCallbacks.DeleteCallbackHandler cb);
-
-  void watchForData(final String path);
-
-  List<String> watchForChilds(final String path);
-
-  long getCreationTime(String path);
-
-  List<OpResult> multi(final Iterable<Op> ops);
-
-  // ZK state control
-  boolean waitUntilConnected(long time, TimeUnit timeUnit);
-
-  /**
-   * Waits for SyncConnected state and returns a valid session ID(non-zero). The implementation of
-   * this method should wait for SyncConnected state and ZK session to be established, and should
-   * guarantee the established session's ID is returned before keeper state changes.
-   *
-   * Please note: this default implementation may have race condition issue and return an unexpected
-   * session ID that is zero or another new session's ID. The default implementation is for backward
-   * compatibility purpose.
-   *
-   * @param timeout Max waiting time for connecting to ZK server.
-   * @param timeUnit Time unit for the timeout.
-   * @return A valid ZK session ID which is non-zero.
-   */
-  default long waitForEstablishedSession(long timeout, TimeUnit timeUnit) {
-    if (!waitUntilConnected(timeout, timeUnit)) {
-      throw new ZkTimeoutException(
-          "Failed to get established session because connecting to ZK server has timed out in "
-              + timeout + " " + timeUnit);
-    }
-    return getSessionId();
-  }
-
-  String getServers();
-
-  long getSessionId();
-
-  void close();
-
-  boolean isClosed();
-
-  // other
-  byte[] serialize(Object data, String path);
-
-  <T extends Object> T deserialize(byte[] data, String path);
-
-  void setZkSerializer(ZkSerializer zkSerializer);
-
-  void setZkSerializer(PathBasedZkSerializer zkSerializer);
-
-  PathBasedZkSerializer getZkSerializer();
-
-  /**
-   * A class that wraps a default implementation of
-   * {@link org.apache.helix.manager.zk.zookeeper.IZkStateListener}, which means this listener
-   * runs the methods of {@link org.apache.helix.manager.zk.zookeeper.IZkStateListener}.
-   * This is for backward compatibility and to avoid breaking the original implementation of
-   * {@link org.I0Itec.zkclient.IZkStateListener}.
-   */
-  class I0ItecIZkStateListenerHelixImpl implements org.I0Itec.zkclient.IZkStateListener {
-    private IZkStateListener _listener;
-
-    I0ItecIZkStateListenerHelixImpl(IZkStateListener listener) {
-      _listener = listener;
-    }
-
-    @Override
-    public void handleStateChanged(KeeperState keeperState) throws Exception {
-      _listener.handleStateChanged(keeperState);
-    }
-
-    @Override
-    public void handleNewSession() throws Exception {
-      /*
-       * org.apache.helix.manager.zk.zookeeper.IZkStateListener does not have handleNewSession(),
-       * so null is passed into handleNewSession(sessionId).
-       */
-      _listener.handleNewSession(null);
-    }
-
-    @Override
-    public void handleSessionEstablishmentError(Throwable error) throws Exception {
-      _listener.handleSessionEstablishmentError(error);
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-      if (obj == this) {
-        return true;
-      }
-      if (!(obj instanceof I0ItecIZkStateListenerHelixImpl)) {
-        return false;
-      }
-      if (_listener == null) {
-        return false;
-      }
-
-      I0ItecIZkStateListenerHelixImpl defaultListener = (I0ItecIZkStateListenerHelixImpl) obj;
-
-      return _listener.equals(defaultListener._listener);
-    }
-
-    @Override
-    public int hashCode() {
-      /*
-       * The original listener's hashcode helps find the wrapped listener with the same original
-       * listener. This is helpful in unsubscribeStateChanges(listener).
-       */
-      return _listener.hashCode();
-    }
-  }
-
-  /**
-   * Configuration for creating a new ZkConnection.
-   */
-  class ZkConnectionConfig {
-    // Connection configs
-    private final String _zkServers;
-    private int _sessionTimeout = HelixZkClient.DEFAULT_SESSION_TIMEOUT;
-
-    public ZkConnectionConfig(String zkServers) {
-      _zkServers = zkServers;
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-      if (obj == this) {
-        return true;
-      }
-      if (!(obj instanceof ZkConnectionConfig)) {
-        return false;
-      }
-      ZkConnectionConfig configObj = (ZkConnectionConfig) obj;
-      return (_zkServers == null && configObj._zkServers == null ||
-          _zkServers != null && _zkServers.equals(configObj._zkServers)) &&
-          _sessionTimeout == configObj._sessionTimeout;
-    }
-
-    @Override
-    public int hashCode() {
-      return _sessionTimeout * 31 + _zkServers.hashCode();
-    }
-
-    @Override
-    public String toString() {
-      return (_zkServers + "_" + _sessionTimeout).replaceAll("[\\W]", "_");
-    }
-
-    public ZkConnectionConfig setSessionTimeout(Integer sessionTimeout) {
-      this._sessionTimeout = sessionTimeout;
-      return this;
-    }
-
-    public String getZkServers() {
-      return _zkServers;
-    }
-
-    public int getSessionTimeout() {
-      return _sessionTimeout;
-    }
-  }
-
-  /**
-   * Configuration for creating a new ZkClient with serializer and monitor.
-   */
-  class ZkClientConfig {
-    // For client to init the connection
-    private long _connectInitTimeout = HelixZkClient.DEFAULT_CONNECTION_TIMEOUT;
-
-    // Data access configs
-    private long _operationRetryTimeout = HelixZkClient.DEFAULT_OPERATION_TIMEOUT;
-
-    // Others
-    private PathBasedZkSerializer _zkSerializer;
-
-    // Monitoring
-    private String _monitorType;
-    private String _monitorKey;
-    private String _monitorInstanceName = null;
-    private boolean _monitorRootPathOnly = true;
-
-    public ZkClientConfig setZkSerializer(PathBasedZkSerializer zkSerializer) {
-      this._zkSerializer = zkSerializer;
-      return this;
-    }
-
-    public ZkClientConfig setZkSerializer(ZkSerializer zkSerializer) {
-      this._zkSerializer = new BasicZkSerializer(zkSerializer);
-      return this;
-    }
-
-    /**
-     * Used as part of the MBean ObjectName. This item is required for enabling monitoring.
-     *
-     * @param monitorType
-     */
-    public ZkClientConfig setMonitorType(String monitorType) {
-      this._monitorType = monitorType;
-      return this;
-    }
-
-    /**
-     * Used as part of the MBean ObjectName. This item is required for enabling monitoring.
-     *
-     * @param monitorKey
-     */
-    public ZkClientConfig setMonitorKey(String monitorKey) {
-      this._monitorKey = monitorKey;
-      return this;
-    }
-
-    /**
-     * Used as part of the MBean ObjectName. This item is optional.
-     *
-     * @param instanceName
-     */
-    public ZkClientConfig setMonitorInstanceName(String instanceName) {
-      this._monitorInstanceName = instanceName;
-      return this;
-    }
-
-    public ZkClientConfig setMonitorRootPathOnly(Boolean monitorRootPathOnly) {
-      this._monitorRootPathOnly = monitorRootPathOnly;
-      return this;
-    }
-
-    public ZkClientConfig setOperationRetryTimeout(Long operationRetryTimeout) {
-      this._operationRetryTimeout = operationRetryTimeout;
-      return this;
-    }
-
-    public ZkClientConfig setConnectInitTimeout(long _connectInitTimeout) {
-      this._connectInitTimeout = _connectInitTimeout;
-      return this;
-    }
-
-    public PathBasedZkSerializer getZkSerializer() {
-      if (_zkSerializer == null) {
-        _zkSerializer = new BasicZkSerializer(new SerializableSerializer());
-      }
-      return _zkSerializer;
-    }
-
-    public long getOperationRetryTimeout() {
-      return _operationRetryTimeout;
-    }
-
-    public String getMonitorType() {
-      return _monitorType;
-    }
-
-    public String getMonitorKey() {
-      return _monitorKey;
-    }
-
-    public String getMonitorInstanceName() {
-      return _monitorInstanceName;
-    }
-
-    public boolean isMonitorRootPathOnly() {
-      return _monitorRootPathOnly;
-    }
-
-    public long getConnectInitTimeout() {
-      return _connectInitTimeout;
-    }
-  }
+@Deprecated
+public interface HelixZkClient extends org.apache.helix.zookeeper.api.client.HelixZkClient {
 }
diff --git a/helix-core/src/main/java/org/apache/helix/manager/zk/client/HelixZkClientFactory.java b/helix-core/src/main/java/org/apache/helix/manager/zk/client/HelixZkClientFactory.java
deleted file mode 100644
index e6dc90e..0000000
--- a/helix-core/src/main/java/org/apache/helix/manager/zk/client/HelixZkClientFactory.java
+++ /dev/null
@@ -1,46 +0,0 @@
-package org.apache.helix.manager.zk.client;
-
-import org.I0Itec.zkclient.IZkConnection;
-import org.apache.helix.HelixException;
-import org.apache.helix.manager.zk.zookeeper.ZkConnection;
-
-/**
- * Abstract class of the ZkClient factory.
- */
-abstract class HelixZkClientFactory {
-
-  /**
-   * Build a ZkClient using specified connection config and client config
-   *
-   * @param connectionConfig
-   * @param clientConfig
-   * @return HelixZkClient
-   */
-  public abstract HelixZkClient buildZkClient(HelixZkClient.ZkConnectionConfig connectionConfig,
-      HelixZkClient.ZkClientConfig clientConfig);
-
-  /**
-   * Build a ZkClient using specified connection config and default client config
-   *
-   * @param connectionConfig
-   * @return HelixZkClient
-   */
-  public HelixZkClient buildZkClient(HelixZkClient.ZkConnectionConfig connectionConfig) {
-    return buildZkClient(connectionConfig, new HelixZkClient.ZkClientConfig());
-  }
-
-  /**
-   * Construct a new ZkConnection instance based on connection configuration.
-   * Note that the connection is not really made until someone calls zkConnection.connect().
-   * @param connectionConfig
-   * @return
-   */
-  protected IZkConnection createZkConnection(HelixZkClient.ZkConnectionConfig connectionConfig) {
-    if (connectionConfig.getZkServers() == null) {
-      throw new HelixException(
-          "Failed to build ZkClient since no connection or ZK server address is specified.");
-    } else {
-      return new ZkConnection(connectionConfig.getZkServers(), connectionConfig.getSessionTimeout());
-    }
-  }
-}
diff --git a/helix-core/src/main/java/org/apache/helix/manager/zk/client/SharedZkClient.java b/helix-core/src/main/java/org/apache/helix/manager/zk/client/SharedZkClient.java
index 5c6ade0..52a2c17 100644
--- a/helix-core/src/main/java/org/apache/helix/manager/zk/client/SharedZkClient.java
+++ b/helix-core/src/main/java/org/apache/helix/manager/zk/client/SharedZkClient.java
@@ -1,92 +1,37 @@
 package org.apache.helix.manager.zk.client;
 
-import java.util.List;
-
-import org.I0Itec.zkclient.IZkConnection;
-import org.apache.helix.HelixException;
-import org.apache.helix.manager.zk.zookeeper.ZkConnection;
-import org.apache.zookeeper.CreateMode;
-import org.apache.zookeeper.data.ACL;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+/*
+ * 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.
+ */
 
 /**
- * ZkClient that uses shared ZkConnection.
- * A SharedZkClient won't manipulate the shared ZkConnection directly.
+ * Deprecated; use SharedZkClient in zookeeper-api instead.
  */
-class SharedZkClient extends org.apache.helix.manager.zk.ZkClient implements HelixZkClient {
-  private static Logger LOG = LoggerFactory.getLogger(SharedZkClient.class);
-  /*
-   * Since we cannot really disconnect the ZkConnection, we need a dummy ZkConnection placeholder.
-   * This is to ensure connection field is never null even the shared ZkClient instance is closed so as to avoid NPE.
-   */
-  private final static ZkConnection IDLE_CONNECTION = new ZkConnection("Dummy_ZkServers");
-  private final OnCloseCallback _onCloseCallback;
-  private final ZkConnectionManager _connectionManager;
-
-  interface OnCloseCallback {
-    /**
-     * Triggered after the ZkClient is closed.
-     */
-    void onClose();
-  }
-
+@Deprecated
+class SharedZkClient extends org.apache.helix.zookeeper.impl.client.SharedZkClient {
   /**
-   * Construct a shared ZkClient that uses a shared ZkConnection.
-   *
-   * @param connectionManager     The manager of the shared ZkConnection.
-   * @param clientConfig          ZkClientConfig details to create the shared ZkClient.
-   * @param callback              Clean up logic when the shared ZkClient is closed.
+   * Construct a shared RealmAwareZkClient that uses a shared ZkConnection.
+   *  @param connectionManager     The manager of the shared ZkConnection.
+   * @param clientConfig          ZkClientConfig details to create the shared RealmAwareZkClient.
+   * @param callback              Clean up logic when the shared RealmAwareZkClient is closed.
    */
   protected SharedZkClient(ZkConnectionManager connectionManager, ZkClientConfig clientConfig,
-      OnCloseCallback callback) {
-    super(connectionManager.getConnection(), 0, clientConfig.getOperationRetryTimeout(),
-        clientConfig.getZkSerializer(), clientConfig.getMonitorType(), clientConfig.getMonitorKey(),
-        clientConfig.getMonitorInstanceName(), clientConfig.isMonitorRootPathOnly());
-    _connectionManager = connectionManager;
-    // Register to the base dedicated ZkClient
-    _connectionManager.registerWatcher(this);
-    _onCloseCallback = callback;
-  }
-
-  @Override
-  public void close() {
-    super.close();
-    if (isClosed()) {
-      // Note that if register is not done while constructing, these private fields may not be init yet.
-      if (_connectionManager != null) {
-        _connectionManager.unregisterWatcher(this);
-      }
-      if (_onCloseCallback != null) {
-        _onCloseCallback.onClose();
-      }
-    }
-  }
-
-  @Override
-  public IZkConnection getConnection() {
-    if (isClosed()) {
-      return IDLE_CONNECTION;
-    }
-    return super.getConnection();
-  }
-
-  /**
-   * Since ZkConnection session is shared in this ZkClient, do not create ephemeral node using a SharedZKClient.
-   */
-  @Override
-  public String create(final String path, Object datat, final List<ACL> acl,
-      final CreateMode mode) {
-    if (mode.isEphemeral()) {
-      throw new HelixException(
-          "Create ephemeral nodes using a " + SharedZkClient.class.getSimpleName()
-              + " ZkClient is not supported.");
-    }
-    return super.create(path, datat, acl, mode);
-  }
-
-  @Override
-  protected boolean isManagingZkConnection() {
-    return false;
+      org.apache.helix.zookeeper.impl.client.SharedZkClient.OnCloseCallback callback) {
+    super(connectionManager, clientConfig, callback);
   }
 }
diff --git a/helix-core/src/main/java/org/apache/helix/manager/zk/client/SharedZkClientFactory.java b/helix-core/src/main/java/org/apache/helix/manager/zk/client/SharedZkClientFactory.java
index ed4b5de..0a00336 100644
--- a/helix-core/src/main/java/org/apache/helix/manager/zk/client/SharedZkClientFactory.java
+++ b/helix-core/src/main/java/org/apache/helix/manager/zk/client/SharedZkClientFactory.java
@@ -1,87 +1,29 @@
 package org.apache.helix.manager.zk.client;
 
-import java.util.HashMap;
-
-import org.apache.helix.HelixException;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+/*
+ * 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.
+ */
 
 /**
+ * Deprecated: Please use SharedZkClientFactory in zookeeper-api module instead.
+ *
  * Singleton factory that build shared ZkClient which use a shared ZkConnection.
  */
-public class SharedZkClientFactory extends HelixZkClientFactory {
-  private static Logger LOG = LoggerFactory.getLogger(SharedZkClient.class);
-  // The connection pool to track all created connections.
-  private final HashMap<HelixZkClient.ZkConnectionConfig, ZkConnectionManager>
-      _connectionManagerPool = new HashMap<>();
-
-  protected SharedZkClientFactory() {}
-
-  private static class SingletonHelper {
-    private static final SharedZkClientFactory INSTANCE = new SharedZkClientFactory();
-  }
-
-  public static SharedZkClientFactory getInstance() {
-    return SingletonHelper.INSTANCE;
-  }
-
-  /**
-   * Build a Shared ZkClient that uses sharing ZkConnection that is created based on the specified connection config.
-   *
-   * @param connectionConfig The connection configuration that is used to search for a shared connection. Or create new connection if necessary.
-   * @param clientConfig
-   * @return Shared ZkClient
-   */
-  @Override
-  public HelixZkClient buildZkClient(HelixZkClient.ZkConnectionConfig connectionConfig,
-      HelixZkClient.ZkClientConfig clientConfig) {
-    synchronized (_connectionManagerPool) {
-      final ZkConnectionManager zkConnectionManager =
-          getOrCreateZkConnectionNamanger(connectionConfig, clientConfig.getConnectInitTimeout());
-      if (zkConnectionManager == null) {
-        throw new HelixException("Failed to create a connection manager in the pool to share.");
-      }
-      LOG.info("Sharing ZkConnection {} to a new SharedZkClient.", connectionConfig.toString());
-      return new SharedZkClient(zkConnectionManager, clientConfig,
-          new SharedZkClient.OnCloseCallback() {
-            @Override
-            public void onClose() {
-              cleanupConnectionManager(zkConnectionManager);
-            }
-          });
-    }
-  }
-
-  private ZkConnectionManager getOrCreateZkConnectionNamanger(
-      HelixZkClient.ZkConnectionConfig connectionConfig, long connectInitTimeout) {
-    ZkConnectionManager connectionManager = _connectionManagerPool.get(connectionConfig);
-    if (connectionManager == null || connectionManager.isClosed()) {
-      connectionManager = new ZkConnectionManager(createZkConnection(connectionConfig), connectInitTimeout,
-          connectionConfig.toString());
-      _connectionManagerPool.put(connectionConfig, connectionManager);
-    }
-    return connectionManager;
-  }
-
-  // Close the ZkConnectionManager if no other shared client is referring to it.
-  // Note the close operation of connection manager needs to be synchronized with the pool operation
-  // to avoid race condition.
-  private void cleanupConnectionManager(ZkConnectionManager zkConnectionManager) {
-    synchronized (_connectionManagerPool) {
-      zkConnectionManager.close(true);
-    }
-  }
-
-  // For test only
-  protected int getActiveConnectionCount() {
-    int count = 0;
-    synchronized (_connectionManagerPool) {
-      for (ZkConnectionManager manager : _connectionManagerPool.values()) {
-        if (!manager.isClosed()) {
-          count++;
-        }
-      }
-    }
-    return count;
-  }
+@Deprecated
+public class SharedZkClientFactory extends org.apache.helix.zookeeper.impl.factory.SharedZkClientFactory {
 }
diff --git a/helix-core/src/main/java/org/apache/helix/manager/zk/client/ZkConnectionManager.java b/helix-core/src/main/java/org/apache/helix/manager/zk/client/ZkConnectionManager.java
index 0a9ddc1..c3ccfaa 100644
--- a/helix-core/src/main/java/org/apache/helix/manager/zk/client/ZkConnectionManager.java
+++ b/helix-core/src/main/java/org/apache/helix/manager/zk/client/ZkConnectionManager.java
@@ -1,113 +1,53 @@
 package org.apache.helix.manager.zk.client;
 
+/*
+ * 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 java.util.HashSet;
 import java.util.Set;
 
-import org.I0Itec.zkclient.IZkConnection;
-import org.I0Itec.zkclient.serialize.SerializableSerializer;
-import org.apache.helix.HelixException;
-import org.apache.helix.manager.zk.BasicZkSerializer;
-import org.apache.zookeeper.WatchedEvent;
+import org.apache.helix.zookeeper.zkclient.IZkConnection;
 import org.apache.zookeeper.Watcher;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+
 
 /**
- * A ZkConnection manager that maintain connection status and allows additional watchers to be registered.
- * It will forward events to those watchers.
- *
- * TODO Separate connection management logic from the raw ZkClient class.
- * So this manager is a peer to the ZkClient. Connection Manager for maintaining the connection and
- * ZkClient to handle user request.
- * After this is done, Dedicated ZkClient hires one manager for it's connection.
- * While multiple Shared ZkClients can use single connection manager if possible.
+ * Deprecated - use ZkConnectionManager in zookeeper-api instead.
  */
-class ZkConnectionManager extends org.apache.helix.manager.zk.ZkClient {
-  private static Logger LOG = LoggerFactory.getLogger(ZkConnectionManager.class);
-  // Client type that is used in monitor, and metrics.
-  private final static String MONITOR_TYPE = "ZkConnectionManager";
-  private final String _monitorKey;
-  // Set of all registered watchers
-  private final Set<Watcher> _sharedWatchers = new HashSet<>();
-
+@Deprecated
+class ZkConnectionManager extends org.apache.helix.zookeeper.impl.factory.ZkConnectionManager {
   /**
    * Construct and init a ZkConnection Manager.
-   *
-   * @param zkConnection
+   *  @param zkConnection
    * @param connectionTimeout
+   * @param monitorKey
    */
   protected ZkConnectionManager(IZkConnection zkConnection, long connectionTimeout,
       String monitorKey) {
-    super(zkConnection, (int) connectionTimeout, HelixZkClient.DEFAULT_OPERATION_TIMEOUT,
-        new BasicZkSerializer(new SerializableSerializer()), MONITOR_TYPE, monitorKey, null, true);
-    _monitorKey = monitorKey;
-    LOG.info("ZkConnection {} was created for sharing.", _monitorKey);
+    super(zkConnection, connectionTimeout, monitorKey);
   }
 
   /**
-   * Register event watcher.
-   *
-   * @param watcher
-   * @return true if the watcher is newly added. false if it is already in record.
+   * Need to override because of the "instanceof" usage doesn't cover subclasses.
    */
-  protected synchronized boolean registerWatcher(Watcher watcher) {
-    if (isClosed()) {
-      throw new HelixException("Cannot add watcher to a closed client.");
-    }
-    return _sharedWatchers.add(watcher);
-  }
-
-  /**
-   * Unregister the event watcher.
-   *
-   * @param watcher
-   * @return number of the remaining event watchers
-   */
-  protected synchronized int unregisterWatcher(Watcher watcher) {
-    _sharedWatchers.remove(watcher);
-    return _sharedWatchers.size();
-  }
-
   @Override
-  public void process(final WatchedEvent event) {
-    super.process(event);
-    forwardingEvent(event);
-  }
-
-  private synchronized void forwardingEvent(final WatchedEvent event) {
-    // note that process (then forwardingEvent) could be triggered during construction, when sharedWatchers is still null.
-    if (_sharedWatchers == null || _sharedWatchers.isEmpty()) {
-      return;
-    }
-    // forward event to all the watchers' event queue
-    for (final Watcher watcher : _sharedWatchers) {
-      watcher.process(event);
-    }
-  }
-
-  @Override
-  public void close() {
-    // Enforce closing, if any watcher exists, throw Exception.
-    close(false);
-  }
-
-  protected synchronized void close(boolean skipIfWatched) {
-    cleanupInactiveWatchers();
-    if (_sharedWatchers.size() > 0) {
-      if (skipIfWatched) {
-        LOG.debug("Skip closing ZkConnection due to existing watchers. Watcher count {}.",
-            _sharedWatchers.size());
-        return;
-      } else {
-        throw new HelixException(
-            "Cannot close the connection when there are still shared watchers listen on the event.");
-      }
-    }
-    super.close();
-    LOG.info("ZkConnection {} was closed.", _monitorKey);
-  }
-
-  private void cleanupInactiveWatchers() {
+  protected void cleanupInactiveWatchers() {
+    super.cleanupInactiveWatchers();
     Set<Watcher> closedWatchers = new HashSet<>();
     for (Watcher watcher : _sharedWatchers) {
       // TODO ideally, we shall have a ClosableWatcher interface so as to check accordingly. -- JJ
diff --git a/helix-core/src/main/java/org/apache/helix/manager/zk/zookeeper/IZkStateListener.java b/helix-core/src/main/java/org/apache/helix/manager/zk/zookeeper/IZkStateListener.java
index aa1fdd6..32e203d 100644
--- a/helix-core/src/main/java/org/apache/helix/manager/zk/zookeeper/IZkStateListener.java
+++ b/helix-core/src/main/java/org/apache/helix/manager/zk/zookeeper/IZkStateListener.java
@@ -19,43 +19,10 @@ package org.apache.helix.manager.zk.zookeeper;
  * under the License.
  */
 
-import org.apache.zookeeper.Watcher.Event.KeeperState;
-
-
-public interface IZkStateListener {
-
-  /**
-   * Called when the zookeeper connection state has changed.
-   *
-   * @param state the new zookeeper state.
-   * @throws Exception if any error occurs.
-   */
-  void handleStateChanged(KeeperState state) throws Exception;
-
-  /**
-   * Called after the zookeeper session has expired and a new session has been created. The new
-   * session id has to be passed in as the parameter.
-   * And you would have to re-create any ephemeral nodes here. This is a session aware operation.
-   * The ephemeral nodes have to be created within the expected session id, which means passed-in
-   * session id has to be checked with current zookeeper's session id. If the passed-in session id
-   * does not match current zookeeper's session id, ephemeral nodes should not be created.
-   * Otherwise, session race condition may occur and the newly created ephemeral nodes may not be in
-   * the expected session.
-   *
-   * @param sessionId the new session's id. The ephemeral nodes are expected to be created in this
-   *                  session. If this session id is expired, ephemeral nodes should not be created.
-   * @throws Exception if any error occurs.
-   */
-  void handleNewSession(final String sessionId) throws Exception;
+/**
+ * Use IZkStateListener in zookeeper-api module instead.
+ */
+@Deprecated
+public interface IZkStateListener extends org.apache.helix.zookeeper.zkclient.IZkStateListener {
 
-  /**
-   * Called when a session cannot be re-established. This should be used to implement connection
-   * failure handling e.g. retry to connect or pass the error up
-   *
-   * @param error
-   *            The error that prevents a session from being established
-   * @throws Exception
-   *             On any error.
-   */
-  void handleSessionEstablishmentError(final Throwable error) throws Exception;
 }
diff --git a/helix-core/src/main/java/org/apache/helix/manager/zk/zookeeper/ZkClient.java b/helix-core/src/main/java/org/apache/helix/manager/zk/zookeeper/ZkClient.java
index 453c8c3..39e80ba 100644
--- a/helix-core/src/main/java/org/apache/helix/manager/zk/zookeeper/ZkClient.java
+++ b/helix-core/src/main/java/org/apache/helix/manager/zk/zookeeper/ZkClient.java
@@ -10,2154 +10,19 @@
  */
 package org.apache.helix.manager.zk.zookeeper;
 
-import java.lang.reflect.Method;
-import java.util.Arrays;
-import java.util.Date;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.OptionalLong;
-import java.util.Set;
-import java.util.concurrent.Callable;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.CopyOnWriteArraySet;
-import java.util.concurrent.TimeUnit;
-import javax.management.JMException;
-
-import org.I0Itec.zkclient.DataUpdater;
-import org.I0Itec.zkclient.ExceptionUtil;
-import org.I0Itec.zkclient.IZkChildListener;
-import org.I0Itec.zkclient.IZkConnection;
-import org.I0Itec.zkclient.IZkDataListener;
-import org.I0Itec.zkclient.ZkLock;
-import org.I0Itec.zkclient.exception.ZkBadVersionException;
-import org.I0Itec.zkclient.exception.ZkException;
-import org.I0Itec.zkclient.exception.ZkInterruptedException;
-import org.I0Itec.zkclient.exception.ZkNoNodeException;
-import org.I0Itec.zkclient.exception.ZkNodeExistsException;
-import org.I0Itec.zkclient.exception.ZkTimeoutException;
-import org.I0Itec.zkclient.serialize.ZkSerializer;
-import org.apache.helix.HelixException;
-import org.apache.helix.ZNRecord;
-import org.apache.helix.api.listeners.PreFetch;
-import org.apache.helix.manager.zk.BasicZkSerializer;
-import org.apache.helix.manager.zk.PathBasedZkSerializer;
-import org.apache.helix.manager.zk.ZKUtil;
-import org.apache.helix.manager.zk.ZkAsyncCallbacks;
-import org.apache.helix.manager.zk.ZkSessionMismatchedException;
-import org.apache.helix.manager.zk.zookeeper.ZkEventThread.ZkEvent;
-import org.apache.helix.monitoring.mbeans.ZkClientMonitor;
-import org.apache.helix.util.ExponentialBackoffStrategy;
-import org.apache.zookeeper.CreateMode;
-import org.apache.zookeeper.KeeperException;
-import org.apache.zookeeper.KeeperException.ConnectionLossException;
-import org.apache.zookeeper.KeeperException.SessionExpiredException;
-import org.apache.zookeeper.Op;
-import org.apache.zookeeper.OpResult;
-import org.apache.zookeeper.WatchedEvent;
-import org.apache.zookeeper.Watcher;
-import org.apache.zookeeper.Watcher.Event.EventType;
-import org.apache.zookeeper.Watcher.Event.KeeperState;
-import org.apache.zookeeper.ZooDefs;
-import org.apache.zookeeper.ZooKeeper;
-import org.apache.zookeeper.data.ACL;
-import org.apache.zookeeper.data.Stat;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import org.apache.helix.zookeeper.zkclient.IZkConnection;
+import org.apache.helix.zookeeper.zkclient.serialize.PathBasedZkSerializer;
 
 
 /**
- * Abstracts the interaction with zookeeper and allows permanent (not just one time) watches on
- * nodes in ZooKeeper.
- * WARN: Do not use this class directly, use {@link org.apache.helix.manager.zk.ZkClient} instead.
+ * Use ZkClient in zookeeper-api module instead.
  */
-public class ZkClient implements Watcher {
-  private static Logger LOG = LoggerFactory.getLogger(ZkClient.class);
-  private static long MAX_RECONNECT_INTERVAL_MS = 30000; // 30 seconds
-
-  private final IZkConnection _connection;
-  private final long _operationRetryTimeoutInMillis;
-  private final Map<String, Set<IZkChildListener>> _childListener = new ConcurrentHashMap<>();
-  private final ConcurrentHashMap<String, Set<IZkDataListenerEntry>> _dataListener =
-      new ConcurrentHashMap<>();
-  private final Set<IZkStateListener> _stateListener = new CopyOnWriteArraySet<>();
-  private KeeperState _currentState;
-  private final ZkLock _zkEventLock = new ZkLock();
-
-  // When a new zookeeper instance is created in reconnect, its session id is not yet valid before
-  // the zookeeper session is established(SyncConnected). To avoid session race condition in
-  // handling new session, the new session event is only fired after SyncConnected. Meanwhile,
-  // SyncConnected state is also received when re-opening the zk connection. So to avoid firing
-  // new session event more than once, this flag is used to check.
-  // It is set to false right after the new zookeeper instance is created in reconnect before the
-  // session is established. And set it to true once the new session event is fired the first time.
-  private boolean _isNewSessionEventFired;
-
-  private boolean _shutdownTriggered;
-  private ZkEventThread _eventThread;
-  // TODO PVo remove this later
-  private Thread _zookeeperEventThread;
-  private volatile boolean _closed;
-  private PathBasedZkSerializer _pathBasedZkSerializer;
-  private ZkClientMonitor _monitor;
-
-  private class IZkDataListenerEntry {
-    final IZkDataListener _dataListener;
-    final boolean _prefetchData;
-
-    public IZkDataListenerEntry(IZkDataListener dataListener, boolean prefetchData) {
-      _dataListener = dataListener;
-      _prefetchData = prefetchData;
-    }
-
-    public IZkDataListenerEntry(IZkDataListener dataListener) {
-      _dataListener = dataListener;
-      _prefetchData = false;
-    }
-
-    public IZkDataListener getDataListener() {
-      return _dataListener;
-    }
-
-    public boolean isPrefetchData() {
-      return _prefetchData;
-    }
-
-    @Override
-    public boolean equals(Object o) {
-      if (this == o) {
-        return true;
-      }
-      if (!(o instanceof IZkDataListenerEntry)) {
-        return false;
-      }
-
-      IZkDataListenerEntry that = (IZkDataListenerEntry) o;
-
-      return _dataListener.equals(that._dataListener);
-    }
-
-    @Override
-    public int hashCode() {
-      return _dataListener.hashCode();
-    }
-  }
-
-  private class ZkPathStatRecord {
-    private final String _path;
-    private Stat _stat = null;
-    private boolean _checked = false;
-
-    public ZkPathStatRecord(String path) {
-      _path = path;
-    }
-
-    public boolean pathExists() {
-      return _stat != null;
-    }
-
-    public boolean pathChecked() {
-      return _checked;
-    }
-
-    /*
-     * Note this method is not thread safe.
-     */
-    public void recordPathStat(Stat stat, OptionalLong notificationTime) {
-      _checked = true;
-      _stat = stat;
-
-      if (_monitor != null && stat != null && notificationTime.isPresent()) {
-        long updateTime = Math.max(stat.getCtime(), stat.getMtime());
-        if (notificationTime.getAsLong() > updateTime) {
-          _monitor.recordDataPropagationLatency(_path, notificationTime.getAsLong() - updateTime);
-        } // else, the node was updated again after the notification. Propagation latency is
-          // unavailable.
-      }
-    }
-  }
-
+@Deprecated
+public class ZkClient extends org.apache.helix.zookeeper.zkclient.ZkClient {
   protected ZkClient(IZkConnection zkConnection, int connectionTimeout, long operationRetryTimeout,
       PathBasedZkSerializer zkSerializer, String monitorType, String monitorKey,
       String monitorInstanceName, boolean monitorRootPathOnly) {
-    if (zkConnection == null) {
-      throw new NullPointerException("Zookeeper connection is null!");
-    }
-    _connection = zkConnection;
-    _pathBasedZkSerializer = zkSerializer;
-    _operationRetryTimeoutInMillis = operationRetryTimeout;
-    _isNewSessionEventFired = false;
-
-    connect(connectionTimeout, this);
-
-    // initiate monitor
-    try {
-      if (monitorKey != null && !monitorKey.isEmpty() && monitorType != null
-          && !monitorType.isEmpty()) {
-        _monitor = new ZkClientMonitor(monitorType, monitorKey, monitorInstanceName,
-            monitorRootPathOnly, _eventThread);
-        _monitor.register();
-      } else {
-        LOG.info("ZkClient monitor key or type is not provided. Skip monitoring.");
-      }
-    } catch (JMException e) {
-      LOG.error("Error in creating ZkClientMonitor", e);
-    }
-  }
-
-  public List<String> subscribeChildChanges(String path, IZkChildListener listener) {
-    synchronized (_childListener) {
-      Set<IZkChildListener> listeners = _childListener.get(path);
-      if (listeners == null) {
-        listeners = new CopyOnWriteArraySet<>();
-        _childListener.put(path, listeners);
-      }
-      listeners.add(listener);
-    }
-    return watchForChilds(path);
-  }
-
-  public void unsubscribeChildChanges(String path, IZkChildListener childListener) {
-    synchronized (_childListener) {
-      final Set<IZkChildListener> listeners = _childListener.get(path);
-      if (listeners != null) {
-        listeners.remove(childListener);
-      }
-    }
-  }
-
-  /**
-   * Subscribe the path and the listener will handle data events of the path
-   * WARNING: if the path is created after deletion, users need to re-subscribe the path
-   * @param path The zookeeper path
-   * @param listener Instance of {@link IZkDataListener}
-   */
-  public void subscribeDataChanges(String path, IZkDataListener listener) {
-    Set<IZkDataListenerEntry> listenerEntries;
-    synchronized (_dataListener) {
-      listenerEntries = _dataListener.get(path);
-      if (listenerEntries == null) {
-        listenerEntries = new CopyOnWriteArraySet<>();
-        _dataListener.put(path, listenerEntries);
-      }
-
-      boolean prefetchEnabled = isPrefetchEnabled(listener);
-      IZkDataListenerEntry listenerEntry = new IZkDataListenerEntry(listener, prefetchEnabled);
-      listenerEntries.add(listenerEntry);
-      if (prefetchEnabled) {
-        if (LOG.isDebugEnabled()) {
-          LOG.debug("Subscribed data changes for " + path + ", listener: " + listener
-              + ", prefetch data: " + prefetchEnabled);
-        }
-      }
-    }
-    watchForData(path);
-    if (LOG.isDebugEnabled()) {
-      LOG.debug("Subscribed data changes for " + path);
-    }
-  }
-
-  private boolean isPrefetchEnabled(IZkDataListener dataListener) {
-    PreFetch preFetch = dataListener.getClass().getAnnotation(PreFetch.class);
-    if (preFetch != null) {
-      return preFetch.enabled();
-    }
-
-    Method callbackMethod = IZkDataListener.class.getMethods()[0];
-    try {
-      Method method = dataListener.getClass().getMethod(callbackMethod.getName(),
-          callbackMethod.getParameterTypes());
-      PreFetch preFetchInMethod = method.getAnnotation(PreFetch.class);
-      if (preFetchInMethod != null) {
-        return preFetchInMethod.enabled();
-      }
-    } catch (NoSuchMethodException e) {
-      LOG.warn("No method " + callbackMethod.getName() + " defined in listener "
-          + dataListener.getClass().getCanonicalName());
-    }
-
-    return true;
-  }
-
-  public void unsubscribeDataChanges(String path, IZkDataListener dataListener) {
-    synchronized (_dataListener) {
-      final Set<IZkDataListenerEntry> listeners = _dataListener.get(path);
-      if (listeners != null) {
-        IZkDataListenerEntry listenerEntry = new IZkDataListenerEntry(dataListener);
-        listeners.remove(listenerEntry);
-      }
-      if (listeners == null || listeners.isEmpty()) {
-        _dataListener.remove(path);
-      }
-    }
-  }
-
-  public void subscribeStateChanges(final IZkStateListener listener) {
-    synchronized (_stateListener) {
-      _stateListener.add(listener);
-    }
-  }
-
-  /**
-   * Subscribes state changes for a {@link org.I0Itec.zkclient.IZkStateListener} listener.
-   *
-   * @deprecated
-   * This is deprecated. It is kept for backwards compatibility. Please use
-   * {@link #subscribeStateChanges(IZkStateListener)}.
-   *
-   * @param listener {@link org.I0Itec.zkclient.IZkStateListener} listener
-   */
-  @Deprecated
-  public void subscribeStateChanges(final org.I0Itec.zkclient.IZkStateListener listener) {
-    subscribeStateChanges(new IZkStateListenerI0ItecImpl(listener));
-  }
-
-  public void unsubscribeStateChanges(IZkStateListener stateListener) {
-    synchronized (_stateListener) {
-      _stateListener.remove(stateListener);
-    }
-  }
-
-  /**
-   * Unsubscribes state changes for a {@link org.I0Itec.zkclient.IZkStateListener} listener.
-   *
-   * @deprecated
-   * This is deprecated. It is kept for backwards compatibility. Please use
-   * {@link #unsubscribeStateChanges(IZkStateListener)}.
-   *
-   * @param stateListener {@link org.I0Itec.zkclient.IZkStateListener} listener
-   */
-  @Deprecated
-  public void unsubscribeStateChanges(org.I0Itec.zkclient.IZkStateListener stateListener) {
-    unsubscribeStateChanges(new IZkStateListenerI0ItecImpl(stateListener));
-  }
-
-  public void unsubscribeAll() {
-    synchronized (_childListener) {
-      _childListener.clear();
-    }
-    synchronized (_dataListener) {
-      _dataListener.clear();
-    }
-    synchronized (_stateListener) {
-      _stateListener.clear();
-    }
-  }
-
-  // </listeners>
-
-  /**
-   * Create a persistent node.
-   * @param path
-   * @throws ZkInterruptedException
-   *           if operation was interrupted, or a required reconnection got interrupted
-   * @throws IllegalArgumentException
-   *           if called from anything except the ZooKeeper event thread
-   * @throws ZkException
-   *           if any ZooKeeper exception occurred
-   * @throws RuntimeException
-   *           if any other exception occurs
-   */
-  public void createPersistent(String path)
-      throws ZkInterruptedException, IllegalArgumentException, ZkException, RuntimeException {
-    createPersistent(path, false);
-  }
-
-  /**
-   * Create a persistent node and set its ACLs.
-   * @param path
-   * @param createParents
-   *          if true all parent dirs are created as well and no {@link ZkNodeExistsException} is
-   *          thrown in case the
-   *          path already exists
-   * @throws ZkInterruptedException
-   *           if operation was interrupted, or a required reconnection got interrupted
-   * @throws IllegalArgumentException
-   *           if called from anything except the ZooKeeper event thread
-   * @throws ZkException
-   *           if any ZooKeeper exception occurred
-   * @throws RuntimeException
-   *           if any other exception occurs
-   */
-  public void createPersistent(String path, boolean createParents)
-      throws ZkInterruptedException, IllegalArgumentException, ZkException, RuntimeException {
-    createPersistent(path, createParents, ZooDefs.Ids.OPEN_ACL_UNSAFE);
-  }
-
-  /**
-   * Create a persistent node and set its ACLs.
-   * @param path
-   * @param acl
-   *          List of ACL permissions to assign to the node
-   * @param createParents
-   *          if true all parent dirs are created as well and no {@link ZkNodeExistsException} is
-   *          thrown in case the
-   *          path already exists
-   * @throws ZkInterruptedException
-   *           if operation was interrupted, or a required reconnection got interrupted
-   * @throws IllegalArgumentException
-   *           if called from anything except the ZooKeeper event thread
-   * @throws ZkException
-   *           if any ZooKeeper exception occurred
-   * @throws RuntimeException
-   *           if any other exception occurs
-   */
-  public void createPersistent(String path, boolean createParents, List<ACL> acl)
-      throws ZkInterruptedException, IllegalArgumentException, ZkException, RuntimeException {
-    try {
-      create(path, null, acl, CreateMode.PERSISTENT);
-    } catch (ZkNodeExistsException e) {
-      if (!createParents) {
-        throw e;
-      }
-    } catch (ZkNoNodeException e) {
-      if (!createParents) {
-        throw e;
-      }
-      String parentDir = path.substring(0, path.lastIndexOf('/'));
-      createPersistent(parentDir, createParents, acl);
-      createPersistent(path, createParents, acl);
-    }
-  }
-
-  /**
-   * Create a persistent node.
-   * @param path
-   * @param data
-   * @throws ZkInterruptedException
-   *           if operation was interrupted, or a required reconnection got interrupted
-   * @throws IllegalArgumentException
-   *           if called from anything except the ZooKeeper event thread
-   * @throws ZkException
-   *           if any ZooKeeper exception occurred
-   * @throws RuntimeException
-   *           if any other exception occurs
-   */
-  public void createPersistent(String path, Object data)
-      throws ZkInterruptedException, IllegalArgumentException, ZkException, RuntimeException {
-    create(path, data, CreateMode.PERSISTENT);
-  }
-
-  /**
-   * Create a persistent node.
-   * @param path
-   * @param data
-   * @param acl
-   * @throws ZkInterruptedException
-   *           if operation was interrupted, or a required reconnection got interrupted
-   * @throws IllegalArgumentException
-   *           if called from anything except the ZooKeeper event thread
-   * @throws ZkException
-   *           if any ZooKeeper exception occurred
-   * @throws RuntimeException
-   *           if any other exception occurs
-   */
-  public void createPersistent(String path, Object data, List<ACL> acl) {
-    create(path, data, acl, CreateMode.PERSISTENT);
-  }
-
-  /**
-   * Create a persistent, sequental node.
-   * @param path
-   * @param data
-   * @return create node's path
-   * @throws ZkInterruptedException
-   *           if operation was interrupted, or a required reconnection got interrupted
-   * @throws IllegalArgumentException
-   *           if called from anything except the ZooKeeper event thread
-   * @throws ZkException
-   *           if any ZooKeeper exception occurred
-   * @throws RuntimeException
-   *           if any other exception occurs
-   */
-  public String createPersistentSequential(String path, Object data)
-      throws ZkInterruptedException, IllegalArgumentException, ZkException, RuntimeException {
-    return create(path, data, CreateMode.PERSISTENT_SEQUENTIAL);
-  }
-
-  /**
-   * Create a persistent, sequential node and set its ACL.
-   * @param path
-   * @param acl
-   * @param data
-   * @return create node's path
-   * @throws ZkInterruptedException
-   *           if operation was interrupted, or a required reconnection got interrupted
-   * @throws IllegalArgumentException
-   *           if called from anything except the ZooKeeper event thread
-   * @throws ZkException
-   *           if any ZooKeeper exception occurred
-   * @throws RuntimeException
-   *           if any other exception occurs
-   */
-  public String createPersistentSequential(String path, Object data, List<ACL> acl)
-      throws ZkInterruptedException, IllegalArgumentException, ZkException, RuntimeException {
-    return create(path, data, acl, CreateMode.PERSISTENT_SEQUENTIAL);
-  }
-
-  /**
-   * Create an ephemeral node.
-   * @param path
-   * @throws ZkInterruptedException
-   *           if operation was interrupted, or a required reconnection got interrupted
-   * @throws IllegalArgumentException
-   *           if called from anything except the ZooKeeper event thread
-   * @throws ZkException
-   *           if any ZooKeeper exception occurred
-   * @throws RuntimeException
-   *           if any other exception occurs
-   */
-  public void createEphemeral(final String path)
-      throws ZkInterruptedException, IllegalArgumentException, ZkException, RuntimeException {
-    create(path, null, CreateMode.EPHEMERAL);
-  }
-
-  /**
-   * Creates an ephemeral node. This ephemeral node is created by the expected(passed-in) ZK session.
-   * If the expected session does not match the current ZK session, the node will not be created.
-   *
-   * @param path path of the node
-   * @param sessionId expected session id of the ZK connection. If the session id of current ZK
-   *                  connection does not match the expected session id, ephemeral creation will
-   *                  fail
-   * @throws ZkInterruptedException
-   *           if operation was interrupted, or a required reconnection got interrupted
-   * @throws IllegalArgumentException
-   *           if called from anything except the ZooKeeper event thread
-   * @throws ZkException
-   *           if any ZooKeeper exception occurred
-   * @throws RuntimeException
-   *           if any other exception occurs
-   */
-  public void createEphemeral(final String path, final String sessionId)
-      throws ZkInterruptedException, IllegalArgumentException, ZkException, RuntimeException {
-    createEphemeral(path, null, sessionId);
-  }
-
-  /**
-   * Create an ephemeral node and set its ACL.
-   * @param path
-   * @param acl
-   * @throws ZkInterruptedException
-   *           if operation was interrupted, or a required reconnection got interrupted
-   * @throws IllegalArgumentException
-   *           if called from anything except the ZooKeeper event thread
-   * @throws ZkException
-   *           if any ZooKeeper exception occurred
-   * @throws RuntimeException
-   *           if any other exception occurs
-   */
-  public void createEphemeral(final String path, final List<ACL> acl)
-      throws ZkInterruptedException, IllegalArgumentException, ZkException, RuntimeException {
-    create(path, null, acl, CreateMode.EPHEMERAL);
-  }
-
-  /**
-   * Creates an ephemeral node and set its ACL. This ephemeral node is created by the
-   * expected(passed-in) ZK session. If the expected session does not match the current ZK session,
-   * the node will not be created.
-   *
-   * @param path path of the ephemeral node
-   * @param acl a list of ACL for the ephemeral node.
-   * @param sessionId expected session id of the ZK connection. If the session id of current ZK
-   *                  connection does not match the expected session id, ephemeral creation will
-   *                  fail.
-   * @throws ZkInterruptedException
-   *           if operation was interrupted, or a required reconnection got interrupted
-   * @throws IllegalArgumentException
-   *           if called from anything except the ZooKeeper event thread
-   * @throws ZkException
-   *           if any ZooKeeper exception occurred
-   * @throws RuntimeException
-   *           if any other exception occurs
-   */
-  public void createEphemeral(final String path, final List<ACL> acl, final String sessionId)
-      throws ZkInterruptedException, IllegalArgumentException, ZkException, RuntimeException {
-    create(path, null, acl, CreateMode.EPHEMERAL, sessionId);
-  }
-
-  /**
-   * Create a node.
-   * @param path
-   * @param data
-   * @param mode
-   * @return create node's path
-   * @throws ZkInterruptedException
-   *           if operation was interrupted, or a required reconnection got interrupted
-   * @throws IllegalArgumentException
-   *           if called from anything except the ZooKeeper event thread
-   * @throws ZkException
-   *           if any ZooKeeper exception occurred
-   * @throws RuntimeException
-   *           if any other exception occurs
-   */
-  public String create(final String path, Object data, final CreateMode mode)
-      throws ZkInterruptedException, IllegalArgumentException, ZkException, RuntimeException {
-    return create(path, data, ZooDefs.Ids.OPEN_ACL_UNSAFE, mode);
-  }
-
-  /**
-   * Create a node with ACL.
-   * @param path
-   * @param datat
-   * @param acl
-   * @param mode
-   * @return create node's path
-   * @throws ZkInterruptedException
-   *           if operation was interrupted, or a required reconnection got interrupted
-   * @throws IllegalArgumentException
-   *           if called from anything except the ZooKeeper event thread
-   * @throws ZkException
-   *           if any ZooKeeper exception occurred
-   * @throws RuntimeException
-   *           if any other exception occurs
-   */
-  public String create(final String path, Object datat, final List<ACL> acl, final CreateMode mode)
-      throws IllegalArgumentException, ZkException {
-    return create(path, datat, acl, mode, null);
-  }
-
-  /**
-   * Creates a node and returns the actual path of the created node.
-   *
-   * Given an expected non-null session id, if the node is successfully created, it is guaranteed to
-   * be created in the expected(passed-in) session.
-   *
-   * If the expected session is expired, which means the expected session does not match the current
-   * session of ZK connection, the node will not be created.
-   *
-   * @param path the path where you want the node to be created
-   * @param dataObject data of the node
-   * @param acl list of ACL for the node
-   * @param mode {@link CreateMode} of the node
-   * @param expectedSessionId the expected session ID of the ZK connection. It is not necessarily the
-   *                  session ID of current ZK Connection. If the expected session ID is NOT null,
-   *                  the node is guaranteed to be created in the expected session, or creation is
-   *                  failed if the expected session id doesn't match current connected zk session.
-   *                  If the session id is null, it means the create operation is NOT session aware.
-   * @return path of the node created
-   * @throws IllegalArgumentException if called from anything else except the ZooKeeper event thread
-   * @throws ZkException if any zookeeper exception occurs
-   */
-  private String create(final String path, final Object dataObject, final List<ACL> acl,
-      final CreateMode mode, final String expectedSessionId)
-      throws IllegalArgumentException, ZkException {
-    if (path == null) {
-      throw new NullPointerException("Path must not be null.");
-    }
-    if (acl == null || acl.size() == 0) {
-      throw new NullPointerException("Missing value for ACL");
-    }
-    long startT = System.currentTimeMillis();
-    try {
-      final byte[] dataBytes = dataObject == null ? null : serialize(dataObject, path);
-      checkDataSizeLimit(dataBytes);
-
-      final String actualPath = retryUntilConnected(() -> {
-        ZooKeeper zooKeeper = ((ZkConnection) getConnection()).getZookeeper();
-
-        /*
-         * 1. If operation is session aware, we have to check whether or not the
-         * passed-in(expected) session id matches actual session's id.
-         * If not, ephemeral node creation is failed. This validation is
-         * critical to guarantee the ephemeral node created by the expected ZK session.
-         *
-         * 2. Otherwise, the operation is NOT session aware.
-         * In this case, we will use the actual zookeeper session to create the node.
-         */
-        if (isSessionAwareOperation(expectedSessionId, mode)) {
-          acquireEventLock();
-          try {
-            final String actualSessionId = ZKUtil.toHexSessionId(zooKeeper.getSessionId());
-            if (!actualSessionId.equals(expectedSessionId)) {
-              throw new ZkSessionMismatchedException(
-                  "Failed to create ephemeral node! There is a session id mismatch. Expected: "
-                      + expectedSessionId + ". Actual: " + actualSessionId);
-            }
-
-            /*
-             * Cache the zookeeper reference and make sure later zooKeeper.create() is being run
-             * under this zookeeper connection. This is to avoid locking zooKeeper.create() which
-             * may cause potential performance issue.
-             */
-            zooKeeper = ((ZkConnection) getConnection()).getZookeeper();
-          } finally {
-            getEventLock().unlock();
-          }
-        }
-
-        return zooKeeper.create(path, dataBytes, acl, mode);
-      });
-
-      record(path, dataBytes, startT, ZkClientMonitor.AccessType.WRITE);
-      return actualPath;
-    } catch (Exception e) {
-      recordFailure(path, ZkClientMonitor.AccessType.WRITE);
-      throw e;
-    } finally {
-      long endT = System.currentTimeMillis();
-      if (LOG.isTraceEnabled()) {
-        LOG.trace("create, path: " + path + ", time: " + (endT - startT) + " ms");
-      }
-    }
-  }
-
-  /**
-   * Create an ephemeral node.
-   * @param path
-   * @param data
-   * @throws ZkInterruptedException
-   *           if operation was interrupted, or a required reconnection got interrupted
-   * @throws IllegalArgumentException
-   *           if called from anything except the ZooKeeper event thread
-   * @throws ZkException
-   *           if any ZooKeeper exception occurred
-   * @throws RuntimeException
-   *           if any other exception occurs
-   */
-  public void createEphemeral(final String path, final Object data)
-      throws ZkInterruptedException, IllegalArgumentException, ZkException, RuntimeException {
-    create(path, data, CreateMode.EPHEMERAL);
-  }
-
-  /**
-   * Creates an ephemeral node. Given an expected non-null session id, if the ephemeral
-   * node is successfully created, it is guaranteed to be in the expected(passed-in) session.
-   *
-   * If the expected session is expired, which means the expected session does not match the session
-   * of current ZK connection, the ephemeral node will not be created.
-   * If connection is timed out or interrupted, exception is thrown.
-   *
-   * @param path path of the ephemeral node being created
-   * @param data data of the ephemeral node being created
-   * @param sessionId the expected session ID of the ZK connection. It is not necessarily the
-   *                  session ID of current ZK Connection. If the expected session ID is NOT null,
-   *                  the node is guaranteed to be created in the expected session, or creation is
-   *                  failed if the expected session id doesn't match current connected zk session.
-   *                  If the session id is null, it means the operation is NOT session aware
-   *                  and the node will be created by current ZK session.
-   * @throws ZkInterruptedException if operation is interrupted, or a required reconnection gets
-   *         interrupted
-   * @throws IllegalArgumentException if called from anything except the ZooKeeper event thread
-   * @throws ZkException if any ZooKeeper exception occurs
-   * @throws RuntimeException if any other exception occurs
-   */
-  public void createEphemeral(final String path, final Object data, final String sessionId)
-      throws ZkInterruptedException, IllegalArgumentException, ZkException, RuntimeException {
-    create(path, data, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL, sessionId);
-  }
-
-  /**
-   * Create an ephemeral node.
-   * @param path
-   * @param data
-   * @param acl
-   * @throws ZkInterruptedException
-   *           if operation was interrupted, or a required reconnection got interrupted
-   * @throws IllegalArgumentException
-   *           if called from anything except the ZooKeeper event thread
-   * @throws ZkException
-   *           if any ZooKeeper exception occurred
-   * @throws RuntimeException
-   *           if any other exception occurs
-   */
-  public void createEphemeral(final String path, final Object data, final List<ACL> acl)
-      throws ZkInterruptedException, IllegalArgumentException, ZkException, RuntimeException {
-    create(path, data, acl, CreateMode.EPHEMERAL);
-  }
-
-  /**
-   * Creates an ephemeral node in an expected ZK session. Given an expected non-null session id,
-   * if the ephemeral node is successfully created, it is guaranteed to be in the expected session.
-   * If the expected session is expired, which means the expected session does not match the session
-   * of current ZK connection, the ephemeral node will not be created.
-   * If connection is timed out or interrupted, exception is thrown.
-   *
-   * @param path path of the ephemeral node being created
-   * @param data data of the ephemeral node being created
-   * @param acl list of ACL for the ephemeral node
-   * @param sessionId the expected session ID of the ZK connection. It is not necessarily the
-   *                  session ID of current ZK Connection. If the expected session ID is NOT null,
-   *                  the node is guaranteed to be created in the expected session, or creation is
-   *                  failed if the expected session id doesn't match current connected zk session.
-   *                  If the session id is null, it means the create operation is NOT session aware
-   *                  and the node will be created by current ZK session.
-   * @throws ZkInterruptedException
-   *           if operation was interrupted, or a required reconnection got interrupted
-   * @throws IllegalArgumentException
-   *           if called from anything except the ZooKeeper event thread
-   * @throws ZkException
-   *           if any ZooKeeper exception occurred
-   * @throws RuntimeException
-   *           if any other exception occurs
-   */
-  public void createEphemeral(final String path, final Object data, final List<ACL> acl,
-      final String sessionId)
-      throws ZkInterruptedException, IllegalArgumentException, ZkException, RuntimeException {
-    create(path, data, acl, CreateMode.EPHEMERAL, sessionId);
-  }
-
-  /**
-   * Create an ephemeral, sequential node.
-   * @param path
-   * @param data
-   * @return created path
-   * @throws ZkInterruptedException
-   *           if operation was interrupted, or a required reconnection got interrupted
-   * @throws IllegalArgumentException
-   *           if called from anything except the ZooKeeper event thread
-   * @throws ZkException
-   *           if any ZooKeeper exception occurred
-   * @throws RuntimeException
-   *           if any other exception occurs
-   */
-  public String createEphemeralSequential(final String path, final Object data)
-      throws ZkInterruptedException, IllegalArgumentException, ZkException, RuntimeException {
-    return create(path, data, CreateMode.EPHEMERAL_SEQUENTIAL);
-  }
-
-  /**
-   * Creates an ephemeral, sequential node with ACL in an expected ZK session.
-   * Given an expected non-null session id, if the ephemeral node is successfully created,
-   * it is guaranteed to be in the expected session.
-   * If the expected session is expired, which means the expected session does not match the session
-   * of current ZK connection, the ephemeral node will not be created.
-   * If connection is timed out or interrupted, exception is thrown.
-   *
-   * @param path path of the node
-   * @param data data of the node
-   * @param acl list of ACL for the node
-   * @return created path
-   * @throws ZkInterruptedException
-   *           if operation was interrupted, or a required reconnection got interrupted
-   * @throws IllegalArgumentException
-   *           if called from anything except the ZooKeeper event thread
-   * @throws ZkException
-   *           if any ZooKeeper exception occurred
-   * @throws RuntimeException
-   *           if any other exception occurs
-   */
-  public String createEphemeralSequential(final String path, final Object data, final List<ACL> acl,
-      final String sessionId)
-      throws ZkInterruptedException, IllegalArgumentException, ZkException, RuntimeException {
-    return create(path, data, acl, CreateMode.EPHEMERAL_SEQUENTIAL, sessionId);
-  }
-
-  /**
-   * Creates an ephemeral, sequential node. Given an expected non-null session id,
-   * if the ephemeral node is successfully created, it is guaranteed to be in the expected session.
-   * If the expected session is expired, which means the expected session does not match the session
-   * of current ZK connection, the ephemeral node will not be created.
-   * If connection is timed out or interrupted, exception is thrown.
-   *
-   * @param path path of the node
-   * @param data data of the node
-   * @param sessionId the expected session ID of the ZK connection. It is not necessarily the
-   *                  session ID of current ZK Connection. If the expected session ID is NOT null,
-   *                  the node is guaranteed to be created in the expected session, or creation is
-   *                  failed if the expected session id doesn't match current connected zk session.
-   *                  If the session id is null, it means the create operation is NOT session aware
-   *                  and the node will be created by current ZK session.
-   * @return created path
-   * @throws ZkInterruptedException
-   *           if operation was interrupted, or a required reconnection got interrupted
-   * @throws IllegalArgumentException
-   *           if called from anything except the ZooKeeper event thread
-   * @throws ZkException
-   *           if any ZooKeeper exception occurred
-   * @throws RuntimeException
-   *           if any other exception occurs
-   */
-  public String createEphemeralSequential(final String path, final Object data,
-      final String sessionId)
-      throws ZkInterruptedException, IllegalArgumentException, ZkException, RuntimeException {
-    return create(path, data, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL,
-        sessionId);
-  }
-
-  /**
-   * Create an ephemeral, sequential node with ACL.
-   * @param path
-   * @param data
-   * @param acl
-   * @return created path
-   * @throws ZkInterruptedException
-   *           if operation was interrupted, or a required reconnection got interrupted
-   * @throws IllegalArgumentException
-   *           if called from anything except the ZooKeeper event thread
-   * @throws ZkException
-   *           if any ZooKeeper exception occurred
-   * @throws RuntimeException
-   *           if any other exception occurs
-   */
-  public String createEphemeralSequential(final String path, final Object data, final List<ACL> acl)
-      throws ZkInterruptedException, IllegalArgumentException, ZkException, RuntimeException {
-    return create(path, data, acl, CreateMode.EPHEMERAL_SEQUENTIAL);
-  }
-
-  @Override
-  public void process(WatchedEvent event) {
-    long notificationTime = System.currentTimeMillis();
-    if (LOG.isDebugEnabled()) {
-      LOG.debug("Received event: " + event);
-    }
-    _zookeeperEventThread = Thread.currentThread();
-
-    boolean stateChanged = event.getPath() == null;
-    boolean znodeChanged = event.getPath() != null;
-    boolean dataChanged = event.getType() == Event.EventType.NodeDataChanged
-        || event.getType() == Event.EventType.NodeDeleted
-        || event.getType() == Event.EventType.NodeCreated
-        || event.getType() == Event.EventType.NodeChildrenChanged;
-    if (event.getType() == EventType.NodeDeleted) {
-      LOG.debug("Path {} is deleted", event.getPath());
-    }
-
-    getEventLock().lock();
-    try {
-      // We might have to install child change event listener if a new node was created
-      if (getShutdownTrigger()) {
-        if (LOG.isDebugEnabled()) {
-          LOG.debug("ignoring event '{" + event.getType() + " | " + event.getPath()
-              + "}' since shutdown triggered");
-        }
-        return;
-      }
-      if (stateChanged) {
-        processStateChanged(event);
-      }
-      if (dataChanged) {
-        processDataOrChildChange(event, notificationTime);
-      }
-    } finally {
-      if (stateChanged) {
-        getEventLock().getStateChangedCondition().signalAll();
-
-        // If the session expired we have to signal all conditions, because watches might have been
-        // removed and
-        // there is no guarantee that those
-        // conditions will be signaled at all after an Expired event
-        // TODO PVo write a test for this
-        if (event.getState() == KeeperState.Expired) {
-          getEventLock().getZNodeEventCondition().signalAll();
-          getEventLock().getDataChangedCondition().signalAll();
-        }
-      }
-      if (znodeChanged) {
-        getEventLock().getZNodeEventCondition().signalAll();
-      }
-      if (dataChanged) {
-        getEventLock().getDataChangedCondition().signalAll();
-      }
-      getEventLock().unlock();
-
-      // update state change counter.
-      recordStateChange(stateChanged, dataChanged);
-
-      if (LOG.isDebugEnabled()) {
-        LOG.debug("Leaving process event");
-      }
-    }
-  }
-
-  private void fireAllEvents() {
-    //TODO: During handling new session, if the path is deleted, watcher leakage could still happen
-    for (Entry<String, Set<IZkChildListener>> entry : _childListener.entrySet()) {
-      fireChildChangedEvents(entry.getKey(), entry.getValue(), true);
-    }
-    for (Entry<String, Set<IZkDataListenerEntry>> entry : _dataListener.entrySet()) {
-      fireDataChangedEvents(entry.getKey(), entry.getValue(), OptionalLong.empty(), true);
-    }
-  }
-
-  public List<String> getChildren(String path) {
-    return getChildren(path, hasListeners(path));
-  }
-
-  protected List<String> getChildren(final String path, final boolean watch) {
-    long startT = System.currentTimeMillis();
-    try {
-      List<String> children = retryUntilConnected(new Callable<List<String>>() {
-        @Override
-        public List<String> call() throws Exception {
-          return getConnection().getChildren(path, watch);
-        }
-      });
-      record(path, null, startT, ZkClientMonitor.AccessType.READ);
-      return children;
-    } catch (ZkNoNodeException e) {
-      record(path, null, startT, ZkClientMonitor.AccessType.READ);
-      throw e;
-    } catch (Exception e) {
-      recordFailure(path, ZkClientMonitor.AccessType.READ);
-      throw e;
-    } finally {
-      long endT = System.currentTimeMillis();
-      if (LOG.isTraceEnabled()) {
-        LOG.trace("getChildren, path: " + path + ", time: " + (endT - startT) + " ms");
-      }
-    }
-  }
-
-  /**
-   * Counts number of children for the given path.
-   * @param path
-   * @return number of children or 0 if path does not exist.
-   */
-  public int countChildren(String path) {
-    try {
-      return getChildren(path).size();
-    } catch (ZkNoNodeException e) {
-      return 0;
-    }
-  }
-
-  public boolean exists(final String path) {
-    return exists(path, hasListeners(path));
-  }
-
-  protected boolean exists(final String path, final boolean watch) {
-    long startT = System.currentTimeMillis();
-    try {
-      boolean exists = retryUntilConnected(new Callable<Boolean>() {
-        @Override
-        public Boolean call() throws Exception {
-          return getConnection().exists(path, watch);
-        }
-      });
-      record(path, null, startT, ZkClientMonitor.AccessType.READ);
-      return exists;
-    } catch (ZkNoNodeException e) {
-      record(path, null, startT, ZkClientMonitor.AccessType.READ);
-      throw e;
-    } catch (Exception e) {
-      recordFailure(path, ZkClientMonitor.AccessType.READ);
-      throw e;
-    } finally {
-      long endT = System.currentTimeMillis();
-      if (LOG.isTraceEnabled()) {
-        LOG.trace("exists, path: " + path + ", time: " + (endT - startT) + " ms");
-      }
-    }
-  }
-
-  public Stat getStat(final String path) {
-    return getStat(path, false);
-  }
-
-  private Stat getStat(final String path, final boolean watch) {
-    long startT = System.currentTimeMillis();
-    try {
-      Stat stat = retryUntilConnected(
-          () -> ((ZkConnection) getConnection()).getZookeeper().exists(path, watch));
-      record(path, null, startT, ZkClientMonitor.AccessType.READ);
-      return stat;
-    } catch (ZkNoNodeException e) {
-      record(path, null, startT, ZkClientMonitor.AccessType.READ);
-      throw e;
-    } catch (Exception e) {
-      recordFailure(path, ZkClientMonitor.AccessType.READ);
-      throw e;
-    } finally {
-      long endT = System.currentTimeMillis();
-      if (LOG.isTraceEnabled()) {
-        LOG.trace("exists, path: " + path + ", time: " + (endT - startT) + " ms");
-      }
-    }
-  }
-
-  protected void processStateChanged(WatchedEvent event) {
-    LOG.info("zookeeper state changed (" + event.getState() + ")");
-    setCurrentState(event.getState());
-    if (getShutdownTrigger()) {
-      return;
-    }
-
-    fireStateChangedEvent(event.getState());
-
-    if (!isManagingZkConnection()) {
-      return;
-    }
-
-    if (event.getState() == KeeperState.SyncConnected) {
-      if (!_isNewSessionEventFired && !"0".equals(getHexSessionId())) {
-        /*
-         * Before the new zookeeper instance is connected to the zookeeper service and its session
-         * is established, its session id is 0.
-         * New session event is not fired until the new zookeeper session receives the first
-         * SyncConnected state(the zookeeper session is established).
-         * Now the session id is available and non-zero, and we can fire new session events.
-         */
-        fireNewSessionEvents();
-        /*
-         * Set it true to avoid firing events again for the same session next time
-         * when SyncConnected events are received.
-         */
-        _isNewSessionEventFired = true;
-
-        /*
-         * With this first SyncConnected state, we just get connected to zookeeper service after
-         * reconnecting when the session expired. Because previous session expired, we also have to
-         * notify all listeners that something might have changed.
-         */
-        fireAllEvents();
-      }
-    } else if (event.getState() == KeeperState.Expired) {
-      reconnectOnExpiring();
-    }
-  }
-
-  private void reconnectOnExpiring() {
-    int retryCount = 0;
-    ExponentialBackoffStrategy retryStrategy =
-        new ExponentialBackoffStrategy(MAX_RECONNECT_INTERVAL_MS, true);
-
-    Exception reconnectException = new ZkException("Shutdown triggered.");
-    while (!isClosed()) {
-      try {
-        reconnect();
-        return;
-      } catch (ZkInterruptedException interrupt) {
-        reconnectException = interrupt;
-        break;
-      } catch (Exception e) {
-        reconnectException = e;
-        long waitInterval = retryStrategy.getNextWaitInterval(retryCount++);
-        LOG.warn("ZkClient reconnect on expiring failed. Will retry after {} ms", waitInterval, e);
-        try {
-          Thread.sleep(waitInterval);
-        } catch (InterruptedException ex) {
-          reconnectException = ex;
-          break;
-        }
-      }
-    }
-
-    LOG.info("Unable to re-establish connection. Notifying consumer of the following exception: ",
-        reconnectException);
-    fireSessionEstablishmentError(reconnectException);
-  }
-
-  private void reconnect() {
-    getEventLock().lock();
-    try {
-      ZkConnection connection = ((ZkConnection) getConnection());
-      connection.reconnect(this);
-      _isNewSessionEventFired = false;
-    } catch (InterruptedException e) {
-      throw new ZkInterruptedException(e);
-    } finally {
-      getEventLock().unlock();
-    }
-  }
-
-  private void fireNewSessionEvents() {
-    final String sessionId = getHexSessionId();
-    for (final IZkStateListener stateListener : _stateListener) {
-      _eventThread.send(new ZkEvent("New session event sent to " + stateListener, sessionId) {
-
-        @Override
-        public void run() throws Exception {
-          stateListener.handleNewSession(sessionId);
-        }
-      });
-    }
-  }
-
-  protected void fireStateChangedEvent(final KeeperState state) {
-    final String sessionId = getHexSessionId();
-    for (final IZkStateListener stateListener : _stateListener) {
-      final String description = "State changed to " + state + " sent to " + stateListener;
-      _eventThread.send(new ZkEvent(description, sessionId) {
-
-        @Override
-        public void run() throws Exception {
-          stateListener.handleStateChanged(state);
-        }
-      });
-    }
-  }
-
-  private void fireSessionEstablishmentError(final Throwable error) {
-    for (final IZkStateListener stateListener : _stateListener) {
-      _eventThread
-          .send(new ZkEvent("Session establishment error(" + error + ") sent to " + stateListener) {
-
-            @Override
-            public void run() throws Exception {
-              stateListener.handleSessionEstablishmentError(error);
-            }
-          });
-    }
-  }
-
-  private boolean hasListeners(String path) {
-    Set<IZkDataListenerEntry> dataListeners = _dataListener.get(path);
-    if (dataListeners != null && dataListeners.size() > 0) {
-      return true;
-    }
-    Set<IZkChildListener> childListeners = _childListener.get(path);
-    if (childListeners != null && childListeners.size() > 0) {
-      return true;
-    }
-    return false;
-  }
-
-  /**
-   * Delete the path as well as all its children.
-   * This method is deprecated, please use {@link #deleteRecursively(String)}} instead
-   * @param path ZK path
-   * @return true if successfully deleted all children, and the given path, else false
-   */
-  @Deprecated
-  public boolean deleteRecursive(String path) {
-    try {
-      deleteRecursively(path);
-      return true;
-    } catch (HelixException e) {
-      LOG.error("Failed to recursively delete path " + path, e);
-      return false;
-    }
-  }
-
-  /**
-   * Delete the path as well as all its children.
-   * @param path
-   * @throws HelixException
-   */
-  public void deleteRecursively(String path) throws HelixException {
-    List<String> children;
-    try {
-      children = getChildren(path, false);
-    } catch (ZkNoNodeException e) {
-      // if the node to be deleted does not exist, treat it as success.
-      return;
-    }
-
-    for (String subPath : children) {
-      deleteRecursively(path + "/" + subPath);
-    }
-
-    // delete() function call will return true if successful, false if the path does not
-    // exist (in this context, it should be treated as successful), and throw exception
-    // if there is any other failure case.
-    try {
-      delete(path);
-    } catch (Exception e) {
-      LOG.error("Failed to delete " + path, e);
-      throw new HelixException("Failed to delete " + path, e);
-    }
-  }
-
-  private void processDataOrChildChange(WatchedEvent event, long notificationTime) {
-    final String path = event.getPath();
-    final boolean pathExists = event.getType() != EventType.NodeDeleted;
-
-    if (event.getType() == EventType.NodeChildrenChanged || event.getType() == EventType.NodeCreated
-        || event.getType() == EventType.NodeDeleted) {
-      Set<IZkChildListener> childListeners = _childListener.get(path);
-      if (childListeners != null && !childListeners.isEmpty()) {
-        // TODO recording child changed event propagation latency as well. Note this change will
-        // introduce additional ZK access.
-        fireChildChangedEvents(path, childListeners, pathExists);
-      }
-    }
-
-    if (event.getType() == EventType.NodeDataChanged || event.getType() == EventType.NodeDeleted
-        || event.getType() == EventType.NodeCreated) {
-      Set<IZkDataListenerEntry> listeners = _dataListener.get(path);
-      if (listeners != null && !listeners.isEmpty()) {
-        fireDataChangedEvents(event.getPath(), listeners, OptionalLong.of(notificationTime), pathExists);
-      }
-    }
-  }
-
-  private void fireDataChangedEvents(final String path, Set<IZkDataListenerEntry> listeners,
-      final OptionalLong notificationTime, boolean pathExists) {
-    try {
-      final ZkPathStatRecord pathStatRecord = new ZkPathStatRecord(path);
-      // Trigger listener callbacks
-      for (final IZkDataListenerEntry listener : listeners) {
-        _eventThread.send(new ZkEvent("Data of " + path + " changed sent to "
-            + listener.getDataListener() + " prefetch data: " + listener.isPrefetchData()) {
-          @Override
-          public void run() throws Exception {
-            if (!pathStatRecord.pathChecked()) {
-              // getStat will re-install watcher only when the path exists
-              pathStatRecord.recordPathStat(getStat(path, pathExists), notificationTime);
-            }
-            if (!pathStatRecord.pathExists()) {
-              listener.getDataListener().handleDataDeleted(path);
-            } else {
-              Object data = null;
-              if (listener.isPrefetchData()) {
-                if (LOG.isDebugEnabled()) {
-                  LOG.debug("Prefetch data for path: {}", path);
-                }
-                try {
-                  // TODO: the data is redundantly read multiple times when multiple listeners exist
-                  data = readData(path, null, true);
-                } catch (ZkNoNodeException e) {
-                  LOG.warn("Prefetch data for path: {} failed.", path, e);
-                  listener.getDataListener().handleDataDeleted(path);
-                  return;
-                }
-              }
-              listener.getDataListener().handleDataChange(path, data);
-            }
-          }
-        });
-      }
-    } catch (Exception e) {
-      LOG.error("Failed to fire data changed event for path: {}", path, e);
-    }
-  }
-
-  private void fireChildChangedEvents(final String path, Set<IZkChildListener> childListeners, boolean pathExists) {
-    try {
-      final ZkPathStatRecord pathStatRecord = new ZkPathStatRecord(path);
-      for (final IZkChildListener listener : childListeners) {
-        _eventThread.send(new ZkEvent("Children of " + path + " changed sent to " + listener) {
-          @Override
-          public void run() throws Exception {
-            if (!pathStatRecord.pathChecked()) {
-              pathStatRecord.recordPathStat(getStat(path, hasListeners(path) && pathExists),
-                  OptionalLong.empty());
-            }
-            List<String> children = null;
-            if (pathStatRecord.pathExists()) {
-              try {
-                //TODO: duplicate reads when multiple child listener exists
-                children = getChildren(path);
-              } catch (ZkNoNodeException e) {
-                LOG.warn("Get children under path: {} failed.", path, e);
-                // Continue trigger the change handler
-              }
-            }
-            listener.handleChildChange(path, children);
-          }
-        });
-      }
-    } catch (Exception e) {
-      LOG.error("Failed to fire child changed event. Unable to getChildren.", e);
-    }
-  }
-
-  public boolean waitUntilExists(String path, TimeUnit timeUnit, long time)
-      throws ZkInterruptedException {
-    Date timeout = new Date(System.currentTimeMillis() + timeUnit.toMillis(time));
-    if (LOG.isDebugEnabled()) {
-      LOG.debug("Waiting until znode '" + path + "' becomes available.");
-    }
-    if (exists(path)) {
-      return true;
-    }
-    acquireEventLock();
-    try {
-      while (!exists(path, true)) {
-        boolean gotSignal = getEventLock().getZNodeEventCondition().awaitUntil(timeout);
-        if (!gotSignal) {
-          return false;
-        }
-      }
-      return true;
-    } catch (InterruptedException e) {
-      throw new ZkInterruptedException(e);
-    } finally {
-      getEventLock().unlock();
-    }
-  }
-
-  public IZkConnection getConnection() {
-    return _connection;
-  }
-
-  public long waitForEstablishedSession(long timeout, TimeUnit timeUnit) {
-    validateCurrentThread();
-
-    acquireEventLock();
-    try {
-      if (!waitForKeeperState(KeeperState.SyncConnected, timeout, timeUnit)) {
-        throw new ZkTimeoutException("Waiting to be connected to ZK server has timed out.");
-      }
-      // Reading session ID before unlocking event lock is critical to guarantee the established
-      // session's ID won't change.
-      return getSessionId();
-    } finally {
-      getEventLock().unlock();
-    }
-  }
-
-  public boolean waitUntilConnected(long time, TimeUnit timeUnit) throws ZkInterruptedException {
-    return waitForKeeperState(KeeperState.SyncConnected, time, timeUnit);
-  }
-
-  public boolean waitForKeeperState(KeeperState keeperState, long time, TimeUnit timeUnit)
-      throws ZkInterruptedException {
-    validateCurrentThread();
-    Date timeout = new Date(System.currentTimeMillis() + timeUnit.toMillis(time));
-
-    LOG.debug("Waiting for keeper state " + keeperState);
-    acquireEventLock();
-    try {
-      boolean stillWaiting = true;
-      while (_currentState != keeperState) {
-        if (!stillWaiting) {
-          return false;
-        }
-        stillWaiting = getEventLock().getStateChangedCondition().awaitUntil(timeout);
-      }
-      LOG.debug("State is " + (_currentState == null ? "CLOSED" : _currentState));
-      return true;
-    } catch (InterruptedException e) {
-      throw new ZkInterruptedException(e);
-    } finally {
-      getEventLock().unlock();
-    }
-  }
-
-  private void acquireEventLock() {
-    try {
-      getEventLock().lockInterruptibly();
-    } catch (InterruptedException e) {
-      throw new ZkInterruptedException(e);
-    }
-  }
-
-  /**
-   * @param <T>
-   * @param callable
-   * @return result of Callable
-   * @throws ZkInterruptedException
-   *           if operation was interrupted, or a required reconnection got interrupted
-   * @throws IllegalArgumentException
-   *           if called from anything except the ZooKeeper event thread
-   * @throws ZkException
-   *           if any ZooKeeper exception occurred
-   * @throws RuntimeException
-   *           if any other exception occurs from invoking the Callable
-   */
-  public <T> T retryUntilConnected(final Callable<T> callable)
-      throws IllegalArgumentException, ZkException {
-    if (_zookeeperEventThread != null && Thread.currentThread() == _zookeeperEventThread) {
-      throw new IllegalArgumentException("Must not be done in the zookeeper event thread.");
-    }
-    final long operationStartTime = System.currentTimeMillis();
-    if (_monitor != null) {
-      _monitor.increaseOutstandingRequestGauge();
-    }
-    try {
-      while (true) {
-        // Because ConnectionLossException and SessionExpiredException are caught but not thrown,
-        // we don't know what causes retry. This is used to record which one of the two exceptions
-        // causes retry in ZkTimeoutException.
-        // This also helps the test testConnectionLossWhileCreateEphemeral.
-        KeeperException.Code retryCauseCode;
-
-        if (isClosed()) {
-          throw new IllegalStateException("ZkClient already closed!");
-        }
-        try {
-          final ZkConnection zkConnection = (ZkConnection) getConnection();
-          // Validate that the connection is not null before trigger callback
-          if (zkConnection == null || zkConnection.getZookeeper() == null) {
-            throw new IllegalStateException(
-                "ZkConnection is in invalid state! Please close this ZkClient and create new client.");
-          }
-          return callable.call();
-        } catch (ConnectionLossException e) {
-          retryCauseCode = e.code();
-          // we give the event thread some time to update the status to 'Disconnected'
-          Thread.yield();
-          waitForRetry();
-        } catch (SessionExpiredException e) {
-          retryCauseCode = e.code();
-          // we give the event thread some time to update the status to 'Expired'
-          Thread.yield();
-          waitForRetry();
-        } catch (ZkSessionMismatchedException e) {
-          throw e;
-        } catch (KeeperException e) {
-          throw ZkException.create(e);
-        } catch (InterruptedException e) {
-          throw new ZkInterruptedException(e);
-        } catch (Exception e) {
-          throw ExceptionUtil.convertToRuntimeException(e);
-        }
-        // before attempting a retry, check whether retry timeout has elapsed
-        if (System.currentTimeMillis() - operationStartTime > _operationRetryTimeoutInMillis) {
-          throw new ZkTimeoutException("Operation cannot be retried because of retry timeout ("
-              + _operationRetryTimeoutInMillis + " milli seconds). Retry was caused by "
-              + retryCauseCode);
-        }
-      }
-    } finally {
-      if (_monitor != null) {
-        _monitor.decreaseOutstandingRequestGauge();
-      }
-    }
-  }
-
-  private void waitForRetry() {
-    waitUntilConnected(_operationRetryTimeoutInMillis, TimeUnit.MILLISECONDS);
-  }
-
-  public void setCurrentState(KeeperState currentState) {
-    getEventLock().lock();
-    try {
-      _currentState = currentState;
-    } finally {
-      getEventLock().unlock();
-    }
-  }
-
-  /**
-   * Returns a mutex all zookeeper events are synchronized aginst. So in case you need to do
-   * something without getting
-   * any zookeeper event interruption synchronize against this mutex. Also all threads waiting on
-   * this mutex object
-   * will be notified on an event.
-   * @return the mutex.
-   */
-  public ZkLock getEventLock() {
-    return _zkEventLock;
-  }
-
-  /**
-   * Delete the given path. Path should not have any children or the deletion will fail.
-   * This function will throw exception if we fail to delete an existing path
-   * @param path
-   * @return true if path is successfully deleted, false if path does not exist
-   */
-  public boolean delete(final String path) {
-    long startT = System.currentTimeMillis();
-    boolean success;
-    try {
-      try {
-        retryUntilConnected(new Callable<Object>() {
-
-          @Override
-          public Object call() throws Exception {
-            getConnection().delete(path);
-            return null;
-          }
-        });
-        success = true;
-      } catch (ZkNoNodeException e) {
-        success = false;
-        if (LOG.isDebugEnabled()) {
-          LOG.debug("Failed to delete path " + path + ", znode does not exist!");
-        }
-      }
-      record(path, null, startT, ZkClientMonitor.AccessType.WRITE);
-    } catch (Exception e) {
-      recordFailure(path, ZkClientMonitor.AccessType.WRITE);
-      LOG.warn("Failed to delete path " + path + "! " + e);
-      throw e;
-    } finally {
-      long endT = System.currentTimeMillis();
-      if (LOG.isTraceEnabled()) {
-        LOG.trace("delete, path: " + path + ", time: " + (endT - startT) + " ms");
-      }
-    }
-    return success;
-  }
-
-  public void setZkSerializer(ZkSerializer zkSerializer) {
-    _pathBasedZkSerializer = new BasicZkSerializer(zkSerializer);
-  }
-
-  public void setZkSerializer(PathBasedZkSerializer zkSerializer) {
-    _pathBasedZkSerializer = zkSerializer;
-  }
-
-  public PathBasedZkSerializer getZkSerializer() {
-    return _pathBasedZkSerializer;
-  }
-
-  public byte[] serialize(Object data, String path) {
-    return _pathBasedZkSerializer.serialize(data, path);
-  }
-
-  @SuppressWarnings("unchecked")
-  public <T extends Object> T deserialize(byte[] data, String path) {
-    if (data == null) {
-      return null;
-    }
-    return (T) _pathBasedZkSerializer.deserialize(data, path);
-  }
-
-  @SuppressWarnings("unchecked")
-  public <T extends Object> T readData(String path) {
-    return (T) readData(path, false);
-  }
-
-  @SuppressWarnings("unchecked")
-  public <T extends Object> T readData(String path, boolean returnNullIfPathNotExists) {
-    T data = null;
-    try {
-      data = (T) readData(path, null);
-    } catch (ZkNoNodeException e) {
-      if (!returnNullIfPathNotExists) {
-        throw e;
-      }
-    }
-    return data;
-  }
-
-  @SuppressWarnings("unchecked")
-  public <T extends Object> T readData(String path, Stat stat) {
-    return (T) readData(path, stat, hasListeners(path));
-  }
-
-  @SuppressWarnings("unchecked")
-  public <T extends Object> T readData(final String path, final Stat stat, final boolean watch) {
-    long startT = System.currentTimeMillis();
-    byte[] data = null;
-    try {
-      data = retryUntilConnected(new Callable<byte[]>() {
-
-        @Override
-        public byte[] call() throws Exception {
-          return getConnection().readData(path, stat, watch);
-        }
-      });
-      record(path, data, startT, ZkClientMonitor.AccessType.READ);
-      return (T) deserialize(data, path);
-    } catch (ZkNoNodeException e) {
-      record(path, data, startT, ZkClientMonitor.AccessType.READ);
-      throw e;
-    } catch (Exception e) {
-      recordFailure(path, ZkClientMonitor.AccessType.READ);
-      throw e;
-    } finally {
-      long endT = System.currentTimeMillis();
-      if (LOG.isTraceEnabled()) {
-        LOG.trace("getData, path: " + path + ", time: " + (endT - startT) + " ms");
-      }
-    }
-  }
-
-  @SuppressWarnings("unchecked")
-  public <T extends Object> T readDataAndStat(String path, Stat stat,
-      boolean returnNullIfPathNotExists) {
-    T data = null;
-    try {
-      data = readData(path, stat);
-    } catch (ZkNoNodeException e) {
-      if (!returnNullIfPathNotExists) {
-        throw e;
-      }
-    }
-    return data;
-  }
-
-  public void writeData(String path, Object object) {
-    writeData(path, object, -1);
-  }
-
-  /**
-   * Updates data of an existing znode. The current content of the znode is passed to the
-   * {@link DataUpdater} that is
-   * passed into this method, which returns the new content. The new content is only written back to
-   * ZooKeeper if
-   * nobody has modified the given znode in between. If a concurrent change has been detected the
-   * new data of the
-   * znode is passed to the updater once again until the new contents can be successfully written
-   * back to ZooKeeper.
-   * @param <T>
-   * @param path
-   *          The path of the znode.
-   * @param updater
-   *          Updater that creates the new contents.
-   */
-  @SuppressWarnings("unchecked")
-  public <T extends Object> void updateDataSerialized(String path, DataUpdater<T> updater) {
-    Stat stat = new Stat();
-    boolean retry;
-    do {
-      retry = false;
-      try {
-        T oldData = (T) readData(path, stat);
-        T newData = updater.update(oldData);
-        writeData(path, newData, stat.getVersion());
-      } catch (ZkBadVersionException e) {
-        retry = true;
-      }
-    } while (retry);
-  }
-
-  public void writeData(final String path, Object datat, final int expectedVersion) {
-    writeDataReturnStat(path, datat, expectedVersion);
-  }
-
-  public Stat writeDataReturnStat(final String path, Object datat, final int expectedVersion) {
-    long startT = System.currentTimeMillis();
-    try {
-      final byte[] data = serialize(datat, path);
-      checkDataSizeLimit(data);
-      final Stat stat = (Stat) retryUntilConnected(new Callable<Object>() {
-        @Override
-        public Object call() throws Exception {
-          return getConnection().writeDataReturnStat(path, data, expectedVersion);
-        }
-      });
-      record(path, data, startT, ZkClientMonitor.AccessType.WRITE);
-      return stat;
-    } catch (Exception e) {
-      recordFailure(path, ZkClientMonitor.AccessType.WRITE);
-      throw e;
-    } finally {
-      long endT = System.currentTimeMillis();
-      if (LOG.isTraceEnabled()) {
-        LOG.trace("setData, path: " + path + ", time: " + (endT - startT) + " ms");
-      }
-    }
-  }
-
-  public Stat writeDataGetStat(final String path, Object datat, final int expectedVersion) {
-    return writeDataReturnStat(path, datat, expectedVersion);
-  }
-
-  public void asyncCreate(final String path, Object datat, final CreateMode mode,
-      final ZkAsyncCallbacks.CreateCallbackHandler cb) {
-    final long startT = System.currentTimeMillis();
-    final byte[] data = (datat == null ? null : serialize(datat, path));
-    retryUntilConnected(new Callable<Object>() {
-      @Override
-      public Object call() throws Exception {
-        ((ZkConnection) getConnection()).getZookeeper().create(path, data,
-            ZooDefs.Ids.OPEN_ACL_UNSAFE,
-            // Arrays.asList(DEFAULT_ACL),
-            mode, cb, new ZkAsyncCallbacks.ZkAsyncCallContext(_monitor, startT,
-                data == null ? 0 : data.length, false));
-        return null;
-      }
-    });
-  }
-
-  // Async Data Accessors
-  public void asyncSetData(final String path, Object datat, final int version,
-      final ZkAsyncCallbacks.SetDataCallbackHandler cb) {
-    final long startT = System.currentTimeMillis();
-    final byte[] data = serialize(datat, path);
-    retryUntilConnected(new Callable<Object>() {
-      @Override
-      public Object call() throws Exception {
-        ((ZkConnection) getConnection()).getZookeeper().setData(path, data, version, cb,
-            new ZkAsyncCallbacks.ZkAsyncCallContext(_monitor, startT,
-                data == null ? 0 : data.length, false));
-        return null;
-      }
-    });
-  }
-
-  public void asyncGetData(final String path, final ZkAsyncCallbacks.GetDataCallbackHandler cb) {
-    final long startT = System.currentTimeMillis();
-    retryUntilConnected(new Callable<Object>() {
-      @Override
-      public Object call() throws Exception {
-        ((ZkConnection) getConnection()).getZookeeper().getData(path, null, cb,
-            new ZkAsyncCallbacks.ZkAsyncCallContext(_monitor, startT, 0, true));
-        return null;
-      }
-    });
-  }
-
-  public void asyncExists(final String path, final ZkAsyncCallbacks.ExistsCallbackHandler cb) {
-    final long startT = System.currentTimeMillis();
-    retryUntilConnected(new Callable<Object>() {
-      @Override
-      public Object call() throws Exception {
-        ((ZkConnection) getConnection()).getZookeeper().exists(path, null, cb,
-            new ZkAsyncCallbacks.ZkAsyncCallContext(_monitor, startT, 0, true));
-        return null;
-      }
-    });
-  }
-
-  public void asyncDelete(final String path, final ZkAsyncCallbacks.DeleteCallbackHandler cb) {
-    final long startT = System.currentTimeMillis();
-    retryUntilConnected(new Callable<Object>() {
-      @Override
-      public Object call() throws Exception {
-        ((ZkConnection) getConnection()).getZookeeper().delete(path, -1, cb,
-            new ZkAsyncCallbacks.ZkAsyncCallContext(_monitor, startT, 0, false));
-        return null;
-      }
-    });
-  }
-
-  private void checkDataSizeLimit(byte[] data) {
-    if (data != null && data.length > ZNRecord.SIZE_LIMIT) {
-      LOG.error("Data size larger than 1M, will not write to zk. Data (first 1k): "
-          + new String(data).substring(0, 1024));
-      throw new HelixException("Data size larger than 1M");
-    }
-  }
-
-  public void watchForData(final String path) {
-    retryUntilConnected(new Callable<Object>() {
-      @Override
-      public Object call() throws Exception {
-        getConnection().exists(path, true);
-        return null;
-      }
-    });
-  }
-
-  /**
-   * Installs a child watch for the given path.
-   * @param path
-   * @return the current children of the path or null if the zk node with the given path doesn't
-   *         exist.
-   */
-  public List<String> watchForChilds(final String path) {
-    if (_zookeeperEventThread != null && Thread.currentThread() == _zookeeperEventThread) {
-      throw new IllegalArgumentException("Must not be done in the zookeeper event thread.");
-    }
-    return retryUntilConnected(new Callable<List<String>>() {
-      @Override
-      public List<String> call() throws Exception {
-        exists(path, true);
-        try {
-          return getChildren(path, true);
-        } catch (ZkNoNodeException e) {
-          // ignore, the "exists" watch will listen for the parent node to appear
-        }
-        return null;
-      }
-    });
-  }
-
-  /**
-   * Add authentication information to the connection. This will be used to identify the user and
-   * check access to
-   * nodes protected by ACLs
-   * @param scheme
-   * @param auth
-   */
-  public void addAuthInfo(final String scheme, final byte[] auth) {
-    retryUntilConnected(new Callable<Object>() {
-      @Override
-      public Object call() throws Exception {
-        getConnection().addAuthInfo(scheme, auth);
-        return null;
-      }
-    });
-  }
-
-  /**
-   * Connect to ZooKeeper.
-   * @param maxMsToWaitUntilConnected
-   * @param watcher
-   * @throws ZkInterruptedException
-   *           if the connection timed out due to thread interruption
-   * @throws ZkTimeoutException
-   *           if the connection timed out
-   * @throws IllegalStateException
-   *           if the connection timed out due to thread interruption
-   */
-  public void connect(final long maxMsToWaitUntilConnected, Watcher watcher)
-      throws ZkInterruptedException, ZkTimeoutException, IllegalStateException {
-    if (isClosed()) {
-      throw new IllegalStateException("ZkClient already closed!");
-    }
-    boolean started = false;
-    acquireEventLock();
-    try {
-      setShutdownTrigger(false);
-
-      IZkConnection zkConnection = getConnection();
-      _eventThread = new ZkEventThread(zkConnection.getServers());
-      _eventThread.start();
-
-      if (isManagingZkConnection()) {
-        zkConnection.connect(watcher);
-        LOG.debug("Awaiting connection to Zookeeper server");
-        if (!waitUntilConnected(maxMsToWaitUntilConnected, TimeUnit.MILLISECONDS)) {
-          throw new ZkTimeoutException(
-              "Unable to connect to zookeeper server within timeout: " + maxMsToWaitUntilConnected);
-        }
-      } else {
-        // if the client is not managing connection, the input connection is supposed to connect.
-        if (isConnectionClosed()) {
-          throw new HelixException(
-              "Unable to connect to zookeeper server with the specified ZkConnection");
-        }
-        // TODO Refine the init state here. Here we pre-config it to be connected. This may not be
-        // the case, if the connection is connecting or recovering. -- JJ
-        // For shared client, the event notification will not be forwarded before wather add to the
-        // connection manager.
-        setCurrentState(KeeperState.SyncConnected);
-      }
-
-      started = true;
-    } finally {
-      getEventLock().unlock();
-
-      // we should close the zookeeper instance, otherwise it would keep
-      // on trying to connect
-      if (!started) {
-        close();
-      }
-    }
-  }
-
-  public long getCreationTime(String path) {
-    acquireEventLock();
-    try {
-      return getConnection().getCreateTime(path);
-    } catch (KeeperException e) {
-      throw ZkException.create(e);
-    } catch (InterruptedException e) {
-      throw new ZkInterruptedException(e);
-    } finally {
-      getEventLock().unlock();
-    }
-  }
-
-  public String getServers() {
-    return getConnection().getServers();
-  }
-
-  /**
-   * Close the client.
-   * @throws ZkInterruptedException
-   */
-  public void close() throws ZkInterruptedException {
-    if (LOG.isTraceEnabled()) {
-      StackTraceElement[] calls = Thread.currentThread().getStackTrace();
-      LOG.trace("closing a zkclient. callStack: " + Arrays.asList(calls));
-    }
-    getEventLock().lock();
-    IZkConnection connection = getConnection();
-    try {
-      if (connection == null || _closed) {
-        return;
-      }
-      setShutdownTrigger(true);
-      _eventThread.interrupt();
-      _eventThread.join(2000);
-      if (isManagingZkConnection()) {
-        LOG.info("Closing zkclient: " + ((ZkConnection) connection).getZookeeper());
-        connection.close();
-      }
-      _closed = true;
-
-      // send state change notification to unlock any wait
-      setCurrentState(null);
-      getEventLock().getStateChangedCondition().signalAll();
-
-    } catch (InterruptedException e) {
-      /**
-       * Workaround for HELIX-264: calling ZkClient#close() in its own eventThread context will
-       * throw ZkInterruptedException and skip ZkConnection#close()
-       */
-      if (connection != null) {
-        try {
-          /**
-           * ZkInterruptedException#construct() honors InterruptedException by calling
-           * Thread.currentThread().interrupt(); clear it first, so we can safely close the
-           * zk-connection
-           */
-          Thread.interrupted();
-          if (isManagingZkConnection()) {
-            connection.close();
-          }
-          /**
-           * restore interrupted status of current thread
-           */
-          Thread.currentThread().interrupt();
-        } catch (InterruptedException e1) {
-          throw new ZkInterruptedException(e1);
-        }
-      }
-    } finally {
-      getEventLock().unlock();
-      if (_monitor != null) {
-        _monitor.unregister();
-      }
-      LOG.info("Closed zkclient");
-    }
-  }
-
-  public boolean isClosed() {
-    try {
-      getEventLock().lock();
-      return _closed;
-    } finally {
-      getEventLock().unlock();
-    }
-  }
-
-  public boolean isConnectionClosed() {
-    IZkConnection connection = getConnection();
-    return (connection == null || connection.getZookeeperState() == null
-        || !connection.getZookeeperState().isAlive());
-  }
-
-  public void setShutdownTrigger(boolean triggerState) {
-    _shutdownTriggered = triggerState;
-  }
-
-  public boolean getShutdownTrigger() {
-    return _shutdownTriggered;
-  }
-
-  public int numberOfListeners() {
-    int listeners = 0;
-    for (Set<IZkChildListener> childListeners : _childListener.values()) {
-      listeners += childListeners.size();
-    }
-    for (Set<IZkDataListenerEntry> dataListeners : _dataListener.values()) {
-      listeners += dataListeners.size();
-    }
-    listeners += _stateListener.size();
-
-    return listeners;
-  }
-
-  public List<OpResult> multi(final Iterable<Op> ops) throws ZkException {
-    if (ops == null) {
-      throw new NullPointerException("ops must not be null.");
-    }
-
-    return retryUntilConnected(new Callable<List<OpResult>>() {
-
-      @Override
-      public List<OpResult> call() throws Exception {
-        return getConnection().multi(ops);
-      }
-    });
-  }
-
-  /**
-   * @return true if this ZkClient is managing the ZkConnection.
-   */
-  protected boolean isManagingZkConnection() {
-    return true;
-  }
-
-  public long getSessionId() {
-    ZkConnection zkConnection = ((ZkConnection) getConnection());
-    ZooKeeper zk = zkConnection.getZookeeper();
-    if (zk == null) {
-      throw new HelixException(
-          "ZooKeeper connection information is not available now. ZkClient might be disconnected.");
-    } else {
-      return zkConnection.getZookeeper().getSessionId();
-    }
-  }
-
-  /*
-   * Gets a session id in hexadecimal notation.
-   * Ex. 1000a5ceb930004 is returned.
-   */
-  private String getHexSessionId() {
-    return ZKUtil.toHexSessionId(getSessionId());
-  }
-
-  /*
-   * Session aware operation needs below requirements:
-   * 1. the session id is NOT null or empty
-   * 2. create mode is EPHEMERAL or EPHEMERAL_SEQUENTIAL
-   */
-  private boolean isSessionAwareOperation(String expectedSessionId, CreateMode mode) {
-    return expectedSessionId != null && !expectedSessionId.isEmpty()
-        && (mode == CreateMode.EPHEMERAL || mode == CreateMode.EPHEMERAL_SEQUENTIAL);
-  }
-
-  // operations to update monitor's counters
-  private void record(String path, byte[] data, long startTimeMilliSec,
-      ZkClientMonitor.AccessType accessType) {
-    if (_monitor != null) {
-      int dataSize = (data != null) ? data.length : 0;
-      _monitor.record(path, dataSize, startTimeMilliSec, accessType);
-    }
-  }
-
-  private void recordFailure(String path, ZkClientMonitor.AccessType accessType) {
-    if (_monitor != null) {
-      _monitor.recordFailure(path, accessType);
-    }
-  }
-
-  private void recordStateChange(boolean stateChanged, boolean dataChanged) {
-    // update state change counter.
-    if (_monitor != null) {
-      if (stateChanged) {
-        _monitor.increaseStateChangeEventCounter();
-      }
-      if (dataChanged) {
-        _monitor.increaseDataChangeEventCounter();
-      }
-    }
-  }
-
-  /**
-   * Creates a {@link org.apache.helix.manager.zk.zookeeper.IZkStateListener} that wraps a default
-   * implementation of {@link org.I0Itec.zkclient.IZkStateListener}, which means the returned
-   * listener runs the methods of {@link org.I0Itec.zkclient.IZkStateListener}.
-   * This is for backward compatibility with {@link org.I0Itec.zkclient.IZkStateListener}.
-   */
-  private static class IZkStateListenerI0ItecImpl implements IZkStateListener {
-    private org.I0Itec.zkclient.IZkStateListener _listener;
-
-    IZkStateListenerI0ItecImpl(org.I0Itec.zkclient.IZkStateListener listener) {
-      _listener = listener;
-    }
-
-    @Override
-    public void handleStateChanged(Watcher.Event.KeeperState keeperState) throws Exception {
-      _listener.handleStateChanged(keeperState);
-    }
-
-    @Override
-    public void handleNewSession(final String sessionId) throws Exception {
-      /*
-       * org.I0Itec.zkclient.IZkStateListener does not have handleNewSession(sessionId),
-       * so just call handleNewSession() by default.
-       */
-      _listener.handleNewSession();
-    }
-
-    @Override
-    public void handleSessionEstablishmentError(Throwable error) throws Exception {
-      _listener.handleSessionEstablishmentError(error);
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-      if (obj == this) {
-        return true;
-      }
-      if (!(obj instanceof IZkStateListenerI0ItecImpl)) {
-        return false;
-      }
-      if (_listener == null) {
-        return false;
-      }
-
-      IZkStateListenerI0ItecImpl defaultListener = (IZkStateListenerI0ItecImpl) obj;
-
-      return _listener.equals(defaultListener._listener);
-    }
-
-    @Override
-    public int hashCode() {
-      /*
-       * The original listener's hashcode helps find the wrapped listener with the same original
-       * listener. This is helpful in unsubscribeStateChanges(listener) when finding the listener
-       * to remove.
-       */
-      return _listener.hashCode();
-    }
-  }
-
-  private void validateCurrentThread() {
-    if (_zookeeperEventThread != null && Thread.currentThread() == _zookeeperEventThread) {
-      throw new IllegalArgumentException("Must not be done in the zookeeper event thread.");
-    }
+    super(zkConnection, connectionTimeout, operationRetryTimeout, zkSerializer, monitorType,
+        monitorKey, monitorInstanceName, monitorRootPathOnly);
   }
 }
diff --git a/helix-core/src/main/java/org/apache/helix/manager/zk/zookeeper/ZkConnection.java b/helix-core/src/main/java/org/apache/helix/manager/zk/zookeeper/ZkConnection.java
index 07397ed..c623824 100644
--- a/helix-core/src/main/java/org/apache/helix/manager/zk/zookeeper/ZkConnection.java
+++ b/helix-core/src/main/java/org/apache/helix/manager/zk/zookeeper/ZkConnection.java
@@ -11,177 +11,17 @@
 
 package org.apache.helix.manager.zk.zookeeper;
 
-import java.io.IOException;
-import java.util.List;
-import java.util.concurrent.locks.Lock;
-import java.util.concurrent.locks.ReentrantLock;
-
-import org.I0Itec.zkclient.IZkConnection;
-import org.I0Itec.zkclient.exception.ZkException;
-import org.apache.log4j.Logger;
-import org.apache.zookeeper.CreateMode;
-import org.apache.zookeeper.KeeperException;
-import org.apache.zookeeper.Op;
-import org.apache.zookeeper.OpResult;
-import org.apache.zookeeper.Watcher;
-import org.apache.zookeeper.ZooDefs.Ids;
-import org.apache.zookeeper.ZooKeeper;
-import org.apache.zookeeper.ZooKeeper.States;
-import org.apache.zookeeper.data.ACL;
-import org.apache.zookeeper.data.Stat;
-
-public class ZkConnection implements IZkConnection {
-  private static final Logger LOG = Logger.getLogger(ZkConnection.class);
-
-  /** It is recommended to use quite large sessions timeouts for ZooKeeper. */
-  private static final int DEFAULT_SESSION_TIMEOUT = 30000;
-
-  private ZooKeeper _zk = null;
-  private Lock _zookeeperLock = new ReentrantLock();
-
-  private final String _servers;
-  private final int _sessionTimeOut;
+/**
+ * Use ZkConnection in zookeeper-api module instead.
+ */
+@Deprecated
+public class ZkConnection extends org.apache.helix.zookeeper.zkclient.ZkConnection {
 
   public ZkConnection(String zkServers) {
-    this(zkServers, DEFAULT_SESSION_TIMEOUT);
+    super(zkServers);
   }
 
   public ZkConnection(String zkServers, int sessionTimeOut) {
-    _servers = zkServers;
-    _sessionTimeOut = sessionTimeOut;
-  }
-
-  @Override
-  public void connect(Watcher watcher) {
-    _zookeeperLock.lock();
-    try {
-      if (_zk != null) {
-        throw new IllegalStateException("zk client has already been started");
-      }
-      try {
-        LOG.debug("Creating new ZookKeeper instance to connect to " + _servers + ".");
-        _zk = new ZooKeeper(_servers, _sessionTimeOut, watcher);
-      } catch (IOException e) {
-        throw new ZkException("Unable to connect to " + _servers, e);
-      }
-    } finally {
-      _zookeeperLock.unlock();
-    }
-  }
-
-  @Override
-  public void close() throws InterruptedException {
-    _zookeeperLock.lock();
-    try {
-      if (_zk != null) {
-        LOG.debug("Closing ZooKeeper connected to " + _servers);
-        _zk.close();
-        _zk = null;
-      }
-    } finally {
-      _zookeeperLock.unlock();
-    }
-  }
-
-  protected void reconnect(Watcher watcher) throws InterruptedException {
-    _zookeeperLock.lock();
-    try {
-      if (_zk == null) {
-        throw new IllegalStateException("zk client has not been connected or already been closed");
-      }
-      ZooKeeper prevZk = _zk;
-      try {
-        LOG.debug("Creating new ZookKeeper instance to reconnect to " + _servers + ".");
-        _zk = new ZooKeeper(_servers, _sessionTimeOut, watcher);
-        prevZk.close();
-      } catch (IOException e) {
-        throw new ZkException("Unable to connect to " + _servers, e);
-      }
-    } finally {
-      _zookeeperLock.unlock();
-    }
-  }
-
-  @Override
-  public String create(String path, byte[] data, CreateMode mode)
-      throws KeeperException, InterruptedException {
-    return _zk.create(path, data, Ids.OPEN_ACL_UNSAFE, mode);
-  }
-
-  @Override
-  public String create(String path, byte[] data, List<ACL> acl, CreateMode mode)
-      throws KeeperException, InterruptedException {
-    return _zk.create(path, data, acl, mode);
-  }
-
-  @Override
-  public void delete(String path) throws InterruptedException, KeeperException {
-    _zk.delete(path, -1);
-  }
-
-  @Override
-  public boolean exists(String path, boolean watch) throws KeeperException, InterruptedException {
-    return _zk.exists(path, watch) != null;
-  }
-
-  @Override
-  public List<String> getChildren(final String path, final boolean watch)
-      throws KeeperException, InterruptedException {
-    return _zk.getChildren(path, watch);
-  }
-
-  @Override
-  public byte[] readData(String path, Stat stat, boolean watch)
-      throws KeeperException, InterruptedException {
-    return _zk.getData(path, watch, stat);
-  }
-
-  public void writeData(String path, byte[] data) throws KeeperException, InterruptedException {
-    writeData(path, data, -1);
-  }
-
-  @Override
-  public void writeData(String path, byte[] data, int version)
-      throws KeeperException, InterruptedException {
-    _zk.setData(path, data, version);
-  }
-
-  @Override
-  public Stat writeDataReturnStat(String path, byte[] data, int version)
-      throws KeeperException, InterruptedException {
-    return _zk.setData(path, data, version);
-  }
-
-  @Override
-  public States getZookeeperState() {
-    return _zk != null ? _zk.getState() : null;
-  }
-
-  public ZooKeeper getZookeeper() {
-    return _zk;
-  }
-
-  @Override
-  public long getCreateTime(String path) throws KeeperException, InterruptedException {
-    Stat stat = _zk.exists(path, false);
-    if (stat != null) {
-      return stat.getCtime();
-    }
-    return -1;
-  }
-
-  @Override
-  public String getServers() {
-    return _servers;
-  }
-
-  @Override
-  public List<OpResult> multi(Iterable<Op> ops) throws KeeperException, InterruptedException {
-    return _zk.multi(ops);
-  }
-
-  @Override
-  public void addAuthInfo(String scheme, byte[] auth) {
-    _zk.addAuthInfo(scheme, auth);
+    super(zkServers, sessionTimeOut);
   }
 }
diff --git a/helix-core/src/main/java/org/apache/helix/messaging/ZNRecordRow.java b/helix-core/src/main/java/org/apache/helix/messaging/ZNRecordRow.java
index 5a2effd..d1289aa 100644
--- a/helix-core/src/main/java/org/apache/helix/messaging/ZNRecordRow.java
+++ b/helix-core/src/main/java/org/apache/helix/messaging/ZNRecordRow.java
@@ -25,7 +25,7 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
 
 /**
  * A Normalized form of ZNRecord
diff --git a/helix-core/src/main/java/org/apache/helix/messaging/handling/HelixStateTransitionHandler.java b/helix-core/src/main/java/org/apache/helix/messaging/handling/HelixStateTransitionHandler.java
index 316284b..7229bc7 100644
--- a/helix-core/src/main/java/org/apache/helix/messaging/handling/HelixStateTransitionHandler.java
+++ b/helix-core/src/main/java/org/apache/helix/messaging/handling/HelixStateTransitionHandler.java
@@ -38,10 +38,10 @@ import org.apache.helix.NotificationContext;
 import org.apache.helix.NotificationContext.MapKey;
 import org.apache.helix.PropertyKey;
 import org.apache.helix.PropertyKey.Builder;
-import org.apache.helix.ZNRecord;
-import org.apache.helix.ZNRecordBucketizer;
-import org.apache.helix.ZNRecordDelta;
-import org.apache.helix.ZNRecordDelta.MergeOperation;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecordBucketizer;
+import org.apache.helix.zookeeper.datamodel.ZNRecordDelta;
+import org.apache.helix.zookeeper.datamodel.ZNRecordDelta.MergeOperation;
 import org.apache.helix.model.CurrentState;
 import org.apache.helix.model.Message;
 import org.apache.helix.model.Message.Attributes;
diff --git a/helix-core/src/main/java/org/apache/helix/model/AlertHistory.java b/helix-core/src/main/java/org/apache/helix/model/AlertHistory.java
index 58db71d..ccfcb8c 100644
--- a/helix-core/src/main/java/org/apache/helix/model/AlertHistory.java
+++ b/helix-core/src/main/java/org/apache/helix/model/AlertHistory.java
@@ -19,7 +19,7 @@ package org.apache.helix.model;
  * under the License.
  */
 import org.apache.helix.HelixProperty;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
 
 /**
  * Maintains a history of alerts that have been fired, as well as actions taken, if any.
diff --git a/helix-core/src/main/java/org/apache/helix/model/AlertStatus.java b/helix-core/src/main/java/org/apache/helix/model/AlertStatus.java
index d90ec1a..e6c1e99 100644
--- a/helix-core/src/main/java/org/apache/helix/model/AlertStatus.java
+++ b/helix-core/src/main/java/org/apache/helix/model/AlertStatus.java
@@ -22,7 +22,7 @@ package org.apache.helix.model;
 import java.util.Map;
 
 import org.apache.helix.HelixProperty;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
 import org.apache.helix.model.Alerts.AlertsProperty;
 
 /**
diff --git a/helix-core/src/main/java/org/apache/helix/model/Alerts.java b/helix-core/src/main/java/org/apache/helix/model/Alerts.java
index 506e3d5..e32efb3 100644
--- a/helix-core/src/main/java/org/apache/helix/model/Alerts.java
+++ b/helix-core/src/main/java/org/apache/helix/model/Alerts.java
@@ -22,7 +22,7 @@ package org.apache.helix.model;
 import java.util.Map;
 
 import org.apache.helix.HelixProperty;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
 
 /**
  * Describe alerts and corresponding metrics. An alert is triggered when cluster health
diff --git a/helix-core/src/main/java/org/apache/helix/model/ClusterConfig.java b/helix-core/src/main/java/org/apache/helix/model/ClusterConfig.java
index f88d2f5..165919c 100644
--- a/helix-core/src/main/java/org/apache/helix/model/ClusterConfig.java
+++ b/helix-core/src/main/java/org/apache/helix/model/ClusterConfig.java
@@ -30,7 +30,7 @@ import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.Maps;
 import org.apache.helix.HelixException;
 import org.apache.helix.HelixProperty;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
 import org.apache.helix.api.config.HelixConfigProperty;
 import org.apache.helix.api.config.StateTransitionThrottleConfig;
 import org.apache.helix.api.config.StateTransitionTimeoutConfig;
diff --git a/helix-core/src/main/java/org/apache/helix/model/ClusterConstraints.java b/helix-core/src/main/java/org/apache/helix/model/ClusterConstraints.java
index 520f17d..12beabe 100644
--- a/helix-core/src/main/java/org/apache/helix/model/ClusterConstraints.java
+++ b/helix-core/src/main/java/org/apache/helix/model/ClusterConstraints.java
@@ -26,7 +26,7 @@ import java.util.Set;
 import java.util.TreeMap;
 
 import org.apache.helix.HelixProperty;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
 import org.apache.helix.model.Message.MessageType;
 import org.apache.helix.model.builder.ConstraintItemBuilder;
 import org.slf4j.Logger;
diff --git a/helix-core/src/main/java/org/apache/helix/model/ControllerHistory.java b/helix-core/src/main/java/org/apache/helix/model/ControllerHistory.java
index 955a5bf..a76a957 100644
--- a/helix-core/src/main/java/org/apache/helix/model/ControllerHistory.java
+++ b/helix-core/src/main/java/org/apache/helix/model/ControllerHistory.java
@@ -30,7 +30,7 @@ import java.util.Map;
 import java.util.TimeZone;
 
 import org.apache.helix.HelixProperty;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
 import org.codehaus.jackson.map.ObjectMapper;
 
 /**
diff --git a/helix-core/src/main/java/org/apache/helix/model/CurrentState.java b/helix-core/src/main/java/org/apache/helix/model/CurrentState.java
index c227060..0bc9052 100644
--- a/helix-core/src/main/java/org/apache/helix/model/CurrentState.java
+++ b/helix-core/src/main/java/org/apache/helix/model/CurrentState.java
@@ -24,7 +24,7 @@ import java.util.Map;
 import java.util.TreeMap;
 
 import org.apache.helix.HelixProperty;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
diff --git a/helix-core/src/main/java/org/apache/helix/model/Error.java b/helix-core/src/main/java/org/apache/helix/model/Error.java
index 7744b91..a64905e 100644
--- a/helix-core/src/main/java/org/apache/helix/model/Error.java
+++ b/helix-core/src/main/java/org/apache/helix/model/Error.java
@@ -20,7 +20,7 @@ package org.apache.helix.model;
  */
 
 import org.apache.helix.HelixProperty;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
 
 /**
  * Defines an error that occurs in computing a valid ideal state or external view
diff --git a/helix-core/src/main/java/org/apache/helix/model/ExternalView.java b/helix-core/src/main/java/org/apache/helix/model/ExternalView.java
index efe6b4d..7ae9e34 100644
--- a/helix-core/src/main/java/org/apache/helix/model/ExternalView.java
+++ b/helix-core/src/main/java/org/apache/helix/model/ExternalView.java
@@ -24,7 +24,7 @@ import java.util.Set;
 import java.util.TreeMap;
 
 import org.apache.helix.HelixProperty;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
 
 /**
  * External view is an aggregation (across all instances)
diff --git a/helix-core/src/main/java/org/apache/helix/model/HealthStat.java b/helix-core/src/main/java/org/apache/helix/model/HealthStat.java
index b8ac32f..f1fee8c 100644
--- a/helix-core/src/main/java/org/apache/helix/model/HealthStat.java
+++ b/helix-core/src/main/java/org/apache/helix/model/HealthStat.java
@@ -24,7 +24,7 @@ import java.util.HashMap;
 import java.util.Map;
 
 import org.apache.helix.HelixProperty;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
 import org.apache.helix.model.Message.Attributes;
 
 /**
diff --git a/helix-core/src/main/java/org/apache/helix/model/IdealState.java b/helix-core/src/main/java/org/apache/helix/model/IdealState.java
index 3908a95..f41bc2c 100644
--- a/helix-core/src/main/java/org/apache/helix/model/IdealState.java
+++ b/helix-core/src/main/java/org/apache/helix/model/IdealState.java
@@ -29,7 +29,6 @@ import java.util.TreeSet;
 
 import org.apache.helix.HelixConstants;
 import org.apache.helix.HelixProperty;
-import org.apache.helix.ZNRecord;
 import org.apache.helix.controller.rebalancer.Rebalancer;
 import org.apache.helix.model.ResourceConfig.ResourceConfigProperty;
 import org.apache.helix.task.FixedTargetTaskRebalancer;
@@ -37,6 +36,7 @@ import org.apache.helix.task.GenericTaskRebalancer;
 import org.apache.helix.task.JobRebalancer;
 import org.apache.helix.task.TaskRebalancer;
 import org.apache.helix.task.WorkflowRebalancer;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
diff --git a/helix-core/src/main/java/org/apache/helix/model/InstanceConfig.java b/helix-core/src/main/java/org/apache/helix/model/InstanceConfig.java
index b55ba83..24e6154 100644
--- a/helix-core/src/main/java/org/apache/helix/model/InstanceConfig.java
+++ b/helix-core/src/main/java/org/apache/helix/model/InstanceConfig.java
@@ -32,8 +32,8 @@ import java.util.stream.Collectors;
 import com.google.common.base.Splitter;
 import org.apache.helix.HelixException;
 import org.apache.helix.HelixProperty;
-import org.apache.helix.ZNRecord;
 import org.apache.helix.util.HelixUtil;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
diff --git a/helix-core/src/main/java/org/apache/helix/model/LeaderStandbySMD.java b/helix-core/src/main/java/org/apache/helix/model/LeaderStandbySMD.java
index 092f8ba..5d98d23 100644
--- a/helix-core/src/main/java/org/apache/helix/model/LeaderStandbySMD.java
+++ b/helix-core/src/main/java/org/apache/helix/model/LeaderStandbySMD.java
@@ -25,7 +25,7 @@ import java.util.List;
 import java.util.Map;
 
 import org.apache.helix.HelixDefinedState;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
 
 /**
  * Helix built-in Leader-standby state model definition
diff --git a/helix-core/src/main/java/org/apache/helix/model/LiveInstance.java b/helix-core/src/main/java/org/apache/helix/model/LiveInstance.java
index f9a5d6a..74260cc 100644
--- a/helix-core/src/main/java/org/apache/helix/model/LiveInstance.java
+++ b/helix-core/src/main/java/org/apache/helix/model/LiveInstance.java
@@ -22,7 +22,7 @@ package org.apache.helix.model;
 import java.util.Map;
 
 import org.apache.helix.HelixProperty;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
diff --git a/helix-core/src/main/java/org/apache/helix/model/MaintenanceSignal.java b/helix-core/src/main/java/org/apache/helix/model/MaintenanceSignal.java
index 511e6f3..6a30525 100644
--- a/helix-core/src/main/java/org/apache/helix/model/MaintenanceSignal.java
+++ b/helix-core/src/main/java/org/apache/helix/model/MaintenanceSignal.java
@@ -19,7 +19,7 @@ package org.apache.helix.model;
  * under the License.
  */
 
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
 
 /**
  * A ZNode that signals that the cluster is in maintenance mode.
diff --git a/helix-core/src/main/java/org/apache/helix/model/MasterSlaveSMD.java b/helix-core/src/main/java/org/apache/helix/model/MasterSlaveSMD.java
index f2eca27..45f63a3 100644
--- a/helix-core/src/main/java/org/apache/helix/model/MasterSlaveSMD.java
+++ b/helix-core/src/main/java/org/apache/helix/model/MasterSlaveSMD.java
@@ -25,7 +25,7 @@ import java.util.List;
 import java.util.Map;
 
 import org.apache.helix.HelixDefinedState;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
 
 /**
  * Helix built-in Master-slave state model definition
diff --git a/helix-core/src/main/java/org/apache/helix/model/Message.java b/helix-core/src/main/java/org/apache/helix/model/Message.java
index 6317af1..eefecec 100644
--- a/helix-core/src/main/java/org/apache/helix/model/Message.java
+++ b/helix-core/src/main/java/org/apache/helix/model/Message.java
@@ -36,7 +36,7 @@ import org.apache.helix.HelixProperty;
 import org.apache.helix.InstanceType;
 import org.apache.helix.PropertyKey;
 import org.apache.helix.PropertyKey.Builder;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
 
 /**
  * Messages sent internally among nodes in the system to respond to changes in state.
diff --git a/helix-core/src/main/java/org/apache/helix/model/OnlineOfflineSMD.java b/helix-core/src/main/java/org/apache/helix/model/OnlineOfflineSMD.java
index 56c477d..4e0d968 100644
--- a/helix-core/src/main/java/org/apache/helix/model/OnlineOfflineSMD.java
+++ b/helix-core/src/main/java/org/apache/helix/model/OnlineOfflineSMD.java
@@ -25,7 +25,7 @@ import java.util.List;
 import java.util.Map;
 
 import org.apache.helix.HelixDefinedState;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
 
 /**
  * Helix built-in Online-offline state model definition
diff --git a/helix-core/src/main/java/org/apache/helix/model/ParticipantHistory.java b/helix-core/src/main/java/org/apache/helix/model/ParticipantHistory.java
index 6e5a8c6..c17d172 100644
--- a/helix-core/src/main/java/org/apache/helix/model/ParticipantHistory.java
+++ b/helix-core/src/main/java/org/apache/helix/model/ParticipantHistory.java
@@ -29,7 +29,7 @@ import java.util.Map;
 import java.util.TimeZone;
 
 import org.apache.helix.HelixProperty;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
diff --git a/helix-core/src/main/java/org/apache/helix/model/PauseSignal.java b/helix-core/src/main/java/org/apache/helix/model/PauseSignal.java
index ed89e9a..80a2aa7 100644
--- a/helix-core/src/main/java/org/apache/helix/model/PauseSignal.java
+++ b/helix-core/src/main/java/org/apache/helix/model/PauseSignal.java
@@ -20,7 +20,7 @@ package org.apache.helix.model;
  */
 
 import org.apache.helix.HelixProperty;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
 
 /**
  * Represent a pause in the cluster
diff --git a/helix-core/src/main/java/org/apache/helix/model/PersistentStats.java b/helix-core/src/main/java/org/apache/helix/model/PersistentStats.java
index 8f0cb69..b61e413 100644
--- a/helix-core/src/main/java/org/apache/helix/model/PersistentStats.java
+++ b/helix-core/src/main/java/org/apache/helix/model/PersistentStats.java
@@ -22,7 +22,7 @@ package org.apache.helix.model;
 import java.util.Map;
 
 import org.apache.helix.HelixProperty;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
diff --git a/helix-core/src/main/java/org/apache/helix/model/RESTConfig.java b/helix-core/src/main/java/org/apache/helix/model/RESTConfig.java
index 7e7cb22..b42b208 100644
--- a/helix-core/src/main/java/org/apache/helix/model/RESTConfig.java
+++ b/helix-core/src/main/java/org/apache/helix/model/RESTConfig.java
@@ -1,7 +1,7 @@
 package org.apache.helix.model;
 
 import org.apache.helix.HelixProperty;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
 
 
 /**
diff --git a/helix-core/src/main/java/org/apache/helix/model/ResourceAssignment.java b/helix-core/src/main/java/org/apache/helix/model/ResourceAssignment.java
index b9f6a15..756f373 100644
--- a/helix-core/src/main/java/org/apache/helix/model/ResourceAssignment.java
+++ b/helix-core/src/main/java/org/apache/helix/model/ResourceAssignment.java
@@ -25,7 +25,7 @@ import java.util.List;
 import java.util.Map;
 
 import org.apache.helix.HelixProperty;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
 
 /**
  * Represents the assignments of replicas for an entire resource, keyed on partitions of the
diff --git a/helix-core/src/main/java/org/apache/helix/model/ResourceConfig.java b/helix-core/src/main/java/org/apache/helix/model/ResourceConfig.java
index 9cdb673..f4d8b2b 100644
--- a/helix-core/src/main/java/org/apache/helix/model/ResourceConfig.java
+++ b/helix-core/src/main/java/org/apache/helix/model/ResourceConfig.java
@@ -27,7 +27,7 @@ import java.util.Map;
 import java.util.TreeMap;
 
 import org.apache.helix.HelixProperty;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
 import org.apache.helix.api.config.HelixConfigProperty;
 import org.apache.helix.api.config.RebalanceConfig;
 import org.apache.helix.api.config.StateTransitionTimeoutConfig;
diff --git a/helix-core/src/main/java/org/apache/helix/model/ScheduledTaskSMD.java b/helix-core/src/main/java/org/apache/helix/model/ScheduledTaskSMD.java
index c85e5dd..c267f16 100644
--- a/helix-core/src/main/java/org/apache/helix/model/ScheduledTaskSMD.java
+++ b/helix-core/src/main/java/org/apache/helix/model/ScheduledTaskSMD.java
@@ -25,7 +25,7 @@ import java.util.List;
 import java.util.Map;
 
 import org.apache.helix.HelixDefinedState;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
 import org.apache.helix.manager.zk.DefaultSchedulerMessageHandlerFactory;
 import org.apache.helix.model.builder.StateTransitionTableBuilder;
 
diff --git a/helix-core/src/main/java/org/apache/helix/model/StateModelDefinition.java b/helix-core/src/main/java/org/apache/helix/model/StateModelDefinition.java
index 0a40331..9a24816 100644
--- a/helix-core/src/main/java/org/apache/helix/model/StateModelDefinition.java
+++ b/helix-core/src/main/java/org/apache/helix/model/StateModelDefinition.java
@@ -32,9 +32,10 @@ import java.util.TreeMap;
 
 import org.apache.helix.HelixDefinedState;
 import org.apache.helix.HelixProperty;
-import org.apache.helix.ZNRecord;
 import org.apache.helix.model.builder.StateTransitionTableBuilder;
 import org.apache.helix.model.util.StateModelDefinitionValidator;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
+
 
 /**
  * Describe the state model
diff --git a/helix-core/src/main/java/org/apache/helix/model/StatusUpdate.java b/helix-core/src/main/java/org/apache/helix/model/StatusUpdate.java
index f4857ee..8f162e3 100644
--- a/helix-core/src/main/java/org/apache/helix/model/StatusUpdate.java
+++ b/helix-core/src/main/java/org/apache/helix/model/StatusUpdate.java
@@ -20,7 +20,7 @@ package org.apache.helix.model;
  */
 
 import org.apache.helix.HelixProperty;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
 
 /**
  * Wraps updates to Helix constructs, e.g. state transitions and controller task statuses
diff --git a/helix-core/src/main/java/org/apache/helix/model/StorageSchemataSMD.java b/helix-core/src/main/java/org/apache/helix/model/StorageSchemataSMD.java
index 46d54a9..d9dad7e 100644
--- a/helix-core/src/main/java/org/apache/helix/model/StorageSchemataSMD.java
+++ b/helix-core/src/main/java/org/apache/helix/model/StorageSchemataSMD.java
@@ -25,7 +25,7 @@ import java.util.List;
 import java.util.Map;
 
 import org.apache.helix.HelixDefinedState;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
 
 /**
  * Helix built-in StorageSchemata state model definition
diff --git a/helix-core/src/main/java/org/apache/helix/model/TaskSMD.java b/helix-core/src/main/java/org/apache/helix/model/TaskSMD.java
index 33b62e7..6f8f1e9 100644
--- a/helix-core/src/main/java/org/apache/helix/model/TaskSMD.java
+++ b/helix-core/src/main/java/org/apache/helix/model/TaskSMD.java
@@ -24,7 +24,7 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
 import org.apache.helix.model.builder.StateTransitionTableBuilder;
 import org.apache.helix.task.TaskConstants;
 import org.apache.helix.task.TaskPartitionState;
diff --git a/helix-core/src/main/java/org/apache/helix/model/builder/IdealStateBuilder.java b/helix-core/src/main/java/org/apache/helix/model/builder/IdealStateBuilder.java
index 4701181..1fd3916 100644
--- a/helix-core/src/main/java/org/apache/helix/model/builder/IdealStateBuilder.java
+++ b/helix-core/src/main/java/org/apache/helix/model/builder/IdealStateBuilder.java
@@ -21,7 +21,7 @@ package org.apache.helix.model.builder;
 
 import org.apache.helix.HelixConstants;
 import org.apache.helix.HelixException;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
 import org.apache.helix.model.IdealState;
 
 public abstract class IdealStateBuilder {
diff --git a/helix-core/src/main/java/org/apache/helix/monitoring/ZKPathDataDumpTask.java b/helix-core/src/main/java/org/apache/helix/monitoring/ZKPathDataDumpTask.java
index c0d6285..1028b85 100644
--- a/helix-core/src/main/java/org/apache/helix/monitoring/ZKPathDataDumpTask.java
+++ b/helix-core/src/main/java/org/apache/helix/monitoring/ZKPathDataDumpTask.java
@@ -28,7 +28,7 @@ import org.apache.helix.HelixDataAccessor;
 import org.apache.helix.HelixManager;
 import org.apache.helix.PropertyKey.Builder;
 import org.apache.helix.PropertyPathBuilder;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
 import org.apache.helix.manager.zk.ZNRecordSerializer;
 import org.apache.zookeeper.data.Stat;
 import org.slf4j.Logger;
diff --git a/helix-core/src/main/java/org/apache/helix/monitoring/mbeans/ZkClientMonitor.java b/helix-core/src/main/java/org/apache/helix/monitoring/mbeans/ZkClientMonitor.java
index 61b574c..f76a459 100644
--- a/helix-core/src/main/java/org/apache/helix/monitoring/mbeans/ZkClientMonitor.java
+++ b/helix-core/src/main/java/org/apache/helix/monitoring/mbeans/ZkClientMonitor.java
@@ -19,231 +19,16 @@ package org.apache.helix.monitoring.mbeans;
  * under the License.
  */
 
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-import javax.management.JMException;
-import javax.management.MBeanAttributeInfo;
-import javax.management.MalformedObjectNameException;
-import javax.management.ObjectName;
-
-import org.apache.helix.HelixException;
-import org.apache.helix.manager.zk.zookeeper.ZkEventThread;
-import org.apache.helix.monitoring.mbeans.dynamicMBeans.DynamicMBeanProvider;
-import org.apache.helix.monitoring.mbeans.dynamicMBeans.DynamicMetric;
-import org.apache.helix.monitoring.mbeans.dynamicMBeans.SimpleDynamicMetric;
-
-public class ZkClientMonitor extends DynamicMBeanProvider {
-  public static final String MONITOR_TYPE = "Type";
-  public static final String MONITOR_KEY = "Key";
-  protected static final String MBEAN_DESCRIPTION = "Helix Zookeeper Client Monitor";
-
-  public enum AccessType {
-    READ, WRITE
-  }
-
-  private String _sensorName;
-  private String _monitorType;
-  private String _monitorKey;
-  private String _monitorInstanceName;
-  private boolean _monitorRootOnly;
-
-  private SimpleDynamicMetric<Long> _stateChangeEventCounter;
-  private SimpleDynamicMetric<Long> _dataChangeEventCounter;
-  private SimpleDynamicMetric<Long> _outstandingRequestGauge;
-
-  private ZkThreadMetric _zkEventThreadMetric;
-
-  private Map<ZkClientPathMonitor.PredefinedPath, ZkClientPathMonitor> _zkClientPathMonitorMap =
-      new ConcurrentHashMap<>();
+import org.apache.helix.zookeeper.zkclient.ZkEventThread;
 
+/**
+ * Use ZkClientMonitor in zookeeper-api module instead.
+ */
+@Deprecated
+public class ZkClientMonitor
+    extends org.apache.helix.zookeeper.zkclient.metric.ZkClientMonitor {
   public ZkClientMonitor(String monitorType, String monitorKey, String monitorInstanceName,
       boolean monitorRootOnly, ZkEventThread zkEventThread) {
-    if (monitorKey == null || monitorKey.isEmpty() || monitorType == null || monitorType
-        .isEmpty()) {
-      throw new HelixException("Cannot create ZkClientMonitor without monitor key and type.");
-    }
-
-    _sensorName =
-        String.format("%s.%s.%s", MonitorDomainNames.HelixZkClient.name(), monitorType, monitorKey);
-    _monitorType = monitorType;
-    _monitorKey = monitorKey;
-    _monitorInstanceName = monitorInstanceName;
-    _monitorRootOnly = monitorRootOnly;
-
-    _stateChangeEventCounter = new SimpleDynamicMetric("StateChangeEventCounter", 0l);
-    _dataChangeEventCounter = new SimpleDynamicMetric("DataChangeEventCounter", 0l);
-    _outstandingRequestGauge = new SimpleDynamicMetric("OutstandingRequestGauge", 0l);
-    if (zkEventThread != null) {
-      _zkEventThreadMetric = new ZkThreadMetric(zkEventThread);
-    }
-  }
-
-  protected static ObjectName getObjectName(String monitorType, String monitorKey,
-      String monitorInstanceName) throws MalformedObjectNameException {
-    return MBeanRegistrar
-        .buildObjectName(MonitorDomainNames.HelixZkClient.name(), MONITOR_TYPE, monitorType,
-            MONITOR_KEY,
-            (monitorKey + (monitorInstanceName == null ? "" : "." + monitorInstanceName)));
-  }
-
-  @Override
-  public DynamicMBeanProvider register() throws JMException {
-    List<DynamicMetric<?, ?>> attributeList = new ArrayList<>();
-    attributeList.add(_dataChangeEventCounter);
-    attributeList.add(_outstandingRequestGauge);
-    attributeList.add(_stateChangeEventCounter);
-    if (_zkEventThreadMetric != null) {
-      attributeList.add(_zkEventThreadMetric);
-    }
-    doRegister(attributeList, MBEAN_DESCRIPTION,
-        getObjectName(_monitorType, _monitorKey, _monitorInstanceName));
-    for (ZkClientPathMonitor.PredefinedPath path : ZkClientPathMonitor.PredefinedPath.values()) {
-      // If monitor root path only, check if the current path is Root.
-      // Otherwise, add monitors for every path.
-      if (!_monitorRootOnly || path.equals(ZkClientPathMonitor.PredefinedPath.Root)) {
-        _zkClientPathMonitorMap.put(path,
-            new ZkClientPathMonitor(path, _monitorType, _monitorKey, _monitorInstanceName)
-                .register());
-      }
-    }
-    return this;
-  }
-
-  /**
-   * After unregistered, the MBean can't be registered again, a new monitor has be to created.
-   */
-  public void unregister() {
-    super.unregister();
-    for (ZkClientPathMonitor zkClientPathMonitor : _zkClientPathMonitorMap.values()) {
-      zkClientPathMonitor.unregister();
-    }
-  }
-
-  @Override
-  public String getSensorName() {
-    return _sensorName;
-  }
-
-  public void increaseStateChangeEventCounter() {
-    synchronized (_stateChangeEventCounter) {
-      _stateChangeEventCounter.updateValue(_stateChangeEventCounter.getValue() + 1);
-    }
-  }
-
-  public void increaseDataChangeEventCounter() {
-    synchronized (_dataChangeEventCounter) {
-      _dataChangeEventCounter.updateValue(_dataChangeEventCounter.getValue() + 1);
-    }
-  }
-
-  public void increaseOutstandingRequestGauge() {
-    synchronized (_outstandingRequestGauge) {
-      _outstandingRequestGauge.updateValue(_outstandingRequestGauge.getValue() + 1);
-    }
-  }
-
-  public void decreaseOutstandingRequestGauge() {
-    synchronized (_outstandingRequestGauge) {
-      _outstandingRequestGauge.updateValue(_outstandingRequestGauge.getValue() - 1);
-    }
-  }
-
-  public void recordDataPropagationLatency(String path, long latencyMilliSec) {
-    if (null == path) {
-      return;
-    }
-    Arrays.stream(ZkClientPathMonitor.PredefinedPath.values())
-        .filter(predefinedPath -> predefinedPath.match(path))
-        .forEach(predefinedPath -> {
-      ZkClientPathMonitor zkClientPathMonitor = _zkClientPathMonitorMap.get(predefinedPath);
-      if (zkClientPathMonitor != null) {
-        zkClientPathMonitor.recordDataPropagationLatency(latencyMilliSec);
-      }
-    });
-  }
-
-  private void record(String path, int bytes, long latencyMilliSec, boolean isFailure,
-      boolean isRead) {
-    if (null == path) {
-      return;
-    }
-    Arrays.stream(ZkClientPathMonitor.PredefinedPath.values())
-        .filter(predefinedPath -> predefinedPath.match(path))
-        .forEach(predefinedPath -> {
-      ZkClientPathMonitor zkClientPathMonitor = _zkClientPathMonitorMap.get(predefinedPath);
-      if (zkClientPathMonitor != null) {
-        zkClientPathMonitor.record(bytes, latencyMilliSec, isFailure, isRead);
-      }
-    });
-  }
-
-  public void record(String path, int dataSize, long startTimeMilliSec, AccessType accessType) {
-    switch (accessType) {
-    case READ:
-      record(path, dataSize, System.currentTimeMillis() - startTimeMilliSec, false, true);
-      return;
-    case WRITE:
-      record(path, dataSize, System.currentTimeMillis() - startTimeMilliSec, false, false);
-      return;
-    default:
-      return;
-    }
-  }
-
-  public void recordFailure(String path, AccessType accessType) {
-    switch (accessType) {
-    case READ:
-      record(path, 0, 0, true, true);
-      return;
-    case WRITE:
-      record(path, 0, 0, true, false);
-      return;
-    default:
-      return;
-    }
-  }
-
-  class ZkThreadMetric extends DynamicMetric<ZkEventThread, ZkEventThread> {
-    public ZkThreadMetric(ZkEventThread eventThread) {
-      super("ZkEventThead", eventThread);
-    }
-
-    @Override
-    protected Set<MBeanAttributeInfo> generateAttributeInfos(String metricName,
-        ZkEventThread eventThread) {
-      Set<MBeanAttributeInfo> attributeInfoSet = new HashSet<>();
-      attributeInfoSet.add(new MBeanAttributeInfo("PendingCallbackGauge", Long.TYPE.getName(),
-          DEFAULT_ATTRIBUTE_DESCRIPTION, true, false, false));
-      attributeInfoSet.add(new MBeanAttributeInfo("TotalCallbackCounter", Long.TYPE.getName(),
-          DEFAULT_ATTRIBUTE_DESCRIPTION, true, false, false));
-      attributeInfoSet.add(
-          new MBeanAttributeInfo("TotalCallbackHandledCounter", Long.TYPE.getName(),
-              DEFAULT_ATTRIBUTE_DESCRIPTION, true, false, false));
-      return attributeInfoSet;
-    }
-
-    @Override
-    public Object getAttributeValue(String attributeName) {
-      switch (attributeName) {
-      case "PendingCallbackGauge":
-        return getMetricObject().getPendingEventsCount();
-      case "TotalCallbackCounter":
-        return getMetricObject().getTotalEventCount();
-      case "TotalCallbackHandledCounter":
-        return getMetricObject().getTotalHandledEventCount();
-      default:
-        throw new HelixException("Unknown attribute name: " + attributeName);
-      }
-    }
-
-    @Override
-    public void updateValue(ZkEventThread newEventThread) {
-      setMetricObject(newEventThread);
-    }
+    super(monitorType, monitorKey, monitorInstanceName, monitorRootOnly, zkEventThread);
   }
 }
diff --git a/helix-core/src/main/java/org/apache/helix/monitoring/mbeans/ZkClientPathMonitor.java b/helix-core/src/main/java/org/apache/helix/monitoring/mbeans/ZkClientPathMonitor.java
index 1795243..6b8d642 100644
--- a/helix-core/src/main/java/org/apache/helix/monitoring/mbeans/ZkClientPathMonitor.java
+++ b/helix-core/src/main/java/org/apache/helix/monitoring/mbeans/ZkClientPathMonitor.java
@@ -19,228 +19,14 @@ package org.apache.helix.monitoring.mbeans;
  * under the License.
  */
 
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.TimeUnit;
-import javax.management.JMException;
-import javax.management.ObjectName;
-
-import com.codahale.metrics.Histogram;
-import com.codahale.metrics.SlidingTimeWindowArrayReservoir;
-import org.apache.helix.monitoring.mbeans.dynamicMBeans.DynamicMBeanProvider;
-import org.apache.helix.monitoring.mbeans.dynamicMBeans.DynamicMetric;
-import org.apache.helix.monitoring.mbeans.dynamicMBeans.HistogramDynamicMetric;
-import org.apache.helix.monitoring.mbeans.dynamicMBeans.SimpleDynamicMetric;
-
-public class ZkClientPathMonitor extends DynamicMBeanProvider {
-  public static final String MONITOR_PATH = "PATH";
-  private final String _sensorName;
-  private final String _type;
-  private final String _key;
-  private final String _instanceName;
-  private final PredefinedPath _path;
-
-  public enum PredefinedPath {
-    IdealStates(".*/IDEALSTATES/.*"),
-    Instances(".*/INSTANCES/.*"),
-    Configs(".*/CONFIGS/.*"),
-    Controller(".*/CONTROLLER/.*"),
-    ExternalView(".*/EXTERNALVIEW/.*"),
-    LiveInstances(".*/LIVEINSTANCES/.*"),
-    PropertyStore(".*/PROPERTYSTORE/.*"),
-    CurrentStates(".*/CURRENTSTATES/.*"),
-    Messages(".*/MESSAGES/.*"),
-    Root(".*");
-
-    private final String _matchString;
-
-    PredefinedPath(String matchString) {
-      _matchString = matchString;
-    }
-
-    public boolean match(String path) {
-      return path.matches(this._matchString);
-    }
-  }
-
-  public enum PredefinedMetricDomains {
-    WriteTotalLatencyCounter,
-    ReadTotalLatencyCounter,
-    WriteFailureCounter,
-    ReadFailureCounter,
-    WriteBytesCounter,
-    ReadBytesCounter,
-    WriteCounter,
-    ReadCounter,
-    ReadLatencyGauge,
-    WriteLatencyGauge,
-    ReadBytesGauge,
-    WriteBytesGauge,
-    /*
-     * The latency between a ZK data change happening on the server side and the client side.
-     */
-    DataPropagationLatencyGauge,
-    /**
-     * @deprecated
-     * This domain name has a typo. Keep it in case its historical metric data is being used.
-     */
-    @Deprecated
-    DataPropagationLatencyGuage
-  }
-
-  private SimpleDynamicMetric<Long> _readCounter;
-  private SimpleDynamicMetric<Long> _writeCounter;
-  private SimpleDynamicMetric<Long> _readBytesCounter;
-  private SimpleDynamicMetric<Long> _writeBytesCounter;
-  private SimpleDynamicMetric<Long> _readFailureCounter;
-  private SimpleDynamicMetric<Long> _writeFailureCounter;
-  private SimpleDynamicMetric<Long> _readTotalLatencyCounter;
-  private SimpleDynamicMetric<Long> _writeTotalLatencyCounter;
-
-  private HistogramDynamicMetric _readLatencyGauge;
-  private HistogramDynamicMetric _writeLatencyGauge;
-  private HistogramDynamicMetric _readBytesGauge;
-  private HistogramDynamicMetric _writeBytesGauge;
-  private HistogramDynamicMetric _dataPropagationLatencyGauge;
-
-  /**
-   * @deprecated
-   * Keep it for backward-compatibility purpose.
-   */
-  @Deprecated
-  private HistogramDynamicMetric _dataPropagationLatencyGuage;
-
-  @Override
-  public String getSensorName() {
-    return _sensorName;
-  }
-
+/**
+ * Use ZkClientPathMonitor in zookeeper-api module instead.
+ */
+@Deprecated
+public class ZkClientPathMonitor
+    extends org.apache.helix.zookeeper.zkclient.metric.ZkClientPathMonitor {
   public ZkClientPathMonitor(PredefinedPath path, String monitorType, String monitorKey,
       String monitorInstanceName) {
-    _type = monitorType;
-    _key = monitorKey;
-    _instanceName = monitorInstanceName;
-    _path = path;
-    _sensorName = String
-        .format("%s.%s.%s.%s", MonitorDomainNames.HelixZkClient.name(), monitorType, monitorKey,
-            path.name());
-
-    _writeTotalLatencyCounter =
-        new SimpleDynamicMetric(PredefinedMetricDomains.WriteTotalLatencyCounter.name(), 0l);
-    _readTotalLatencyCounter =
-        new SimpleDynamicMetric(PredefinedMetricDomains.ReadTotalLatencyCounter.name(), 0l);
-    _writeFailureCounter =
-        new SimpleDynamicMetric(PredefinedMetricDomains.WriteFailureCounter.name(), 0l);
-    _readFailureCounter =
-        new SimpleDynamicMetric(PredefinedMetricDomains.ReadFailureCounter.name(), 0l);
-    _writeBytesCounter =
-        new SimpleDynamicMetric(PredefinedMetricDomains.WriteBytesCounter.name(), 0l);
-    _readBytesCounter =
-        new SimpleDynamicMetric(PredefinedMetricDomains.ReadBytesCounter.name(), 0l);
-    _writeCounter = new SimpleDynamicMetric(PredefinedMetricDomains.WriteCounter.name(), 0l);
-    _readCounter = new SimpleDynamicMetric(PredefinedMetricDomains.ReadCounter.name(), 0l);
-
-    _readLatencyGauge = new HistogramDynamicMetric(PredefinedMetricDomains.ReadLatencyGauge.name(),
-        new Histogram(
-            new SlidingTimeWindowArrayReservoir(getResetIntervalInMs(), TimeUnit.MILLISECONDS)));
-    _writeLatencyGauge =
-        new HistogramDynamicMetric(PredefinedMetricDomains.WriteLatencyGauge.name(), new Histogram(
-            new SlidingTimeWindowArrayReservoir(getResetIntervalInMs(), TimeUnit.MILLISECONDS)));
-    _readBytesGauge = new HistogramDynamicMetric(PredefinedMetricDomains.ReadBytesGauge.name(),
-        new Histogram(
-            new SlidingTimeWindowArrayReservoir(getResetIntervalInMs(), TimeUnit.MILLISECONDS)));
-    _writeBytesGauge = new HistogramDynamicMetric(PredefinedMetricDomains.WriteBytesGauge.name(),
-        new Histogram(
-            new SlidingTimeWindowArrayReservoir(getResetIntervalInMs(), TimeUnit.MILLISECONDS)));
-    _dataPropagationLatencyGauge =
-        new HistogramDynamicMetric(PredefinedMetricDomains.DataPropagationLatencyGauge.name(),
-            new Histogram(new SlidingTimeWindowArrayReservoir(getResetIntervalInMs(),
-                TimeUnit.MILLISECONDS)));
-
-    // This is deprecated and keep it for backward-compatibility purpose.
-    _dataPropagationLatencyGuage =
-        new HistogramDynamicMetric(PredefinedMetricDomains.DataPropagationLatencyGuage.name(),
-            new Histogram(new SlidingTimeWindowArrayReservoir(getResetIntervalInMs(),
-                TimeUnit.MILLISECONDS)));
-  }
-
-  public ZkClientPathMonitor register() throws JMException {
-    List<DynamicMetric<?, ?>> attributeList = new ArrayList<>();
-    attributeList.add(_readCounter);
-    attributeList.add(_writeCounter);
-    attributeList.add(_readBytesCounter);
-    attributeList.add(_writeBytesCounter);
-    attributeList.add(_readFailureCounter);
-    attributeList.add(_writeFailureCounter);
-    attributeList.add(_readTotalLatencyCounter);
-    attributeList.add(_writeTotalLatencyCounter);
-    attributeList.add(_readLatencyGauge);
-    attributeList.add(_writeLatencyGauge);
-    attributeList.add(_readBytesGauge);
-    attributeList.add(_writeBytesGauge);
-    attributeList.add(_dataPropagationLatencyGauge);
-    // This is deprecated and keep it for backward-compatibility purpose.
-    attributeList.add(_dataPropagationLatencyGuage);
-
-    ObjectName objectName = new ObjectName(String
-        .format("%s,%s=%s", ZkClientMonitor.getObjectName(_type, _key, _instanceName).toString(),
-            MONITOR_PATH, _path.name()));
-    doRegister(attributeList, ZkClientMonitor.MBEAN_DESCRIPTION, objectName);
-
-    return this;
-  }
-
-  protected synchronized void record(int bytes, long latencyMilliSec, boolean isFailure,
-      boolean isRead) {
-    if (isFailure) {
-      increaseFailureCounter(isRead);
-    } else {
-      increaseCounter(isRead);
-      increaseTotalLatency(isRead, latencyMilliSec);
-      if (bytes > 0) {
-        increaseBytesCounter(isRead, bytes);
-      }
-    }
-  }
-
-  public void recordDataPropagationLatency(long latency) {
-    _dataPropagationLatencyGauge.updateValue(latency);
-    _dataPropagationLatencyGuage.updateValue(latency);
-  }
-
-  private void increaseFailureCounter(boolean isRead) {
-    if (isRead) {
-      _readFailureCounter.updateValue(_readFailureCounter.getValue() + 1);
-    } else {
-      _writeFailureCounter.updateValue(_writeFailureCounter.getValue() + 1);
-    }
-  }
-
-  private void increaseCounter(boolean isRead) {
-    if (isRead) {
-      _readCounter.updateValue(_readCounter.getValue() + 1);
-    } else {
-      _writeCounter.updateValue(_writeCounter.getValue() + 1);
-    }
-  }
-
-  private void increaseBytesCounter(boolean isRead, int bytes) {
-    if (isRead) {
-      _readBytesCounter.updateValue(_readBytesCounter.getValue() + bytes);
-      _readBytesGauge.updateValue((long) bytes);
-    } else {
-      _writeBytesCounter.updateValue(_writeBytesCounter.getValue() + bytes);
-      _writeBytesGauge.updateValue((long) bytes);
-    }
-  }
-
-  private void increaseTotalLatency(boolean isRead, long latencyDelta) {
-    if (isRead) {
-      _readTotalLatencyCounter.updateValue(_readTotalLatencyCounter.getValue() + latencyDelta);
-      _readLatencyGauge.updateValue(latencyDelta);
-    } else {
-      _writeTotalLatencyCounter.updateValue(_writeTotalLatencyCounter.getValue() + latencyDelta);
-      _writeLatencyGauge.updateValue(latencyDelta);
-    }
+    super(path, monitorType, monitorKey, monitorInstanceName);
   }
 }
diff --git a/helix-core/src/main/java/org/apache/helix/participant/HelixCustomCodeRunner.java b/helix-core/src/main/java/org/apache/helix/participant/HelixCustomCodeRunner.java
index b29126c..8d10e8f 100644
--- a/helix-core/src/main/java/org/apache/helix/participant/HelixCustomCodeRunner.java
+++ b/helix-core/src/main/java/org/apache/helix/participant/HelixCustomCodeRunner.java
@@ -23,21 +23,21 @@ import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
 
+import org.apache.helix.zookeeper.api.client.HelixZkClient;
 import org.apache.helix.HelixConstants.ChangeType;
 import org.apache.helix.HelixDataAccessor;
 import org.apache.helix.HelixManager;
 import org.apache.helix.PropertyKey.Builder;
-import org.apache.helix.ZNRecord;
 import org.apache.helix.manager.zk.ZKHelixDataAccessor;
 import org.apache.helix.manager.zk.ZNRecordSerializer;
 import org.apache.helix.manager.zk.ZkBaseDataAccessor;
-import org.apache.helix.manager.zk.client.HelixZkClient;
-import org.apache.helix.manager.zk.client.SharedZkClientFactory;
 import org.apache.helix.model.IdealState;
 import org.apache.helix.model.IdealState.RebalanceMode;
+import org.apache.helix.zookeeper.impl.factory.SharedZkClientFactory;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+
 /**
  * This provides the ability for users to run a custom code in exactly one
  * process using a LeaderStandBy state model. <br/>
@@ -136,12 +136,11 @@ public class HelixCustomCodeRunner {
       // model
       HelixZkClient.ZkClientConfig clientConfig = new HelixZkClient.ZkClientConfig();
       clientConfig.setZkSerializer(new ZNRecordSerializer());
-      zkClient = SharedZkClientFactory
-          .getInstance().buildZkClient(new HelixZkClient.ZkConnectionConfig(_zkAddr), clientConfig);
+      zkClient = SharedZkClientFactory.getInstance()
+          .buildZkClient(new HelixZkClient.ZkConnectionConfig(_zkAddr), clientConfig);
 
       HelixDataAccessor accessor =
-          new ZKHelixDataAccessor(_manager.getClusterName(), new ZkBaseDataAccessor<ZNRecord>(
-              zkClient));
+          new ZKHelixDataAccessor(_manager.getClusterName(), new ZkBaseDataAccessor<>(zkClient));
       Builder keyBuilder = accessor.keyBuilder();
 
       IdealState idealState = new IdealState(_resourceName);
@@ -150,8 +149,8 @@ public class HelixCustomCodeRunner {
       idealState.setNumPartitions(1);
       idealState.setStateModelDefRef(LEADER_STANDBY);
       idealState.setStateModelFactoryName(_resourceName);
-      List<String> prefList =
-          new ArrayList<String>(Arrays.asList(IdealState.IdealStateConstants.ANY_LIVEINSTANCE.toString()));
+      List<String> prefList = new ArrayList<String>(
+          Arrays.asList(IdealState.IdealStateConstants.ANY_LIVEINSTANCE.toString()));
       idealState.getRecord().setListField(_resourceName + "_0", prefList);
 
       List<String> idealStates = accessor.getChildNames(keyBuilder.idealStates());
@@ -160,14 +159,13 @@ public class HelixCustomCodeRunner {
         idealStates = accessor.getChildNames(keyBuilder.idealStates());
       }
 
-      LOG.info("Set idealState for participantLeader:" + _resourceName + ", idealState:"
-          + idealState);
+      LOG.info(
+          "Set idealState for participantLeader:" + _resourceName + ", idealState:" + idealState);
     } finally {
       if (zkClient != null && !zkClient.isClosed()) {
         zkClient.close();
       }
     }
-
   }
 
   /**
@@ -175,7 +173,7 @@ public class HelixCustomCodeRunner {
    */
   public void stop() {
     LOG.info("Removing stateModelFactory for " + _resourceName);
-    _manager.getStateMachineEngine().removeStateModelFactory(LEADER_STANDBY, _stateModelFty,
-        _resourceName);
+    _manager.getStateMachineEngine()
+        .removeStateModelFactory(LEADER_STANDBY, _stateModelFty, _resourceName);
   }
 }
diff --git a/helix-core/src/main/java/org/apache/helix/participant/statemachine/ScheduledTaskStateModel.java b/helix-core/src/main/java/org/apache/helix/participant/statemachine/ScheduledTaskStateModel.java
index 750c7c9..8a54570 100644
--- a/helix-core/src/main/java/org/apache/helix/participant/statemachine/ScheduledTaskStateModel.java
+++ b/helix-core/src/main/java/org/apache/helix/participant/statemachine/ScheduledTaskStateModel.java
@@ -23,7 +23,7 @@ import java.util.Map;
 
 import org.apache.helix.HelixException;
 import org.apache.helix.NotificationContext;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
 import org.apache.helix.messaging.handling.HelixTaskExecutor;
 import org.apache.helix.messaging.handling.MessageHandler;
 import org.apache.helix.model.Message;
diff --git a/helix-core/src/main/java/org/apache/helix/store/PropertyJsonSerializer.java b/helix-core/src/main/java/org/apache/helix/store/PropertyJsonSerializer.java
index d9bb82d..75d056b 100644
--- a/helix-core/src/main/java/org/apache/helix/store/PropertyJsonSerializer.java
+++ b/helix-core/src/main/java/org/apache/helix/store/PropertyJsonSerializer.java
@@ -23,7 +23,7 @@ import java.io.ByteArrayInputStream;
 import java.io.StringWriter;
 
 import org.apache.helix.HelixException;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
 import org.codehaus.jackson.map.DeserializationConfig;
 import org.codehaus.jackson.map.ObjectMapper;
 import org.codehaus.jackson.map.SerializationConfig;
diff --git a/helix-core/src/main/java/org/apache/helix/store/ZNRecordJsonSerializer.java b/helix-core/src/main/java/org/apache/helix/store/ZNRecordJsonSerializer.java
index dfb0a0d..64bf74f 100644
--- a/helix-core/src/main/java/org/apache/helix/store/ZNRecordJsonSerializer.java
+++ b/helix-core/src/main/java/org/apache/helix/store/ZNRecordJsonSerializer.java
@@ -19,7 +19,7 @@ package org.apache.helix.store;
  * under the License.
  */
 
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
 import org.apache.helix.manager.zk.ZNRecordSerializer;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
diff --git a/helix-core/src/main/java/org/apache/helix/store/zk/AutoFallbackPropertyStore.java b/helix-core/src/main/java/org/apache/helix/store/zk/AutoFallbackPropertyStore.java
index dafa36d..47b1dfa 100644
--- a/helix-core/src/main/java/org/apache/helix/store/zk/AutoFallbackPropertyStore.java
+++ b/helix-core/src/main/java/org/apache/helix/store/zk/AutoFallbackPropertyStore.java
@@ -26,9 +26,9 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
-import org.I0Itec.zkclient.DataUpdater;
 import org.apache.helix.AccessOption;
 import org.apache.helix.manager.zk.ZkBaseDataAccessor;
+import org.apache.helix.zookeeper.zkclient.DataUpdater;
 import org.apache.zookeeper.data.Stat;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
diff --git a/helix-core/src/main/java/org/apache/helix/store/zk/ZkHelixPropertyStore.java b/helix-core/src/main/java/org/apache/helix/store/zk/ZkHelixPropertyStore.java
index a6e7a9c..1ea9c6f 100644
--- a/helix-core/src/main/java/org/apache/helix/store/zk/ZkHelixPropertyStore.java
+++ b/helix-core/src/main/java/org/apache/helix/store/zk/ZkHelixPropertyStore.java
@@ -21,9 +21,10 @@ package org.apache.helix.store.zk;
 
 import java.util.List;
 
-import org.I0Itec.zkclient.serialize.ZkSerializer;
 import org.apache.helix.manager.zk.ZkBaseDataAccessor;
 import org.apache.helix.manager.zk.ZkCacheBaseDataAccessor;
+import org.apache.helix.zookeeper.zkclient.serialize.ZkSerializer;
+
 
 public class ZkHelixPropertyStore<T> extends ZkCacheBaseDataAccessor<T> {
   public static final String MONITOR_TYPE = "HelixPropertyStore";
diff --git a/helix-core/src/main/java/org/apache/helix/task/DeprecatedTaskRebalancer.java b/helix-core/src/main/java/org/apache/helix/task/DeprecatedTaskRebalancer.java
index 115237f..d508d1b 100644
--- a/helix-core/src/main/java/org/apache/helix/task/DeprecatedTaskRebalancer.java
+++ b/helix-core/src/main/java/org/apache/helix/task/DeprecatedTaskRebalancer.java
@@ -44,14 +44,13 @@ import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
 import com.google.common.collect.Sets;
-import org.I0Itec.zkclient.DataUpdater;
 import org.apache.helix.AccessOption;
 import org.apache.helix.HelixDataAccessor;
 import org.apache.helix.HelixDefinedState;
 import org.apache.helix.HelixManager;
 import org.apache.helix.HelixProperty;
 import org.apache.helix.PropertyKey;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
 import org.apache.helix.controller.dataproviders.WorkflowControllerDataProvider;
 import org.apache.helix.controller.rebalancer.Rebalancer;
 import org.apache.helix.controller.rebalancer.internal.MappingCalculator;
@@ -62,6 +61,7 @@ import org.apache.helix.model.Message;
 import org.apache.helix.model.Partition;
 import org.apache.helix.model.Resource;
 import org.apache.helix.model.ResourceAssignment;
+import org.apache.helix.zookeeper.zkclient.DataUpdater;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
diff --git a/helix-core/src/main/java/org/apache/helix/task/JobContext.java b/helix-core/src/main/java/org/apache/helix/task/JobContext.java
index 26628a4..9917c83 100644
--- a/helix-core/src/main/java/org/apache/helix/task/JobContext.java
+++ b/helix-core/src/main/java/org/apache/helix/task/JobContext.java
@@ -29,7 +29,7 @@ import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
 import com.google.common.collect.Sets;
 import org.apache.helix.HelixProperty;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
 
 /**
  * Provides a typed interface to the context information stored by {@link TaskRebalancer} in the
diff --git a/helix-core/src/main/java/org/apache/helix/task/JobDispatcher.java b/helix-core/src/main/java/org/apache/helix/task/JobDispatcher.java
index 90729d6..479b47c 100644
--- a/helix-core/src/main/java/org/apache/helix/task/JobDispatcher.java
+++ b/helix-core/src/main/java/org/apache/helix/task/JobDispatcher.java
@@ -30,7 +30,7 @@ import java.util.TreeMap;
 import java.util.TreeSet;
 
 import com.google.common.collect.ImmutableMap;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
 import org.apache.helix.controller.dataproviders.WorkflowControllerDataProvider;
 import org.apache.helix.controller.stages.CurrentStateOutput;
 import org.apache.helix.model.Message;
diff --git a/helix-core/src/main/java/org/apache/helix/task/TaskDriver.java b/helix-core/src/main/java/org/apache/helix/task/TaskDriver.java
index 9eb46fc..0b8fa17 100644
--- a/helix-core/src/main/java/org/apache/helix/task/TaskDriver.java
+++ b/helix-core/src/main/java/org/apache/helix/task/TaskDriver.java
@@ -28,7 +28,6 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
-import org.I0Itec.zkclient.DataUpdater;
 import org.apache.helix.AccessOption;
 import org.apache.helix.BaseDataAccessor;
 import org.apache.helix.ConfigAccessor;
@@ -39,17 +38,18 @@ import org.apache.helix.HelixManager;
 import org.apache.helix.PropertyKey;
 import org.apache.helix.PropertyPathBuilder;
 import org.apache.helix.SystemPropertyKeys;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
 import org.apache.helix.manager.zk.ZKHelixAdmin;
 import org.apache.helix.manager.zk.ZKHelixDataAccessor;
 import org.apache.helix.manager.zk.ZkBaseDataAccessor;
-import org.apache.helix.manager.zk.client.HelixZkClient;
+import org.apache.helix.zookeeper.api.client.HelixZkClient;
 import org.apache.helix.model.IdealState;
 import org.apache.helix.model.ResourceConfig;
 import org.apache.helix.model.builder.CustomModeISBuilder;
 import org.apache.helix.store.HelixPropertyStore;
 import org.apache.helix.store.zk.ZkHelixPropertyStore;
 import org.apache.helix.util.HelixUtil;
+import org.apache.helix.zookeeper.zkclient.DataUpdater;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
diff --git a/helix-core/src/main/java/org/apache/helix/task/TaskUtil.java b/helix-core/src/main/java/org/apache/helix/task/TaskUtil.java
index 5c93469..6b36db4 100644
--- a/helix-core/src/main/java/org/apache/helix/task/TaskUtil.java
+++ b/helix-core/src/main/java/org/apache/helix/task/TaskUtil.java
@@ -29,14 +29,13 @@ import java.util.Set;
 
 import com.google.common.base.Joiner;
 import com.google.common.collect.Sets;
-import org.I0Itec.zkclient.DataUpdater;
 import org.apache.helix.AccessOption;
 import org.apache.helix.HelixDataAccessor;
 import org.apache.helix.HelixException;
 import org.apache.helix.HelixManager;
 import org.apache.helix.HelixProperty;
 import org.apache.helix.PropertyKey;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
 import org.apache.helix.controller.dataproviders.WorkflowControllerDataProvider;
 import org.apache.helix.controller.rebalancer.util.RebalanceScheduler;
 import org.apache.helix.model.HelixConfigScope;
@@ -44,6 +43,7 @@ import org.apache.helix.model.ResourceConfig;
 import org.apache.helix.model.builder.HelixConfigScopeBuilder;
 import org.apache.helix.store.HelixPropertyStore;
 import org.apache.helix.util.RebalanceUtil;
+import org.apache.helix.zookeeper.zkclient.DataUpdater;
 import org.codehaus.jackson.map.ObjectMapper;
 import org.codehaus.jackson.type.TypeReference;
 import org.slf4j.Logger;
diff --git a/helix-core/src/main/java/org/apache/helix/task/WorkflowContext.java b/helix-core/src/main/java/org/apache/helix/task/WorkflowContext.java
index c915e3b..3cbdad8 100644
--- a/helix-core/src/main/java/org/apache/helix/task/WorkflowContext.java
+++ b/helix-core/src/main/java/org/apache/helix/task/WorkflowContext.java
@@ -27,7 +27,7 @@ import java.util.Set;
 import java.util.TreeMap;
 
 import org.apache.helix.HelixProperty;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
diff --git a/helix-core/src/main/java/org/apache/helix/task/WorkflowDispatcher.java b/helix-core/src/main/java/org/apache/helix/task/WorkflowDispatcher.java
index 1ed9ab0..11d6687 100644
--- a/helix-core/src/main/java/org/apache/helix/task/WorkflowDispatcher.java
+++ b/helix-core/src/main/java/org/apache/helix/task/WorkflowDispatcher.java
@@ -37,7 +37,7 @@ import org.apache.helix.HelixDataAccessor;
 import org.apache.helix.HelixManager;
 import org.apache.helix.HelixProperty;
 import org.apache.helix.PropertyKey;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
 import org.apache.helix.common.caches.TaskDataCache;
 import org.apache.helix.controller.LogUtil;
 import org.apache.helix.controller.dataproviders.WorkflowControllerDataProvider;
diff --git a/helix-core/src/main/java/org/apache/helix/tools/ClusterExternalViewVerifier.java b/helix-core/src/main/java/org/apache/helix/tools/ClusterExternalViewVerifier.java
index a342c2e..d10ba71 100644
--- a/helix-core/src/main/java/org/apache/helix/tools/ClusterExternalViewVerifier.java
+++ b/helix-core/src/main/java/org/apache/helix/tools/ClusterExternalViewVerifier.java
@@ -35,7 +35,7 @@ import org.apache.helix.controller.stages.ClusterEvent;
 import org.apache.helix.controller.stages.ClusterEventType;
 import org.apache.helix.controller.stages.CurrentStateComputationStage;
 import org.apache.helix.controller.stages.ResourceComputationStage;
-import org.apache.helix.manager.zk.client.HelixZkClient;
+import org.apache.helix.zookeeper.api.client.HelixZkClient;
 import org.apache.helix.model.ExternalView;
 import org.apache.helix.model.Partition;
 import org.slf4j.Logger;
diff --git a/helix-core/src/main/java/org/apache/helix/tools/ClusterLiveNodesVerifier.java b/helix-core/src/main/java/org/apache/helix/tools/ClusterLiveNodesVerifier.java
index 164cfcc..c5c1311 100644
--- a/helix-core/src/main/java/org/apache/helix/tools/ClusterLiveNodesVerifier.java
+++ b/helix-core/src/main/java/org/apache/helix/tools/ClusterLiveNodesVerifier.java
@@ -22,7 +22,7 @@ package org.apache.helix.tools;
 import java.util.Collections;
 import java.util.List;
 
-import org.apache.helix.manager.zk.client.HelixZkClient;
+import org.apache.helix.zookeeper.api.client.HelixZkClient;
 
 /**
  * Please use the class is in tools.ClusterVerifiers.
diff --git a/helix-core/src/main/java/org/apache/helix/tools/ClusterSetup.java b/helix-core/src/main/java/org/apache/helix/tools/ClusterSetup.java
index 5d5f864..7ac20a1 100644
--- a/helix-core/src/main/java/org/apache/helix/tools/ClusterSetup.java
+++ b/helix-core/src/main/java/org/apache/helix/tools/ClusterSetup.java
@@ -27,7 +27,6 @@ import java.util.Arrays;
 import java.util.List;
 import java.util.Map;
 
-import org.I0Itec.zkclient.DataUpdater;
 import org.apache.commons.cli.CommandLine;
 import org.apache.commons.cli.CommandLineParser;
 import org.apache.commons.cli.GnuParser;
@@ -41,13 +40,13 @@ import org.apache.helix.HelixAdmin;
 import org.apache.helix.HelixConstants;
 import org.apache.helix.HelixException;
 import org.apache.helix.PropertyKey.Builder;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
 import org.apache.helix.manager.zk.ZKHelixAdmin;
 import org.apache.helix.manager.zk.ZKHelixDataAccessor;
 import org.apache.helix.manager.zk.ZNRecordSerializer;
 import org.apache.helix.manager.zk.ZkBaseDataAccessor;
-import org.apache.helix.manager.zk.client.HelixZkClient;
-import org.apache.helix.manager.zk.client.SharedZkClientFactory;
+import org.apache.helix.zookeeper.api.client.HelixZkClient;
+import org.apache.helix.zookeeper.impl.factory.SharedZkClientFactory;
 import org.apache.helix.model.BuiltInStateModelDefinitions;
 import org.apache.helix.model.ClusterConfig;
 import org.apache.helix.model.ClusterConstraints;
@@ -64,6 +63,7 @@ import org.apache.helix.model.StateModelDefinition;
 import org.apache.helix.model.builder.ConstraintItemBuilder;
 import org.apache.helix.model.builder.HelixConfigScopeBuilder;
 import org.apache.helix.util.HelixUtil;
+import org.apache.helix.zookeeper.zkclient.DataUpdater;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
diff --git a/helix-core/src/main/java/org/apache/helix/tools/ClusterStateVerifier.java b/helix-core/src/main/java/org/apache/helix/tools/ClusterStateVerifier.java
index a398c24..80ccb68 100644
--- a/helix-core/src/main/java/org/apache/helix/tools/ClusterStateVerifier.java
+++ b/helix-core/src/main/java/org/apache/helix/tools/ClusterStateVerifier.java
@@ -29,9 +29,6 @@ import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
 
 import com.google.common.collect.Sets;
-import org.I0Itec.zkclient.IZkChildListener;
-import org.I0Itec.zkclient.IZkDataListener;
-import org.I0Itec.zkclient.exception.ZkNodeExistsException;
 import org.apache.commons.cli.CommandLine;
 import org.apache.commons.cli.CommandLineParser;
 import org.apache.commons.cli.GnuParser;
@@ -45,7 +42,8 @@ import org.apache.helix.HelixDefinedState;
 import org.apache.helix.PropertyKey;
 import org.apache.helix.PropertyKey.Builder;
 import org.apache.helix.PropertyPathBuilder;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.impl.client.ZkClient;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
 import org.apache.helix.api.listeners.PreFetch;
 import org.apache.helix.controller.dataproviders.ResourceControllerDataProvider;
 import org.apache.helix.controller.pipeline.Stage;
@@ -60,14 +58,16 @@ import org.apache.helix.controller.stages.ResourceComputationStage;
 import org.apache.helix.manager.zk.ZKHelixDataAccessor;
 import org.apache.helix.manager.zk.ZNRecordSerializer;
 import org.apache.helix.manager.zk.ZkBaseDataAccessor;
-import org.apache.helix.manager.zk.ZkClient;
-import org.apache.helix.manager.zk.client.DedicatedZkClientFactory;
-import org.apache.helix.manager.zk.client.HelixZkClient;
+import org.apache.helix.zookeeper.impl.factory.DedicatedZkClientFactory;
+import org.apache.helix.zookeeper.api.client.HelixZkClient;
 import org.apache.helix.model.ExternalView;
 import org.apache.helix.model.IdealState;
 import org.apache.helix.model.Partition;
 import org.apache.helix.model.Resource;
 import org.apache.helix.task.TaskConstants;
+import org.apache.helix.zookeeper.zkclient.IZkChildListener;
+import org.apache.helix.zookeeper.zkclient.IZkDataListener;
+import org.apache.helix.zookeeper.zkclient.exception.ZkNodeExistsException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
diff --git a/helix-core/src/main/java/org/apache/helix/tools/ClusterVerifier.java b/helix-core/src/main/java/org/apache/helix/tools/ClusterVerifier.java
index bbae075..272d8ae 100644
--- a/helix-core/src/main/java/org/apache/helix/tools/ClusterVerifier.java
+++ b/helix-core/src/main/java/org/apache/helix/tools/ClusterVerifier.java
@@ -23,15 +23,15 @@ import java.util.List;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
 
-import org.I0Itec.zkclient.IZkChildListener;
-import org.I0Itec.zkclient.IZkDataListener;
 import org.apache.helix.HelixDataAccessor;
 import org.apache.helix.PropertyKey;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
 import org.apache.helix.api.listeners.PreFetch;
 import org.apache.helix.manager.zk.ZKHelixDataAccessor;
 import org.apache.helix.manager.zk.ZkBaseDataAccessor;
-import org.apache.helix.manager.zk.client.HelixZkClient;
+import org.apache.helix.zookeeper.api.client.HelixZkClient;
+import org.apache.helix.zookeeper.zkclient.IZkChildListener;
+import org.apache.helix.zookeeper.zkclient.IZkDataListener;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
diff --git a/helix-core/src/main/java/org/apache/helix/tools/ClusterVerifiers/BestPossibleExternalViewVerifier.java b/helix-core/src/main/java/org/apache/helix/tools/ClusterVerifiers/BestPossibleExternalViewVerifier.java
index 66143fe..0efd187 100644
--- a/helix-core/src/main/java/org/apache/helix/tools/ClusterVerifiers/BestPossibleExternalViewVerifier.java
+++ b/helix-core/src/main/java/org/apache/helix/tools/ClusterVerifiers/BestPossibleExternalViewVerifier.java
@@ -50,8 +50,8 @@ import org.apache.helix.controller.stages.CurrentStateComputationStage;
 import org.apache.helix.controller.stages.CurrentStateOutput;
 import org.apache.helix.controller.stages.ResourceComputationStage;
 import org.apache.helix.manager.zk.ZkBucketDataAccessor;
-import org.apache.helix.manager.zk.ZkClient;
-import org.apache.helix.manager.zk.client.HelixZkClient;
+import org.apache.helix.zookeeper.impl.client.ZkClient;
+import org.apache.helix.zookeeper.api.client.HelixZkClient;
 import org.apache.helix.model.ClusterConfig;
 import org.apache.helix.model.ExternalView;
 import org.apache.helix.model.IdealState;
diff --git a/helix-core/src/main/java/org/apache/helix/tools/ClusterVerifiers/ClusterLiveNodesVerifier.java b/helix-core/src/main/java/org/apache/helix/tools/ClusterVerifiers/ClusterLiveNodesVerifier.java
index b4d3862..0c284ff 100644
--- a/helix-core/src/main/java/org/apache/helix/tools/ClusterVerifiers/ClusterLiveNodesVerifier.java
+++ b/helix-core/src/main/java/org/apache/helix/tools/ClusterVerifiers/ClusterLiveNodesVerifier.java
@@ -24,7 +24,7 @@ import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
 
-import org.apache.helix.manager.zk.client.HelixZkClient;
+import org.apache.helix.zookeeper.api.client.HelixZkClient;
 
 public class ClusterLiveNodesVerifier extends ZkHelixClusterVerifier {
 
diff --git a/helix-core/src/main/java/org/apache/helix/tools/ClusterVerifiers/StrictMatchExternalViewVerifier.java b/helix-core/src/main/java/org/apache/helix/tools/ClusterVerifiers/StrictMatchExternalViewVerifier.java
index 0b3c97e..fcc7261 100644
--- a/helix-core/src/main/java/org/apache/helix/tools/ClusterVerifiers/StrictMatchExternalViewVerifier.java
+++ b/helix-core/src/main/java/org/apache/helix/tools/ClusterVerifiers/StrictMatchExternalViewVerifier.java
@@ -33,8 +33,8 @@ import org.apache.helix.HelixException;
 import org.apache.helix.PropertyKey;
 import org.apache.helix.controller.dataproviders.ResourceControllerDataProvider;
 import org.apache.helix.controller.rebalancer.AbstractRebalancer;
-import org.apache.helix.manager.zk.ZkClient;
-import org.apache.helix.manager.zk.client.HelixZkClient;
+import org.apache.helix.zookeeper.impl.client.ZkClient;
+import org.apache.helix.zookeeper.api.client.HelixZkClient;
 import org.apache.helix.model.ClusterConfig;
 import org.apache.helix.model.ExternalView;
 import org.apache.helix.model.IdealState;
diff --git a/helix-core/src/main/java/org/apache/helix/tools/ClusterVerifiers/ZkHelixClusterVerifier.java b/helix-core/src/main/java/org/apache/helix/tools/ClusterVerifiers/ZkHelixClusterVerifier.java
index 6efdff5..e82fccf 100644
--- a/helix-core/src/main/java/org/apache/helix/tools/ClusterVerifiers/ZkHelixClusterVerifier.java
+++ b/helix-core/src/main/java/org/apache/helix/tools/ClusterVerifiers/ZkHelixClusterVerifier.java
@@ -25,17 +25,17 @@ import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 import java.util.concurrent.TimeUnit;
 
-import org.I0Itec.zkclient.IZkChildListener;
-import org.I0Itec.zkclient.IZkDataListener;
 import org.apache.helix.HelixDataAccessor;
 import org.apache.helix.PropertyKey;
 import org.apache.helix.api.listeners.PreFetch;
 import org.apache.helix.manager.zk.ZKHelixDataAccessor;
 import org.apache.helix.manager.zk.ZNRecordSerializer;
 import org.apache.helix.manager.zk.ZkBaseDataAccessor;
-import org.apache.helix.manager.zk.ZkClient;
-import org.apache.helix.manager.zk.client.DedicatedZkClientFactory;
-import org.apache.helix.manager.zk.client.HelixZkClient;
+import org.apache.helix.zookeeper.impl.client.ZkClient;
+import org.apache.helix.zookeeper.impl.factory.DedicatedZkClientFactory;
+import org.apache.helix.zookeeper.api.client.HelixZkClient;
+import org.apache.helix.zookeeper.zkclient.IZkChildListener;
+import org.apache.helix.zookeeper.zkclient.IZkDataListener;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
diff --git a/helix-core/src/main/java/org/apache/helix/tools/DefaultIdealStateCalculator.java b/helix-core/src/main/java/org/apache/helix/tools/DefaultIdealStateCalculator.java
index 886790a..ae68a8f 100644
--- a/helix-core/src/main/java/org/apache/helix/tools/DefaultIdealStateCalculator.java
+++ b/helix-core/src/main/java/org/apache/helix/tools/DefaultIdealStateCalculator.java
@@ -27,7 +27,7 @@ import java.util.Random;
 import java.util.TreeMap;
 
 import org.apache.helix.HelixException;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
 import org.apache.helix.model.IdealState.IdealStateProperty;
 
 /**
diff --git a/helix-core/src/main/java/org/apache/helix/tools/IdealCalculatorByConsistentHashing.java b/helix-core/src/main/java/org/apache/helix/tools/IdealCalculatorByConsistentHashing.java
index 1101a6d..8c1e8d7 100644
--- a/helix-core/src/main/java/org/apache/helix/tools/IdealCalculatorByConsistentHashing.java
+++ b/helix-core/src/main/java/org/apache/helix/tools/IdealCalculatorByConsistentHashing.java
@@ -29,7 +29,7 @@ import java.util.Set;
 import java.util.TreeMap;
 import java.util.TreeSet;
 
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
 import org.apache.helix.model.IdealState.IdealStateProperty;
 
 public class IdealCalculatorByConsistentHashing {
diff --git a/helix-core/src/main/java/org/apache/helix/tools/IdealStateCalculatorByRush.java b/helix-core/src/main/java/org/apache/helix/tools/IdealStateCalculatorByRush.java
index 7677b42..d776952 100644
--- a/helix-core/src/main/java/org/apache/helix/tools/IdealStateCalculatorByRush.java
+++ b/helix-core/src/main/java/org/apache/helix/tools/IdealStateCalculatorByRush.java
@@ -26,7 +26,7 @@ import java.util.Map;
 import java.util.Random;
 import java.util.TreeMap;
 
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
 import org.apache.helix.model.IdealState.IdealStateProperty;
 
 public class IdealStateCalculatorByRush {
diff --git a/helix-core/src/main/java/org/apache/helix/tools/IdealStateCalculatorByShuffling.java b/helix-core/src/main/java/org/apache/helix/tools/IdealStateCalculatorByShuffling.java
index d4764ef..57bf276 100644
--- a/helix-core/src/main/java/org/apache/helix/tools/IdealStateCalculatorByShuffling.java
+++ b/helix-core/src/main/java/org/apache/helix/tools/IdealStateCalculatorByShuffling.java
@@ -26,7 +26,7 @@ import java.util.Map;
 import java.util.Random;
 import java.util.TreeMap;
 
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
 import org.apache.helix.model.IdealState.IdealStateProperty;
 
 /*
diff --git a/helix-core/src/main/java/org/apache/helix/tools/MessagePoster.java b/helix-core/src/main/java/org/apache/helix/tools/MessagePoster.java
index 4d096e9..b2b5689 100644
--- a/helix-core/src/main/java/org/apache/helix/tools/MessagePoster.java
+++ b/helix-core/src/main/java/org/apache/helix/tools/MessagePoster.java
@@ -22,10 +22,10 @@ package org.apache.helix.tools;
 import java.util.UUID;
 
 import org.apache.helix.PropertyPathBuilder;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
 import org.apache.helix.manager.zk.ZNRecordSerializer;
-import org.apache.helix.manager.zk.client.HelixZkClient;
-import org.apache.helix.manager.zk.client.SharedZkClientFactory;
+import org.apache.helix.zookeeper.api.client.HelixZkClient;
+import org.apache.helix.zookeeper.impl.factory.SharedZkClientFactory;
 import org.apache.helix.model.LiveInstance.LiveInstanceProperty;
 import org.apache.helix.model.Message;
 import org.apache.helix.model.Message.MessageState;
diff --git a/helix-core/src/main/java/org/apache/helix/tools/StateModelConfigGenerator.java b/helix-core/src/main/java/org/apache/helix/tools/StateModelConfigGenerator.java
index 992797f..1cbb0f9 100644
--- a/helix-core/src/main/java/org/apache/helix/tools/StateModelConfigGenerator.java
+++ b/helix-core/src/main/java/org/apache/helix/tools/StateModelConfigGenerator.java
@@ -19,7 +19,7 @@ package org.apache.helix.tools;
  * under the License.
  */
 
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
 import org.apache.helix.manager.zk.ZNRecordSerializer;
 import org.apache.helix.model.LeaderStandbySMD;
 import org.apache.helix.model.MasterSlaveSMD;
diff --git a/helix-core/src/main/java/org/apache/helix/tools/TestExecutor.java b/helix-core/src/main/java/org/apache/helix/tools/TestExecutor.java
index df14af4..565a860 100644
--- a/helix-core/src/main/java/org/apache/helix/tools/TestExecutor.java
+++ b/helix-core/src/main/java/org/apache/helix/tools/TestExecutor.java
@@ -29,17 +29,17 @@ import java.util.TreeMap;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.CountDownLatch;
 
-import org.I0Itec.zkclient.exception.ZkBadVersionException;
-import org.I0Itec.zkclient.exception.ZkNodeExistsException;
 import org.apache.helix.HelixManager;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
 import org.apache.helix.manager.zk.ZNRecordSerializer;
-import org.apache.helix.manager.zk.client.HelixZkClient;
-import org.apache.helix.manager.zk.client.SharedZkClientFactory;
+import org.apache.helix.zookeeper.api.client.HelixZkClient;
+import org.apache.helix.zookeeper.impl.factory.SharedZkClientFactory;
 import org.apache.helix.store.PropertyJsonComparator;
 import org.apache.helix.store.PropertyJsonSerializer;
 import org.apache.helix.store.PropertyStoreException;
 import org.apache.helix.tools.TestCommand.CommandType;
+import org.apache.helix.zookeeper.zkclient.exception.ZkBadVersionException;
+import org.apache.helix.zookeeper.zkclient.exception.ZkNodeExistsException;
 import org.apache.zookeeper.data.Stat;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
diff --git a/helix-core/src/main/java/org/apache/helix/tools/TestTrigger.java b/helix-core/src/main/java/org/apache/helix/tools/TestTrigger.java
index 7c5bdf4..96253ee 100644
--- a/helix-core/src/main/java/org/apache/helix/tools/TestTrigger.java
+++ b/helix-core/src/main/java/org/apache/helix/tools/TestTrigger.java
@@ -22,7 +22,7 @@ package org.apache.helix.tools;
 import java.util.List;
 import java.util.Map;
 
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
 
 public class TestTrigger {
   public long _startTime;
diff --git a/helix-core/src/main/java/org/apache/helix/tools/ZnodeOpArg.java b/helix-core/src/main/java/org/apache/helix/tools/ZnodeOpArg.java
index e60ce8e..53801f6 100644
--- a/helix-core/src/main/java/org/apache/helix/tools/ZnodeOpArg.java
+++ b/helix-core/src/main/java/org/apache/helix/tools/ZnodeOpArg.java
@@ -22,7 +22,7 @@ package org.apache.helix.tools;
 import java.util.List;
 import java.util.Map;
 
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
 import org.apache.helix.tools.TestExecutor.ZnodePropertyType;
 
 public class ZnodeOpArg {
diff --git a/helix-core/src/main/java/org/apache/helix/tools/ZnodeValue.java b/helix-core/src/main/java/org/apache/helix/tools/ZnodeValue.java
index c975b6f..be40449 100644
--- a/helix-core/src/main/java/org/apache/helix/tools/ZnodeValue.java
+++ b/helix-core/src/main/java/org/apache/helix/tools/ZnodeValue.java
@@ -22,7 +22,7 @@ package org.apache.helix.tools;
 import java.util.List;
 import java.util.Map;
 
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
 
 public class ZnodeValue {
   public String _singleValue;
diff --git a/helix-core/src/main/java/org/apache/helix/tools/commandtools/CurrentStateCleanUp.java b/helix-core/src/main/java/org/apache/helix/tools/commandtools/CurrentStateCleanUp.java
index 29bcdf8..5c276f3 100644
--- a/helix-core/src/main/java/org/apache/helix/tools/commandtools/CurrentStateCleanUp.java
+++ b/helix-core/src/main/java/org/apache/helix/tools/commandtools/CurrentStateCleanUp.java
@@ -4,7 +4,6 @@ import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
 
-import org.I0Itec.zkclient.DataUpdater;
 import org.apache.commons.cli.CommandLine;
 import org.apache.commons.cli.HelpFormatter;
 import org.apache.commons.cli.Option;
@@ -18,8 +17,9 @@ import org.apache.helix.HelixManager;
 import org.apache.helix.HelixManagerFactory;
 import org.apache.helix.InstanceType;
 import org.apache.helix.PropertyKey;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
 import org.apache.helix.model.CurrentState;
+import org.apache.helix.zookeeper.zkclient.DataUpdater;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
diff --git a/helix-core/src/main/java/org/apache/helix/tools/commandtools/IntegrationTestUtil.java b/helix-core/src/main/java/org/apache/helix/tools/commandtools/IntegrationTestUtil.java
index ed7f479..ba9628f 100644
--- a/helix-core/src/main/java/org/apache/helix/tools/commandtools/IntegrationTestUtil.java
+++ b/helix-core/src/main/java/org/apache/helix/tools/commandtools/IntegrationTestUtil.java
@@ -33,10 +33,10 @@ import org.apache.commons.cli.OptionGroup;
 import org.apache.commons.cli.Options;
 import org.apache.commons.cli.ParseException;
 import org.apache.helix.PropertyKey;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
 import org.apache.helix.manager.zk.ZNRecordSerializer;
-import org.apache.helix.manager.zk.client.DedicatedZkClientFactory;
-import org.apache.helix.manager.zk.client.HelixZkClient;
+import org.apache.helix.zookeeper.impl.factory.DedicatedZkClientFactory;
+import org.apache.helix.zookeeper.api.client.HelixZkClient;
 import org.apache.helix.tools.ClusterExternalViewVerifier;
 import org.apache.helix.tools.ClusterVerifiers.BestPossibleExternalViewVerifier;
 import org.apache.helix.tools.ClusterVerifiers.ClusterLiveNodesVerifier;
diff --git a/helix-core/src/main/java/org/apache/helix/tools/commandtools/LocalZKServer.java b/helix-core/src/main/java/org/apache/helix/tools/commandtools/LocalZKServer.java
index bb13380..d15d39f 100644
--- a/helix-core/src/main/java/org/apache/helix/tools/commandtools/LocalZKServer.java
+++ b/helix-core/src/main/java/org/apache/helix/tools/commandtools/LocalZKServer.java
@@ -19,9 +19,10 @@ package org.apache.helix.tools.commandtools;
  * under the License.
  */
 
-import org.I0Itec.zkclient.IDefaultNameSpace;
-import org.I0Itec.zkclient.ZkClient;
-import org.I0Itec.zkclient.ZkServer;
+import org.apache.helix.zookeeper.zkclient.IDefaultNameSpace;
+import org.apache.helix.zookeeper.zkclient.ZkClient;
+import org.apache.helix.zookeeper.zkclient.ZkServer;
+
 
 /**
  * Provides ability to start zookeeper locally on a particular port
diff --git a/helix-core/src/main/java/org/apache/helix/tools/commandtools/ZKDumper.java b/helix-core/src/main/java/org/apache/helix/tools/commandtools/ZKDumper.java
index 7d9eeec..bb69e9d 100644
--- a/helix-core/src/main/java/org/apache/helix/tools/commandtools/ZKDumper.java
+++ b/helix-core/src/main/java/org/apache/helix/tools/commandtools/ZKDumper.java
@@ -28,7 +28,6 @@ import java.io.InputStream;
 import java.io.OutputStream;
 import java.util.List;
 
-import org.I0Itec.zkclient.serialize.ZkSerializer;
 import org.apache.commons.cli.CommandLine;
 import org.apache.commons.cli.CommandLineParser;
 import org.apache.commons.cli.HelpFormatter;
@@ -38,8 +37,10 @@ import org.apache.commons.cli.OptionGroup;
 import org.apache.commons.cli.Options;
 import org.apache.commons.cli.PosixParser;
 import org.apache.helix.manager.zk.ByteArraySerializer;
-import org.apache.helix.manager.zk.client.HelixZkClient;
-import org.apache.helix.manager.zk.client.SharedZkClientFactory;
+import org.apache.helix.zookeeper.api.client.HelixZkClient;
+import org.apache.helix.zookeeper.impl.factory.SharedZkClientFactory;
+import org.apache.helix.zookeeper.zkclient.serialize.ZkSerializer;
+
 
 /**
  * Dumps the Zookeeper file structure on to Disk
diff --git a/helix-core/src/main/java/org/apache/helix/tools/commandtools/ZkCopy.java b/helix-core/src/main/java/org/apache/helix/tools/commandtools/ZkCopy.java
index 805847c..2ea48a3 100644
--- a/helix-core/src/main/java/org/apache/helix/tools/commandtools/ZkCopy.java
+++ b/helix-core/src/main/java/org/apache/helix/tools/commandtools/ZkCopy.java
@@ -37,8 +37,8 @@ import org.apache.helix.AccessOption;
 import org.apache.helix.BaseDataAccessor;
 import org.apache.helix.manager.zk.ByteArraySerializer;
 import org.apache.helix.manager.zk.ZkBaseDataAccessor;
-import org.apache.helix.manager.zk.client.HelixZkClient;
-import org.apache.helix.manager.zk.client.SharedZkClientFactory;
+import org.apache.helix.zookeeper.api.client.HelixZkClient;
+import org.apache.helix.zookeeper.impl.factory.SharedZkClientFactory;
 import org.apache.zookeeper.common.PathUtils;
 import org.apache.zookeeper.data.Stat;
 import org.slf4j.Logger;
diff --git a/helix-core/src/main/java/org/apache/helix/tools/commandtools/ZkLogCSVFormatter.java b/helix-core/src/main/java/org/apache/helix/tools/commandtools/ZkLogCSVFormatter.java
index d9d4f98..3052441 100644
--- a/helix-core/src/main/java/org/apache/helix/tools/commandtools/ZkLogCSVFormatter.java
+++ b/helix-core/src/main/java/org/apache/helix/tools/commandtools/ZkLogCSVFormatter.java
@@ -32,7 +32,7 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
 import org.apache.helix.manager.zk.ZNRecordSerializer;
 import org.apache.helix.model.IdealState.IdealStateProperty;
 import org.apache.helix.util.HelixUtil;
diff --git a/helix-core/src/main/java/org/apache/helix/util/ExponentialBackoffStrategy.java b/helix-core/src/main/java/org/apache/helix/util/ExponentialBackoffStrategy.java
index b1a66c9..40b81e3 100644
--- a/helix-core/src/main/java/org/apache/helix/util/ExponentialBackoffStrategy.java
+++ b/helix-core/src/main/java/org/apache/helix/util/ExponentialBackoffStrategy.java
@@ -1,33 +1,31 @@
 package org.apache.helix.util;
 
-import java.util.Random;
-
-public class ExponentialBackoffStrategy {
-  private final long INIT_RETRY_INTERVAL = 500;
-  private final long _maxRetryInterval;
-  private final boolean _addJitter;
-  private final Random _ran;
+/*
+ * 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.
+ */
 
+/**
+ * Use ExponentialBackoffStrategy in zookeeper-api module instead.
+ */
+@Deprecated
+public class ExponentialBackoffStrategy
+    extends org.apache.helix.zookeeper.zkclient.util.ExponentialBackoffStrategy {
   public ExponentialBackoffStrategy(long maxRetryInterval, boolean addJitter) {
-    _maxRetryInterval = maxRetryInterval;
-    _addJitter = addJitter;
-    _ran = new Random(System.currentTimeMillis());
-  }
-
-  public long getNextWaitInterval(int numberOfTriesFailed) {
-    double exponentialMultiplier = Math.pow(2.0, numberOfTriesFailed - 1);
-    double result = exponentialMultiplier * INIT_RETRY_INTERVAL;
-
-    if (_maxRetryInterval > 0 && result > _maxRetryInterval) {
-      result = _maxRetryInterval;
-    }
-
-    if (_addJitter) {
-      // Adding jitter so the real result would be 75% to 100% of the original result.
-      // Don't directly add jitter here, since it may exceed the max retry interval setup
-      result = result * (0.75 + _ran.nextDouble() % 0.25);
-    }
-
-    return (long) result;
+    super(maxRetryInterval, addJitter);
   }
 }
diff --git a/helix-core/src/main/java/org/apache/helix/util/GZipCompressionUtil.java b/helix-core/src/main/java/org/apache/helix/util/GZipCompressionUtil.java
index f29a301..358c969 100644
--- a/helix-core/src/main/java/org/apache/helix/util/GZipCompressionUtil.java
+++ b/helix-core/src/main/java/org/apache/helix/util/GZipCompressionUtil.java
@@ -19,55 +19,9 @@ package org.apache.helix.util;
  * under the License.
  */
 
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.util.zip.GZIPInputStream;
-import java.util.zip.GZIPOutputStream;
-
-public class GZipCompressionUtil {
-  /**
-   * Compresses a byte array by applying GZIP compression
-   * @param serializedBytes
-   * @return
-   * @throws IOException
-   */
-  public static byte[] compress(byte[] buffer) throws IOException {
-    ByteArrayOutputStream gzipByteArrayOutputStream = new ByteArrayOutputStream();
-    GZIPOutputStream gzipOutputStream = null;
-    gzipOutputStream = new GZIPOutputStream(gzipByteArrayOutputStream);
-    gzipOutputStream.write(buffer, 0, buffer.length);
-    gzipOutputStream.close();
-    byte[] compressedBytes = gzipByteArrayOutputStream.toByteArray();
-    return compressedBytes;
-  }
-
-  public static byte[] uncompress(ByteArrayInputStream bais) throws IOException {
-    GZIPInputStream gzipInputStream = new GZIPInputStream(bais);
-    byte[] buffer = new byte[1024];
-    int length;
-    ByteArrayOutputStream baos = new ByteArrayOutputStream();
-    while ((length = gzipInputStream.read(buffer)) != -1) {
-      baos.write(buffer, 0, length);
-    }
-    gzipInputStream.close();
-    baos.close();
-    byte[] uncompressedBytes = baos.toByteArray();
-    return uncompressedBytes;
-  }
-
-  /*
-   * Determines if a byte array is compressed. The java.util.zip GZip
-   * implementaiton does not expose the GZip header so it is difficult to determine
-   * if a string is compressed.
-   * @param bytes an array of bytes
-   * @return true if the array is compressed or false otherwise
-   */
-  public static boolean isCompressed(byte[] bytes) {
-    if ((bytes == null) || (bytes.length < 2)) {
-      return false;
-    } else {
-      return ((bytes[0] == (byte) (GZIPInputStream.GZIP_MAGIC)) && (bytes[1] == (byte) (GZIPInputStream.GZIP_MAGIC >> 8)));
-    }
-  }
+/**
+ * Deprecated - please use GZipCompressionUtil in zookeeper-api.
+ */
+@Deprecated
+public class GZipCompressionUtil extends org.apache.helix.zookeeper.util.GZipCompressionUtil {
 }
diff --git a/helix-core/src/main/java/org/apache/helix/util/StatusUpdateUtil.java b/helix-core/src/main/java/org/apache/helix/util/StatusUpdateUtil.java
index 1249fec..7a82347 100644
--- a/helix-core/src/main/java/org/apache/helix/util/StatusUpdateUtil.java
+++ b/helix-core/src/main/java/org/apache/helix/util/StatusUpdateUtil.java
@@ -39,7 +39,7 @@ import org.apache.helix.HelixProperty;
 import org.apache.helix.InstanceType;
 import org.apache.helix.PropertyKey;
 import org.apache.helix.PropertyKey.Builder;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
 import org.apache.helix.model.Error;
 import org.apache.helix.model.Message;
 import org.apache.helix.model.Message.MessageType;
diff --git a/helix-core/src/main/java/org/apache/helix/util/WeightAwareRebalanceUtil.java b/helix-core/src/main/java/org/apache/helix/util/WeightAwareRebalanceUtil.java
index 7bef7b7..f6f692a 100644
--- a/helix-core/src/main/java/org/apache/helix/util/WeightAwareRebalanceUtil.java
+++ b/helix-core/src/main/java/org/apache/helix/util/WeightAwareRebalanceUtil.java
@@ -7,7 +7,7 @@ import java.util.List;
 import java.util.Map;
 
 import org.apache.helix.HelixException;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
 import org.apache.helix.api.config.RebalanceConfig;
 import org.apache.helix.api.rebalancer.constraint.AbstractRebalanceHardConstraint;
 import org.apache.helix.api.rebalancer.constraint.AbstractRebalanceSoftConstraint;
diff --git a/helix-core/src/main/java/org/apache/helix/util/ZKClientPool.java b/helix-core/src/main/java/org/apache/helix/util/ZKClientPool.java
index 3350d57..51b1ab9 100644
--- a/helix-core/src/main/java/org/apache/helix/util/ZKClientPool.java
+++ b/helix-core/src/main/java/org/apache/helix/util/ZKClientPool.java
@@ -23,7 +23,7 @@ import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
 
 import org.apache.helix.manager.zk.ZNRecordSerializer;
-import org.apache.helix.manager.zk.ZkClient;
+import org.apache.helix.zookeeper.impl.client.ZkClient;
 import org.apache.zookeeper.ZooKeeper.States;
 
 public class ZKClientPool {
diff --git a/helix-core/src/main/java/org/apache/helix/util/ZNRecordUtil.java b/helix-core/src/main/java/org/apache/helix/util/ZNRecordUtil.java
index 989b54a..d2127b9 100644
--- a/helix-core/src/main/java/org/apache/helix/util/ZNRecordUtil.java
+++ b/helix-core/src/main/java/org/apache/helix/util/ZNRecordUtil.java
@@ -25,12 +25,13 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+
 //TODO find a proper place for these methods
-public final class ZNRecordUtil {
+public class ZNRecordUtil {
   private static final Logger logger = LoggerFactory.getLogger(ZNRecordUtil.class.getName());
 
   private ZNRecordUtil() {
diff --git a/helix-core/src/test/java/org/apache/helix/MockAccessor.java b/helix-core/src/test/java/org/apache/helix/MockAccessor.java
index c0a0e46..4e9a014 100644
--- a/helix-core/src/test/java/org/apache/helix/MockAccessor.java
+++ b/helix-core/src/test/java/org/apache/helix/MockAccessor.java
@@ -24,15 +24,18 @@ import java.util.Collections;
 import java.util.List;
 import java.util.Map;
 
-import org.I0Itec.zkclient.DataUpdater;
-import org.I0Itec.zkclient.exception.ZkNoNodeException;
 import org.apache.helix.mock.MockBaseDataAccessor;
 import org.apache.helix.model.LiveInstance;
 import org.apache.helix.model.MaintenanceSignal;
 import org.apache.helix.model.Message;
 import org.apache.helix.model.PauseSignal;
 import org.apache.helix.model.StateModelDefinition;
+import org.apache.helix.zookeeper.zkclient.DataUpdater;
+import org.apache.helix.zookeeper.zkclient.exception.ZkNoNodeException;
 import org.apache.zookeeper.data.Stat;
+import org.apache.helix.zookeeper.datamodel.ZNRecordUpdater;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
+
 
 public class MockAccessor implements HelixDataAccessor {
   private final String _clusterName;
@@ -69,11 +72,13 @@ public class MockAccessor implements HelixDataAccessor {
     return false;
   }
 
-  @Override public boolean createMaintenance(MaintenanceSignal maintenanceSignal) {
+  @Override
+  public boolean createMaintenance(MaintenanceSignal maintenanceSignal) {
     return false;
   }
 
-  @Override public boolean setProperty(PropertyKey key, HelixProperty value) {
+  @Override
+  public boolean setProperty(PropertyKey key, HelixProperty value) {
     String path = key.getPath();
     _baseDataAccessor.set(path, value.getRecord(), AccessOption.PERSISTENT);
     return true;
@@ -81,11 +86,12 @@ public class MockAccessor implements HelixDataAccessor {
 
   @Override
   public <T extends HelixProperty> boolean updateProperty(PropertyKey key, T value) {
-    return updateProperty(key, new ZNRecordUpdater(value.getRecord()) , value);
+    return updateProperty(key, new ZNRecordUpdater(value.getRecord()), value);
   }
 
   @Override
-  public <T extends HelixProperty> boolean updateProperty(PropertyKey key, DataUpdater<ZNRecord> updater, T value) {
+  public <T extends HelixProperty> boolean updateProperty(PropertyKey key,
+      DataUpdater<ZNRecord> updater, T value) {
     String path = key.getPath();
     PropertyType type = key.getType();
     if (type.updateOnlyOnExists) {
@@ -143,7 +149,8 @@ public class MockAccessor implements HelixDataAccessor {
     try {
       Stat stat = _baseDataAccessor.getStat(path, 0);
       if (stat != null) {
-        return new HelixProperty.Stat(stat.getVersion(), stat.getCtime(), stat.getMtime(), stat.getEphemeralOwner());
+        return new HelixProperty.Stat(stat.getVersion(), stat.getCtime(), stat.getMtime(),
+            stat.getEphemeralOwner());
       }
     } catch (ZkNoNodeException e) {
 
@@ -170,7 +177,8 @@ public class MockAccessor implements HelixDataAccessor {
       HelixProperty.Stat propertyStat = null;
       if (zkStat != null) {
         propertyStat =
-            new HelixProperty.Stat(zkStat.getVersion(), zkStat.getCtime(), zkStat.getMtime(), zkStat.getEphemeralOwner());
+            new HelixProperty.Stat(zkStat.getVersion(), zkStat.getCtime(), zkStat.getMtime(),
+                zkStat.getEphemeralOwner());
       }
       propertyStats.add(propertyStat);
     }
@@ -185,14 +193,15 @@ public class MockAccessor implements HelixDataAccessor {
   }
 
   @SuppressWarnings("unchecked")
-  @Override public <T extends HelixProperty> List<T> getChildValues(PropertyKey propertyKey) {
+  @Override
+  public <T extends HelixProperty> List<T> getChildValues(PropertyKey propertyKey) {
     String path = propertyKey.getPath(); // PropertyPathConfig.getPath(type,
     List<ZNRecord> children = _baseDataAccessor.getChildren(path, null, 0);
     return (List<T>) HelixProperty.convertToTypedList(propertyKey.getTypeClass(), children);
   }
 
-  @Override public <T extends HelixProperty> List<T> getChildValues(PropertyKey key,
-      boolean throwException) {
+  @Override
+  public <T extends HelixProperty> List<T> getChildValues(PropertyKey key, boolean throwException) {
     return getChildValues(key);
   }
 
@@ -202,7 +211,8 @@ public class MockAccessor implements HelixDataAccessor {
     return HelixProperty.convertListToMap(list);
   }
 
... 9245 lines suppressed ...


Mime
View raw message