@Override
  public SymbolTable getSymbolTable(String symbolTableName)
  {
    try
    {
      SymbolTableMetadata metadata = METADATA_EXTRACTOR.extractMetadata(symbolTableName);
      String serverNodeUri = metadata.getServerNodeUri();
      String tableName = metadata.getSymbolTableName();
      boolean isRemote = metadata.isRemote();

      // First check the cache.
      SymbolTable symbolTable = _cache.getIfPresent(tableName);
      if (symbolTable != null)
      {
        return symbolTable;
      }

      // If this is not a remote table, and we didn't find it in the cache, cry foul.
      if (!isRemote)
      {
        throw new IllegalStateException("Unable to fetch symbol table with name: " + symbolTableName);
      }

      // Ok, we didn't find it in the cache, let's go query the service the table was served from.
      String url = serverNodeUri + "/" + SYMBOL_TABLE_URI_PATH + "/" + tableName;
      HttpURLConnection connection = openConnection(url);
      try
      {
        if (DEFAULT_HEADERS != null)
        {
          DEFAULT_HEADERS.entrySet().forEach(entry -> connection.setRequestProperty(entry.getKey(), entry.getValue()));
        }
        if (HEADER_PROVIDER != null)
        {
          HEADER_PROVIDER.getHeaders().entrySet().forEach(entry -> connection.setRequestProperty(entry.getKey(), entry.getValue()));
        }
        connection.setRequestProperty(ACCEPT_HEADER, ProtobufDataCodec.DEFAULT_HEADER);
        connection.setRequestProperty(SYMBOL_TABLE_HEADER, Boolean.toString(true));
        int responseCode = connection.getResponseCode();

        if (responseCode == HttpURLConnection.HTTP_OK)
        {
          InputStream inputStream = connection.getInputStream();
          // Deserialize
          symbolTable = SymbolTableSerializer.fromInputStream(inputStream, CODEC, null);
        }
        else
        {
          throw new IOException("Unexpected response status: " + responseCode);
        }
      }
      finally
      {
        connection.disconnect();
      }

      // Cache the retrieved table.
      _cache.put(tableName, symbolTable);
      return symbolTable;
    }
    catch (MalformedURLException ex)
    {
      LOGGER.error("Failed to construct symbol table URL from symbol table name: " + symbolTableName, ex);
    }
    catch (Exception e)
    {
      LOGGER.error("Failed to fetch remote symbol table with name: " + symbolTableName, e);
    }

    throw new IllegalStateException("Unable to fetch symbol table with name: " + symbolTableName);
  }
@Test(expectedExceptions = IllegalStateException.class)
  public void testLocalSymbolTableFailure()
  {
    DefaultSymbolTableProvider provider = new DefaultSymbolTableProvider();
    provider.getSymbolTable("random");
  }