code: public byte[] torrentData(boolean extra) {
          if (invalid) {
              return null;
          }
  
          if (data != null) {
              return data;
          }
  
          sync.lock();
  
          try {
              if (invalid) {
                  return null;
              }
  
              if (data != null) {
                  return data;
              }
  
              torrent_handle th = alert.getHandle();
              if (th == null || !th.is_valid()) {
                  invalid = true;
                  return null;
              }
  
              torrent_info ti = th.torrent_file_ptr();
              if (ti == null || !ti.is_valid()) {
                  invalid = true;
                  return null;
              }
  
              size = ti.metadata_size();
              data = createTorrent(th, ti, extra);
  
          } catch (Throwable e) {
              invalid = true;
          } finally {
              sync.unlock();
          }
  
          return data;
      }
docs: This method construct the torrent lazily. If the metadata
  is very big it can be a problem in memory constrained devices.
  <p>
  Internally it uses a lock synchronization to make it thread-safe.
  
  @param extra this controls if extra data, like trackers and web seeds
  are included
  @return the torrent info bencoded data