anchor.diff:      ok = perform_read_internal(Coordinator, Key, Type, Transaction, [], SD0),
       {noreply, SD0};
   
  -handle_info({pvc_perform_read_cast, Coordinator, IndexNode, Key, Type, Tx}, State) ->
  -    ok = pvc_perform_read_internal(Coordinator, IndexNode, Key, Type, Tx, State),
  +handle_info({pvc_wait_scan, IndexNode, Coordinator, Transaction, Key, Type}, State) ->
  +    ok = pvc_wait_scan(IndexNode, Coordinator, Transaction, Key, Type, State),
       {noreply, State};
   
   handle_info(_Info, StateData) ->
  
positive.code:             end
      end.
  
  -spec perform_read_internal(pid(), key(), type(), #transaction{}, [], #state{}) -> ok.
  perform_read_internal(Coordinator, Key, Type, Tx = #transaction{transactional_protocol=pvc}, _PropList, State) ->
      CurrentPartition = State#state.partition,
      HasRead = Tx#transaction.pvc_meta#pvc_tx_meta.hasread,
  
      GetMax = case sets:is_element(CurrentPartition, HasRead) of
          true ->
              VCaggr = Tx#transaction.pvc_meta#pvc_tx_meta.time#pvc_time.vcaggr,
              lager:info("PVC read Key ~p has been read before, will use supplied time ~p", [Key, dict:to_list(VCaggr)]),
              {ok, VCaggr};
  
          false ->
              lager:info("PVC read Key ~p has not been read before, will perform CLog scan", [Key]),
              %% Sanity check
              {CurrentPartition, _}=Node = log_utilities:get_key_partition(Key),
              LogId = log_utilities:get_logid_from_key(Key),
              pvc_find_maxvc(Node, LogId, Tx)
      end,
      case GetMax of
          {error, Reason} ->
              reply_to_coordinator(Coordinator, {error, Reason});
  
          {ok, MaxVC} ->
              pvc_perform_read(Coordinator, Key, Type, MaxVC, State)
      end;
  
  perform_read_internal(Coordinator, Key, Type, Tx, [], State = #state{
      partition=Partition,
  
negative.code:     ok = pvc_perform_read_internal(Coordinator, IndexNode, Key, Type, Tx, State),
      {noreply, State}.
  
  %% @doc Performs a PVC read in this partition.
  %%
  %%      During the first phase, it finds the maximum vector clock
  %%      valid for this specific read. If this partition has been read
  %%      before, use the included VCaggr in the current transaction.
  %%
  %%      If it has been not, it will find the vector clock in the CLog
  %%      (represented as the replication log in Antidote).
  %%
  -spec pvc_perform_read_internal(
      {fsm, pid()} | pid(),
      index_node(),
      key(),
      type(),
      #transaction{},
      #state{}
  ) -> ok.
  
  pvc_perform_read_internal(Coordinator, IndexNode, Key, Type, Tx, State = #state{
      partition = CurrentPartition
  }) ->
      %% Sanity check
      pvc = Tx#transaction.transactional_protocol,
  
      HasRead = Tx#transaction.pvc_meta#pvc_tx_meta.hasread,
      case sets:is_element(CurrentPartition, HasRead) of
          false ->
              pvc_wait_scan(IndexNode, Coordinator, Tx, Key, Type, State);
  
          true ->
              VCaggr = Tx#transaction.pvc_meta#pvc_tx_meta.time#pvc_time.vcaggr,
              lager:info("PVC read Key ~p has been read before, will use supplied time ~p", [Key, dict:to_list(VCaggr)]),
              pvc_perform_read(Coordinator, Key, Type, VCaggr, State)
      end.
  
  %% @doc Wait until this PVC partition is ready to perform a read.
  %%
  %%      If this partition has not been read before, wait until the most
  %%      recent vc of this partition is greater or equal that the passed
  %%      VCaggr from the current transaction.
  %%
  %%      Once this happens, perform the read at this partition.
  %%
  -spec pvc_wait_scan(
      index_node(),
      {fsm, pid()} | pid(),
      #transaction{},
      key(),
      type(),
      #state{}
  ) -> ok.
  
  pvc_wait_scan(IndexNode, Coordinator, Transaction, Key, Type, State = #state{
      partition = CurrentPartition
  }) ->
  
      VCaggr = Transaction#transaction.pvc_meta#pvc_tx_meta.time#pvc_time.vcaggr,
      {ok, MostRecentVC} = clocksi_vnode:pvc_get_most_recent_vc(IndexNode),
      case pvc_check_time(CurrentPartition, MostRecentVC, VCaggr) of
          {not_ready, WaitTime} ->
              lager:info("PVC Partition not ready, will wait ~p ms", [WaitTime]),
              erlang:send_after(WaitTime, self(), {pvc_wait_scan, IndexNode, Coordinator, Transaction, Key, Type}),
              ok;
  
          ready ->
              pvc_scan_and_read(Coordinator, Key, Type, Transaction, State)
      end.
  
  %% @doc Check if this partition is ready to proceed with a PVC read.
  %%
  %%      If it is not, will sleep for 1000 ms and try again.
  %%
  -spec pvc_check_time(
      partition_id(),
      vectorclock_partition:partition_vc(),
      vectorclock_partition:partition_vc()
  ) -> ready | {not_ready, non_neg_integer()}.
  
  pvc_check_time(Partition, MostRecentVC, VCaggr) ->
      MostRecentTime = vectorclock_partition:get_partition_time(Partition, MostRecentVC),
      AggregateTime = vectorclock_partition:get_partition_time(Partition, VCaggr),
      lager:info("PVC Will wait until MostRecentVC[i] (~p) >= VCaggr[i] (~p)", [MostRecentTime, AggregateTime]),
      case MostRecentTime < AggregateTime of
          true ->
              {not_ready, ?PVC_WAIT_MS};
          false ->
              ready
      end.
  
  %% @doc Scan the replication log for a valid vector clock time for a read at this partition
  %%
  %%      The valid time is the maximum vector clock such that for every partition
  %%      that the current partition has read, that partition time is smaller or
  %%      equal than the VCaggr of the current transaction.
  %%
  -spec pvc_scan_and_read(
      {fsm, pid()} | pid(),
      key(),
      type(),
      #transaction{},
      #state{}
  ) -> ok.
  
  pvc_scan_and_read(Coordinator, Key, Type, Transaction, State = #state{
      partition = Partition
  }) ->
      %% Sanity check
      {Partition, _}=Node = log_utilities:get_key_partition(Key),
      LogId = log_utilities:get_logid_from_key(Key),
      case pvc_find_maxvc(Node, LogId, Transaction) of
          {error, Reason} ->
              reply_to_coordinator(Coordinator, {error, Reason});
  
          {ok, MaxVC} ->
              pvc_perform_read(Coordinator, Key, Type, MaxVC, State)
      end.
  
  %% @doc Scan the log for the maximum aggregate time that will be used for a read
  -spec pvc_find_maxvc(index_node(), log_id(), #transaction{}) -> {ok, vectorclock_partition:partition_vc()}
                                                                | {error, reason()}.
  
  pvc_find_maxvc(IndexNode, LogId, #transaction{
      %% Sanity check
      transactional_protocol = pvc,
  