// and try again if we did not reach the timeout...
IbisSocket connect(TcpSendPort sp, ibis.ipl.impl.ReceivePortIdentifier rip,
            int timeout, boolean fillTimeout) throws IOException {
        IbisIdentifier id = (IbisIdentifier) rip.ibisIdentifier();
        String name = rip.name();
        IbisSocketAddress idAddr;
        synchronized (addresses) {
            idAddr = addresses.get(id);
            if (idAddr == null) {
                idAddr = new IbisSocketAddress(id.getImplementationData());
                addresses.put(id, idAddr);
            }
        }
        long startTime = System.currentTimeMillis();
        if (logger.isDebugEnabled()) {
            logger.debug("--> Creating socket for connection to " + name
                    + " at " + idAddr);
        }
        PortType sendPortType = sp.getPortType();
        do {
            DataOutputStream out = null;
            IbisSocket s = null;
            int result = -1;
            sp.printManagementProperties(System.out);
            try {
                s = factory.createClientSocket(idAddr, timeout, fillTimeout,
                        sp.managementProperties());
                s.setTcpNoDelay(true);
                out = new DataOutputStream(new BufferedArrayOutputStream(
                        s.getOutputStream()));
                out.writeUTF(name);
                sp.getIdent().writeTo(out);
                sendPortType.writeTo(out);
                out.flush();
                result = s.getInputStream().read();
                switch (result) {
                case ReceivePort.ACCEPTED:
                    return s;
                case ReceivePort.ALREADY_CONNECTED:
                    throw new AlreadyConnectedException("Already connected",
                            rip);
                case ReceivePort.TYPE_MISMATCH:
                    // Read receiveport type from input, to produce a
                    // better error message.
                    DataInputStream in = new DataInputStream(s.getInputStream());
                    PortType rtp = new PortType(in);
                    CapabilitySet s1 = rtp.unmatchedCapabilities(sendPortType);
                    CapabilitySet s2 = sendPortType.unmatchedCapabilities(rtp);
                    String message = "";
                    if (s1.size() != 0) {
                        message = message
                                + "\nUnmatched receiveport capabilities: "
                                + s1.toString() + ".";
                    }
                    if (s2.size() != 0) {
                        message = message
                                + "\nUnmatched sendport capabilities: "
                                + s2.toString() + ".";
                    }
                    throw new PortMismatchException(
                            "Cannot connect ports of different port types."
                                    + message, rip);
                case ReceivePort.DENIED:
                    throw new ConnectionRefusedException(
                            "Receiver denied connection", rip);
                case ReceivePort.NO_MANY_TO_X:
                    throw new ConnectionRefusedException(
                            "Receiver already has a connection and neither ManyToOne not ManyToMany "
                                    + "is set", rip);
                case ReceivePort.NOT_PRESENT:
                case ReceivePort.DISABLED:
                    // and try again if we did not reach the timeout...
                    if (timeout > 0
                            && System.currentTimeMillis() > startTime + timeout) {
                        throw new ConnectionTimedOutException(
                                "Could not connect", rip);
                    }
                    break;
                case -1:
                    throw new IOException("Encountered EOF in TcpIbis.connect");
                default:
                    throw new IOException("Illegal opcode in TcpIbis.connect");
                }
            } catch (SocketTimeoutException e) {
                throw new ConnectionTimedOutException("Could not connect", rip);
            } finally {
                if (result != ReceivePort.ACCEPTED) {
                    try {
                        if (out != null) {
                            out.close();
                        }
                    } catch (Throwable e) {
                        // ignored
                    }
                    try {
                        s.close();
                    } catch (Throwable e) {
                        // ignored
                    }
                }
            }
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                // ignore
            }
        } while (true);
    }
case ReceivePort.NOT_PRESENT:
case ReceivePort.DISABLED:
// and try again if we did not reach the timeout...
if (timeout > 0
&& System.currentTimeMillis() > startTime + timeout) {
+ message, rip);
case ReceivePort.DENIED:
throw new ConnectionRefusedException(
"Receiver denied connection", rip);
case ReceivePort.NO_MANY_TO_X:
throw new ConnectionRefusedException(
"Receiver already has a connection and neither ManyToOne not ManyToMany "
+ "is set", rip);
case ReceivePort.NOT_PRESENT:
case ReceivePort.DISABLED:
// and try again if we did not reach the timeout...
if (timeout > 0
&& System.currentTimeMillis() > startTime + timeout) {
throw new ConnectionTimedOutException(
"Could not connect", rip);
}
break;
case -1:
throw new IOException("Encountered EOF in TcpIbis.connect");
default:
throw new IOException("Illegal opcode in TcpIbis.connect");
+ "\nUnmatched receiveport capabilities: "
+ s1.toString() + ".";
}
if (s2.size() != 0) {
message = message
+ "\nUnmatched sendport capabilities: "
+ s2.toString() + ".";
}
throw new PortMismatchException(
"Cannot connect ports of different port types."
+ message, rip);
case ReceivePort.DENIED:
throw new ConnectionRefusedException(
"Receiver denied connection", rip);
case ReceivePort.NO_MANY_TO_X:
throw new ConnectionRefusedException(
"Receiver already has a connection and neither ManyToOne not ManyToMany "
+ "is set", rip);
case ReceivePort.NOT_PRESENT:
case ReceivePort.DISABLED:
// and try again if we did not reach the timeout...
if (timeout > 0
&& System.currentTimeMillis() > startTime + timeout) {
throw new ConnectionTimedOutException(
"Could not connect", rip);
}
break;
case -1:
throw new IOException("Encountered EOF in TcpIbis.connect");
default:
throw new IOException("Illegal opcode in TcpIbis.connect");
}
} catch (SocketTimeoutException e) {
throw new ConnectionTimedOutException("Could not connect", rip);
} finally {
if (result != ReceivePort.ACCEPTED) {
try {
if (out != null) {
out.close();
}
} catch (Throwable e) {