title: In Android, I'm Trying to Fetch Data From a URL To Plot on a Map, but I'm Having Problems Even Getting it To Print
body: <p>I am trying to fetch some data from online, which is in CSV format, however, I am getting an extremely long amount of errors in my log cat monitor and now I can't even get it to display those anymore. It won't return the data and crashes when attempting to plot it on the map.</p>
  
  <p>Here's My Code For The Thread That Performs The Fetch:</p>
  
  <pre><code>package com.example.alexlevine.oceanapp;
  
  import android.os.AsyncTask;
  
  import com
          .google.android.gms.maps.model.LatLng;
  import com.google.maps.android.heatmaps.HeatmapTileProvider;
  import com.google.maps.android.heatmaps.WeightedLatLng;
  
  import java.io.BufferedReader;
  import java.io.IOException;
  import java.io.InputStreamReader;
  import java.lang.reflect.Array;
  import java.net.MalformedURLException;
  import java.net.URL;
  import java.net.URLConnection;
  import java.util.ArrayList;
  import java.util.List;
  
  import static java.lang.Double.parseDouble;
  
  /**
   * Created by Alex Levine on 8/14/2017.
   */
  
  public class fetchFFDASData extends AsyncTask&lt;URL, Void, List&lt;String[]&gt;&gt; {
      public static ArrayList&lt;WeightedLatLng&gt; ffdasArray;
  
      protected List&lt;String[]&gt; doInBackground(URL... urls) {
  
          String typekey;
  
          ffdasArray = new ArrayList&lt;WeightedLatLng&gt;();
          Object[] ffdasObjects = null;
          URL mUrl = null;
          List&lt;String[]&gt; csvLine = new ArrayList&lt;&gt;();
          String[] content = null;
          try {
              //mUrl = new URL("http://hpcg.purdue.edu/FFDAS/Download/"+MainActivity.typeKey+"_yearly_date="+MainActivity.displayyear+"s-01-01-00_res=0.1_origin=-180,90_size=360,-180.csv");
              mUrl = new URL ("http://hpcg.purdue.edu/FFDAS/Download/" + MainActivity.typeKey + "_yearly_date=" + MainActivity.displayyear + "-01-01-00_res=0.1_origin=-180,90_size=360,-180.csv");
          } catch (MalformedURLException e) {
              e.printStackTrace();
          }
          try {
              //assert mUrl != null;
              URLConnection connection = mUrl.openConnection();
              BufferedReader br = new BufferedReader(new
                      InputStreamReader(connection.getInputStream()));
              String line = "";
              while((line = br.readLine()) != null){
                  content = line.split(",");
                  csvLine.add(content);
              }
              br.close();
          } catch (IOException e) {
              e.printStackTrace();
          }
  
          for(int i = 3; i &lt; /*csvLine.size()*/7; i++) {
              double lt = Double.parseDouble(csvLine.get(i)[0]);
              double ln = Double.parseDouble(csvLine.get(i)[2]);
              double w = Double.parseDouble(csvLine.get(i)[2]);
              LatLng ltln = new LatLng(lt, ln);
              WeightedLatLng wll = new WeightedLatLng(ltln, w);
              ffdasArray.add(wll);
          }
          return null;
      }
  
      protected void onPostExecute(List&lt;String[]&gt; result) {
          super.onPostExecute(result);
          //
          }
      }
  </code></pre>
  
  <p>Here Is My Main Activity:</p>
  
  <pre><code> package com.example.alexlevine.oceanapp;
  
  import android.app.Dialog;
  import android.support.v7.app.AppCompatActivity;
  import android.os.Bundle;
  import android.util.Log;
  import android.view.Menu;
  import android.view.MenuItem;
  import android.widget.AdapterView;
  import android.widget.ArrayAdapter;
  import android.widget.SeekBar;
  import android.widget.Spinner;
  import android.widget.TextView;
  import android.widget.Toast;
  
  import com.google.android.gms.common.ConnectionResult;
  import com.google.android.gms.common.GoogleApiAvailability;
  import com.google.android.gms.maps.CameraUpdate;
  import com.google.android.gms.maps.CameraUpdateFactory;
  import com.google.android.gms.maps.GoogleMap;
  import com.google.android.gms.maps.OnMapReadyCallback;
  import com.google.android.gms.maps.SupportMapFragment;
  import com.google.android.gms.maps.model.LatLng;
  import com.google.android.gms.maps.model.TileOverlayOptions;
  import com.google.maps.android.heatmaps.HeatmapTileProvider;
  import com.google.maps.android.heatmaps.WeightedLatLng;
  
  import android.view.View;
  
  import java.util.ArrayList;
  import java.util.List;
  
  import static com.example.alexlevine.oceanapp.R.id.seekBar;
  
  public class MainActivity extends AppCompatActivity implements OnMapReadyCallback {
  
      public static SeekBar seekbar;
  
      public static GoogleMap mGoogleMap;
      private HeatmapTileProvider mProvider;
  
      public static TextView minyear;
      public static TextView maxyear;
      public static TextView currentyeartext;
      public static int displayyear;
      public static boolean usingSOCAT;
      public static String typeKey;
      public static Spinner dropdown;
  
      @Override
      protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.activity_main);
          if (googleServicesAvailable()) {
              Toast.makeText(this, "Play services available", Toast.LENGTH_LONG).show();;
              initMap();
  
              //get the spinner from the xml.
              dropdown = (Spinner)findViewById(R.id.spinner);
              //create a list of items for the spinner.
              String[] items = new String[]{"Ocean CO2 Densities", "Land CO2 Emissions (all sources)", "Electricity CO2 Emissions", "Aviation CO2 Emissions", "Ocean Shipping CO2 Emissions"};
              //create an adapter to describe how the items are displayed, adapters are used in several places in android.
              //There are multiple variations of this, but this is the basic variant.
              ArrayAdapter&lt;String&gt; adapter = new ArrayAdapter&lt;String&gt;(this, android.R.layout.simple_spinner_dropdown_item, items);
              //set the spinners adapter to the previously created one.
              dropdown.setAdapter(adapter);
  
  
              currentyeartext = (TextView) findViewById(R.id.currentyear);
  
              minyear = (TextView) findViewById(R.id.minyear);
              maxyear = (TextView) findViewById(R.id.maxyear);
  
              typeKey = "00totals";
              dropdown.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
                  public void onItemSelected(AdapterView&lt;?&gt; parent, View view, int position, long id)
                  {
                      switch (position) {
                          case 0: {
                              usingSOCAT = true;
                              displayyear = 1957;
                              seekbar.setMax(58);
                              minyear.setText("1957");
                              maxyear.setText("2015");
                              break;
                          }
                          case 1: {
                              usingSOCAT = false;
                              displayyear = 1997;
                              minyear.setText("1997");
                              maxyear.setText("2010");
                              seekbar.setMax(14);
                              typeKey = "00totals";
                              break;
                          }
                          case 2: {
                              usingSOCAT = false;
                              displayyear = 1997;
                              minyear.setText("1997");
                              maxyear.setText("2010");
                              seekbar.setMax(14);
                              typeKey = "01elec";
  
                              // Whatever you want to happen when the thrid item gets selected
                              break;
                          }
                          case 3: {
                              usingSOCAT = false;
                              displayyear = 1997;
                              minyear.setText("1997");
                              maxyear.setText("2010");
                              seekbar.setMax(14);
                              typeKey = "11aviation";;
                              // Whatever you want to happen when the thrid item gets selected
                              break;
                          }
                          case 4: {
                              usingSOCAT = false;
                              displayyear = 1997;
                              minyear.setText("1997");
                              maxyear.setText("2010");
                              seekbar.setMax(14);
                              typeKey = "12shipping";
                              // Whatever you want to happen when the thrid item gets selected
                              break;
                          }
                      }
                  }
                  public void onNothingSelected(AdapterView&lt;?&gt; parent)
                  {
  
                  }
              });
  
              seekbar = (SeekBar) findViewById(seekBar);
              seekbar.setOnSeekBarChangeListener(
                      new SeekBar.OnSeekBarChangeListener() {
  
                          @Override
                          public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
  
                              displayyear = progress + 1997;
                              if(usingSOCAT)
                              {
                                  displayyear = progress + 1957;
                                  new fetchSOCATData().execute();
                                  //createHeatMap(fetchSOCATData.co2array);
                              }
                              else
                              {
                                  displayyear = progress + 1997;
                                  new fetchFFDASData().execute();
                                  //List&lt;WeightedLatLng&gt; calledData = fetchFFDASData.ffdasArray;
                                  //List&lt;WeightedLatLng&gt; tryit = new ArrayList&lt;WeightedLatLng&gt;();
                                  /*tryit.add(new WeightedLatLng(new LatLng(62, 42), 99));
                                  tryit.add(new WeightedLatLng(new LatLng(86, 42), 14));
                                  tryit.add(new WeightedLatLng(new LatLng(94, 42), 82));
                                  tryit.add(new WeightedLatLng(new LatLng(71, 42), 22));
                                  tryit.add(new WeightedLatLng(new LatLng(21, 42), 23));*/
                                  //createHeatMap(fetchFFDASData.ffdasArray);
                                  minyear.setText((CharSequence) fetchFFDASData.ffdasArray);
                              }
                              currentyeartext.setText("Showing: " + displayyear);
                          }
  
                          @Override
                          public void onStartTrackingTouch(SeekBar seekBar) {
  
                          }
  
                          @Override
                          public void onStopTrackingTouch(SeekBar seekBar) {
  
                          }
                      });
  
              if(usingSOCAT) {
  
              }
              //new fetchSOCATData().execute();
              /*minyear = (TextView) findViewById(R.id.minyear);
              maxyear = (TextView) findViewById(R.id.maxyear);
              minyear.setText("1957");
              maxyear.setText("2015");*/
  
              //fetchSOCATData process = new fetchSOCATData();
              //process.execute();
  
          } else {
              //No maps layout
          }
      }
  
      //@Override
      public void onNothingSelected(AdapterView&lt;?&gt; parent) {
  
      }
  
      public void initMap() {
         SupportMapFragment mapFragment = (SupportMapFragment) this.getSupportFragmentManager()
                 .findFragmentById(R.id.mapFragment);
  
         if(mapFragment != null) {
             mapFragment.getMapAsync((OnMapReadyCallback)this);
         }
      }
  
      public void createHeatMap(List&lt;WeightedLatLng&gt; dataset)
      {
         List&lt;WeightedLatLng&gt; locations = dataset;
         /*mProvider = new HeatmapTileProvider.Builder().weightedData(locations).build();
         mProvider.setRadius( HeatmapTileProvider.DEFAULT_RADIUS );
         mGoogleMap.addTileOverlay(new TileOverlayOptions().tileProvider(mProvider));
          mProvider = new HeatmapTileProvider();
          mProvider.setWeightedData(dataset);
          mProvider = mProvider.build();*/
  
          //for (LatLng coordinate : coordinates) {
              //WeightedLatLng weightedCoordinate = new WeightedLatLng(coordinate);
              //com.google.maps.android.geometry.Point point = weightedCoordinate.getPoint();
  
              // Filter points at infinity
             /* if (Double.isInfinite(point.x) || Double.isInfinite(point.y)) {
                  Log.w(TAG, "Attempted to add undefined point " + coordinate);
                  continue;
              }
              weightedCoordinates.add(weightedCoordinate);*/
          //}
  
          mProvider = new HeatmapTileProvider.Builder()
                  .weightedData(dataset)
                  .opacity(0.5)
                  .build();
          mGoogleMap.addTileOverlay(new TileOverlayOptions().tileProvider(mProvider));
          Toast.makeText(this, "working", Toast.LENGTH_SHORT).show();
      }
  
      public void onMapReady(GoogleMap googleMap) {
          mGoogleMap = googleMap;
          goToLocation(-65, -12);
      }
  
      public void goToLocation(double lat, double lng) {
          LatLng ll = new LatLng(lat, lng);
          CameraUpdate update = CameraUpdateFactory.newLatLng(ll);
          mGoogleMap.moveCamera(update);
      }
  
      public boolean googleServicesAvailable() {
          GoogleApiAvailability api = GoogleApiAvailability.getInstance();
          int isAvailable = api.isGooglePlayServicesAvailable(this);
          if (isAvailable == ConnectionResult.SUCCESS)
              return true;
          else if (api.isUserResolvableError(isAvailable)) {
              Dialog dialog = api.getErrorDialog(this, isAvailable, 0);
              dialog.show();
          } else
              Toast.makeText(this, "Can't connect to play services", Toast.LENGTH_LONG).show();
          return false;
      }
  
  
  } 
  </code></pre>
  
  <p>Please note that there are calls to other methods in the MainActivity which I have excluded in this post because they are not relevant, so that's not an error. However, could someone please take a look at my code and help me debug this? Thanks!</p>
  
  <p>EDITED: Here's my log from where the error starts:</p>
  
  <p>I saw some information on memory allocation, but I highly doubt that their is a huge overflow because I'm only calling like 4 lines of data to test this. Also, previously, there was some type of error displaying about some missing header, but I can't recreate it anymore.</p>
  
  <pre><code>08-29 01:05:22.311 11369-11378/com.example.alexlevine.oceanapp I/zygote: WaitForGcToComplete blocked for 9.873s for cause ObjectsAllocated
  08-29 01:05:22.311 11369-11378/com.example.alexlevine.oceanapp I/zygote: Forcing collection of SoftReferences for 32B allocation
  08-29 01:05:22.312 11369-11380/com.example.alexlevine.oceanapp I/zygote: WaitForGcToComplete blocked for 4.880s for cause HeapTrim
  08-29 01:05:22.312 11369-11369/com.example.alexlevine.oceanapp I/zygote: WaitForGcToComplete blocked for 5.472s for cause ObjectsAllocated
  08-29 01:05:22.312 11369-11856/com.example.alexlevine.oceanapp I/zygote: Waiting for a blocking GC ObjectsAllocated
  08-29 01:05:22.312 11369-11376/com.example.alexlevine.oceanapp I/zygote: Waiting for a blocking GC ObjectsAllocated
  08-29 01:05:22.312 11369-11378/com.example.alexlevine.oceanapp I/zygote: Waiting for a blocking GC Alloc
  08-29 01:05:22.312 11369-11379/com.example.alexlevine.oceanapp I/zygote: Waiting for a blocking GC ObjectsAllocated
  08-29 01:05:22.313 11369-11369/com.example.alexlevine.oceanapp W/zygote: Throwing OutOfMemoryError "Failed to allocate a 40 byte allocation with 8 free bytes and 8B until OOM, max allowed footprint 402653184, growth limit 402653184"
  08-29 01:05:22.313 11369-11856/com.example.alexlevine.oceanapp I/zygote: WaitForGcToComplete blocked for 27.854s for cause ObjectsAllocated
  08-29 01:05:22.313 11369-11856/com.example.alexlevine.oceanapp I/zygote: Starting a blocking GC Alloc
  08-29 01:05:22.313 11369-11376/com.example.alexlevine.oceanapp I/zygote: Waiting for a blocking GC ObjectsAllocated
  08-29 01:05:22.313 11369-11369/com.example.alexlevine.oceanapp I/zygote: Waiting for a blocking GC Alloc
  08-29 01:05:22.318 11369-11378/com.example.alexlevine.oceanapp I/zygote: Waiting for a blocking GC Alloc
  08-29 01:05:22.318 11369-11379/com.example.alexlevine.oceanapp I/zygote: Waiting for a blocking GC ObjectsAllocated
  08-29 01:05:23.535 11369-11856/com.example.alexlevine.oceanapp I/zygote: Clamp target GC heap from 389MB to 384MB
  08-29 01:05:23.535 11369-11856/com.example.alexlevine.oceanapp I/zygote: Alloc concurrent copying GC freed 0(0B) AllocSpace objects, 0(0B) LOS objects, 0% free, 383MB/384MB, paused 553us total 1.222s
  08-29 01:05:23.535 11369-11376/com.example.alexlevine.oceanapp I/zygote: WaitForGcToComplete blocked for 2.496s for cause ObjectsAllocated
  08-29 01:05:23.535 11369-11376/com.example.alexlevine.oceanapp W/zygote: Throwing OutOfMemoryError "Failed to allocate a 32 byte allocation with 8 free bytes and 8B until OOM, max allowed footprint 402653184, growth limit 402653184" (recursive case)
  08-29 01:05:23.536 11369-11378/com.example.alexlevine.oceanapp I/zygote: WaitForGcToComplete blocked for 1.223s for cause Alloc
  08-29 01:05:23.536 11369-11378/com.example.alexlevine.oceanapp I/zygote: Starting a blocking GC Alloc
  08-29 01:05:23.536 11369-11376/com.example.alexlevine.oceanapp W/zygote: "JDWP" daemon prio=5 tid=4 Runnable
  08-29 01:05:23.536 11369-11376/com.example.alexlevine.oceanapp W/zygote:   | group="system" sCount=0 dsCount=0 flags=0 obj=0x12c467e8 self=0xa7c0bc00
  08-29 01:05:23.536 11369-11376/com.example.alexlevine.oceanapp W/zygote:   | sysTid=11376 nice=0 cgrp=default sched=0/0 handle=0x96aea970
  08-29 01:05:23.536 11369-11376/com.example.alexlevine.oceanapp W/zygote:   | state=R schedstat=( 29027554235 2495307398 3483 ) utm=2703 stm=199 core=0 HZ=100
  08-29 01:05:23.536 11369-11376/com.example.alexlevine.oceanapp W/zygote:   | stack=0x969f0000-0x969f2000 stackSize=1006KB
  08-29 01:05:23.536 11369-11376/com.example.alexlevine.oceanapp W/zygote:   | held mutexes= "mutator lock"(shared held)
  08-29 01:05:23.536 11369-11376/com.example.alexlevine.oceanapp W/zygote:     at java.lang.Throwable.toString(Throwable.java:474)
  08-29 01:05:23.536 11369-11376/com.example.alexlevine.oceanapp W/zygote:     at java.lang.String.valueOf(String.java:2827)
  08-29 01:05:23.536 11369-11376/com.example.alexlevine.oceanapp W/zygote:     at java.lang.StringBuilder.append(StringBuilder.java:132)
  08-29 01:05:23.536 11369-11376/com.example.alexlevine.oceanapp W/zygote:     at com.android.internal.os.LoggingPrintStream.println(LoggingPrintStream.java:290)
  08-29 01:05:23.536 11369-11376/com.example.alexlevine.oceanapp W/zygote:     at java.lang.Throwable$WrappedPrintStream.println(Throwable.java:740)
  08-29 01:05:23.536 11369-11376/com.example.alexlevine.oceanapp W/zygote:     at java.lang.Throwable.printStackTrace(Throwable.java:648)
  08-29 01:05:23.536 11369-11376/com.example.alexlevine.oceanapp W/zygote:     at java.lang.Throwable.printStackTrace(Throwable.java:636)
  08-29 01:05:23.536 11369-11376/com.example.alexlevine.oceanapp W/zygote:     at java.lang.Throwable.printStackTrace(Throwable.java:627)
  08-29 01:05:23.536 11369-11379/com.example.alexlevine.oceanapp I/zygote: Waiting for a blocking GC ObjectsAllocated
  08-29 01:05:23.536 11369-11369/com.example.alexlevine.oceanapp I/zygote: Waiting for a blocking GC Alloc
  08-29 01:05:23.536 11369-11376/com.example.alexlevine.oceanapp W/zygote: JNI WARNING: java.lang.OutOfMemoryError thrown while calling printStackTrace
  08-29 01:05:23.537 11369-11376/com.example.alexlevine.oceanapp I/zygote: Waiting for a blocking GC Alloc
  08-29 01:05:23.538 11369-11856/com.example.alexlevine.oceanapp I/zygote: Waiting for a blocking GC ObjectsAllocated
  08-29 01:05:25.781 11369-11378/com.example.alexlevine.oceanapp I/zygote: Clamp target GC heap from 389MB to 384MB
  08-29 01:05:25.781 11369-11378/com.example.alexlevine.oceanapp I/zygote: Alloc concurrent copying GC freed 10(728B) AllocSpace objects, 0(0B) LOS objects, 0% free, 383MB/384MB, paused 1.299ms total 2.245s
  08-29 01:05:25.781 11369-11369/com.example.alexlevine.oceanapp I/zygote: Waiting for a blocking GC Alloc
  08-29 01:05:25.781 11369-11379/com.example.alexlevine.oceanapp I/zygote: Waiting for a blocking GC ObjectsAllocated
  08-29 01:05:25.781 11369-11856/com.example.alexlevine.oceanapp I/zygote: Waiting for a blocking GC ObjectsAllocated
  08-29 01:05:25.782 11369-11376/com.example.alexlevine.oceanapp I/zygote: Waiting for a blocking GC Alloc
  08-29 01:05:25.782 11369-11369/com.example.alexlevine.oceanapp I/zygote: WaitForGcToComplete blocked for 3.469s for cause Alloc
  08-29 01:05:25.782 11369-11369/com.example.alexlevine.oceanapp I/zygote: Starting a blocking GC Alloc
  08-29 01:05:25.782 11369-11379/com.example.alexlevine.oceanapp I/zygote: WaitForGcToComplete blocked for 3.469s for cause ObjectsAllocated
  08-29 01:05:25.782 11369-11369/com.example.alexlevine.oceanapp I/zygote: Waiting for a blocking GC Alloc
  08-29 01:05:25.783 11369-11376/com.example.alexlevine.oceanapp I/zygote: Waiting for a blocking GC Alloc
  08-29 01:05:25.783 11369-11379/com.example.alexlevine.oceanapp I/zygote: Starting a blocking GC Alloc
  08-29 01:05:25.783 11369-11378/com.example.alexlevine.oceanapp W/zygote: Throwing OutOfMemoryError "Failed to allocate a 32 byte allocation with 0 free bytes and 0B until OOM, max allowed footprint 402653184, growth limit 402653184" (recursive case)
  08-29 01:05:25.783 11369-11379/com.example.alexlevine.oceanapp I/zygote: Starting a blocking GC Alloc
  08-29 01:05:25.783 11369-11376/com.example.alexlevine.oceanapp I/zygote: Waiting for a blocking GC Alloc
  08-29 01:05:25.783 11369-11369/com.example.alexlevine.oceanapp I/zygote: Waiting for a blocking GC Alloc
  08-29 01:05:25.784 11369-11856/com.example.alexlevine.oceanapp I/zygote: Waiting for a blocking GC ObjectsAllocated
  08-29 01:05:25.784 11369-11378/com.example.alexlevine.oceanapp W/zygote: "FinalizerDaemon" daemon prio=5 tid=9 Runnable
  08-29 01:05:25.784 11369-11378/com.example.alexlevine.oceanapp W/zygote:   | group="system" sCount=0 dsCount=0 flags=0 obj=0x12c863f0 self=0xa5263a00
  08-29 01:05:25.784 11369-11378/com.example.alexlevine.oceanapp W/zygote:   | sysTid=11378 nice=4 cgrp=default sched=0/0 handle=0x968e8970
  08-29 01:05:25.784 11369-11378/com.example.alexlevine.oceanapp W/zygote:   | state=R schedstat=( 16464684522 913376415 1721 ) utm=1514 stm=132 core=0 HZ=100
  08-29 01:05:25.784 11369-11378/com.example.alexlevine.oceanapp W/zygote:   | stack=0x967e6000-0x967e8000 stackSize=1038KB
  08-29 01:05:25.784 11369-11378/com.example.alexlevine.oceanapp W/zygote:   | held mutexes= "mutator lock"(shared held)
  08-29 01:05:25.784 11369-11378/com.example.alexlevine.oceanapp W/zygote:     at com.android.internal.os.BinderInternal$GcWatcher.finalize(BinderInternal.java:53)
  08-29 01:05:25.784 11369-11378/com.example.alexlevine.oceanapp W/zygote:     at java.lang.Daemons$FinalizerDaemon.doFinalize(Daemons.java:250)
  08-29 01:05:25.784 11369-11378/com.example.alexlevine.oceanapp W/zygote:     at java.lang.Daemons$FinalizerDaemon.runInternal(Daemons.java:237)
  08-29 01:05:25.784 11369-11378/com.example.alexlevine.oceanapp W/zygote:     at java.lang.Daemons$Daemon.run(Daemons.java:103)
  08-29 01:05:25.784 11369-11378/com.example.alexlevine.oceanapp W/zygote:     at java.lang.Thread.run(Thread.java:764)
  08-29 01:05:25.786 11369-11378/com.example.alexlevine.oceanapp E/System: Uncaught exception thrown by finalizer
  08-29 01:05:25.786 11369-11378/com.example.alexlevine.oceanapp I/zygote: Waiting for a blocking GC Alloc 
  </code></pre>