/****************************************************************
 * Licensed to the Apache Software Foundation (ASF) under one   *
 * or more contributor license agreements.  See the NOTICE file *
 * distributed with this work for additional information        *
 * regarding copyright ownership.  The ASF licenses this file   *
 * to you under the Apache License, Version 2.0 (the            *
 * "License"); you may not use this file except in compliance   *
 * with the License.  You may obtain a copy of the License at   *
 *                                                              *
 *   http://www.apache.org/licenses/LICENSE-2.0                 *
 *                                                              *
 * Unless required by applicable law or agreed to in writing,   *
 * software distributed under the License is distributed on an  *
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
 * KIND, either express or implied.  See the License for the    *
 * specific language governing permissions and limitations      *
 * under the License.                                           *
 ****************************************************************/
package org.apache.james.util;

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Iterator;

import org.apache.commons.logging.Log;
import org.apache.james.dnsservice.api.DNSService;
import org.apache.mailet.HostAddress;

/**
 * 
 *
 */
public class MXHostAddressIterator implements Iterator<HostAddress>{

    
    private Iterator<HostAddress> addresses = null;
    private Iterator<String> hosts;
    private DNSService dns;
    private boolean useSingleIP;
    private Log logger;

    public MXHostAddressIterator(Iterator<String> hosts, DNSService dns, boolean useSingleIP, Log logger) {
        this.hosts = hosts;
        this.dns = dns;
        this.useSingleIP = useSingleIP;
        this.logger = logger;
    }
    
    /*
     * (non-Javadoc)
     * @see java.util.Iterator#hasNext()
     */
    public boolean hasNext() {
        /* Make sure that when next() is called, that we can
         * provide a HostAddress.  This means that we need to
         * have an inner iterator, and verify that it has
         * addresses.  We could, for example, run into a
         * situation where the next mxHost didn't have any valid
         * addresses.
         */
        if ((addresses == null || !addresses.hasNext()) && hosts.hasNext()) do {
            String nextHostname = (String)hosts.next();
            final String hostname;
            final String port;
            

            int idx = nextHostname.indexOf(':');
            if ( idx > 0) {
                port = nextHostname.substring(idx+1);
                hostname = nextHostname.substring(0,idx);
            } else {
                hostname = nextHostname;
                port = "25";
            }
            
            InetAddress[] addrs = null;
            try {
                if (useSingleIP) {
                    addrs = new InetAddress[] {dns.getByName(hostname)};
                } else {
                    addrs = dns.getAllByName(hostname);
                }
            } catch (UnknownHostException uhe) {
                // this should never happen, since we just got
                // this host from mxHosts, which should have
                // already done this check.
                StringBuffer logBuffer = new StringBuffer(128)
                                         .append("Couldn't resolve IP address for discovered host ")
                                         .append(hostname)
                                         .append(".");
                logger.error(logBuffer.toString());
            }
            final InetAddress[] ipAddresses = addrs;

            addresses = new Iterator<HostAddress>() {
                int i = 0;

                public boolean hasNext() {
                    return ipAddresses != null && i < ipAddresses.length;
                }

                public HostAddress next() {
                    return new org.apache.mailet.HostAddress(hostname, "smtp://" + ipAddresses[i++].getHostAddress() +":" + port);
                }

                public void remove() {
                    throw new UnsupportedOperationException ("remove not supported by this iterator");
                }
            };
        } while (!addresses.hasNext() && hosts.hasNext());

        return addresses != null && addresses.hasNext();
    }

    /*
     * (non-Javadoc)
     * @see java.util.Iterator#next()
     */
    public HostAddress next() {
        return addresses != null ? addresses.next() : null;
    }

    /**
     * Not supported. 
     */
    public void remove() {
        throw new UnsupportedOperationException ("remove not supported by this iterator");
    }

}

@@ -1700,16 +1700,45 @@
  logger;
+%0A    private int defaultPort;
 %0A%0A    pu
@@ -1835,24 +1835,212 @@
 g logger) %7B%0A
+        this(hosts, 25, dns, useSingleIP, logger);%0A    %7D%0A    %0A%0A    public MXHostAddressIterator(Iterator%3CString%3E hosts, int defaultPort, DNSService dns, boolean useSingleIP, Log logger) %7B%0A
         this
@@ -2115,24 +2115,24 @@
 seSingleIP;%0A
-
         this
@@ -2145,24 +2145,64 @@
 r = logger;%0A
+        this.defaultPort = defaultPort;%0A
     %7D%0A    %0A 
@@ -3140,11 +3140,23 @@
 t = 
-%2225
+defaultPort + %22
 %22;%0A 

Allow to specify the default port when creating HostAddress instances