private void announceConnectionDown() {

    if (client.getLogger() != null)
      client.getLogger().log(Level.INFO, "Announcing connection down...");

    try {

      if (socket != null) {

        try {

          socket.close();

        } catch (Exception ex) {

        }
      }

      if (input != null) {

        try {

          input.close();

        } catch (Exception ex) {

        }
      }

      if (output != null) {

        try {

          output.close();

        } catch (Exception ex) {

        }
      }

    } catch (Exception ex) {

    }

    if (this.client != null) {

      this.client.setDisconnected();
    }

    this.stopActivity();
    killBufferBridgeThread();
  }
  private synchronized void bufferBytes(byte[] b) throws Exception {

    if (b == null) {

      return;
    }

    if (this.buffer != null) {

      if (client.getLogger() != null)
        client.getLogger().log(Level.INFO, "Buffering " + b.length + " bytes");

      this.buffer.buffer(b);

    } else {

      if (client.getLogger() != null) client.getLogger().log(Level.INFO, "Buffer is null.");
    }
  }
  @Override
  public void write(byte[] toWrite) {

    if (this.output != null) {

      try {

        this.output.write(toWrite);
        totalSentBytes += toWrite.length;

      } catch (IOException ex) {

        if (client.getLogger() != null)
          client
              .getLogger()
              .log(Level.SEVERE, "Could not write data to client's output stream", ex);

        this.announceConnectionDown();
      }
    }
  }
  private void startReading() {

    if (this.input == null) {

      return;
    }

    final long totalBytesReceivedEver = 0;

    Runnable readJob =
        new Runnable() {

          @Override
          public void run() {

            while (true) {

              try {

                // Block and wait for one byte
                if (client.getLogger() != null)
                  client.getLogger().log(Level.INFO, "Blocked reading (waiting for bytes)...");

                int b = input.read();

                if (client.getLogger() != null)
                  client.getLogger().log(Level.INFO, ":) UnBlocked reading");

                // Connection closed
                if (b == -1) {

                  announceConnectionDown();
                  break;
                }

                // Read all available data on the stream
                int available = input.available();
                byte[] data = new byte[available + 1];
                data[0] = (byte) b;
                int totalBytesRead = input.read(data, 1, available);
                final byte[] all_bytes = Arrays.copyOf(data, totalBytesRead + 1);

                totalBytesRead += all_bytes.length;

                if (client.getLogger() != null)
                  client
                      .getLogger()
                      .log(
                          Level.INFO,
                          totalBytesRead + " bytes read. Total available was " + available);

                // Send the data to the buffer and keep reading
                Runnable bufferWork =
                    new Runnable() {

                      int wIndex = workIndex;

                      @Override
                      public void run() {

                        if (client.getLogger() != null)
                          client
                              .getLogger()
                              .log(Level.INFO, "Work [" + wIndex + "]  Buffering on work queue...");

                        bufferBytes(all_bytes);
                      }
                    };

                workIndex++;
                queueItUp(bufferWork);

              } catch (IOException ex) {

                if (client.getLogger() != null)
                  client.getLogger().log(Level.INFO, "Connection lost");

                try {

                  input.close();

                } catch (Exception ex_) {

                }

                try {

                  output.close();

                } catch (Exception ex_) {

                }

                try {

                  socket.close();

                } catch (Exception ex_) {

                }

                announceConnectionDown();
                break;
              }
            }
          }
        };

    client.getExecutorService().submit(readJob);
    if (client.getLogger() != null) client.getLogger().log(Level.INFO, "ReadingThread started...");
  }