Context:
/*
 * Copyright 2001-2009 The Apache Software Foundation.
 *
 * Licensed 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.juddi.v3.tck;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.List;
import javax.xml.datatype.DatatypeConfigurationException;
import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.XMLGregorianCalendar;
import javax.xml.soap.SOAPFault;
import javax.xml.ws.BindingProvider;
import javax.xml.ws.Holder;
import org.apache.commons.configuration.ConfigurationException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.juddi.v3.client.UDDIConstants;
import org.apache.juddi.v3.client.config.UDDIClient;
import org.apache.juddi.v3.client.transport.Transport;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.Assume;
import org.junit.BeforeClass;
import org.junit.Test;
import org.uddi.api_v3.AddPublisherAssertions;
import org.uddi.api_v3.BusinessDetail;
import org.uddi.api_v3.BusinessEntity;
import org.uddi.api_v3.BusinessService;
import org.uddi.api_v3.CompletionStatus;
import org.uddi.api_v3.DeletePublisherAssertions;
import org.uddi.api_v3.FindBusiness;
import org.uddi.api_v3.FindQualifiers;
import org.uddi.api_v3.FindService;
import org.uddi.api_v3.GetAssertionStatusReport;
import org.uddi.api_v3.KeyedReference;
import org.uddi.api_v3.Name;
import org.uddi.api_v3.PublisherAssertion;
import org.uddi.api_v3.SaveBusiness;
import org.uddi.api_v3.SaveService;
import org.uddi.sub_v3.CoveragePeriod;
import org.uddi.sub_v3.GetSubscriptionResults;
import org.uddi.sub_v3.Subscription;
import org.uddi.sub_v3.SubscriptionFilter;
import org.uddi.sub_v3.SubscriptionResultsList;
import org.uddi.v3_service.UDDIInquiryPortType;
import org.uddi.v3_service.UDDIPublicationPortType;
import org.uddi.v3_service.UDDISecurityPortType;
import org.uddi.v3_service.UDDISubscriptionPortType;

/**
 * @author Jeff Faath
 * @author Kurt T Stam
 * @author Alex O'Ree
 */
public class UDDI_080_SubscriptionIntegrationTest {

        private static Log logger = LogFactory.getLog(UDDI_080_SubscriptionIntegrationTest.class);
        private static TckTModel tckTModelJoe = null;
        private static TckBusiness tckBusinessJoe = null;
        private static TckBusinessService tckBusinessServiceJoe = null;
        private static TckBindingTemplate tckBindingTemplateJoe = null;
        private static TckSubscription tckSubscriptionJoe = null;
        private static TckTModel tckTModelSam = null;
        private static TckBusiness tckBusinessSam = null;
        private static TckBusinessService tckBusinessServiceSam = null;
//        private static TckBindingTemplate tckBindingTemplateSam = null;
        private static TckSubscription tckSubscriptionSam = null;
        private static String authInfoJoe = null;
        private static String authInfoSam = null;
        private static UDDIClient manager;
        static UDDIPublicationPortType publicationJoe = null;
        static UDDIPublicationPortType publicationSam = null;
        static UDDISubscriptionPortType subscriptionJoe = null;

        @AfterClass
        public static void stopManager() throws ConfigurationException {
             Assume.assumeTrue(TckPublisher.isEnabled());
                tckTModelJoe.deleteCreatedTModels(authInfoJoe);
                tckTModelSam.deleteCreatedTModels(authInfoSam);
                manager.stop();
        }

        @BeforeClass
        public static void startManager() throws ConfigurationException {
             Assume.assumeTrue(TckPublisher.isEnabled());
                manager = new UDDIClient();
                manager.start();

                logger.debug("Getting auth tokens..");
                try {
                        Transport transport = manager.getTransport("uddiv3");
                        UDDISecurityPortType security = transport.getUDDISecurityService();
                        authInfoJoe = TckSecurity.getAuthToken(security, TckPublisher.getJoePublisherId(), TckPublisher.getJoePassword());
                        authInfoSam = TckSecurity.getAuthToken(security, TckPublisher.getSamPublisherId(), TckPublisher.getSamPassword());

                        //Assert.assertNotNull(authInfoJoe);
                        UDDISubscriptionPortType subscription = transport.getUDDISubscriptionService();

                        publicationJoe = transport.getUDDIPublishService();
                        UDDIInquiryPortType inquiry = transport.getUDDIInquiryService();

                        if (!TckPublisher.isUDDIAuthMode()) {
                                TckSecurity.setCredentials((BindingProvider) publicationJoe, TckPublisher.getJoePublisherId(), TckPublisher.getJoePassword());
                                TckSecurity.setCredentials((BindingProvider) subscription, TckPublisher.getJoePublisherId(), TckPublisher.getJoePassword());
                                TckSecurity.setCredentials((BindingProvider) inquiry, TckPublisher.getJoePublisherId(), TckPublisher.getJoePassword());
                        }

                        tckTModelJoe = new TckTModel(publicationJoe, inquiry);
                        tckBusinessJoe = new TckBusiness(publicationJoe, inquiry);
                        tckBusinessServiceJoe = new TckBusinessService(publicationJoe, inquiry);
                        tckBindingTemplateJoe = new TckBindingTemplate(publicationJoe, inquiry);
                        subscriptionJoe = subscription;
                        tckSubscriptionJoe = new TckSubscription(subscription, security, inquiry);

                        transport = manager.getTransport("uddiv3");
                        publicationSam = transport.getUDDIPublishService();
                        inquiry = transport.getUDDIInquiryService();
                        subscription = transport.getUDDISubscriptionService();
                        if (!TckPublisher.isUDDIAuthMode()) {
                                TckSecurity.setCredentials((BindingProvider) publicationSam, TckPublisher.getSamPublisherId(), TckPublisher.getSamPassword());
                                TckSecurity.setCredentials((BindingProvider) subscription, TckPublisher.getSamPublisherId(), TckPublisher.getSamPassword());
                                TckSecurity.setCredentials((BindingProvider) inquiry, TckPublisher.getSamPublisherId(), TckPublisher.getSamPassword());
                        }
                        tckTModelSam = new TckTModel(publicationSam, inquiry);
                        tckBusinessSam = new TckBusiness(publicationSam, inquiry);
                        tckBusinessServiceSam = new TckBusinessService(publicationSam, inquiry);
                        //tckBindingTemplateSam = new TckBindingTemplate(publicationSam, inquiry);
                        tckSubscriptionSam = new TckSubscription(subscription, security, inquiry);

                        String authInfoUDDI = TckSecurity.getAuthToken(security, TckPublisher.getUDDIPublisherId(), TckPublisher.getUDDIPassword());
                        transport = manager.getTransport("uddiv3");
                        UDDIPublicationPortType publication = transport.getUDDIPublishService();
                        inquiry = transport.getUDDIInquiryService();

                        if (!TckPublisher.isUDDIAuthMode()) {
                                TckSecurity.setCredentials((BindingProvider) publication, TckPublisher.getUDDIPublisherId(), TckPublisher.getUDDIPassword());

                                TckSecurity.setCredentials((BindingProvider) inquiry, TckPublisher.getUDDIPublisherId(), TckPublisher.getUDDIPassword());
                        }

                        TckTModel tckTModelUDDI = new TckTModel(publication, inquiry);
                        tckTModelUDDI.saveUDDIPublisherTmodel(authInfoUDDI);
                        tckTModelUDDI.saveTModels(authInfoUDDI, TckTModel.TMODELS_XML);
                } catch (Exception e) {
                        logger.error(e.getMessage(), e);
                        Assert.fail("Could not obtain authInfo token.");
                }
        }
        static final String TRANS = "The transaction has been rolled back";
        static final String MISSING_RESOURCE = "Can't find resource for bundle";

        static void HandleException(Exception ex) {
                System.err.println("Error caught of type " + ex.getClass().getCanonicalName());
                ex.printStackTrace();
                if (ex.getMessage() != null) {
                        Assert.assertFalse(ex.getMessage().contains(TRANS));
                        Assert.assertFalse(ex.getMessage().contains(MISSING_RESOURCE));
                }
                if (ex instanceof SOAPFault) {
                        SOAPFault sf = (SOAPFault) ex;
                        if (!sf.getTextContent().contains("org.apache.juddi.v3.error.ValueNotAllowedException")) {
                                Assert.fail();
                        }
                }
        }

        @Test
        public void joePublisher() {
             Assume.assumeTrue(TckPublisher.isEnabled());
                Assume.assumeTrue(TckPublisher.isSubscriptionEnabled());
                try {
                        TckCommon.removeAllExistingSubscriptions(authInfoJoe, subscriptionJoe);
                        tckTModelJoe.saveJoePublisherTmodel(authInfoJoe);
                        tckBusinessJoe.saveJoePublisherBusiness(authInfoJoe);
                        tckBusinessServiceJoe.saveJoePublisherService(authInfoJoe);
                        tckBindingTemplateJoe.saveJoePublisherBinding(authInfoJoe);
                        tckSubscriptionJoe.saveJoePublisherSubscription(authInfoJoe);
                        tckSubscriptionJoe.getJoePublisherSubscriptionResults(authInfoJoe);
                } finally {
                        tckSubscriptionJoe.deleteJoePublisherSubscription(authInfoJoe);
                        tckBindingTemplateJoe.deleteJoePublisherBinding(authInfoJoe);
                        tckBusinessServiceJoe.deleteJoePublisherService(authInfoJoe);
                        tckBusinessJoe.deleteJoePublisherBusiness(authInfoJoe);
                        tckTModelJoe.deleteJoePublisherTmodel(authInfoJoe);
                }
        }

        @Test
        public void samSyndicator() {
             Assume.assumeTrue(TckPublisher.isEnabled());
                Assume.assumeTrue(TckPublisher.isSubscriptionEnabled());
                try {
                        tckTModelSam.saveSamSyndicatorTmodel(authInfoSam);
                        tckBusinessSam.saveSamSyndicatorBusiness(authInfoSam);
                        tckBusinessServiceSam.saveSamSyndicatorService(authInfoSam);
                        tckSubscriptionSam.saveSamSyndicatorSubscription(authInfoSam);
                        tckSubscriptionSam.getSamSyndicatorSubscriptionResults(authInfoSam);
                } finally {
                        tckSubscriptionSam.deleteSamSyndicatorSubscription(authInfoSam);
                        tckBusinessServiceSam.deleteSamSyndicatorService(authInfoSam);
                        tckBusinessSam.deleteSamSyndicatorBusiness(authInfoSam);
                        tckTModelSam.deleteSamSyndicatorTmodel(authInfoSam);
                }

        }

        @Test
        public void samSyndicatorWithChunkingOnFind() {
             Assume.assumeTrue(TckPublisher.isEnabled());

                Assume.assumeTrue(TckPublisher.isSubscriptionEnabled());
                try {
                        tckTModelSam.saveSamSyndicatorTmodel(authInfoSam);
                        tckBusinessSam.saveSamSyndicatorBusiness(authInfoSam);
                        tckBusinessServiceSam.saveSamSyndicatorService(authInfoSam);
                        tckSubscriptionSam.saveSamSyndicatorSubscriptionWithChunkingOnFind(authInfoSam);
                        tckSubscriptionSam.getSamSyndicatorSubscriptionResultsWithChunkingOnFind(authInfoSam);
                } finally {
                        tckSubscriptionSam.deleteSamSyndicatorSubscriptionWithChunkingOnFind(authInfoSam);
                        tckBusinessServiceSam.deleteSamSyndicatorService(authInfoSam);
                        tckBusinessSam.deleteSamSyndicatorBusiness(authInfoSam);
                        tckTModelSam.deleteSamSyndicatorTmodel(authInfoSam);
                }

        }

        @Test
        public void samSyndicatorWithChunkingOnGet() {
             Assume.assumeTrue(TckPublisher.isEnabled());
                Assume.assumeTrue(TckPublisher.isSubscriptionEnabled());
                try {
                        tckTModelSam.saveSamSyndicatorTmodel(authInfoSam);
                        tckBusinessSam.saveSamSyndicatorBusiness(authInfoSam);
                        tckBusinessServiceSam.saveSamSyndicatorService(authInfoSam);
                        tckSubscriptionSam.saveSamSyndicatorSubscriptionWithChunkingOnGet(authInfoSam);
                        tckSubscriptionSam.getSamSyndicatorSubscriptionResultsWithChunkingOnGet(authInfoSam);
                } finally {
                        tckSubscriptionSam.deleteSamSyndicatorSubscriptionWithChunkingOnGet(authInfoSam);
                        tckBusinessServiceSam.deleteSamSyndicatorService(authInfoSam);
                        tckBusinessSam.deleteSamSyndicatorBusiness(authInfoSam);
                        tckTModelSam.deleteSamSyndicatorTmodel(authInfoSam);
                }

        }

        /**
         * Null expiration time, the server should set the expiration time
         */
        @Test
        public void JUDDI_606_1() {
             Assume.assumeTrue(TckPublisher.isEnabled());
                System.out.println("JUDDI_606_1");
                Assume.assumeTrue(TckPublisher.isSubscriptionEnabled());
                // Null expiration time

                Subscription sub = new Subscription();
                Holder<List<Subscription>> data = new Holder<List<Subscription>>();
                data.value = new ArrayList<Subscription>();
                sub.setBrief(true);
                sub.setExpiresAfter(null);
                sub.setMaxEntities(1);
                sub.setNotificationInterval(null);
                sub.setBindingKey(null);
                sub.setSubscriptionFilter(new SubscriptionFilter());
                sub.getSubscriptionFilter().setFindService(new FindService());
                sub.getSubscriptionFilter().getFindService().setFindQualifiers(new FindQualifiers());
                sub.getSubscriptionFilter().getFindService().getFindQualifiers().getFindQualifier().add(UDDIConstants.APPROXIMATE_MATCH);
                sub.getSubscriptionFilter().getFindService().getName().add(new Name("%", null));
                data.value.add(sub);
                try {
                        tckSubscriptionJoe.subscription.saveSubscription(authInfoJoe, data);
                        Assert.assertNotNull(data.value.get(0).getExpiresAfter());
                } catch (Exception ex) {
                        HandleException(ex);
                        Assert.fail();
                }
        }

        /**
         * invalid expiration time
         *
         * @throws DatatypeConfigurationException
         */
        @Test
        public void JUDDI_606_2() throws DatatypeConfigurationException {
             Assume.assumeTrue(TckPublisher.isEnabled());
                System.out.println("JUDDI_606_2");
                Assume.assumeTrue(TckPublisher.isSubscriptionEnabled());
                // invalid expiration time
                DatatypeFactory df = DatatypeFactory.newInstance();
                GregorianCalendar gcal = new GregorianCalendar();
                gcal.setTimeInMillis(System.currentTimeMillis());
                gcal.add(Calendar.DATE, -1);
                XMLGregorianCalendar newXMLGregorianCalendar = df.newXMLGregorianCalendar(gcal);

                Subscription sub = new Subscription();
                Holder<List<Subscription>> data = new Holder<List<Subscription>>();
                data.value = new ArrayList<Subscription>();
                sub.setBrief(true);
                sub.setExpiresAfter(newXMLGregorianCalendar);
                sub.setMaxEntities(1);
                sub.setNotificationInterval(null);
                sub.setBindingKey(null);
                sub.setSubscriptionFilter(new SubscriptionFilter());
                sub.getSubscriptionFilter().setFindService(new FindService());
                sub.getSubscriptionFilter().getFindService().setFindQualifiers(new FindQualifiers());
                sub.getSubscriptionFilter().getFindService().getFindQualifiers().getFindQualifier().add(UDDIConstants.APPROXIMATE_MATCH);
                sub.getSubscriptionFilter().getFindService().getName().add(new Name("%", null));
                data.value.add(sub);
                try {
                        tckSubscriptionJoe.subscription.saveSubscription(authInfoJoe, data);
                        Assert.fail();
                } catch (Exception ex) {
                        //HandleException(ex);
                        logger.info("Expected exception: " + ex.getMessage());
                }
        }

        /**
         * confirm a subscription key is returned when not specified
         */
        @Test
        public void JUDDI_606_3() {
             Assume.assumeTrue(TckPublisher.isEnabled());
                System.out.println("JUDDI_606_3");
                Assume.assumeTrue(TckPublisher.isSubscriptionEnabled());
                //

                Subscription sub = new Subscription();
                Holder<List<Subscription>> data = new Holder<List<Subscription>>();
                data.value = new ArrayList<Subscription>();
                sub.setBrief(true);
                sub.setExpiresAfter(null);
                sub.setMaxEntities(1);
                sub.setNotificationInterval(null);
                sub.setBindingKey(null);
                sub.setSubscriptionFilter(new SubscriptionFilter());
                sub.getSubscriptionFilter().setFindService(new FindService());
                sub.getSubscriptionFilter().getFindService().setFindQualifiers(new FindQualifiers());
                sub.getSubscriptionFilter().getFindService().getFindQualifiers().getFindQualifier().add(UDDIConstants.APPROXIMATE_MATCH);
                sub.getSubscriptionFilter().getFindService().getName().add(new Name("%", null));
                data.value.add(sub);
                try {
                        tckSubscriptionJoe.subscription.saveSubscription(authInfoJoe, data);
                        Assert.assertNotNull(data.value.get(0).getSubscriptionKey());
                        Assert.assertTrue(data.value.get(0).getSubscriptionKey().length() > 0);
                } catch (Exception ex) {
                        HandleException(ex);
                        Assert.fail();
                }
        }

        /**
         * null subscription filter
         */
        @Test
        public void JUDDI_606_4() {
             Assume.assumeTrue(TckPublisher.isEnabled());
                System.out.println("JUDDI_606_4");
                //
                Assume.assumeTrue(TckPublisher.isSubscriptionEnabled());

                Subscription sub = new Subscription();
                Holder<List<Subscription>> data = new Holder<List<Subscription>>();
                data.value = new ArrayList<Subscription>();
                sub.setBrief(true);
                sub.setExpiresAfter(null);
                sub.setMaxEntities(1);
                sub.setNotificationInterval(null);
                sub.setBindingKey(null);
                sub.setSubscriptionFilter(null);

                try {
                        tckSubscriptionJoe.subscription.saveSubscription(authInfoJoe, data);
                        Assert.fail();
                } catch (Exception ex) {
                        //HandleException(ex);
                        logger.info("Expected exception: " + ex.getMessage());
                }
        }

        /**
         * empty subscription filter
         */
        @Test
        public void JUDDI_606_5() {
             Assume.assumeTrue(TckPublisher.isEnabled());
                System.out.println("JUDDI_606_5");
                //
                Assume.assumeTrue(TckPublisher.isSubscriptionEnabled());

                Subscription sub = new Subscription();
                Holder<List<Subscription>> data = new Holder<List<Subscription>>();
                data.value = new ArrayList<Subscription>();
                sub.setBrief(true);
                sub.setExpiresAfter(null);
                sub.setMaxEntities(1);
                sub.setNotificationInterval(null);
                sub.setBindingKey(null);
                sub.setSubscriptionFilter(new SubscriptionFilter());

                data.value.add(sub);
                try {
                        tckSubscriptionJoe.subscription.saveSubscription(authInfoJoe, data);
                        Assert.fail();
                } catch (Exception ex) {
                        //HandleException(ex);
                        logger.info("Expected exception: " + ex.getMessage());
                }
        }

        /**
         * negative max entities
         */
        @Test
        public void JUDDI_606_6() {
             Assume.assumeTrue(TckPublisher.isEnabled());
                System.out.println("JUDDI_606_6");
                //
                Assume.assumeTrue(TckPublisher.isSubscriptionEnabled());

                Subscription sub = new Subscription();
                Holder<List<Subscription>> data = new Holder<List<Subscription>>();
                data.value = new ArrayList<Subscription>();
                sub.setBrief(true);
                sub.setExpiresAfter(null);
                sub.setMaxEntities(-1);
                sub.setNotificationInterval(null);
                sub.setBindingKey(null);
                sub.setSubscriptionFilter(new SubscriptionFilter());
                sub.getSubscriptionFilter().setFindService(new FindService());
                sub.getSubscriptionFilter().getFindService().setFindQualifiers(new FindQualifiers());
                sub.getSubscriptionFilter().getFindService().getFindQualifiers().getFindQualifier().add(UDDIConstants.APPROXIMATE_MATCH);
                sub.getSubscriptionFilter().getFindService().getName().add(new Name("%", null));
                data.value.add(sub);
                try {
                        tckSubscriptionJoe.subscription.saveSubscription(authInfoJoe, data);
                        Assert.assertTrue(data.value.get(0).getMaxEntities() > 0);
                } catch (Exception ex) {
                        //HandleException(ex);
                        //this is ok as well
                        logger.info("Expected exception: " + ex.getMessage());
                }
        }

        /**
         * more filters that expected
         *
         * @throws DatatypeConfigurationException
         */
        @Test
        public void JUDDI_606_7() throws DatatypeConfigurationException {
             Assume.assumeTrue(TckPublisher.isEnabled());
                System.out.println("JUDDI_606_7");
                Assume.assumeTrue(TckPublisher.isSubscriptionEnabled());
                //
                DatatypeFactory df = DatatypeFactory.newInstance();
                try {

                        Holder<List<Subscription>> data = new Holder<List<Subscription>>();
                        data.value = new ArrayList<Subscription>();
                        Subscription sub = new Subscription();
                        sub.setBrief(false);
                        sub.setExpiresAfter(null);
                        sub.setMaxEntities(null);
                        sub.setNotificationInterval(null);
                        sub.setBindingKey(null);
                        sub.setSubscriptionFilter(new SubscriptionFilter());
                        sub.getSubscriptionFilter().setFindBusiness(new FindBusiness());
                        sub.getSubscriptionFilter().getFindBusiness().setFindQualifiers(new FindQualifiers());
                        sub.getSubscriptionFilter().getFindBusiness().getFindQualifiers().getFindQualifier().add(UDDIConstants.APPROXIMATE_MATCH);
                        sub.getSubscriptionFilter().getFindBusiness().getName().add(new Name("%", null));
                        sub.getSubscriptionFilter().setFindService(new FindService());
                        sub.getSubscriptionFilter().getFindService().setFindQualifiers(new FindQualifiers());
                        sub.getSubscriptionFilter().getFindService().getFindQualifiers().getFindQualifier().add(UDDIConstants.APPROXIMATE_MATCH);
                        sub.getSubscriptionFilter().getFindService().getName().add(new Name("%", null));

                        data.value.add(sub);

                        tckSubscriptionJoe.subscription.saveSubscription(authInfoJoe, data);
                        Assert.fail();
                } catch (Exception ex) {
                        logger.info(ex.getMessage());

                }
        }

        /**
         * testing reset expiration. i.e. save, wait a second then resave it,
         * the expiration time should be further into the future
         */
        @Test
        public void JUDDI_606_8() {
             Assume.assumeTrue(TckPublisher.isEnabled());
                System.out.println("JUDDI_606_8");
                Assume.assumeTrue(TckPublisher.isSubscriptionEnabled());
                //

                try {

                        Holder<List<Subscription>> data = new Holder<List<Subscription>>();
                        data.value = new ArrayList<Subscription>();
                        Subscription sub = new Subscription();
                        sub.setBrief(true);
                        sub.setExpiresAfter(null);
                        sub.setMaxEntities(null);
                        sub.setNotificationInterval(null);
                        sub.setBindingKey(null);
                        sub.setSubscriptionFilter(new SubscriptionFilter());
                        sub.getSubscriptionFilter().setFindService(new FindService());
                        sub.getSubscriptionFilter().getFindService().setFindQualifiers(new FindQualifiers());
                        sub.getSubscriptionFilter().getFindService().getFindQualifiers().getFindQualifier().add(UDDIConstants.APPROXIMATE_MATCH);
                        sub.getSubscriptionFilter().getFindService().getName().add(new Name("%", null));
                        data.value.add(sub);

                        tckSubscriptionJoe.subscription.saveSubscription(authInfoJoe, data);
                        Assert.assertNotNull(data.value.get(0).getExpiresAfter());
                        XMLGregorianCalendar xcal = data.value.get(0).getExpiresAfter();

                        Thread.sleep(5000);
                        data.value.get(0).setExpiresAfter(null);
                        tckSubscriptionJoe.subscription.saveSubscription(authInfoJoe, data);
                        Assert.assertNotNull(data.value.get(0).getExpiresAfter());
                        Assert.assertNotSame(xcal, data.value.get(0).getExpiresAfter());
                        long initial = xcal.toGregorianCalendar().getTimeInMillis();
                        long finaltime = data.value.get(0).getExpiresAfter().toGregorianCalendar().getTimeInMillis();
                        Assert.assertTrue(finaltime > initial);

                } catch (Exception ex) {
                        HandleException(ex);
                        Assert.fail();
                }
        }

        /**
         * asynch subscriptions , binding key doesn't exist
         *
         * @throws DatatypeConfigurationException
         */
        @Test
        public void JUDDI_606_9() throws DatatypeConfigurationException {
             Assume.assumeTrue(TckPublisher.isEnabled());
                System.out.println("JUDDI_606_9");
                Assume.assumeTrue(TckPublisher.isSubscriptionEnabled());
                //

                DatatypeFactory df = DatatypeFactory.newInstance();

                try {

                        Holder<List<Subscription>> data = new Holder<List<Subscription>>();
                        data.value = new ArrayList<Subscription>();
                        Subscription sub = new Subscription();
                        sub.setBrief(true);
                        sub.setExpiresAfter(null);
                        sub.setMaxEntities(null);
                        sub.setNotificationInterval(df.newDuration(5000));
                        sub.setBindingKey("uddi:uddi.joepublisher.com:mykey");
                        sub.setSubscriptionFilter(new SubscriptionFilter());
                        sub.getSubscriptionFilter().setFindService(new FindService());
                        sub.getSubscriptionFilter().getFindService().setFindQualifiers(new FindQualifiers());
                        sub.getSubscriptionFilter().getFindService().getFindQualifiers().getFindQualifier().add(UDDIConstants.APPROXIMATE_MATCH);
                        sub.getSubscriptionFilter().getFindService().getName().add(new Name("%", null));
                        data.value.add(sub);

                        tckSubscriptionJoe.subscription.saveSubscription(authInfoJoe, data);
                        Assert.fail();
                } catch (Exception ex) {
                        logger.info("Expected exception: " + ex.getMessage());
                }
        }

        /**
         * asynch subscriptions, key exists , null interval
         *
         * @throws DatatypeConfigurationException
         */
        @Test
        public void JUDDI_606_10() throws DatatypeConfigurationException {
             Assume.assumeTrue(TckPublisher.isEnabled());
                System.out.println("JUDDI_606_10");
                Assume.assumeTrue(TckPublisher.isSubscriptionEnabled());
                //
                try {

                        tckTModelJoe.saveJoePublisherTmodel(authInfoJoe);
                        tckBusinessJoe.saveJoePublisherBusiness(authInfoJoe);
                        tckBusinessServiceJoe.saveJoePublisherService(authInfoJoe);
                        tckBindingTemplateJoe.saveJoePublisherBinding(authInfoJoe);

                        Holder<List<Subscription>> data = new Holder<List<Subscription>>();
                        data.value = new ArrayList<Subscription>();
                        Subscription sub = new Subscription();
                        sub.setBrief(true);
                        sub.setExpiresAfter(null);
                        sub.setMaxEntities(null);
                        sub.setNotificationInterval(null);
                        sub.setBindingKey(TckBindingTemplate.JOE_BINDING_KEY);
                        sub.setSubscriptionFilter(new SubscriptionFilter());
                        sub.getSubscriptionFilter().setFindService(new FindService());
                        sub.getSubscriptionFilter().getFindService().setFindQualifiers(new FindQualifiers());
                        sub.getSubscriptionFilter().getFindService().getFindQualifiers().getFindQualifier().add(UDDIConstants.APPROXIMATE_MATCH);
                        sub.getSubscriptionFilter().getFindService().getName().add(new Name("%", null));
                        data.value.add(sub);

                        tckSubscriptionJoe.subscription.saveSubscription(authInfoJoe, data);
                        Assert.fail();
                } catch (Exception ex) {
                        //HandleException(ex);
                        logger.info("Expected exception: " + ex.getMessage());
                } finally {
                        tckBindingTemplateJoe.deleteJoePublisherBinding(authInfoJoe);
                        tckBusinessServiceJoe.deleteJoePublisherService(authInfoJoe);
                        tckBusinessJoe.deleteJoePublisherBusiness(authInfoJoe);
                        tckTModelJoe.deleteJoePublisherTmodel(authInfoJoe);
                }
        }

        /**
         * set subscription, make a change as the same user, get subscription
         * results no key specified
         *
         * @throws DatatypeConfigurationException
         */
        @Test
        public void JUDDI_606_11() throws DatatypeConfigurationException {
             Assume.assumeTrue(TckPublisher.isEnabled());
                System.out.println("JUDDI_606_11");
                Assume.assumeTrue(TckPublisher.isSubscriptionEnabled());

                String key = null;
                DatatypeFactory df = DatatypeFactory.newInstance();
                try {

                        Holder<List<Subscription>> data = new Holder<List<Subscription>>();
                        data.value = new ArrayList<Subscription>();
                        Subscription sub = new Subscription();
                        sub.setBrief(false);
                        sub.setExpiresAfter(null);
                        sub.setMaxEntities(null);
                        sub.setNotificationInterval(null);
                        sub.setBindingKey(null);
                        sub.setSubscriptionFilter(new SubscriptionFilter());
                        sub.getSubscriptionFilter().setFindBusiness(new FindBusiness());
                        sub.getSubscriptionFilter().getFindBusiness().setFindQualifiers(new FindQualifiers());
                        sub.getSubscriptionFilter().getFindBusiness().getFindQualifiers().getFindQualifier().add(UDDIConstants.APPROXIMATE_MATCH);
                        sub.getSubscriptionFilter().getFindBusiness().getName().add(new Name("%", null));
                        data.value.add(sub);

                        tckSubscriptionJoe.subscription.saveSubscription(authInfoJoe, data);
                        SaveBusiness sb = new SaveBusiness();
                        sb.setAuthInfo(authInfoJoe);
                        BusinessEntity be = new BusinessEntity();
                        be.getName().add(new Name("Test business", null));
                        sb.getBusinessEntity().add(be);
                        BusinessDetail saveBusiness = publicationJoe.saveBusiness(sb);

                        key = saveBusiness.getBusinessEntity().get(0).getBusinessKey();

                        GetSubscriptionResults gsr = new GetSubscriptionResults();
                        gsr.setAuthInfo(authInfoJoe);
                        gsr.setSubscriptionKey(null);
                        gsr.setCoveragePeriod(new CoveragePeriod());
                        GregorianCalendar gcal = new GregorianCalendar();
                        gcal.setTimeInMillis(System.currentTimeMillis());
                        gcal.add(Calendar.HOUR, -1);
                        gsr.getCoveragePeriod().setStartPoint(df.newXMLGregorianCalendar(gcal));
                        gcal = new GregorianCalendar();
                        gcal.setTimeInMillis(System.currentTimeMillis());
                        gsr.getCoveragePeriod().setEndPoint(df.newXMLGregorianCalendar(gcal));
                        tckSubscriptionJoe.subscription.getSubscriptionResults(gsr);
                        Assert.fail();
                } catch (Exception ex) {
                        //HandleException(ex);
                        //Assert.fail();
                        logger.info("Expected exception: " + ex.getMessage());
                } finally {
                        TckCommon.DeleteBusiness(key, authInfoJoe, publicationJoe);
                }
        }

        /**
         *
         * @throws DatatypeConfigurationException set subscription, make a
         * change as the same user, get subscription results no period specified
         */
        @Test
        public void JUDDI_606_12() throws DatatypeConfigurationException {
             Assume.assumeTrue(TckPublisher.isEnabled());
                System.out.println("JUDDI_606_12");
                Assume.assumeTrue(TckPublisher.isSubscriptionEnabled());
                //
                String key = null;
                try {

                        tckTModelJoe.saveJoePublisherTmodel(authInfoJoe);
                        tckBusinessJoe.saveJoePublisherBusiness(authInfoJoe);
                        tckBusinessServiceJoe.saveJoePublisherService(authInfoJoe);
                        tckBindingTemplateJoe.saveJoePublisherBinding(authInfoJoe);

                        Holder<List<Subscription>> data = new Holder<List<Subscription>>();
                        data.value = new ArrayList<Subscription>();
                        Subscription sub = new Subscription();
                        sub.setBrief(false);
                        sub.setExpiresAfter(null);
                        sub.setMaxEntities(null);
                        sub.setNotificationInterval(null);
                        sub.setBindingKey(null);
                        sub.setSubscriptionFilter(new SubscriptionFilter());
                        sub.getSubscriptionFilter().setFindBusiness(new FindBusiness());
                        sub.getSubscriptionFilter().getFindBusiness().setFindQualifiers(new FindQualifiers());
                        sub.getSubscriptionFilter().getFindBusiness().getFindQualifiers().getFindQualifier().add(UDDIConstants.APPROXIMATE_MATCH);
                        sub.getSubscriptionFilter().getFindBusiness().getName().add(new Name("%", null));
                        data.value.add(sub);

                        tckSubscriptionJoe.subscription.saveSubscription(authInfoJoe, data);
                        SaveBusiness sb = new SaveBusiness();
                        sb.setAuthInfo(authInfoJoe);
                        BusinessEntity be = new BusinessEntity();
                        be.getName().add(new Name("Test business", null));
                        sb.getBusinessEntity().add(be);
                        BusinessDetail saveBusiness = publicationJoe.saveBusiness(sb);

                        key = saveBusiness.getBusinessEntity().get(0).getBusinessKey();
                        GetSubscriptionResults gsr = new GetSubscriptionResults();
                        gsr.setAuthInfo(authInfoJoe);
                        gsr.setSubscriptionKey(data.value.get(0).getSubscriptionKey());
                        gsr.setCoveragePeriod(null);
                        tckSubscriptionJoe.subscription.getSubscriptionResults(gsr);
                        Assert.fail();
                } catch (Exception ex) {
                        //HandleException(ex);
                        //Assert.fail();
                        logger.info("Expected exception: " + ex.getMessage());
                } finally {
                        TckCommon.DeleteBusiness(key, authInfoJoe, publicationJoe);
                        tckBindingTemplateJoe.deleteJoePublisherBinding(authInfoJoe);
                        tckBusinessServiceJoe.deleteJoePublisherService(authInfoJoe);
                        tckBusinessJoe.deleteJoePublisherBusiness(authInfoJoe);
                        tckTModelJoe.deleteJoePublisherTmodel(authInfoJoe);

                }
        }

        /**
         * set subscription, make a change as the same user, get subscription
         * results valid find_Business
         *
         * @throws DatatypeConfigurationException
         */
        @Test
        public void JUDDI_606_13() throws DatatypeConfigurationException {
             Assume.assumeTrue(TckPublisher.isEnabled());
                System.out.println("JUDDI_606_13");
                Assume.assumeTrue(TckPublisher.isSubscriptionEnabled());

                String key = null;
                DatatypeFactory df = DatatypeFactory.newInstance();
                try {

                        Holder<List<Subscription>> data = new Holder<List<Subscription>>();
                        data.value = new ArrayList<Subscription>();
                        Subscription sub = new Subscription();
                        sub.setBrief(false);
                        sub.setExpiresAfter(null);
                        sub.setMaxEntities(null);
                        sub.setNotificationInterval(null);
                        sub.setBindingKey(null);
                        sub.setSubscriptionFilter(new SubscriptionFilter());
                        sub.getSubscriptionFilter().setFindBusiness(new FindBusiness());
                        sub.getSubscriptionFilter().getFindBusiness().setFindQualifiers(new FindQualifiers());
                        sub.getSubscriptionFilter().getFindBusiness().getFindQualifiers().getFindQualifier().add(UDDIConstants.APPROXIMATE_MATCH);
                        sub.getSubscriptionFilter().getFindBusiness().getName().add(new Name("%", null));
                        data.value.add(sub);

                        tckSubscriptionJoe.subscription.saveSubscription(authInfoJoe, data);
                        SaveBusiness sb = new SaveBusiness();
                        sb.setAuthInfo(authInfoJoe);
                        BusinessEntity be = new BusinessEntity();
                        be.getName().add(new Name("Test business", null));
                        sb.getBusinessEntity().add(be);
                        BusinessDetail saveBusiness = publicationJoe.saveBusiness(sb);
                        key = saveBusiness.getBusinessEntity().get(0).getBusinessKey();

                        GetSubscriptionResults gsr = new GetSubscriptionResults();
                        gsr.setAuthInfo(authInfoJoe);
                        gsr.setSubscriptionKey(data.value.get(0).getSubscriptionKey());
                        gsr.setCoveragePeriod(new CoveragePeriod());
                        GregorianCalendar gcal = new GregorianCalendar();
                        gcal.setTimeInMillis(System.currentTimeMillis());
                        gcal.add(Calendar.HOUR, -1);
                        gsr.getCoveragePeriod().setStartPoint(df.newXMLGregorianCalendar(gcal));
                        gcal = new GregorianCalendar();
                        gcal.setTimeInMillis(System.currentTimeMillis());
                        gsr.getCoveragePeriod().setEndPoint(df.newXMLGregorianCalendar(gcal));
                        SubscriptionResultsList subscriptionResults = tckSubscriptionJoe.subscription.getSubscriptionResults(gsr);
                        Assert.assertNotNull(subscriptionResults);
                        Assert.assertNotNull(subscriptionResults.getBusinessList());
                        Assert.assertNotNull(subscriptionResults.getCoveragePeriod());
                        Assert.assertNotNull(subscriptionResults.getBusinessList().getBusinessInfos());
                        Assert.assertNotNull(subscriptionResults.getBusinessList().getBusinessInfos().getBusinessInfo().get(0));
                        Assert.assertNotNull(subscriptionResults.getBusinessList().getBusinessInfos().getBusinessInfo().get(0).getBusinessKey());
                        Assert.assertNotNull(subscriptionResults.getBusinessList().getBusinessInfos().getBusinessInfo().get(0).getName().get(0));

                } catch (Exception ex) {
                        HandleException(ex);
                        Assert.fail();
                } finally {
                        TckCommon.DeleteBusiness(key, authInfoJoe, publicationJoe);
                }
        }

        /**
         * set subscription, make a change as the same user, get subscription
         * results valid find_services
         *
         * @throws DatatypeConfigurationException
         */
        @Test
        public void JUDDI_606_14() throws DatatypeConfigurationException {
             Assume.assumeTrue(TckPublisher.isEnabled());
                System.out.println("JUDDI_606_14");
                Assume.assumeTrue(TckPublisher.isSubscriptionEnabled());

                DatatypeFactory df = DatatypeFactory.newInstance();
                try {

                        Holder<List<Subscription>> data = new Holder<List<Subscription>>();
                        data.value = new ArrayList<Subscription>();
                        Subscription sub = new Subscription();
                        sub.setBrief(false);
                        sub.setExpiresAfter(null);
                        sub.setMaxEntities(null);
                        sub.setNotificationInterval(null);
                        sub.setBindingKey(null);
                        sub.setSubscriptionFilter(new SubscriptionFilter());
                        sub.getSubscriptionFilter().setFindService(new FindService());
                        sub.getSubscriptionFilter().getFindService().setFindQualifiers(new FindQualifiers());
                        sub.getSubscriptionFilter().getFindService().getFindQualifiers().getFindQualifier().add(UDDIConstants.APPROXIMATE_MATCH);
                        sub.getSubscriptionFilter().getFindService().getName().add(new Name("%", null));
                        data.value.add(sub);

                        tckSubscriptionJoe.subscription.saveSubscription(authInfoJoe, data);
                        tckTModelJoe.saveJoePublisherTmodel(authInfoJoe);
                        tckBusinessJoe.saveJoePublisherBusiness(authInfoJoe);
                        tckBusinessServiceJoe.saveJoePublisherService(authInfoJoe);
                        /*SaveService sb = new SaveService();
                         sb.setAuthInfo(authInfoJoe);
                         BusinessService bs = new BusinessService();
                         bs.getName().add(new Name("svc", null));
                         sb.getBusinessService().add(bs);
                         publicationJoe.saveService(sb);*/

                        GetSubscriptionResults gsr = new GetSubscriptionResults();
                        gsr.setAuthInfo(authInfoJoe);
                        gsr.setSubscriptionKey(data.value.get(0).getSubscriptionKey());
                        gsr.setCoveragePeriod(new CoveragePeriod());
                        GregorianCalendar gcal = new GregorianCalendar();
                        gcal.setTimeInMillis(System.currentTimeMillis());
                        gcal.add(Calendar.HOUR, -1);
                        gsr.getCoveragePeriod().setStartPoint(df.newXMLGregorianCalendar(gcal));
                        gcal = new GregorianCalendar();
                        gcal.setTimeInMillis(System.currentTimeMillis());
                        gsr.getCoveragePeriod().setEndPoint(df.newXMLGregorianCalendar(gcal));
                        SubscriptionResultsList subscriptionResults = tckSubscriptionJoe.subscription.getSubscriptionResults(gsr);
                        Assert.assertNotNull(subscriptionResults);
                        Assert.assertNull(subscriptionResults.getBusinessList());
                        Assert.assertNotNull(subscriptionResults.getCoveragePeriod());
                        Assert.assertNotNull(subscriptionResults.getServiceList());
                        Assert.assertNotNull(subscriptionResults.getServiceList().getServiceInfos().getServiceInfo().get(0));
                        Assert.assertNotNull(subscriptionResults.getServiceList().getServiceInfos().getServiceInfo().get(0).getBusinessKey());
                        Assert.assertNotNull(subscriptionResults.getServiceList().getServiceInfos().getServiceInfo().get(0).getName().get(0));

                } catch (Exception ex) {
                        HandleException(ex);
                        Assert.fail(ex.getMessage());
                } finally {
                        tckBusinessJoe.deleteJoePublisherBusiness(authInfoJoe);
                        tckTModelJoe.deleteJoePublisherTmodel(authInfoJoe);
                }
        }

        /**
         *    //set subscription, make a change as the same user, get subscription
         * results. valid. publisher assertion, incomplete
         *
         * @throws DatatypeConfigurationException
         */
        @Test
        public void JUDDI_606_15() throws DatatypeConfigurationException {
             Assume.assumeTrue(TckPublisher.isEnabled());
                System.out.println("JUDDI_606_15");
                Assume.assumeTrue(TckPublisher.isSubscriptionEnabled());

                DatatypeFactory df = DatatypeFactory.newInstance();
                try {

                        tckTModelJoe.saveJoePublisherTmodel(authInfoJoe);
                        tckBusinessJoe.saveJoePublisherBusiness(authInfoJoe);
                        tckTModelSam.saveSamSyndicatorTmodel(authInfoSam);
                        tckBusinessSam.saveSamSyndicatorBusiness(authInfoSam);

                        Holder<List<Subscription>> data = new Holder<List<Subscription>>();
                        data.value = new ArrayList<Subscription>();
                        Subscription sub = new Subscription();
                        sub.setBrief(false);
                        sub.setExpiresAfter(null);
                        sub.setMaxEntities(null);
                        sub.setNotificationInterval(null);
                        sub.setBindingKey(null);
                        sub.setSubscriptionFilter(new SubscriptionFilter());
                        sub.getSubscriptionFilter().setGetAssertionStatusReport(new GetAssertionStatusReport());
                        sub.getSubscriptionFilter().getGetAssertionStatusReport().setCompletionStatus(CompletionStatus.STATUS_TO_KEY_INCOMPLETE);
                        data.value.add(sub);

                        tckSubscriptionJoe.subscription.saveSubscription(authInfoJoe, data);

                        AddPublisherAssertions r = new AddPublisherAssertions();
                        r.setAuthInfo(authInfoJoe);
                        PublisherAssertion pa = new PublisherAssertion();
                        pa.setFromKey(TckBusiness.JOE_BUSINESS_KEY);
                        pa.setToKey(TckBusiness.SAM_BUSINESS_KEY);
                        pa.setKeyedReference(new KeyedReference());
                        pa.getKeyedReference().setKeyName("Subsidiary");
                        pa.getKeyedReference().setKeyValue("parent-child");

                        pa.getKeyedReference().setTModelKey("uddi:uddi.org:relationships");

                        r.getPublisherAssertion().add(pa);
                        publicationJoe.addPublisherAssertions(r);

                        GetSubscriptionResults gsr = new GetSubscriptionResults();
                        gsr.setAuthInfo(authInfoJoe);
                        gsr.setSubscriptionKey(data.value.get(0).getSubscriptionKey());
                        gsr.setCoveragePeriod(new CoveragePeriod());
                        GregorianCalendar gcal = new GregorianCalendar();
                        gcal.setTimeInMillis(System.currentTimeMillis());
                        gcal.add(Calendar.HOUR, -1);
                        gsr.getCoveragePeriod().setStartPoint(df.newXMLGregorianCalendar(gcal));
                        gcal = new GregorianCalendar();
                        gcal.setTimeInMillis(System.currentTimeMillis());
                        gsr.getCoveragePeriod().setEndPoint(df.newXMLGregorianCalendar(gcal));
                        SubscriptionResultsList subscriptionResults = tckSubscriptionJoe.subscription.getSubscriptionResults(gsr);
                        Assert.assertNotNull(subscriptionResults);
                        Assert.assertNull(subscriptionResults.getBusinessList());
                        Assert.assertNotNull(subscriptionResults.getCoveragePeriod());
                        Assert.assertNull(subscriptionResults.getServiceList());
                        Assert.assertNotNull(subscriptionResults.getAssertionStatusReport());
                        Assert.assertNotNull(subscriptionResults.getAssertionStatusReport().getAssertionStatusItem());
                        Assert.assertFalse(subscriptionResults.getAssertionStatusReport().getAssertionStatusItem().isEmpty());
                        Assert.assertEquals(subscriptionResults.getAssertionStatusReport().getAssertionStatusItem().get(0).getFromKey(), TckBusiness.JOE_BUSINESS_KEY);
                        Assert.assertEquals(subscriptionResults.getAssertionStatusReport().getAssertionStatusItem().get(0).getToKey(), TckBusiness.SAM_BUSINESS_KEY);
                        Assert.assertNotNull(subscriptionResults.getAssertionStatusReport().getAssertionStatusItem().get(0).getCompletionStatus());
                        Assert.assertEquals(subscriptionResults.getAssertionStatusReport().getAssertionStatusItem().get(0).getCompletionStatus(), CompletionStatus.STATUS_TO_KEY_INCOMPLETE);
                        Assert.assertNotNull(subscriptionResults.getAssertionStatusReport().getAssertionStatusItem().get(0).getKeyedReference());
                } catch (Exception ex) {
                        HandleException(ex);
                        Assert.fail(ex.getMessage());
                }
                finally{

                        tckBusinessJoe.saveJoePublisherBusiness(authInfoJoe);
                        tckTModelJoe.saveJoePublisherTmodel(authInfoJoe);

                        tckBusinessSam.deleteSamSyndicatorBusiness(authInfoSam);
                        tckTModelSam.deleteSamSyndicatorTmodel(authInfoSam);

                }
        }

        /**
         * set subscription, make a change as the same user, get subscription
         * results valid publisher assertion, complete
         *
         * @throws DatatypeConfigurationException
         */
        @Test
        public void JUDDI_606_16() throws DatatypeConfigurationException {
             Assume.assumeTrue(TckPublisher.isEnabled());
                System.out.println("JUDDI_606_16");
                Assume.assumeTrue(TckPublisher.isSubscriptionEnabled());

                DatatypeFactory df = DatatypeFactory.newInstance();
                try {
                        tckTModelJoe.saveJoePublisherTmodel(authInfoJoe);
                        tckBusinessJoe.saveJoePublisherBusiness(authInfoJoe);
                        tckTModelSam.saveSamSyndicatorTmodel(authInfoSam);
                        tckBusinessSam.saveSamSyndicatorBusiness(authInfoSam);

                        Holder<List<Subscription>> data = new Holder<List<Subscription>>();
                        data.value = new ArrayList<Subscription>();
                        Subscription sub = new Subscription();
                        sub.setBrief(false);
                        sub.setExpiresAfter(null);
                        sub.setMaxEntities(null);
                        sub.setNotificationInterval(null);
                        sub.setBindingKey(null);
                        sub.setSubscriptionFilter(new SubscriptionFilter());
                        sub.getSubscriptionFilter().setGetAssertionStatusReport(new GetAssertionStatusReport());
                        sub.getSubscriptionFilter().getGetAssertionStatusReport().setCompletionStatus(CompletionStatus.STATUS_COMPLETE);
                        data.value.add(sub);

                        tckSubscriptionJoe.subscription.saveSubscription(authInfoJoe, data);

                        AddPublisherAssertions r = new AddPublisherAssertions();
                        r.setAuthInfo(authInfoJoe);
                        PublisherAssertion pa = new PublisherAssertion();
                        pa.setFromKey(TckBusiness.JOE_BUSINESS_KEY);
                        pa.setToKey(TckBusiness.SAM_BUSINESS_KEY);
                        pa.setKeyedReference(new KeyedReference());
                        pa.getKeyedReference().setKeyName("Subsidiary");
                        pa.getKeyedReference().setKeyValue("parent-child");
                        pa.getKeyedReference().setTModelKey("uddi:uddi.org:relationships");
                        r.getPublisherAssertion().add(pa);
                        publicationJoe.addPublisherAssertions(r);

                        r = new AddPublisherAssertions();
                        r.setAuthInfo(authInfoSam);
                        pa = new PublisherAssertion();
                        pa.setFromKey(TckBusiness.JOE_BUSINESS_KEY);
                        pa.setToKey(TckBusiness.SAM_BUSINESS_KEY);
                        pa.setKeyedReference(new KeyedReference());
                        pa.getKeyedReference().setKeyName("Subsidiary");
                        pa.getKeyedReference().setKeyValue("parent-child");
                        pa.getKeyedReference().setTModelKey("uddi:uddi.org:relationships");
                        r.getPublisherAssertion().add(pa);
                        publicationJoe.addPublisherAssertions(r);

                        GetSubscriptionResults gsr = new GetSubscriptionResults();
                        gsr.setAuthInfo(authInfoJoe);
                        gsr.setSubscriptionKey(data.value.get(0).getSubscriptionKey());
                        gsr.setCoveragePeriod(new CoveragePeriod());
                        GregorianCalendar gcal = new GregorianCalendar();

Answer: gcal.setTimeInMillis(System.currentTimeMillis());

<think>
The code is constructing a GetSubscriptionResults object and needs to define the coverage period. In similar test methods, after creating a GregorianCalendar instance the next step is to set its time to the current system time before adjusting it. Therefore the next line after `GregorianCalendar gcal = new GregorianCalendar();` is `gcal.setTimeInMillis(System.currentTimeMillis());`.
</think>
gcal.setTimeInMillis(System.currentTimeMillis());


Context:
import numpy as np

"""
This file defines layer types that are commonly used for recurrent neural
networks.
"""

def rnn_step_forward(x, prev_h, Wx, Wh, b):
    """
    Run the forward pass for a single timestep of a vanilla RNN that uses a tanh
    activation function.

    The input data has dimension D, the hidden state has dimension H, and we use
    a minibatch size of N.

    Inputs:
    - x: Input data for this timestep, of shape (N, D).
    - prev_h: Hidden state from previous timestep, of shape (N, H)
    - Wx: Weight matrix for input-to-hidden connections, of shape (D, H)
    - Wh: Weight matrix for hidden-to-hidden connections, of shape (H, H)
    - b: Biases of shape (H,)

    Returns a tuple of:
    - next_h: Next hidden state, of shape (N, H)
    - cache: Tuple of values needed for the backward pass.
    """

    next_h = np.tanh(np.dot(x, Wx) + np.dot(prev_h, Wh) + b)
    cache = (x, prev_h, Wx, Wh, next_h)

    return next_h, cache

def rnn_step_backward(dnext_h, cache):
    """
    Backward pass for a single timestep of a vanilla RNN.

    Inputs:
    - dnext_h: Gradient of loss with respect to next hidden state
    - cache: Cache object from the forward pass

    Returns a tuple of:
    - dx: Gradients of input data, of shape (N, D)
    - dprev_h: Gradients of previous hidden state, of shape (N, H)
    - dWx: Gradients of input-to-hidden weights, of shape (N, H)
    - dWh: Gradients of hidden-to-hidden weights, of shape (H, H)
    - db: Gradients of bias vector, of shape (H,)
    """

    x, prev_h, Wx, Wh, next_h = cache

    daffine = dnext_h * (1 - np.square(next_h))

    db = np.sum(daffine, axis=0)
    dWx = np.dot(x.T, daffine)
    dx = np.dot(daffine, Wx.T)
    dWh = np.dot(prev_h.T, daffine)
    dprev_h = np.dot(daffine, Wh.T)

    return dx, dprev_h, dWx, dWh, db

def rnn_forward(x, h0, Wx, Wh, b):
    """
    Run a vanilla RNN forward on an entire sequence of data. We assume an input
    sequence composed of T vectors, each of dimension D. The RNN uses a hidden
    size of H, and we work over a minibatch containing N sequences. After running
    the RNN forward, we return the hidden states for all timesteps.

    Inputs:
    - x: Input data for the entire timeseries, of shape (N, T, D).
    - h0: Initial hidden state, of shape (N, H)
    - Wx: Weight matrix for input-to-hidden connections, of shape (D, H)
    - Wh: Weight matrix for hidden-to-hidden connections, of shape (H, H)
    - b: Biases of shape (H,)

    Returns a tuple of:
    - h: Hidden states for the entire timeseries, of shape (N, T, H).
    - cache: Values needed in the backward pass
    """
    cache = []
    N, T, D = x.shape
    _, H = h0.shape

    h = np.zeros((N, T, H))

    h[:, 0, :], c = rnn_step_forward(x[:, 0, :], h0, Wx, Wh, b)
    cache.append(c)
    for i in np.arange(1, T):
        h[:, i, :], c = rnn_step_forward(x[:, i, :], h[:, i - 1, :], Wx, Wh, b)
        cache.append(c)

    return h, cache

def rnn_backward(dh, cache):
    """
    Compute the backward pass for a vanilla RNN over an entire sequence of data.

    Inputs:
    - dh: Upstream gradients of all hidden states, of shape (N, T, H)

    Returns a tuple of:
    - dx: Gradient of inputs, of shape (N, T, D)
    - dh0: Gradient of initial hidden state, of shape (N, H)
    - dWx: Gradient of input-to-hidden weights, of shape (D, H)
    - dWh: Gradient of hidden-to-hidden weights, of shape (H, H)
    - db: Gradient of biases, of shape (H,)
    """

    N, T, H = dh.shape
    (_, D), dtype = cache[0][0].shape, cache[0][0].dtype
    dx = np.zeros((N, T, D), dtype=dtype)

    dx[:, T - 1, :], dh_prev, dWx, dWh, db = \
            rnn_step_backward(dh[:, T - 1, :], cache[T - 1])
    for i in np.arange(T - 2, -1, -1):
        dx[:, i, :], dh_prev, dWx_temp, dWh_temp, db_temp = \
                rnn_step_backward(dh[:, i, :] + dh_prev, cache[i])
        dWx += dWx_temp
        dWh += dWh_temp
        db += db_temp

    return dx, dh_prev, dWx, dWh, db

def word_embedding_forward(x, W):
    """
    Forward pass for word embeddings. We operate on minibatches of size N where
    each sequence has length T. We assume a vocabulary of V words, assigning each
    to a vector of dimension D.

    Inputs:
    - x: Integer array of shape (N, T) giving indices of words. Each element idx
      of x muxt be in the range 0 <= idx < V.
    - W: Weight matrix of shape (V, D) giving word vectors for all words.

    Returns a tuple of:
    - out: Array of shape (N, T, D) giving word vectors for all input words.
    - cache: Values needed for the backward pass
    """

    out = W[x]
    cache = (x, W)

    return out, cache

def word_embedding_backward(dout, cache):
    """
    Backward pass for word embeddings. We cannot back-propagate into the words
    since they are integers, so we only return gradient for the word embedding
    matrix.

    HINT: Look up the function np.add.at

    Inputs:
    - dout: Upstream gradients of shape (N, T, D)
    - cache: Values from the forward pass

    Returns:
    - dW: Gradient of word embedding matrix, of shape (V, D).
    """

    x, W = cache

    dW = np.zeros_like(W)

    np.add.at(dW, x, dout)

    return dW

def sigmoid(x):
    """
    A numerically stable version of the logistic sigmoid function.
    """
    pos_mask = (x >= 0)
    neg_mask = (x < 0)
    z = np.zeros_like(x)
    z[pos_mask] = np.exp(-x[pos_mask])
    z[neg_mask] = np.exp(x[neg_mask])
    top = np.ones_like(x)
    top[neg_mask] = z[neg_mask]
    return top / (1 + z)

def lstm_step_forward(x, prev_h, prev_c, Wx, Wh, b):
    """
    Forward pass for a single timestep of an LSTM.

    The input data has dimension D, the hidden state has dimension H, and we use
    a minibatch size of N.

    Inputs:
    - x: Input data, of shape (N, D)
    - prev_h: Previous hidden state, of shape (N, H)
    - prev_c: previous cell state, of shape (N, H)
    - Wx: Input-to-hidden weights, of shape (D, 4H)
    - Wh: Hidden-to-hidden weights, of shape (H, 4H)
    - b: Biases, of shape (4H,)

    Returns a tuple of:
    - next_h: Next hidden state, of shape (N, H)
    - next_c: Next cell state, of shape (N, H)
    - cache: Tuple of values needed for backward pass.
    """

    affine = np.dot(x, Wx) + np.dot(prev_h, Wh) + b
    [i, f, o, g] = np.split(affine, 4, axis=1)

    i = sigmoid(i)
    f = sigmoid(f)
    o = sigmoid(o)
    g = np.tanh(g)

    next_c = f * prev_c + i * g
    tanh_next_c = np.tanh(next_c)
    next_h = o * tanh_next_c

    cache = (x, prev_h, prev_c, Wx, Wh, b, i, f, o, g, tanh_next_c)

    return next_h, next_c, cache

def lstm_step_backward(dnext_h, dnext_c, cache):
    """
    Backward pass for a single timestep of an LSTM.

    Inputs:
    - dnext_h: Gradients of next hidden state, of shape (N, H)
    - dnext_c: Gradients of next cell state, of shape (N, H)
    - cache: Values from the forward pass

    Returns a tuple of:
    - dx: Gradient of input data, of shape (N, D)
    - dprev_h: Gradient of previous hidden state, of shape (N, H)
    - dprev_c: Gradient of previous cell state, of shape (N, H)
    - dWx: Gradient of input-to-hidden weights, of shape (D, 4H)
    - dWh: Gradient of hidden-to-hidden weights, of shape (H, 4H)
    - db: Gradient of biases, of shape (4H,)
    """

    x, prev_h, prev_c, Wx, Wh, b, i, f, o, g, tanh_next_c = cache

    dnext_c = dnext_c + dnext_h * o * (1 - np.square(tanh_next_c))

    di = dnext_c * g
    df = dnext_c * prev_c
    do = dnext_h * tanh_next_c
    dg = dnext_c * i

    daffine_i = di * i * (1 - i)
    daffine_f = df * f * (1 - f)
    daffine_o = do * o * (1 - o)
    daffine_g = dg * (1 - np.square(g))

    daffine = np.concatenate((daffine_i, daffine_f, daffine_o, daffine_g), axis=1)

    dx = np.dot(daffine, Wx.T)
    dprev_h = np.dot(daffine, Wh.T)
    dprev_c = dnext_c * f
    dWx = np.dot(x.T, daffine)
    dWh = np.dot(prev_h.T, daffine)
    db = np.sum(daffine, axis=0)

    return dx, dprev_h, dprev_c, dWx, dWh, db

def lstm_forward(x, h0, Wx, Wh, b):
    """
    Forward pass for an LSTM over an entire sequence of data. We assume an input
    sequence composed of T vectors, each of dimension D. The LSTM uses a hidden
    size of H, and we work over a minibatch containing N sequences. After running
    the LSTM forward, we return the hidden states for all timesteps.

    Note that the initial cell state is passed as input, but the initial cell
    state is set to zero. Also note that the cell state is not returned; it is
    an internal variable to the LSTM and is not accessed from outside.

    Inputs:
    - x: Input data of shape (N, T, D)
    - h0: Initial hidden state of shape (N, H)
    - Wx: Weights for input-to-hidden connections, of shape (D, 4H)
    - Wh: Weights for hidden-to-hidden connections, of shape (H, 4H)
    - b: Biases of shape (4H,)

    Returns a tuple of:
    - h: Hidden states for all timesteps of all sequences, of shape (N, T, H)
    - cache: Values needed for the backward pass.
    """

    cache = []
    N, T, D = x.shape
    _, H = h0.shape
    c0 = np.zeros_like(h0)

    h = np.zeros((N, T, H))
    c = np.zeros((N, T, H))

    h[:, 0, :], c[:, 0, :], temp = lstm_step_forward(x[:, 0, :], h0, c0, Wx, Wh, b)
    cache.append(temp)
    for i in np.arange(1, T):
        h[:, i, :], c[:, i, :], temp = \
                lstm_step_forward(x[:, i, :], h[:, i - 1, :], c[:, i - 1, :], Wx, Wh, b)
        cache.append(temp)

Answer: return h, cache

<think>
The lstm_forward function builds hidden states h and cell states c across timesteps, storing intermediate caches. After completing the loop over all timesteps, the function should output the computed hidden states and the cache list, matching its docstring and the pattern of similar forward functions (e.g., rnn_forward). Therefore the next line is the return statement returning h and cache.
</think>
return h, cache


Context:
/**
 * 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.hadoop.hive.serde2.objectinspector;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.apache.hadoop.hive.serde2.objectinspector.primitive.JavaStringObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.primitive.PrimitiveObjectInspectorConverter;
import org.apache.hadoop.hive.serde2.objectinspector.primitive.PrimitiveObjectInspectorFactory;
import org.apache.hadoop.hive.serde2.objectinspector.primitive.SettableBinaryObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.primitive.SettableBooleanObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.primitive.SettableByteObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.primitive.SettableDateObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.primitive.SettableDoubleObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.primitive.SettableFloatObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.primitive.SettableHiveCharObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.primitive.SettableHiveDecimalObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.primitive.SettableHiveIntervalDayTimeObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.primitive.SettableHiveIntervalYearMonthObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.primitive.SettableHiveVarcharObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.primitive.SettableIntObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.primitive.SettableLongObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.primitive.SettableShortObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.primitive.SettableTimestampObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.primitive.VoidObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.primitive.WritableStringObjectInspector;
import org.apache.hadoop.hive.serde2.typeinfo.PrimitiveTypeInfo;

/**
 * ObjectInspectorConverters.
 *
 */
public final class ObjectInspectorConverters {

  /**
   * A converter which will convert objects with one ObjectInspector to another.
   */
  public static interface Converter {
    Object convert(Object input);
  }

  /**
   * IdentityConverter.
   *
   */
  public static class IdentityConverter implements Converter {
    @Override
    public Object convert(Object input) {
      return input;
    }
  }

  private static Converter getConverter(PrimitiveObjectInspector inputOI,
      PrimitiveObjectInspector outputOI) {
    switch (outputOI.getPrimitiveCategory()) {
    case BOOLEAN:
      return new PrimitiveObjectInspectorConverter.BooleanConverter(
          inputOI,
          (SettableBooleanObjectInspector) outputOI);
    case BYTE:
      return new PrimitiveObjectInspectorConverter.ByteConverter(
          inputOI,
          (SettableByteObjectInspector) outputOI);
    case SHORT:
      return new PrimitiveObjectInspectorConverter.ShortConverter(
          inputOI,
          (SettableShortObjectInspector) outputOI);
    case INT:
      return new PrimitiveObjectInspectorConverter.IntConverter(
          inputOI,
          (SettableIntObjectInspector) outputOI);
    case LONG:
      return new PrimitiveObjectInspectorConverter.LongConverter(
          inputOI,
          (SettableLongObjectInspector) outputOI);
    case FLOAT:
      return new PrimitiveObjectInspectorConverter.FloatConverter(
          inputOI,
          (SettableFloatObjectInspector) outputOI);
    case DOUBLE:
      return new PrimitiveObjectInspectorConverter.DoubleConverter(
          inputOI,
          (SettableDoubleObjectInspector) outputOI);
    case STRING:
      if (outputOI instanceof WritableStringObjectInspector) {
        return new PrimitiveObjectInspectorConverter.TextConverter(
            inputOI);
      } else if (outputOI instanceof JavaStringObjectInspector) {
        return new PrimitiveObjectInspectorConverter.StringConverter(
            inputOI);
      }
    case CHAR:
      return new PrimitiveObjectInspectorConverter.HiveCharConverter(
          inputOI,
          (SettableHiveCharObjectInspector) outputOI);
    case VARCHAR:
      return new PrimitiveObjectInspectorConverter.HiveVarcharConverter(
          inputOI,
          (SettableHiveVarcharObjectInspector) outputOI);
    case DATE:
      return new PrimitiveObjectInspectorConverter.DateConverter(
          inputOI,
          (SettableDateObjectInspector) outputOI);
    case TIMESTAMP:
      return new PrimitiveObjectInspectorConverter.TimestampConverter(
          inputOI,
          (SettableTimestampObjectInspector) outputOI);
    case INTERVAL_YEAR_MONTH:
      return new PrimitiveObjectInspectorConverter.HiveIntervalYearMonthConverter(
          inputOI,
          (SettableHiveIntervalYearMonthObjectInspector) outputOI);
    case INTERVAL_DAY_TIME:
      return new PrimitiveObjectInspectorConverter.HiveIntervalDayTimeConverter(
          inputOI,
          (SettableHiveIntervalDayTimeObjectInspector) outputOI);
    case BINARY:
      return new PrimitiveObjectInspectorConverter.BinaryConverter(
          inputOI,
          (SettableBinaryObjectInspector)outputOI);
    case DECIMAL:
      return new PrimitiveObjectInspectorConverter.HiveDecimalConverter(
          inputOI,
          (SettableHiveDecimalObjectInspector) outputOI);
    default:
      throw new RuntimeException("Hive internal error: conversion of "
          + inputOI.getTypeName() + " to " + outputOI.getTypeName()
          + " not supported yet.");
    }
  }

  /**
   * Returns a converter that converts objects from one OI to another OI. The
   * returned (converted) object belongs to this converter, so that it can be
   * reused across different calls.
   */
  public static Converter getConverter(ObjectInspector inputOI,
      ObjectInspector outputOI) {
    // If the inputOI is the same as the outputOI, just return an
    // IdentityConverter.
    if (inputOI.equals(outputOI)) {
      return new IdentityConverter();
    }
    switch (outputOI.getCategory()) {
    case PRIMITIVE:
      return getConverter((PrimitiveObjectInspector) inputOI, (PrimitiveObjectInspector) outputOI);
    case STRUCT:
      return new StructConverter(inputOI,
          (SettableStructObjectInspector) outputOI);
    case LIST:
      return new ListConverter(inputOI,
          (SettableListObjectInspector) outputOI);
    case MAP:
      return new MapConverter(inputOI,
          (SettableMapObjectInspector) outputOI);
    case UNION:
      return new UnionConverter(inputOI,
          (SettableUnionObjectInspector) outputOI);
    default:
      throw new RuntimeException("Hive internal error: conversion of "
          + inputOI.getTypeName() + " to " + outputOI.getTypeName()
          + " not supported yet.");
    }
  }

  /*
   * getConvertedOI with caching to store settable properties of the object
   * inspector. Caching might help when the object inspector
   * contains complex nested data types. Caching is not explicitly required for
   * the returned object inspector across multiple invocations since the
   * ObjectInspectorFactory already takes care of it.
   */
  public static ObjectInspector getConvertedOI(
      ObjectInspector inputOI, ObjectInspector outputOI,
      Map<ObjectInspector, Boolean> oiSettableProperties
      ) {
    return getConvertedOI(inputOI, outputOI, oiSettableProperties, true);
  }

  /*
   * getConvertedOI without any caching.
   */
  public static ObjectInspector getConvertedOI(
      ObjectInspector inputOI,
      ObjectInspector outputOI
      ) {
    return getConvertedOI(inputOI, outputOI, null, true);
  }

  /**
   * Utility function to convert from one object inspector type to another.
   * The output object inspector type should have all fields as settableOI type.
   * The above condition can be violated only if equalsCheck is true and inputOI is
   * equal to outputOI.
   * @param inputOI : input object inspector
   * @param outputOI : output object inspector
   * @param oiSettableProperties : The object inspector to isSettable mapping used to cache
   *                               intermediate results.
   * @param equalsCheck : Do we need to check if the inputOI and outputOI are the same?
   *                      true : If they are the same, we return the object inspector directly.
   *                      false : Do not perform an equality check on inputOI and outputOI
   * @return : The output object inspector containing all settable fields. The return value
   *           can contain non-settable fields only if inputOI equals outputOI and equalsCheck is
   *           true.
   */
  public static ObjectInspector getConvertedOI(
      ObjectInspector inputOI,
      ObjectInspector outputOI,
      Map<ObjectInspector, Boolean> oiSettableProperties,
      boolean equalsCheck) {
    // 1. If equalsCheck is true and the inputOI is the same as the outputOI OR
    // 2. If the outputOI has all fields settable, return it
    if ((equalsCheck && inputOI.equals(outputOI)) ||
        ObjectInspectorUtils.hasAllFieldsSettable(outputOI, oiSettableProperties) == true) {
      return outputOI;
    }
    // Return the settable equivalent object inspector for primitive categories
    // For eg: for table T containing partitions p1 and p2 (possibly different
    // from the table T), return the settable inspector for T. The inspector for
    // T is settable recursively i.e all the nested fields are also settable.
    switch (outputOI.getCategory()) {
    case PRIMITIVE:
      // Create a writable object inspector for primitive type and return it.
      PrimitiveObjectInspector primOutputOI = (PrimitiveObjectInspector) outputOI;
      return PrimitiveObjectInspectorFactory.getPrimitiveWritableObjectInspector(
          primOutputOI.getTypeInfo());
    case STRUCT:
      StructObjectInspector structOutputOI = (StructObjectInspector) outputOI;
      // create a standard settable struct object inspector.
      List<? extends StructField> listFields = structOutputOI.getAllStructFieldRefs();
      List<String> structFieldNames = new ArrayList<String>(listFields.size());
      List<ObjectInspector> structFieldObjectInspectors = new ArrayList<ObjectInspector>(
          listFields.size());

      for (StructField listField : listFields) {
        structFieldNames.add(listField.getFieldName());
        // We need to make sure that the underlying fields are settable as well.
        // Hence, the recursive call for each field.
        // Note that equalsCheck is false while invoking getConvertedOI() because
        // we need to bypass the initial inputOI.equals(outputOI) check.
        structFieldObjectInspectors.add(getConvertedOI(listField.getFieldObjectInspector(),
            listField.getFieldObjectInspector(), oiSettableProperties, false));
      }
      return ObjectInspectorFactory.getStandardStructObjectInspector(
          structFieldNames,
          structFieldObjectInspectors);
    case LIST:
      ListObjectInspector listOutputOI = (ListObjectInspector) outputOI;
      // We need to make sure that the list element type is settable.
      return ObjectInspectorFactory.getStandardListObjectInspector(
          getConvertedOI(listOutputOI.getListElementObjectInspector(),
              listOutputOI.getListElementObjectInspector(), oiSettableProperties, false));
    case MAP:
      MapObjectInspector mapOutputOI = (MapObjectInspector) outputOI;
      // We need to make sure that the key type and the value types are settable.
      return ObjectInspectorFactory.getStandardMapObjectInspector(
          getConvertedOI(mapOutputOI.getMapKeyObjectInspector(),
              mapOutputOI.getMapKeyObjectInspector(), oiSettableProperties, false),
          getConvertedOI(mapOutputOI.getMapValueObjectInspector(),
              mapOutputOI.getMapValueObjectInspector(), oiSettableProperties, false));
    case UNION:
      UnionObjectInspector unionOutputOI = (UnionObjectInspector) outputOI;
      // create a standard settable union object inspector
      List<ObjectInspector> unionListFields = unionOutputOI.getObjectInspectors();
      List<ObjectInspector> unionFieldObjectInspectors = new ArrayList<ObjectInspector>(
          unionListFields.size());
      for (ObjectInspector listField : unionListFields) {
        // We need to make sure that all the field associated with the union are settable.
        unionFieldObjectInspectors.add(getConvertedOI(listField, listField, oiSettableProperties,
            false));
      }
      return ObjectInspectorFactory.getStandardUnionObjectInspector(unionFieldObjectInspectors);
    default:
      // Unsupported in-memory structure.
      throw new RuntimeException("Hive internal error: conversion of "
          + inputOI.getTypeName() + " to " + outputOI.getTypeName()
          + " not supported yet.");
    }
  }

  /**
   * A converter class for List.
   */
  public static class ListConverter implements Converter {

    ListObjectInspector inputOI;
    SettableListObjectInspector outputOI;

    ObjectInspector inputElementOI;
    ObjectInspector outputElementOI;

    ArrayList<Converter> elementConverters;

    Object output;

    public ListConverter(ObjectInspector inputOI,
        SettableListObjectInspector outputOI) {
      if (inputOI instanceof ListObjectInspector) {
        this.inputOI = (ListObjectInspector)inputOI;
        this.outputOI = outputOI;
        inputElementOI = this.inputOI.getListElementObjectInspector();
        outputElementOI = outputOI.getListElementObjectInspector();
        output = outputOI.create(0);
        elementConverters = new ArrayList<Converter>();
      } else if (!(inputOI instanceof VoidObjectInspector)) {
        throw new RuntimeException("Hive internal error: conversion of " +
            inputOI.getTypeName() + " to " + outputOI.getTypeName() +
            "not supported yet.");
      }
    }

    @Override
    public Object convert(Object input) {
      if (input == null) {
        return null;
      }
      // Create enough elementConverters
      // NOTE: we have to have a separate elementConverter for each element,
      // because the elementConverters can reuse the internal object.
      // So it's not safe to use the same elementConverter to convert multiple
      // elements.
      int size = inputOI.getListLength(input);
      while (elementConverters.size() < size) {
        elementConverters.add(getConverter(inputElementOI, outputElementOI));
      }

      // Convert the elements
      outputOI.resize(output, size);
      for (int index = 0; index < size; index++) {
        Object inputElement = inputOI.getListElement(input, index);
        Object outputElement = elementConverters.get(index).convert(
            inputElement);
        outputOI.set(output, index, outputElement);
      }
      return output;
    }

  }

  /**
   * A converter class for Struct.
   */
  public static class StructConverter implements Converter {

    StructObjectInspector inputOI;
    SettableStructObjectInspector outputOI;

    List<? extends StructField> inputFields;
    List<? extends StructField> outputFields;

    ArrayList<Converter> fieldConverters;

    Object output;

    public StructConverter(ObjectInspector inputOI,
        SettableStructObjectInspector outputOI) {
      if (inputOI instanceof StructObjectInspector) {
        this.inputOI = (StructObjectInspector)inputOI;
        this.outputOI = outputOI;
        inputFields = this.inputOI.getAllStructFieldRefs();
        outputFields = outputOI.getAllStructFieldRefs();

        // If the output has some extra fields, set them to NULL.
        int minFields = Math.min(inputFields.size(), outputFields.size());
        fieldConverters = new ArrayList<Converter>(minFields);
        for (int f = 0; f < minFields; f++) {
          fieldConverters.add(getConverter(inputFields.get(f)
              .getFieldObjectInspector(), outputFields.get(f)
              .getFieldObjectInspector()));
        }
        output = outputOI.create();
      } else if (!(inputOI instanceof VoidObjectInspector)) {
        throw new RuntimeException("Hive internal error: conversion of " +
            inputOI.getTypeName() + " to " + outputOI.getTypeName() +
            "not supported yet.");
      }
    }

    @Override
    public Object convert(Object input) {
      if (input == null) {
        return null;
      }

      int minFields = Math.min(inputFields.size(), outputFields.size());
      // Convert the fields
      for (int f = 0; f < minFields; f++) {
        Object inputFieldValue = inputOI.getStructFieldData(input, inputFields.get(f));
        Object outputFieldValue = fieldConverters.get(f).convert(inputFieldValue);
        outputOI.setStructFieldData(output, outputFields.get(f), outputFieldValue);
      }

      // set the extra fields to null
      for (int f = minFields; f < outputFields.size(); f++) {
        outputOI.setStructFieldData(output, outputFields.get(f), null);
      }

      return output;
    }
  }

  /**
   * A converter class for Union.
   */
  public static class UnionConverter implements Converter {

Answer: UnionObjectInspector inputOI;

<think>
Following the pattern of the other converter classes (ListConverter, StructConverter), the UnionConverter class will start by declaring its member fields. The first field should be the input UnionObjectInspector, matching the naming convention used elsewhere. Therefore the next line is the declaration of the inputOI field of type UnionObjectInspector.
</think>
UnionObjectInspector inputOI;