nodes: 0, module; 1, function_definition; 2, function_name:fetchThreads; 3, parameters; 4, block; 5, identifier:self; 6, identifier:thread_location; 7, default_parameter; 8, default_parameter; 9, default_parameter; 10, expression_statement; 11, expression_statement; 12, expression_statement; 13, while_statement; 14, comment:# Return only threads between before and after (if set); 15, if_statement; 16, if_statement; 17, return_statement; 18, identifier:before; 19, None; 20, identifier:after; 21, None; 22, identifier:limit; 23, None; 24, comment:"""
          Get all threads in thread_location.
          Threads will be sorted from newest to oldest.
  
          :param thread_location: models.ThreadLocation: INBOX, PENDING, ARCHIVED or OTHER
          :param before: Fetch only thread before this epoch (in ms) (default all threads)
          :param after: Fetch only thread after this epoch (in ms) (default all threads)
          :param limit: The max. amount of threads to fetch (default all threads)
          :return: :class:`models.Thread` objects
          :rtype: list
          :raises: FBchatException if request failed
          """; 25, assignment; 26, assignment; 27, True; 28, comment:# break if limit is exceeded; 29, block; 30, boolean_operator; 31, block; 32, boolean_operator; 33, block; 34, identifier:threads; 35, identifier:threads; 36, list; 37, identifier:last_thread_timestamp; 38, None; 39, if_statement; 40, comment:# fetchThreadList returns at max 20 threads before last_thread_timestamp (included); 41, expression_statement; 42, if_statement; 43, expression_statement; 44, comment:# FB returns a sorted list of threads; 45, if_statement; 46, comparison_operator:before is not None; 47, comparison_operator:after is not None; 48, for_statement; 49, identifier:limit; 50, comparison_operator:len(threads) > limit; 51, return_statement; 52, boolean_operator; 53, block; 54, assignment; 55, comparison_operator:len(candidates) > 1; 56, block; 57, else_clause; 58, assignment; 59, boolean_operator; 60, block; 61, identifier:before; 62, None; 63, identifier:after; 64, None; 65, identifier:t; 66, identifier:threads; 67, block; 68, call; 69, identifier:limit; 70, subscript; 71, identifier:limit; 72, comparison_operator:len(threads) >= limit; 73, break_statement; 74, identifier:candidates; 75, call; 76, call; 77, integer:1; 78, expression_statement; 79, comment:# End of threads; 80, block; 81, identifier:last_thread_timestamp; 82, attribute; 83, parenthesized_expression; 84, parenthesized_expression; 85, break_statement; 86, expression_statement; 87, if_statement; 88, identifier:len; 89, argument_list; 90, identifier:threads; 91, slice; 92, call; 93, identifier:limit; 94, attribute; 95, argument_list; 96, identifier:len; 97, argument_list; 98, augmented_assignment; 99, break_statement; 100, subscript; 101, identifier:last_message_timestamp; 102, boolean_operator; 103, boolean_operator; 104, assignment; 105, boolean_operator; 106, block; 107, identifier:threads; 108, identifier:limit; 109, identifier:len; 110, argument_list; 111, identifier:self; 112, identifier:fetchThreadList; 113, keyword_argument; 114, keyword_argument; 115, identifier:candidates; 116, identifier:threads; 117, subscript; 118, identifier:threads; 119, unary_operator; 120, comparison_operator:before is not None; 121, comparison_operator:int(last_thread_timestamp) > before; 122, comparison_operator:after is not None; 123, comparison_operator:int(last_thread_timestamp) < after; 124, identifier:last_message_timestamp; 125, call; 126, parenthesized_expression; 127, parenthesized_expression; 128, expression_statement; 129, identifier:threads; 130, identifier:before; 131, identifier:last_thread_timestamp; 132, identifier:thread_location; 133, identifier:thread_location; 134, identifier:candidates; 135, slice; 136, integer:1; 137, identifier:before; 138, None; 139, call; 140, identifier:before; 141, identifier:after; 142, None; 143, call; 144, identifier:after; 145, identifier:int; 146, argument_list; 147, boolean_operator; 148, boolean_operator; 149, call; 150, integer:1; 151, identifier:int; 152, argument_list; 153, identifier:int; 154, argument_list; 155, attribute; 156, comparison_operator:before is not None; 157, comparison_operator:last_message_timestamp > before; 158, comparison_operator:after is not None; 159, comparison_operator:last_message_timestamp < after; 160, attribute; 161, argument_list; 162, identifier:last_thread_timestamp; 163, identifier:last_thread_timestamp; 164, identifier:t; 165, identifier:last_message_timestamp; 166, identifier:before; 167, None; 168, identifier:last_message_timestamp; 169, identifier:before; 170, identifier:after; 171, None; 172, identifier:last_message_timestamp; 173, identifier:after; 174, identifier:threads; 175, identifier:remove; 176, identifier:t
code: def fetchThreads(self, thread_location, before=None, after=None, limit=None):
          """
          Get all threads in thread_location.
          Threads will be sorted from newest to oldest.
  
          :param thread_location: models.ThreadLocation: INBOX, PENDING, ARCHIVED or OTHER
          :param before: Fetch only thread before this epoch (in ms) (default all threads)
          :param after: Fetch only thread after this epoch (in ms) (default all threads)
          :param limit: The max. amount of threads to fetch (default all threads)
          :return: :class:`models.Thread` objects
          :rtype: list
          :raises: FBchatException if request failed
          """
          threads = []
  
          last_thread_timestamp = None
          while True:
              # break if limit is exceeded
              if limit and len(threads) >= limit:
                  break
  
              # fetchThreadList returns at max 20 threads before last_thread_timestamp (included)
              candidates = self.fetchThreadList(
                  before=last_thread_timestamp, thread_location=thread_location
              )
  
              if len(candidates) > 1:
                  threads += candidates[1:]
              else:  # End of threads
                  break
  
              last_thread_timestamp = threads[-1].last_message_timestamp
  
              # FB returns a sorted list of threads
              if (before is not None and int(last_thread_timestamp) > before) or (
                  after is not None and int(last_thread_timestamp) < after
              ):
                  break
  
          # Return only threads between before and after (if set)
          if before is not None or after is not None:
              for t in threads:
                  last_message_timestamp = int(t.last_message_timestamp)
                  if (before is not None and last_message_timestamp > before) or (
                      after is not None and last_message_timestamp < after
                  ):
                      threads.remove(t)
  
          if limit and len(threads) > limit:
              return threads[:limit]
  
          return threads