When data is read, there is always the change the a renegotiation will take place. If so,
this method will be called. Note, it is used by both the sync and async writes.

@param async
@return result of the handshake
@throws IOException
497454
private SSLEngineResult doHandshake(boolean async) throws IOException {
        if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled()) {
            Tr.entry(tc, "doHandshake");
        }

        SSLEngineResult sslResult;
        // Line up all the buffers needed for the SSL handshake. Temporary so
        // use indirect allocation for speed.
        int appSize = getConnLink().getAppBufferSize();
        int packetSize = getConnLink().getPacketBufferSize();
        WsByteBuffer localNetBuffer = SSLUtils.allocateByteBuffer(packetSize, true);
        WsByteBuffer decryptedNetBuffer = SSLUtils.allocateByteBuffer(appSize, false);
        WsByteBuffer encryptedAppBuffer = SSLUtils.allocateByteBuffer(packetSize, true);
        // Callback to be used if the request is async.
        MyHandshakeCompletedCallback handshakeCallback = null;
        if (async) {
            handshakeCallback = new MyHandshakeCompletedCallback(this, callback, localNetBuffer, decryptedNetBuffer, encryptedAppBuffer);
        }

        try {
            // Do the SSL handshake. Note, if synchronous the handshakeCallback is null.
            sslResult = SSLUtils.handleHandshake(
                                                 getConnLink(),
                                                 localNetBuffer,
                                                 decryptedNetBuffer,
                                                 encryptedAppBuffer,
                                                 null,
                                                 handshakeCallback,
                                                 false);
        } catch (IOException e) {
            // Release buffers used in the handshake.
            localNetBuffer.release();
            localNetBuffer = null;
            decryptedNetBuffer.release();
            decryptedNetBuffer = null;
            encryptedAppBuffer.release();
            encryptedAppBuffer = null;
            throw e;
        }
        if (sslResult != null) {
            // Handshake was done synchronously.
            // Release buffers used in the handshake.
            localNetBuffer.release();
            localNetBuffer = null;
            decryptedNetBuffer.release();
            decryptedNetBuffer = null;
            encryptedAppBuffer.release();
            encryptedAppBuffer = null;
        }

        if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled()) {
            Tr.exit(tc, "doHandshake");
        }
        return sslResult;
    }
169550
@Override
    public java.util.concurrent.Future<DescribeInternetGatewaysResult> describeInternetGatewaysAsync(
            com.amazonaws.handlers.AsyncHandler<DescribeInternetGatewaysRequest, DescribeInternetGatewaysResult> asyncHandler) {

        return describeInternetGatewaysAsync(new DescribeInternetGatewaysRequest(), asyncHandler);
    }
170128
public synchronized int read() throws IOException
	{
		if (bytesUntilNextMetadata > 0)
		{
			bytesUntilNextMetadata--;
			return super.read();
		}
		else 
		if (bytesUntilNextMetadata == 0)
		{
			readMetadata();
			bytesUntilNextMetadata = metaint - 1;
			// -1 because we read byte on next line
			return super.read();
		}
		else
		{
			return super.read();
		}
	}
75617
protected void proxyReadHandshake() {

        // setup the read buffer - use JIT on the first read attempt. If it
        // works, then any subsequent reads will use that same buffer.
        connLink.getReadInterface().setJITAllocateSize(1024);
        // reader.setBuffer(WsByteBufferPoolManagerImpl.getRef().allocate(1024));

        if (connLink.isAsyncConnect()) {
            // handshake - read the proxy response
            this.proxyReadCB = new ProxyReadCallback();
            readProxyResponse(connLink.getVirtualConnection());

        } else {
            int rc = STATUS_NOT_DONE;
            while (rc == STATUS_NOT_DONE) {
                readProxyResponse(connLink.getVirtualConnection());
                rc = checkResponse(connLink.getReadInterface());
            }
            if (rc == STATUS_ERROR) {
                if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled()) {
                    Tr.debug(tc, "could not complete proxy handshake, read request failed");
                }
                releaseProxyReadBuffer();
                // if (null == this.syncError) {
                if (connLink.isSyncError() == false) {
                    // create a new connect exception
                    connLink.connectFailed(new IOException("Invalid Proxy Server Response "));
                }
            }
        }
    }
1011012
@Override
  public int read() throws IOException {
    if (mPosition == mLength) { // at end of file
      return -1;
    }
    CountingRetry retry = new CountingRetry(mBlockWorkerClientReadRetry);
    IOException lastException = null;
    while (retry.attempt()) {
      try {
        updateStream();
        int result = mBlockInStream.read();
        if (result != -1) {
          mPosition++;
        }
        return result;
      } catch (UnavailableException | DeadlineExceededException | ConnectException e) {
        lastException = e;
        if (mBlockInStream != null) {
          handleRetryableException(mBlockInStream, e);
          mBlockInStream = null;
        }
      }
    }
    throw lastException;
  }
359938
@Override
    public java.util.concurrent.Future<DescribeNetworkInterfacesResult> describeNetworkInterfacesAsync(
            com.amazonaws.handlers.AsyncHandler<DescribeNetworkInterfacesRequest, DescribeNetworkInterfacesResult> asyncHandler) {

        return describeNetworkInterfacesAsync(new DescribeNetworkInterfacesRequest(), asyncHandler);
    }
995610
public synchronized Message readDatagram ()
        throws IOException, ClassNotFoundException
    {
        // read in the sequence number and determine if it's out-of-order
        int number = _uin.readInt();
        if (number <= _lastReceived) {
            return null;
        }
        _missedCount = number - _lastReceived - 1;
        _lastReceived = number;

        // read the acknowledge number and process all send records up to that one
        int received = _uin.readInt();
        int remove = 0;
        for (int ii = 0, nn = _sendrecs.size(); ii < nn; ii++) {
            SendRecord sendrec = _sendrecs.get(ii);
            if (sendrec.number > received) {
                break;
            }
            remove++;
            if (sendrec.number == received) {
                if (sendrec.mappedClasses != null) {
                    _uout.noteClassMappingsReceived(sendrec.mappedClasses);
                }
                if (sendrec.mappedInterns != null) {
                    _uout.noteInternMappingsReceived(sendrec.mappedInterns);
                }
            }
        }
        if (remove > 0) {
            _sendrecs.subList(0, remove).clear();
        }

        // read the contents of the datagram, note the transport, and return
        Message datagram = (Message)_uin.readObject();
        datagram.setTransport(Transport.UNRELIABLE_ORDERED);
        return datagram;
    }
1200438
@Override
    public java.util.concurrent.Future<DescribeConnectionsResult> describeConnectionsAsync(
            com.amazonaws.handlers.AsyncHandler<DescribeConnectionsRequest, DescribeConnectionsResult> asyncHandler) {

        return describeConnectionsAsync(new DescribeConnectionsRequest(), asyncHandler);
    }
700417
@Override
    public java.util.concurrent.Future<ListKeysResult> listKeysAsync(com.amazonaws.handlers.AsyncHandler<ListKeysRequest, ListKeysResult> asyncHandler) {

        return listKeysAsync(new ListKeysRequest(), asyncHandler);
    }
1336861
public ListenableFuture<ResourceSet<T>> readAsync(final TwilioRestClient client) {
        return Twilio.getExecutorService().submit(new Callable<ResourceSet<T>>() {
            public ResourceSet<T> call() {
                return read(client);
            }
        });
    }
703033
@Override
    public java.util.concurrent.Future<DescribeConversionTasksResult> describeConversionTasksAsync(
            com.amazonaws.handlers.AsyncHandler<DescribeConversionTasksRequest, DescribeConversionTasksResult> asyncHandler) {

        return describeConversionTasksAsync(new DescribeConversionTasksRequest(), asyncHandler);
    }
248754
private IAsyncResultHandler<IApiConnectionResponse> createApiConnectionResponseHandler() {
        return (IAsyncResult<IApiConnectionResponse> result) -> {
            if (result.isSuccess()) {
                requestMetric.setApiEnd(new Date());
                // The result came back. NB: still need to put it through the response chain.
                apiConnectionResponse = result.getResult();
                ApiResponse apiResponse = apiConnectionResponse.getHead();
                context.setAttribute("apiman.engine.apiResponse", apiResponse); //$NON-NLS-1$

                // Execute the response chain to evaluate the response.
                responseChain = createResponseChain((ApiResponse response) -> {
                    // Send the api response to the caller.
                    final EngineResultImpl engineResult = new EngineResultImpl(response);
                    engineResult.setConnectorResponseStream(apiConnectionResponse);

                    resultHandler.handle(AsyncResultImpl.create(engineResult));

                    // We've come all the way through the response chain successfully
                    responseChain.bodyHandler(buffer -> {
                        requestMetric.setBytesDownloaded(requestMetric.getBytesDownloaded() + buffer.length());
                        engineResult.write(buffer);
                    });

                    responseChain.endHandler(isEnd -> {
                        engineResult.end();
                        finished = true;
                        metrics.record(requestMetric);
                    });

                    // Signal to the connector that it's safe to start transmitting data.
                    apiConnectionResponse.transmit();
                });

                // Write data from the back-end response into the response chain.
                apiConnectionResponse.bodyHandler(buffer -> responseChain.write(buffer));

                // Indicate back-end response is finished to the response chain.
                apiConnectionResponse.endHandler(isEnd -> responseChain.end());

                responseChain.doApply(apiResponse);
            } else {
                resultHandler.handle(AsyncResultImpl.create(result.getError()));
            }
        };
    }
350650
private <T extends IGPSObject> T syncCommand(final String command, final Class<T> responseClass) throws IOException {
		synchronized (this.asyncMutex) {
			if (out != null) {
				this.out.write(command + "\n");
				this.out.flush();
			}
			if (responseClass == WatchObject.class) {
				lastWatch = command;
			}
			while (true) {
				// wait for awaited message
				// FIXME possible infinite loop if expected result arrives but new result overrides expected result before getting to this point.
				final IGPSObject result = this.waitForResult();
				if ((result == null) || result.getClass().equals(responseClass)) {
					return responseClass.cast(result);
				}
			}
		}
	}
309885
public void sync() throws ClosedJournalException, IOException {
        try {
            appender.sync().get();
            if (appender.getAsyncException() != null) {
                throw new IOException(appender.getAsyncException());
            }
        } catch (Exception ex) {
            throw new IllegalStateException(ex.getMessage(), ex);
        }
    }
1235579
@Override
    public java.util.concurrent.Future<DescribeApplicationVersionsResult> describeApplicationVersionsAsync(
            com.amazonaws.handlers.AsyncHandler<DescribeApplicationVersionsRequest, DescribeApplicationVersionsResult> asyncHandler) {

        return describeApplicationVersionsAsync(new DescribeApplicationVersionsRequest(), asyncHandler);
    }
529810
@Override
    public java.util.concurrent.Future<DescribeSeverityLevelsResult> describeSeverityLevelsAsync(
            com.amazonaws.handlers.AsyncHandler<DescribeSeverityLevelsRequest, DescribeSeverityLevelsResult> asyncHandler) {

        return describeSeverityLevelsAsync(new DescribeSeverityLevelsRequest(), asyncHandler);
    }
953289
public static Function<IHTTPSession, Response> syncHandler(final ExecutorService pool, final String mimeType, @javax.annotation.Nonnull final Consumer<OutputStream> logic, final boolean async) {
    return session -> {
      try (@javax.annotation.Nonnull ByteArrayOutputStream out = new ByteArrayOutputStream()) {
        logic.accept(out);
        out.flush();
        final byte[] bytes = out.toByteArray();
        return NanoHTTPD.newFixedLengthResponse(Response.Status.OK, mimeType, new ByteArrayInputStream(bytes), bytes.length);
      } catch (@javax.annotation.Nonnull final IOException e) {
        e.printStackTrace();
        throw new RuntimeException(e);
      }
    };
  }