Program: 32156
Project: 32156
Buggy source:
/** 
 * Request older messages than the given token. These will come from storage if available, from the server otherwise.
 * @param roomId the room id
 * @param token the token to go back from. Null to start from live.
 * @param callback the onComplete callback
 */
public void requestRoomHistory(final String roomId,final String token,final ApiCallback<TokensChunkResponse<Event>> callback){
  final TokensChunkResponse<Event> storageResponse=mStore.getEarlierMessages(roomId,token,RoomsRestClient.DEFAULT_MESSAGES_PAGINATION_LIMIT);
  if (storageResponse != null) {
    final android.os.Handler handler=new android.os.Handler(Looper.getMainLooper());
    Runnable r=new Runnable(){
      @Override public void run(){
        handler.postDelayed(new Runnable(){
          public void run(){
            callback.onSuccess(storageResponse);
          }
        }
,(null == token) ? 0 : 100);
      }
    }
;
    Thread t=new Thread(r);
    t.start();
  }
 else {
    mRestClient.getEarlierMessages(roomId,token,RoomsRestClient.DEFAULT_MESSAGES_PAGINATION_LIMIT,new SimpleApiCallback<TokensChunkResponse<Event>>(callback){
      @Override public void onSuccess(      TokensChunkResponse<Event> info){
        Event oldestEvent=mStore.getOldestEvent(roomId);
        if (info.chunk.size() != 0) {
          info.chunk.get(0).mToken=info.start;
          info.chunk.get(info.chunk.size() - 1).mToken=info.end;
          Event firstReturnedEvent=info.chunk.get(0);
          if ((oldestEvent != null) && (firstReturnedEvent != null) && TextUtils.equals(oldestEvent.eventId,firstReturnedEvent.eventId)) {
            info.chunk.remove(0);
          }
          mStore.storeRoomEvents(roomId,info,Room.EventDirection.BACKWARDS);
        }
        callback.onSuccess(info);
      }
    }
);
  }
}

Fixed version (ground truth):
/** 
 * Request older messages than the given token. These will come from storage if available, from the server otherwise.
 * @param roomId the room id
 * @param token the token to go back from. Null to start from live.
 * @param callback the onComplete callback
 */
public void requestRoomHistory(final String roomId,final String token,final ApiCallback<TokensChunkResponse<Event>> callback){
  final TokensChunkResponse<Event> storageResponse=mStore.getEarlierMessages(roomId,token,RoomsRestClient.DEFAULT_MESSAGES_PAGINATION_LIMIT);
synchronized (mPendingRequestTokenByRoomId) {
    mPendingRequestTokenByRoomId.put(roomId,token);
  }
  if (storageResponse != null) {
    final android.os.Handler handler=new android.os.Handler(Looper.getMainLooper());
    Runnable r=new Runnable(){
      @Override public void run(){
        handler.postDelayed(new Runnable(){
          public void run(){
            String expectedToken;
synchronized (mPendingRequestTokenByRoomId) {
              expectedToken=mPendingRequestTokenByRoomId.get(roomId);
            }
            if (TextUtils.equals(expectedToken,token)) {
              callback.onSuccess(storageResponse);
            }
          }
        }
,(null == token) ? 0 : 100);
      }
    }
;
    Thread t=new Thread(r);
    t.start();
  }
 else {
    mRestClient.getEarlierMessages(roomId,token,RoomsRestClient.DEFAULT_MESSAGES_PAGINATION_LIMIT,new SimpleApiCallback<TokensChunkResponse<Event>>(callback){
      @Override public void onSuccess(      TokensChunkResponse<Event> info){
        String expectedToken;
synchronized (mPendingRequestTokenByRoomId) {
          expectedToken=mPendingRequestTokenByRoomId.get(roomId);
        }
        if (TextUtils.equals(expectedToken,token)) {
          Event oldestEvent=mStore.getOldestEvent(roomId);
          if (info.chunk.size() != 0) {
            info.chunk.get(0).mToken=info.start;
            info.chunk.get(info.chunk.size() - 1).mToken=info.end;
            Event firstReturnedEvent=info.chunk.get(0);
            if ((oldestEvent != null) && (firstReturnedEvent != null) && TextUtils.equals(oldestEvent.eventId,firstReturnedEvent.eventId)) {
              info.chunk.remove(0);
            }
            mStore.storeRoomEvents(roomId,info,Room.EventDirection.BACKWARDS);
          }
          callback.onSuccess(info);
        }
      }
    }
);
  }
}