anchor.diff:                  gb_trees:insert({Index, Offs}, Len, Acc)
               end, OpenReqs, Chunks),
               NewPeers = etorrent_monitorset:update(PeerPid, NewReqs, Peers),
  -            %% The piece is in the assigned state if this was the last chunk
  -            NewAssigned = case etorrent_chunkset:size(NewChunkset) of
  -                0 -> etorrent_pieceset:insert(Index, Assigned);
  -                _ -> Assigned
  +
  +            %% We need to consider four transitions at this point:
  +            %% Unassigned -> Begun
  +            %% Unassigned -> Assigned
  +            %% Begun -> Begun
  +            %% Begun -> Assigned
  +            %% The piece may have gone directly from Unassigned to Assigned.
  +            %% Check if it has been assigned before making any transitions.
  +            %% TODO - we want an is_empty function in etorrent_chunkset
  +            Wasassigned = etorrent_chunkset:size(NewChunkset) == 0,
  +            NewUnassigned = case Targetstate of
  +                %% Begun -> Begun
  +                begun ->
  +                    Unassigned;
  +                %% Unassigned -> Begun|Assigned
  +                unassigned ->
  +                    etorrent_pieceset:delete(Index, Unassigned)
               end,
   
  +            NewBegun = case Targetstate of
  +                %% Begun -> Assigned
  +                begun when Wasassigned ->
  +                    etorrent_pieceset:delete(Index, Begun);
  +                %% Begun -> Begun
  +                begun ->
  +                    Begun;
  +                %% Unassigned -> Assigned
  +                unassigned when Wasassigned ->
  +                    Begun;
  +                %% Unassigned -> Begun
  +                unassigned ->
  +                    etorrent_pieceset:insert(Index, Begun)
  +            end,
  +
  +            NewAssigned = case Targetstate of
  +                %% Unassigned|Begun -> Assigned
  +                _ when Wasassigned ->
  +                    etorrent_pieceset:insert(Index, Assigned);
  +                %% Begun -> Begun
  +                begun ->
  +                    Assigned;
  +                %% Unassigned -> Begun
  +                unassigned ->
  +                    Assigned
  +            end,
  +            %% TODO - update order watches if Unassigned or Begun changed
               NewState = State#state{
  +                pieces_unassigned=NewUnassigned,
                   pieces_begun=NewBegun,
                   pieces_assigned=NewAssigned,
                   chunks_assigned=NewAssignedChunks,
  
positive.code: 
  handle_call({request_chunks, PeerPid, Peerset, Numchunks}, _, State) ->
      #state{
          pieces_begun=Begun,
          pieces_assigned=Assigned,
          pieces_stored=Stored,
          chunks_assigned=AssignedChunks,
          peer_monitors=Peers} = State,
  
      %% Consider pieces that has an empty chunkset 
      
      %% If this peer has no pieces that we are already downloading, begin
      %% downloading a new piece if this peer has any interesting pieces.
      Optimal = etorrent_pieceset:intersection(Peerset,
                etorrent_pieceset:difference(Begun, Assigned)),
      HasOptimal = not etorrent_pieceset:is_empty(Optimal),
      {SubOptimal, HasSubOptimal} = case HasOptimal of
          true ->
              {false, false};
          false ->
              ISubOptimal = etorrent_pieceset:difference(Peerset, Assigned),
              IHasSubOptimal = not etorrent_pieceset:is_empty(ISubOptimal),
              {ISubOptimal, IHasSubOptimal}
      end,
  
      PieceIndex = case {HasOptimal, HasSubOptimal} of
          %% None that we are not already downloading
          %% and none that we would want to download
          {false, false} ->
              Interesting = etorrent_pieceset:difference(Peerset, Stored),
              case etorrent_pieceset:is_empty(Interesting) of
                  true  -> not_interested;
                  false -> assigned
              end;
          %% None that we are not already downloading
          %% but one ore more that we would want to download
          {false, _} ->
              etorrent_pieceset:min(SubOptimal);
          %% One or more that we are already downloading
          {_, _} ->
              etorrent_pieceset:min(Optimal)
      end,
  
      case PieceIndex of
  
negative.code:     true = register_chunk_server(TorrentID),
  
      NumPieces = length(PieceSizes),
      PiecesValid = etorrent_pieceset:from_list(FetchedPieces, NumPieces),
      PiecesNone = etorrent_pieceset:from_list([], NumPieces),
  
      %% Initialize a full chunkset for all pieces that are left to download
      %% but don't mark them as begun before a chunk has been deleted from
  