anchor.diff:              end;
           Else ->
               %% TODO: corner case
  -io:format(user, "WTF? Else = ~p\n", [Else]),
  +            io:format(user, "WTF? Else = ~p\n", [Else]),
               Else
  +    end.
  +
  +read_page(#proj{epoch=Epoch} = P, LPN) ->
  +    Chain = project_to_chain(LPN, P),
  +    Tail = lists:last(Chain),
  +    case corfurl_flu:read(flu_pid(Tail), Epoch, LPN) of
  +        {ok, _} = OK ->
  +            OK;
  +        error_badepoch ->
  +            error_badepoch;
  +        error_trimmed ->
  +            %% TODO: A sanity/should-never-happen check would be to
  +            %%       see if everyone else in the chain are also trimmed.
  +            error_trimmed;
  +        error_overwritten ->
  +            error({impossible, ?MODULE, ?LINE, overwritten_reply_to_read});
  +        error_unwritten ->
  +            %% TODO: Check head for possible read-repair
  +            read_page_tail_unwritten_todo
       end.
   
   flu_pid(X) when is_pid(X) ->
  
positive.code:             %% else junked us.
              %% TODO We should go trim our previously successful writes?
              error_trimmed;
          error_written when Nth == 1 ->
              %% The sequencer lied, or we didn't use the sequencer and
              %% guessed and guessed poorly, or someone is accidentally
              %% trying to take our page.  Shouganai, these things happen.
              error_written;
          error_written when Nth > 1 ->
              %% The likely cause is that another reader has noticed that
              %% we haven't finished writing this page in this chain and
              %% has repaired the remainder of the chain while we were
  
negative.code:                                    PageSize, NumPages * (PageSize * ?PAGE_OVERHEAD)))
       end || X <- lists:seq(1, NumFLUs)].
  
  smoke1_test() ->
      NumFLUs = 4,
      PageSize = 8,
      NumPages = 10,
      FLUs = [F1, F2, F3, F4] = setup_basic_flus(NumFLUs, PageSize, NumPages),
      {ok, Seq} = corfurl_sequencer:start_link(FLUs),
  
      %% We know that the first LSN will be 1.
      LPN_Pgs = [{X, list_to_binary(
                       lists:flatten(io_lib:format("~8..0w", [X])))} ||
                    X <- lists:seq(1, 5)],
      try
          P1 = new_simple_projection(1, 1, 1*100, [[F1, F2], [F3, F4]]),
          [begin {ok, LPN} = append_page(Seq, P1, Pg) end || {LPN, Pg} <- LPN_Pgs],
          [begin {ok, Pg} = read_page(P1, LPN) end || {LPN, Pg} <- LPN_Pgs],
          ok
      after
          corfurl_sequencer:stop(Seq),
  