private void postPlugin(final boolean isPing) throws IOException {
        // The plugin's description file containg all of the plugin data such as
        // name, version, author, etc
        final PluginDescriptionFile description = plugin.getDescription();

        // Construct the post data
        final StringBuilder data = new StringBuilder();
        data.append(Metrics.encode("guid")).append('=')
                .append(Metrics.encode(guid));
        Metrics.encodeDataPair(data, "version", description.getVersion());
        Metrics.encodeDataPair(data, "server", Bukkit.getVersion());
        Metrics.encodeDataPair(data, "players",
                Integer.toString(Bukkit.getServer().getOnlinePlayers().length));
        Metrics.encodeDataPair(data, "revision",
                String.valueOf(Metrics.REVISION));

        // If we're pinging, append it
        if (isPing) {
            Metrics.encodeDataPair(data, "ping", "true");
        }

        // Acquire a lock on the graphs, which lets us make the assumption we
        // also lock everything
        // inside of the graph (e.g plotters)
        synchronized (graphs) {
            final Iterator<Graph> iter = graphs.iterator();

            while (iter.hasNext()) {
                final Graph graph = iter.next();

                for (final Plotter plotter : graph.getPlotters()) {
                    // The key name to send to the metrics server
                    // The format is C-GRAPHNAME-PLOTTERNAME where separator -
                    // is defined at the top
                    // Legacy (R4) submitters use the format Custom%s, or
                    // CustomPLOTTERNAME
                    final String key = String.format("C%s%s%s%s",
                            Metrics.CUSTOM_DATA_SEPARATOR, graph.getName(),
                            Metrics.CUSTOM_DATA_SEPARATOR,
                            plotter.getColumnName());

                    // The value to send, which for the foreseeable future is
                    // just the string
                    // value of plotter.getValue()
                    final String value = Integer.toString(plotter.getValue());

                    // Add it to the http post data :)
                    Metrics.encodeDataPair(data, key, value);
                }
            }
        }

        // Create the url
        final URL url = new URL(Metrics.BASE_URL
                + String.format(Metrics.REPORT_URL,
                        Metrics.encode(plugin.getDescription().getName())));

        // Connect to the website
        URLConnection connection;

        // Mineshafter creates a socks proxy, so we can safely bypass it
        // It does not reroute POST requests so we need to go around it
        if (this.isMineshafterPresent()) {
            connection = url.openConnection(Proxy.NO_PROXY);
        } else {
            connection = url.openConnection();
        }

        connection.setDoOutput(true);

        // Write the data
        final OutputStreamWriter writer = new OutputStreamWriter(
                connection.getOutputStream());
        writer.write(data.toString());
        writer.flush();

        // Now read the response
        final BufferedReader reader = new BufferedReader(new InputStreamReader(
                connection.getInputStream()));
        final String response = reader.readLine();

        // close resources
        writer.close();
        reader.close();

        if (response == null || response.startsWith("ERR")) {
            throw new IOException(response); // Throw the exception
        } else {
            // Is this the first update this hour?
            if (response.contains("OK This is your first update this hour")) {
                synchronized (graphs) {
                    final Iterator<Graph> iter = graphs.iterator();

                    while (iter.hasNext()) {
                        final Graph graph = iter.next();

                        for (final Plotter plotter : graph.getPlotters()) {
                            plotter.reset();
                        }
                    }
                }
            }
        }
    }