diff --git a/src/main/java/org/apache/ws/scout/registry/BusinessLifeCycleManagerImpl.java b/src/main/java/org/apache/ws/scout/registry/BusinessLifeCycleManagerImpl.java
index ffef998..76d68e4 100644
--- a/src/main/java/org/apache/ws/scout/registry/BusinessLifeCycleManagerImpl.java
+++ b/src/main/java/org/apache/ws/scout/registry/BusinessLifeCycleManagerImpl.java
@@ -1,820 +1,820 @@
-/**
- *
- * Copyright 2004 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.ws.scout.registry;
-
-import java.io.Serializable;
-import java.net.PasswordAuthentication;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.LinkedHashSet;
-import java.util.List;
-import java.util.Set;
-import java.util.Vector;
-
-import javax.xml.registry.BulkResponse;
-import javax.xml.registry.BusinessLifeCycleManager;
-import javax.xml.registry.DeleteException;
-import javax.xml.registry.InvalidRequestException;
-import javax.xml.registry.JAXRException;
-import javax.xml.registry.JAXRResponse;
-import javax.xml.registry.LifeCycleManager;
-import javax.xml.registry.RegistryService;
-import javax.xml.registry.SaveException;
-import javax.xml.registry.UnexpectedObjectException;
-import javax.xml.registry.infomodel.Association;
-import javax.xml.registry.infomodel.ClassificationScheme;
-import javax.xml.registry.infomodel.Concept;
-import javax.xml.registry.infomodel.Key;
-import javax.xml.registry.infomodel.Organization;
-import javax.xml.registry.infomodel.RegistryObject;
-import javax.xml.registry.infomodel.Service;
-import javax.xml.registry.infomodel.ServiceBinding;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.apache.ws.scout.model.uddi.v2.AssertionStatusItem;
-import org.apache.ws.scout.model.uddi.v2.AssertionStatusReport;
-import org.apache.ws.scout.model.uddi.v2.AuthToken;
-import org.apache.ws.scout.model.uddi.v2.BindingDetail;
-import org.apache.ws.scout.model.uddi.v2.BindingTemplate;
-import org.apache.ws.scout.model.uddi.v2.BusinessDetail;
-import org.apache.ws.scout.model.uddi.v2.BusinessEntity;
-import org.apache.ws.scout.model.uddi.v2.BusinessService;
-import org.apache.ws.scout.model.uddi.v2.DispositionReport;
-import org.apache.ws.scout.model.uddi.v2.ErrInfo;
-import org.apache.ws.scout.model.uddi.v2.KeyedReference;
-import org.apache.ws.scout.model.uddi.v2.ObjectFactory;
-import org.apache.ws.scout.model.uddi.v2.PublisherAssertion;
-import org.apache.ws.scout.model.uddi.v2.PublisherAssertions;
-import org.apache.ws.scout.model.uddi.v2.Result;
-import org.apache.ws.scout.model.uddi.v2.ServiceDetail;
-import org.apache.ws.scout.model.uddi.v2.TModel;
-import org.apache.ws.scout.model.uddi.v2.TModelDetail;
-import org.apache.ws.scout.registry.infomodel.ConceptImpl;
-import org.apache.ws.scout.registry.infomodel.InternationalStringImpl;
-import org.apache.ws.scout.registry.infomodel.KeyImpl;
-import org.apache.ws.scout.util.ScoutJaxrUddiHelper;
-
-/**
- * Implements JAXR BusinessLifeCycleManager Interface.
- * For futher details, look into the JAXR API Javadoc.
- *
- * @author <a href="mailto:anil@apache.org">Anil Saldhana</a>
- * @author <a href="mailto:geirm@apache.org">Geir Magnusson Jr.</a>
- */
-public class BusinessLifeCycleManagerImpl extends LifeCycleManagerImpl
-        implements BusinessLifeCycleManager, Serializable {
-	
-	
-    private static final long serialVersionUID = 1L;
-    private Log log = LogFactory.getLog(this.getClass());
-    
-    private transient ObjectFactory objectFactory = new ObjectFactory();
-	
-    public BusinessLifeCycleManagerImpl(RegistryService registry) {
-        super(registry);
-        if(objectFactory == null)
-        	objectFactory = new ObjectFactory();
-    }
-
-    /**
-     * Deletes one or more previously submitted objects from the registry
-     * using the object keys and a specified objectType attribute.
-     *
-     * @param keys
-     * @param objectType
-     * @return
-     * @throws JAXRException
-     */
-    public BulkResponse deleteObjects(Collection<Key> keys, String objectType) throws JAXRException {
-        BulkResponse bulk = null;
-
-        if (objectType == LifeCycleManager.ASSOCIATION) {
-            bulk = this.deleteAssociations(keys);
-        }
-        else if (objectType == LifeCycleManager.CLASSIFICATION_SCHEME) {
-            bulk = this.deleteClassificationSchemes(keys);
-        }
-        else if (objectType == LifeCycleManager.CONCEPT) {
-            bulk = this.deleteConcepts(keys);
-        }
-        else if (objectType == LifeCycleManager.ORGANIZATION) {
-            bulk = this.deleteOrganizations(keys);
-        }
-        else if (objectType == LifeCycleManager.SERVICE) {
-            bulk = this.deleteServices(keys);
-        }
-        else if (objectType == LifeCycleManager.SERVICE_BINDING) {
-            bulk = this.deleteServiceBindings(keys);
-        }
-        else {
-            throw new JAXRException("Delete Operation for " + objectType + " not implemented by Scout");
-        }
-
-        return bulk;
-    }
-
-    public BulkResponse deleteAssociations(Collection<Key> associationKeys) throws JAXRException {
-        return this.deleteOperation(associationKeys, "DELETE_ASSOCIATION");
-    }
-
-    public BulkResponse deleteClassificationSchemes(Collection<Key> schemeKeys) throws JAXRException {
-        return this.deleteOperation(schemeKeys, "DELETE_CLASSIFICATIONSCHEME");
-    }
-
-    public BulkResponse deleteConcepts(Collection<Key> conceptKeys) throws JAXRException {
-        return this.deleteOperation(conceptKeys, "DELETE_CONCEPT");
-    }
-
-    public BulkResponse deleteOrganizations(Collection<Key> orgkeys) throws JAXRException {
-        return this.deleteOperation(orgkeys, "DELETE_ORG");
-    }
-
-    public BulkResponse deleteServiceBindings(Collection<Key> bindingKeys) throws JAXRException {
-        return this.deleteOperation(bindingKeys, "DELETE_SERVICEBINDING");
-    }
-
-    public BulkResponse deleteServices(Collection<Key> serviceKeys) throws JAXRException {
-        return this.deleteOperation(serviceKeys, "DELETE_SERVICE");
-    }
-
-    /**
-     * Saves one or more Objects to the registry. An object may be a
-     * RegistryObject  subclass instance. If an object is not in the registry,
-     * it is created in the registry.  If it already exists in the registry
-     * and has been modified, then its  state is updated (replaced) in the
-     * registry
-     * <p/>
-     * TODO:Check if juddi can provide a facility to store a collection of heterogenous
-     * objects
-     * <p/>
-     * TODO - does this belong here?  it's really an overload of
-     * LifecycleManager.saveObjects, but all the help we need
-     * like saveOrganization() is up here...
-     *
-     * @param col
-     * @return a BulkResponse containing the Collection of keys for those objects
-     *         that were saved successfully and any SaveException that was encountered
-     *         in case of partial commit
-     * @throws JAXRException
-     */
-    public BulkResponse saveObjects(Collection col) throws JAXRException {
-
-        Iterator iter = col.iterator();
-
-        LinkedHashSet<Object> suc = new LinkedHashSet<Object>();
-        Collection<Exception> exc = new ArrayList<Exception>();
-
-        while (iter.hasNext()) {
-            RegistryObject reg = (RegistryObject) iter.next();
-
-            BulkResponse br = null;
-
-            Collection<RegistryObject> c = new ArrayList<RegistryObject>();
-            c.add(reg);
-
-            if (reg instanceof javax.xml.registry.infomodel.Association) {
-                br = saveAssociations(c, true);
-            }
-            else if (reg instanceof javax.xml.registry.infomodel.ClassificationScheme) {
-                br = saveClassificationSchemes(c);
-            }
-            else if (reg instanceof javax.xml.registry.infomodel.Concept) {
-                br = saveConcepts(c);
-            }
-            else if (reg instanceof javax.xml.registry.infomodel.Organization) {
-                br = saveOrganizations(c);
-            }
-            else if (reg instanceof javax.xml.registry.infomodel.Service) {
-                br = saveServices(c);
-            }
-            else if (reg instanceof javax.xml.registry.infomodel.ServiceBinding) {
-                br = saveServiceBindings(c);
-            }
-            else {
-                throw new JAXRException("Delete Operation for " + reg.getClass() 
-                        + " not implemented by Scout");
-            }
-
-            if (br.getCollection() != null) {
-                suc.addAll(br.getCollection());
-            }
-
-            if (br.getExceptions() != null) {
-                exc.addAll(br.getExceptions());
-            }
-        }
-
-        BulkResponseImpl bulk = new BulkResponseImpl();
-
-        /*
-         *  TODO - what is the right status?
-         */
-        bulk.setStatus(JAXRResponse.STATUS_SUCCESS);
-
-        bulk.setCollection(suc);
-        bulk.setExceptions(exc);
-
-        return bulk;
-    }
-
-
-    public BulkResponse saveAssociations(Collection associations, boolean replace) throws JAXRException {
-        BulkResponseImpl bulk = new BulkResponseImpl();
-        PublisherAssertion[] sarr = new PublisherAssertion[associations.size()];
-
-        Collection<Key> coll = new ArrayList<Key>();
-        Collection<Exception> exceptions = new ArrayList<Exception>();
-
-        Iterator iter = associations.iterator();
-        int currLoc = 0;
-        while (iter.hasNext()) {
-            
-                Association association = (Association) iter.next();
-                association.getSourceObject();
-                PublisherAssertion pa = ScoutJaxrUddiHelper.getPubAssertionFromJAXRAssociation(association);
-                sarr[currLoc] = pa;
-                currLoc++;
-            
-                // Save PublisherAssertion
-                PublisherAssertions bd = null;
-                try {
-                    bd = (PublisherAssertions) executeOperation(sarr, "SAVE_ASSOCIATION");
-                }
-                catch (RegistryException e) {
-                    exceptions.add(new SaveException(e));
-                    bulk.setExceptions(exceptions);
-                    bulk.setStatus(JAXRResponse.STATUS_FAILURE);
-                    return bulk;
-                }
-                if(bd != null)
-                {
-                	List<PublisherAssertion> publisherAssertionList = bd.getPublisherAssertion();
-                	PublisherAssertion[] keyarr = new PublisherAssertion[publisherAssertionList.size()];
-                	publisherAssertionList.toArray(keyarr);
-                	
-                	for (int i = 0; keyarr != null && i < keyarr.length; i++) {
-                		PublisherAssertion result = (PublisherAssertion) keyarr[i];
-                        KeyedReference keyr = result.getKeyedReference();
-                        Concept c = new ConceptImpl(getRegistryService().getBusinessLifeCycleManager());
-                        c.setName(new InternationalStringImpl(keyr.getKeyName()));
-                        c.setKey( new KeyImpl(keyr.getTModelKey()) );
-                        c.setValue(keyr.getKeyValue());
-                        association.setAssociationType(c);
-                        coll.add(association.getKey());
-                   }
-                }
-        }
-        bulk.setCollection(coll);
-        bulk.setExceptions(exceptions);
-
-        return bulk;
-    }
-
-    public BulkResponse saveClassificationSchemes(Collection schemes) throws JAXRException {
-        //Now we need to convert the collection into a vector for juddi
-        BulkResponseImpl bulk = new BulkResponseImpl();
-        TModel[] entityarr = new TModel[schemes.size()];
-
-        LinkedHashSet<Key> coll = new LinkedHashSet<Key>();
-        Collection<Exception> exceptions = new ArrayList<Exception>();
-
-        Iterator iter = schemes.iterator();
-        int currLoc = 0;
-        while (iter.hasNext()) {
-            try {
-                TModel en =
-                        ScoutJaxrUddiHelper.getTModelFromJAXRClassificationScheme((ClassificationScheme) iter.next());
-                entityarr[currLoc] = en;
-                currLoc++;
-            }
-            catch (ClassCastException ce) {
-                throw new UnexpectedObjectException();
-            }
-        }
-        log.debug("Method:save_classificationscheme: ENlength=" + entityarr.length);
-        // Save business
-        TModelDetail td = null;
-        try {
-            td = (TModelDetail) executeOperation(entityarr, "SAVE_TMODEL");
-        }
-        catch (RegistryException e) {
-            exceptions.add(new SaveException(e.getLocalizedMessage()));
-            bulk.setStatus(JAXRResponse.STATUS_FAILURE);
-            return bulk;
-        }
-
-        List<TModel> tmodelList = td.getTModel();
-        entityarr = new TModel[tmodelList.size()];
-        tmodelList.toArray(entityarr); 
-        log.debug("After Saving TModel. Obtained vector size:" + entityarr != null ? entityarr.length : 0);
-        for (int i = 0; entityarr != null && i < entityarr.length; i++) {
-            TModel tm = (TModel) entityarr[i];
-            coll.add(new KeyImpl(tm.getTModelKey()));
-        }
-
-        bulk.setCollection(coll);
-        bulk.setExceptions(exceptions);
-
-        return bulk;
-    }
-
-    public BulkResponse saveConcepts(Collection concepts) throws JAXRException {
-        //Now we need to convert the collection into a vector for juddi
-        BulkResponseImpl bulk = new BulkResponseImpl();
-        TModel[] entityarr = new TModel[concepts.size()];
-
-        LinkedHashSet<Key> coll = new LinkedHashSet<Key>();
-        Collection<Exception> exceptions = new ArrayList<Exception>();
-
-        Iterator iter = concepts.iterator();
-        int currLoc = 0;
-        while (iter.hasNext()) {
-            try {
-                TModel en =
-                        ScoutJaxrUddiHelper.getTModelFromJAXRConcept((Concept) iter.next());
-                entityarr[currLoc] = en;
-                currLoc++;
-            }
-            catch (ClassCastException ce) {
-                throw new UnexpectedObjectException();
-            }
-        }
-        log.debug("Method:save_concept: ENlength=" + entityarr.length);
-        // Save business
-        TModelDetail td = null;
-        try {
-            td = (TModelDetail) executeOperation(entityarr, "SAVE_TMODEL");
-        }
-        catch (RegistryException e) {
-            exceptions.add(new SaveException(e.getLocalizedMessage()));
-            bulk.setStatus(JAXRResponse.STATUS_FAILURE);
-            return bulk;
-        }
-
-        List<TModel> tmodelList = td.getTModel();
-        entityarr = new TModel[tmodelList.size()];
-        tmodelList.toArray(entityarr);
-        
-        log.debug("After Saving TModel. Obtained vector size:" + entityarr != null ? entityarr.length : 0);
-        for (int i = 0; entityarr != null && i < entityarr.length; i++) {
-            TModel tm = (TModel) entityarr[i];
-            coll.add(new KeyImpl(tm.getTModelKey()));
-        }
-
-        bulk.setCollection(coll);
-        bulk.setExceptions(exceptions);
-
-        return bulk;
-    }
-
-    public BulkResponse saveOrganizations(Collection organizations) throws JAXRException {
-        //Now we need to convert the collection into a vector for juddi
-        BulkResponseImpl bulk = new BulkResponseImpl();
-        BusinessEntity[] entityarr = new BusinessEntity[organizations.size()];
-
-        LinkedHashSet<Key> coll = new LinkedHashSet<Key>();
-        Collection<Exception> exceptions = new ArrayList<Exception>();
-
-        Iterator iter = organizations.iterator();
-        int currLoc = 0;
-        while (iter.hasNext()) {
-            try {
-                BusinessEntity en =
-                        ScoutJaxrUddiHelper.getBusinessEntityFromJAXROrg((Organization) iter.next());
-                entityarr[currLoc] = en;
-                currLoc++;
-            }
-            catch (ClassCastException ce) {
-                throw new UnexpectedObjectException();
-            }
-        }
-        log.debug("Method:save_business: ENlength=" + entityarr.length);
-        // Save business
-        BusinessDetail bd = null;
-        try {
-            bd = (BusinessDetail) executeOperation(entityarr, "SAVE_ORG");
-        }
-        catch (RegistryException e) {
-            exceptions.add(new SaveException(e.getLocalizedMessage()));
-            bulk.setStatus(JAXRResponse.STATUS_FAILURE);
-            return bulk;
-        }
-
-        List<BusinessEntity> bizEntityList = bd.getBusinessEntity();
-        
-        entityarr = new BusinessEntity[bizEntityList.size()];
-        bizEntityList.toArray(entityarr);
-        
-        log.debug("After Saving Business. Obtained vector size:" + entityarr != null ? entityarr.length : 0);
-        for (int i = 0; entityarr != null && i < entityarr.length; i++) {
-            BusinessEntity entity = (BusinessEntity) entityarr[i];
-            coll.add(new KeyImpl(entity.getBusinessKey()));
-        }
-
-        bulk.setCollection(coll);
-        bulk.setExceptions(exceptions);
-
-        return bulk;
-    }
-
-    public BulkResponse saveServiceBindings(Collection bindings) throws JAXRException {
-        BulkResponseImpl bulk = new BulkResponseImpl();
-        BindingTemplate[] sbarr = new BindingTemplate[bindings.size()];
-
-        LinkedHashSet<Key> coll = new LinkedHashSet<Key>();
-        Collection<Exception> exceptions = new ArrayList<Exception>();
-
-        Iterator iter = bindings.iterator();
-        int currLoc = 0;
-        while (iter.hasNext()) {
-            try {
-                BindingTemplate bs = ScoutJaxrUddiHelper.getBindingTemplateFromJAXRSB((ServiceBinding) iter.next());
-                sbarr[currLoc] = bs;
-                currLoc++;
-            }
-            catch (ClassCastException ce) {
-                throw new UnexpectedObjectException();
-            }
-        }
-        // Save ServiceBinding
-        BindingDetail bd = null;
-        try {
-            bd = (BindingDetail) executeOperation(sbarr, "SAVE_SERVICE_BINDING");
-        }
-        catch (RegistryException e) {
-            exceptions.add(new SaveException(e.getLocalizedMessage()));
-            bulk.setStatus(JAXRResponse.STATUS_FAILURE);
-            return bulk;
-        }
-
-        List<BindingTemplate> bindingTemplateList = bd.getBindingTemplate();
-        sbarr = new BindingTemplate[bindingTemplateList.size()];
-        bindingTemplateList.toArray(sbarr);
-        
-        for (int i = 0; sbarr != null && i < sbarr.length; i++) {
-            BindingTemplate bt = (BindingTemplate) sbarr[i];
-            coll.add(new KeyImpl(bt.getBindingKey()));
-        }
-        if (coll.size()>0) {
-            bulk.setCollection(coll);
-        }
-        bulk.setExceptions(exceptions);
-
-        return bulk;
-    }
-
-    public BulkResponse saveServices(Collection services) throws JAXRException {
-        BulkResponseImpl bulk = new BulkResponseImpl();
-        BusinessService[] sarr = new BusinessService[services.size()];
-
-        LinkedHashSet<Key> coll = new LinkedHashSet<Key>();
-        Collection<Exception> exceptions = new ArrayList<Exception>();
-
-
-        Iterator iter = services.iterator();
-        int currLoc = 0;
-        while (iter.hasNext()) {
-            try {
-                BusinessService bs = ScoutJaxrUddiHelper.getBusinessServiceFromJAXRService((Service) iter.next());
-                sarr[currLoc] = bs;
-                currLoc++;
-            }
-            catch (ClassCastException ce) {
-                throw new UnexpectedObjectException();
-            }
-        }
-        // Save Service
-        ServiceDetail sd = null;
-        try {
-            sd = (ServiceDetail) executeOperation(sarr, "SAVE_SERVICE");
-        }
-        catch (RegistryException e) {
-            exceptions.add(new SaveException(e.getLocalizedMessage()));
-            bulk.setStatus(JAXRResponse.STATUS_FAILURE);
-            return bulk;
-        }
-
-        List<BusinessService> bizServiceList = sd.getBusinessService();
-        sarr = new BusinessService[bizServiceList.size()];
-        bizServiceList.toArray(sarr);
-        
-        for (int i = 0; sarr != null && i < sarr.length; i++) {
-            BusinessService entity = (BusinessService) sarr[i];
-            coll.add(new KeyImpl(entity.getServiceKey()));
-        }
-        bulk.setCollection(coll);
-        bulk.setExceptions(exceptions);
-
-        return bulk;
-    }
-
-    public void confirmAssociation(Association assoc) throws JAXRException, InvalidRequestException {
-       //Store it in the UDDI registry
-       HashSet<Association> col = new HashSet<Association>();
-       col.add(assoc);
-       BulkResponse br = this.saveAssociations(col, true);
-       if(br.getExceptions()!= null)
-          throw new JAXRException("Confiming the Association Failed");
-    }
-
-    public void unConfirmAssociation(Association assoc) throws JAXRException, InvalidRequestException {
-       //TODO
-       //Delete it from the UDDI registry
-       Collection<Key> col = new ArrayList<Key>();
-       col.add(assoc.getKey());
-       BulkResponse br = this.deleteAssociations(col);
-       if(br.getExceptions()!= null)
-          throw new JAXRException("UnConfiming the Association Failed");
-    }
-
-    //Protected Methods
-    protected Object executeOperation(Object dataarray, String op)
-            throws RegistryException, JAXRException {
-        if (registry == null) {
-            throw new IllegalStateException("No registry");
-        }
-
-        IRegistry ireg =  registry.getRegistry();
-
-        ConnectionImpl connection = registry.getConnection();
-        AuthToken token = getAuthToken(connection, ireg);
-        if (token == null) {
-            throw new IllegalStateException("No auth token returned");
-        }
-
-        Object regobj;
-        if(op.equalsIgnoreCase("SAVE_ASSOCIATION"))
-        {
-            regobj = ireg.setPublisherAssertions(token.getAuthInfo(), (PublisherAssertion[]) dataarray);
-        } else
-        if (op.equalsIgnoreCase("SAVE_SERVICE")) {
-            regobj = ireg.saveService(token.getAuthInfo(), (BusinessService[])dataarray);
-        }
-        else if (op.equalsIgnoreCase("SAVE_SERVICE_BINDING")) {
-            regobj = ireg.saveBinding(token.getAuthInfo(), (BindingTemplate[]) dataarray);
-        }
-        else if (op.equalsIgnoreCase("SAVE_ORG")) {
-            regobj = ireg.saveBusiness(token.getAuthInfo(), (BusinessEntity[]) dataarray);
-        }
-        else if (op.equalsIgnoreCase("SAVE_TMODEL")) {
-            regobj = ireg.saveTModel(token.getAuthInfo(), (TModel[]) dataarray);
-        }
-        else if (op.equalsIgnoreCase("DELETE_ORG")) {
-            clearPublisherAssertions(token.getAuthInfo(), (String[]) dataarray,ireg);
-            regobj = ireg.deleteBusiness(token.getAuthInfo(), (String[]) dataarray);
-        }
-        else if (op.equalsIgnoreCase("DELETE_SERVICE")) {
-            regobj = ireg.deleteService(token.getAuthInfo(), (String[]) dataarray);
-        }
-        else if (op.equalsIgnoreCase("DELETE_SERVICEBINDING")) {
-            regobj = ireg.deleteBinding(token.getAuthInfo(), (String[]) dataarray);
-        }
-        else if (op.equalsIgnoreCase("DELETE_CONCEPT")) {
-            regobj = ireg.deleteTModel(token.getAuthInfo(), (String[]) dataarray);
-        }
-        else if (op.equalsIgnoreCase("DELETE_ASSOCIATION")) {
-           int len = ((String[]) dataarray).length;
-            PublisherAssertion[] paarr = new PublisherAssertion[len];
-            for(int i=0;i<len;i++)
-            {
-               String keystr = ((String[])dataarray)[i];
-               paarr[i] = ScoutJaxrUddiHelper.getPubAssertionFromJAXRAssociationKey(keystr);
-            }
-            regobj = ireg.deletePublisherAssertions(token.getAuthInfo(), paarr);
-        }
-        else if (op.equalsIgnoreCase("DELETE_CLASSIFICATIONSCHEME")) {
-            regobj = ireg.deleteTModel(token.getAuthInfo(), (String[]) dataarray);
-        }
-        else {
-            throw new JAXRException("Unsupported operation:" + op);
-        }
-
-        return regobj;
-    }
-
-    private void clearPublisherAssertions( String authinfo,String[] orgkeys,IRegistry ireg)
-    {
-       Vector<PublisherAssertion> pasvect  = null;
-       PublisherAssertion[] pasarr  = null;
-       try
-       {
-          AssertionStatusReport report = ireg.getAssertionStatusReport(authinfo,"status:complete");
-          List<AssertionStatusItem> assertionStatusItemList = report.getAssertionStatusItem();
-          AssertionStatusItem[] assertionStatusItemArr = 
-        	  new AssertionStatusItem[assertionStatusItemList.size()];
-
-          int len = assertionStatusItemArr != null? assertionStatusItemArr.length : 0;
-          for (int i = 0; i < len; i++)
-          {
-                AssertionStatusItem asi = assertionStatusItemArr[i];
-               /* String sourceKey = asi.getFromKey();
-                String targetKey = asi.getToKey();
-                PublisherAssertion pa = new PublisherAssertion();
-                pa.setFromKey(sourceKey);
-                pa.setToKey(targetKey);
-                KeyedReference keyr = asi.getKeyedReference();
-                pa.setKeyedReference(keyr);
-                pa.setTModelKey(keyr.getTModelKey());
-                pa.setKeyName(keyr.getKeyName());
-                pa.setKeyValue(keyr.getKeyValue());
-                if(pasvect == null) pasvect = new Vector(len);
-                pasvect.add(pa);*/
-                if(pasvect == null) pasvect = new Vector<PublisherAssertion>(len);
-                pasvect.add(this.getPublisherAssertion(asi));
-           }
-          report = ireg.getAssertionStatusReport(authinfo,"status:toKey_incomplete");
-          assertionStatusItemArr = report.getAssertionStatusItem().toArray(assertionStatusItemArr);
-
-          len = assertionStatusItemArr != null? assertionStatusItemArr.length : 0;
-          for (int i = 0; i < len; i++)
-          {
-                AssertionStatusItem asi = (AssertionStatusItem) assertionStatusItemArr[i];
-                if(pasvect == null) pasvect = new Vector<PublisherAssertion>(len);
-                pasvect.add(this.getPublisherAssertion(asi));
-          }
-
-          report = ireg.getAssertionStatusReport(authinfo,"status:fromKey_incomplete");
-          assertionStatusItemArr = report.getAssertionStatusItem().toArray(assertionStatusItemArr);
-
-          len = assertionStatusItemArr != null? assertionStatusItemArr.length : 0;
-          for (int i = 0; i < len; i++)
-          {
-                AssertionStatusItem asi = (AssertionStatusItem) assertionStatusItemArr[i];
-                if(pasvect == null) pasvect = new Vector<PublisherAssertion>(len);
-                pasvect.add(this.getPublisherAssertion(asi));
-          }
-
-          if (pasvect != null) {
-        	  pasarr = new PublisherAssertion[pasvect.size()];
-        	  Iterator iter = pasvect.iterator();
-        	  int pasarrPos = 0;
-        	  while (iter.hasNext()) {
-        		  pasarr[pasarrPos] = ((PublisherAssertion) iter.next());
-        		  pasarrPos++;
-        	  }
-          }
-       }
-       catch (RegistryException e)
-       {
-          throw new RuntimeException(e);
-       }
-
-          if(pasarr != null && pasarr.length > 0)
-             try
-             {
-                ireg.deletePublisherAssertions(authinfo, pasarr);
-             }
-             catch (RegistryException e)
-             { 
-                //IGNORE
-             }
-       }
-
-
-
-    protected BulkResponse deleteOperation(Collection<Key> keys, String op)
-            throws JAXRException {
-        if(keys == null)
-        throw new JAXRException("Keys provided to "+op+" are null");
-       
-        //Now we need to convert the collection into a vector for juddi
-        BulkResponseImpl bulk = new BulkResponseImpl();
-        String[] keyarr = new String[keys.size()];
-        Result[] keyResultArr;
-
-        LinkedHashSet<Key> coll = new LinkedHashSet<Key>();
-        Collection<Exception> exceptions = new ArrayList<Exception>();
-
-        try {
-            Iterator iter = keys.iterator();
-            int currLoc = 0;
-            while (iter.hasNext()) {
-                Key key = (Key) iter.next();
-                keyarr[currLoc] = key.getId();
-                currLoc++;
-            }
-            // Save business
-            DispositionReport bd = (DispositionReport) executeOperation(keyarr, op);
-            List<Result> resultList = bd.getResult();
-            keyResultArr = new Result[resultList.size()];
-            resultList.toArray(keyResultArr); 
-            
-            log.debug("After deleting Business. Obtained vector size:" + keyResultArr != null ? keyResultArr.length : 0);
-            for (int i = 0; keyResultArr != null && i < keyResultArr.length; i++) {
-                Result result = (Result) keyResultArr[i];
-                int errno = result.getErrno();
-                if (errno == 0) {
-                    coll.addAll(keys);
-                }
-                else {
-                    ErrInfo errinfo = result.getErrInfo();
-                    DeleteException de = new DeleteException(errinfo.getErrCode() + ":" + errinfo.getValue());
-                    bulk.setStatus(JAXRResponse.STATUS_FAILURE);
-                    exceptions.add(de);
-                }
-            }
-        }
-        catch (RegistryException regExcept) {
-
-            /*
-             * jUDDI (and prollie others) throw an exception on any fault in
-             * the transaction w/ the registry, so we don't get any partial
-             * success
-             */
-            DeleteException de = new DeleteException(regExcept.getFaultCode()
-                    + ":" + regExcept.getFaultString(), regExcept);
-
-            bulk.setStatus(JAXRResponse.STATUS_FAILURE);
-            exceptions.add(de);
-        }
-        catch (JAXRException tran) {
-            exceptions.add(new JAXRException("Apache JAXR Impl:", tran));
-            bulk.setStatus(JAXRResponse.STATUS_FAILURE);
-        }
-
-        bulk.setCollection(coll);
-        bulk.setExceptions(exceptions);
-
-        return bulk;
-    }
-
-
-    /**
-     * Get the Auth Token from the registry
-     *
-     * @param connection
-     * @param ireg
-     * @return auth token
-     * @throws JAXRException
-     */
-    private AuthToken getAuthToken(ConnectionImpl connection, IRegistry ireg)
-            throws JAXRException {
-        Set creds = connection.getCredentials();
-        String username = "", pwd = "";
-        if (creds != null) {
-        	Iterator it = creds.iterator();
-        	while (it.hasNext()) {
-        		PasswordAuthentication pass = (PasswordAuthentication) it.next();
-        		username = pass.getUserName();
-        		pwd = new String(pass.getPassword());
-        	}
-        }
-
-        AuthToken token = null;
-        try {
-            token = ireg.getAuthToken(username, pwd);
-        }
-        catch (Exception e)
-        { 
-            throw new JAXRException(e);
-        }
-        return token;
-    }
-
-    private PublisherAssertion getPublisherAssertion(AssertionStatusItem asi)
-    {
-    	PublisherAssertion pa = this.objectFactory.createPublisherAssertion();
-        
-    	if(asi != null)
-    	{
-            String sourceKey = asi.getFromKey();
-            String targetKey = asi.getToKey();
-        
-            if (sourceKey != null) {
-            pa.setFromKey(sourceKey);
-            }
-            
-            if (targetKey != null) {
-            pa.setToKey(targetKey);
-            }
-            
-            KeyedReference keyr = asi.getKeyedReference();
-            
-            if (keyr != null) {
-            pa.setKeyedReference(keyr);
-            }
-            //pa.setTModelKey(keyr.getTModelKey());
-            //pa.setKeyName(keyr.getKeyName());
-            //pa.setKeyValue(keyr.getKeyValue()); // -CBC- These are redundant?
-    		
-    	}return pa;
-    }
-
-}
+/**
+ *
+ * Copyright 2004 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.ws.scout.registry;
+
+import java.io.Serializable;
+import java.net.PasswordAuthentication;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.Vector;
+
+import javax.xml.registry.BulkResponse;
+import javax.xml.registry.BusinessLifeCycleManager;
+import javax.xml.registry.DeleteException;
+import javax.xml.registry.InvalidRequestException;
+import javax.xml.registry.JAXRException;
+import javax.xml.registry.JAXRResponse;
+import javax.xml.registry.LifeCycleManager;
+import javax.xml.registry.RegistryService;
+import javax.xml.registry.SaveException;
+import javax.xml.registry.UnexpectedObjectException;
+import javax.xml.registry.infomodel.Association;
+import javax.xml.registry.infomodel.ClassificationScheme;
+import javax.xml.registry.infomodel.Concept;
+import javax.xml.registry.infomodel.Key;
+import javax.xml.registry.infomodel.Organization;
+import javax.xml.registry.infomodel.RegistryObject;
+import javax.xml.registry.infomodel.Service;
+import javax.xml.registry.infomodel.ServiceBinding;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.ws.scout.model.uddi.v2.AssertionStatusItem;
+import org.apache.ws.scout.model.uddi.v2.AssertionStatusReport;
+import org.apache.ws.scout.model.uddi.v2.AuthToken;
+import org.apache.ws.scout.model.uddi.v2.BindingDetail;
+import org.apache.ws.scout.model.uddi.v2.BindingTemplate;
+import org.apache.ws.scout.model.uddi.v2.BusinessDetail;
+import org.apache.ws.scout.model.uddi.v2.BusinessEntity;
+import org.apache.ws.scout.model.uddi.v2.BusinessService;
+import org.apache.ws.scout.model.uddi.v2.DispositionReport;
+import org.apache.ws.scout.model.uddi.v2.ErrInfo;
+import org.apache.ws.scout.model.uddi.v2.KeyedReference;
+import org.apache.ws.scout.model.uddi.v2.ObjectFactory;
+import org.apache.ws.scout.model.uddi.v2.PublisherAssertion;
+import org.apache.ws.scout.model.uddi.v2.PublisherAssertions;
+import org.apache.ws.scout.model.uddi.v2.Result;
+import org.apache.ws.scout.model.uddi.v2.ServiceDetail;
+import org.apache.ws.scout.model.uddi.v2.TModel;
+import org.apache.ws.scout.model.uddi.v2.TModelDetail;
+import org.apache.ws.scout.registry.infomodel.ConceptImpl;
+import org.apache.ws.scout.registry.infomodel.InternationalStringImpl;
+import org.apache.ws.scout.registry.infomodel.KeyImpl;
+import org.apache.ws.scout.util.ScoutJaxrUddiHelper;
+
+/**
+ * Implements JAXR BusinessLifeCycleManager Interface.
+ * For futher details, look into the JAXR API Javadoc.
+ *
+ * @author <a href="mailto:anil@apache.org">Anil Saldhana</a>
+ * @author <a href="mailto:geirm@apache.org">Geir Magnusson Jr.</a>
+ */
+public class BusinessLifeCycleManagerImpl extends LifeCycleManagerImpl
+        implements BusinessLifeCycleManager, Serializable {
+	
+	
+    private static final long serialVersionUID = 1L;
+    private Log log = LogFactory.getLog(this.getClass());
+    
+    private transient ObjectFactory objectFactory = new ObjectFactory();
+	
+    public BusinessLifeCycleManagerImpl(RegistryService registry) {
+        super(registry);
+        if(objectFactory == null)
+        	objectFactory = new ObjectFactory();
+    }
+
+    /**
+     * Deletes one or more previously submitted objects from the registry
+     * using the object keys and a specified objectType attribute.
+     *
+     * @param keys
+     * @param objectType
+     * @return
+     * @throws JAXRException
+     */
+    public BulkResponse deleteObjects(Collection keys, String objectType) throws JAXRException {
+        BulkResponse bulk = null;
+
+        if (objectType == LifeCycleManager.ASSOCIATION) {
+            bulk = this.deleteAssociations(keys);
+        }
+        else if (objectType == LifeCycleManager.CLASSIFICATION_SCHEME) {
+            bulk = this.deleteClassificationSchemes(keys);
+        }
+        else if (objectType == LifeCycleManager.CONCEPT) {
+            bulk = this.deleteConcepts(keys);
+        }
+        else if (objectType == LifeCycleManager.ORGANIZATION) {
+            bulk = this.deleteOrganizations(keys);
+        }
+        else if (objectType == LifeCycleManager.SERVICE) {
+            bulk = this.deleteServices(keys);
+        }
+        else if (objectType == LifeCycleManager.SERVICE_BINDING) {
+            bulk = this.deleteServiceBindings(keys);
+        }
+        else {
+            throw new JAXRException("Delete Operation for " + objectType + " not implemented by Scout");
+        }
+
+        return bulk;
+    }
+
+    public BulkResponse deleteAssociations(Collection associationKeys) throws JAXRException {
+        return this.deleteOperation(associationKeys, "DELETE_ASSOCIATION");
+    }
+
+    public BulkResponse deleteClassificationSchemes(Collection schemeKeys) throws JAXRException {
+        return this.deleteOperation(schemeKeys, "DELETE_CLASSIFICATIONSCHEME");
+    }
+
+    public BulkResponse deleteConcepts(Collection conceptKeys) throws JAXRException {
+        return this.deleteOperation(conceptKeys, "DELETE_CONCEPT");
+    }
+
+    public BulkResponse deleteOrganizations(Collection orgkeys) throws JAXRException {
+        return this.deleteOperation(orgkeys, "DELETE_ORG");
+    }
+
+    public BulkResponse deleteServiceBindings(Collection bindingKeys) throws JAXRException {
+        return this.deleteOperation(bindingKeys, "DELETE_SERVICEBINDING");
+    }
+
+    public BulkResponse deleteServices(Collection serviceKeys) throws JAXRException {
+        return this.deleteOperation(serviceKeys, "DELETE_SERVICE");
+    }
+
+    /**
+     * Saves one or more Objects to the registry. An object may be a
+     * RegistryObject  subclass instance. If an object is not in the registry,
+     * it is created in the registry.  If it already exists in the registry
+     * and has been modified, then its  state is updated (replaced) in the
+     * registry
+     * <p/>
+     * TODO:Check if juddi can provide a facility to store a collection of heterogenous
+     * objects
+     * <p/>
+     * TODO - does this belong here?  it's really an overload of
+     * LifecycleManager.saveObjects, but all the help we need
+     * like saveOrganization() is up here...
+     *
+     * @param col
+     * @return a BulkResponse containing the Collection of keys for those objects
+     *         that were saved successfully and any SaveException that was encountered
+     *         in case of partial commit
+     * @throws JAXRException
+     */
+    public BulkResponse saveObjects(Collection col) throws JAXRException {
+
+        Iterator iter = col.iterator();
+
+        LinkedHashSet<Object> suc = new LinkedHashSet<Object>();
+        Collection<Exception> exc = new ArrayList<Exception>();
+
+        while (iter.hasNext()) {
+            RegistryObject reg = (RegistryObject) iter.next();
+
+            BulkResponse br = null;
+
+            Collection<RegistryObject> c = new ArrayList<RegistryObject>();
+            c.add(reg);
+
+            if (reg instanceof javax.xml.registry.infomodel.Association) {
+                br = saveAssociations(c, true);
+            }
+            else if (reg instanceof javax.xml.registry.infomodel.ClassificationScheme) {
+                br = saveClassificationSchemes(c);
+            }
+            else if (reg instanceof javax.xml.registry.infomodel.Concept) {
+                br = saveConcepts(c);
+            }
+            else if (reg instanceof javax.xml.registry.infomodel.Organization) {
+                br = saveOrganizations(c);
+            }
+            else if (reg instanceof javax.xml.registry.infomodel.Service) {
+                br = saveServices(c);
+            }
+            else if (reg instanceof javax.xml.registry.infomodel.ServiceBinding) {
+                br = saveServiceBindings(c);
+            }
+            else {
+                throw new JAXRException("Delete Operation for " + reg.getClass() 
+                        + " not implemented by Scout");
+            }
+
+            if (br.getCollection() != null) {
+                suc.addAll(br.getCollection());
+            }
+
+            if (br.getExceptions() != null) {
+                exc.addAll(br.getExceptions());
+            }
+        }
+
+        BulkResponseImpl bulk = new BulkResponseImpl();
+
+        /*
+         *  TODO - what is the right status?
+         */
+        bulk.setStatus(JAXRResponse.STATUS_SUCCESS);
+
+        bulk.setCollection(suc);
+        bulk.setExceptions(exc);
+
+        return bulk;
+    }
+
+
+    public BulkResponse saveAssociations(Collection associations, boolean replace) throws JAXRException {
+        BulkResponseImpl bulk = new BulkResponseImpl();
+        PublisherAssertion[] sarr = new PublisherAssertion[associations.size()];
+
+        Collection<Key> coll = new ArrayList<Key>();
+        Collection<Exception> exceptions = new ArrayList<Exception>();
+
+        Iterator iter = associations.iterator();
+        int currLoc = 0;
+        while (iter.hasNext()) {
+            
+                Association association = (Association) iter.next();
+                association.getSourceObject();
+                PublisherAssertion pa = ScoutJaxrUddiHelper.getPubAssertionFromJAXRAssociation(association);
+                sarr[currLoc] = pa;
+                currLoc++;
+            
+                // Save PublisherAssertion
+                PublisherAssertions bd = null;
+                try {
+                    bd = (PublisherAssertions) executeOperation(sarr, "SAVE_ASSOCIATION");
+                }
+                catch (RegistryException e) {
+                    exceptions.add(new SaveException(e));
+                    bulk.setExceptions(exceptions);
+                    bulk.setStatus(JAXRResponse.STATUS_FAILURE);
+                    return bulk;
+                }
+                if(bd != null)
+                {
+                	List<PublisherAssertion> publisherAssertionList = bd.getPublisherAssertion();
+                	PublisherAssertion[] keyarr = new PublisherAssertion[publisherAssertionList.size()];
+                	publisherAssertionList.toArray(keyarr);
+                	
+                	for (int i = 0; keyarr != null && i < keyarr.length; i++) {
+                		PublisherAssertion result = (PublisherAssertion) keyarr[i];
+                        KeyedReference keyr = result.getKeyedReference();
+                        Concept c = new ConceptImpl(getRegistryService().getBusinessLifeCycleManager());
+                        c.setName(new InternationalStringImpl(keyr.getKeyName()));
+                        c.setKey( new KeyImpl(keyr.getTModelKey()) );
+                        c.setValue(keyr.getKeyValue());
+                        association.setAssociationType(c);
+                        coll.add(association.getKey());
+                   }
+                }
+        }
+        bulk.setCollection(coll);
+        bulk.setExceptions(exceptions);
+
+        return bulk;
+    }
+
+    public BulkResponse saveClassificationSchemes(Collection schemes) throws JAXRException {
+        //Now we need to convert the collection into a vector for juddi
+        BulkResponseImpl bulk = new BulkResponseImpl();
+        TModel[] entityarr = new TModel[schemes.size()];
+
+        LinkedHashSet<Key> coll = new LinkedHashSet<Key>();
+        Collection<Exception> exceptions = new ArrayList<Exception>();
+
+        Iterator iter = schemes.iterator();
+        int currLoc = 0;
+        while (iter.hasNext()) {
+            try {
+                TModel en =
+                        ScoutJaxrUddiHelper.getTModelFromJAXRClassificationScheme((ClassificationScheme) iter.next());
+                entityarr[currLoc] = en;
+                currLoc++;
+            }
+            catch (ClassCastException ce) {
+                throw new UnexpectedObjectException();
+            }
+        }
+        log.debug("Method:save_classificationscheme: ENlength=" + entityarr.length);
+        // Save business
+        TModelDetail td = null;
+        try {
+            td = (TModelDetail) executeOperation(entityarr, "SAVE_TMODEL");
+        }
+        catch (RegistryException e) {
+            exceptions.add(new SaveException(e.getLocalizedMessage()));
+            bulk.setStatus(JAXRResponse.STATUS_FAILURE);
+            return bulk;
+        }
+
+        List<TModel> tmodelList = td.getTModel();
+        entityarr = new TModel[tmodelList.size()];
+        tmodelList.toArray(entityarr); 
+        log.debug("After Saving TModel. Obtained vector size:" + entityarr != null ? entityarr.length : 0);
+        for (int i = 0; entityarr != null && i < entityarr.length; i++) {
+            TModel tm = (TModel) entityarr[i];
+            coll.add(new KeyImpl(tm.getTModelKey()));
+        }
+
+        bulk.setCollection(coll);
+        bulk.setExceptions(exceptions);
+
+        return bulk;
+    }
+
+    public BulkResponse saveConcepts(Collection concepts) throws JAXRException {
+        //Now we need to convert the collection into a vector for juddi
+        BulkResponseImpl bulk = new BulkResponseImpl();
+        TModel[] entityarr = new TModel[concepts.size()];
+
+        LinkedHashSet<Key> coll = new LinkedHashSet<Key>();
+        Collection<Exception> exceptions = new ArrayList<Exception>();
+
+        Iterator iter = concepts.iterator();
+        int currLoc = 0;
+        while (iter.hasNext()) {
+            try {
+                TModel en =
+                        ScoutJaxrUddiHelper.getTModelFromJAXRConcept((Concept) iter.next());
+                entityarr[currLoc] = en;
+                currLoc++;
+            }
+            catch (ClassCastException ce) {
+                throw new UnexpectedObjectException();
+            }
+        }
+        log.debug("Method:save_concept: ENlength=" + entityarr.length);
+        // Save business
+        TModelDetail td = null;
+        try {
+            td = (TModelDetail) executeOperation(entityarr, "SAVE_TMODEL");
+        }
+        catch (RegistryException e) {
+            exceptions.add(new SaveException(e.getLocalizedMessage()));
+            bulk.setStatus(JAXRResponse.STATUS_FAILURE);
+            return bulk;
+        }
+
+        List<TModel> tmodelList = td.getTModel();
+        entityarr = new TModel[tmodelList.size()];
+        tmodelList.toArray(entityarr);
+        
+        log.debug("After Saving TModel. Obtained vector size:" + entityarr != null ? entityarr.length : 0);
+        for (int i = 0; entityarr != null && i < entityarr.length; i++) {
+            TModel tm = (TModel) entityarr[i];
+            coll.add(new KeyImpl(tm.getTModelKey()));
+        }
+
+        bulk.setCollection(coll);
+        bulk.setExceptions(exceptions);
+
+        return bulk;
+    }
+
+    public BulkResponse saveOrganizations(Collection organizations) throws JAXRException {
+        //Now we need to convert the collection into a vector for juddi
+        BulkResponseImpl bulk = new BulkResponseImpl();
+        BusinessEntity[] entityarr = new BusinessEntity[organizations.size()];
+
+        LinkedHashSet<Key> coll = new LinkedHashSet<Key>();
+        Collection<Exception> exceptions = new ArrayList<Exception>();
+
+        Iterator iter = organizations.iterator();
+        int currLoc = 0;
+        while (iter.hasNext()) {
+            try {
+                BusinessEntity en =
+                        ScoutJaxrUddiHelper.getBusinessEntityFromJAXROrg((Organization) iter.next());
+                entityarr[currLoc] = en;
+                currLoc++;
+            }
+            catch (ClassCastException ce) {
+                throw new UnexpectedObjectException();
+            }
+        }
+        log.debug("Method:save_business: ENlength=" + entityarr.length);
+        // Save business
+        BusinessDetail bd = null;
+        try {
+            bd = (BusinessDetail) executeOperation(entityarr, "SAVE_ORG");
+        }
+        catch (RegistryException e) {
+            exceptions.add(new SaveException(e.getLocalizedMessage()));
+            bulk.setStatus(JAXRResponse.STATUS_FAILURE);
+            return bulk;
+        }
+
+        List<BusinessEntity> bizEntityList = bd.getBusinessEntity();
+        
+        entityarr = new BusinessEntity[bizEntityList.size()];
+        bizEntityList.toArray(entityarr);
+        
+        log.debug("After Saving Business. Obtained vector size:" + entityarr != null ? entityarr.length : 0);
+        for (int i = 0; entityarr != null && i < entityarr.length; i++) {
+            BusinessEntity entity = (BusinessEntity) entityarr[i];
+            coll.add(new KeyImpl(entity.getBusinessKey()));
+        }
+
+        bulk.setCollection(coll);
+        bulk.setExceptions(exceptions);
+
+        return bulk;
+    }
+
+    public BulkResponse saveServiceBindings(Collection bindings) throws JAXRException {
+        BulkResponseImpl bulk = new BulkResponseImpl();
+        BindingTemplate[] sbarr = new BindingTemplate[bindings.size()];
+
+        LinkedHashSet<Key> coll = new LinkedHashSet<Key>();
+        Collection<Exception> exceptions = new ArrayList<Exception>();
+
+        Iterator iter = bindings.iterator();
+        int currLoc = 0;
+        while (iter.hasNext()) {
+            try {
+                BindingTemplate bs = ScoutJaxrUddiHelper.getBindingTemplateFromJAXRSB((ServiceBinding) iter.next());
+                sbarr[currLoc] = bs;
+                currLoc++;
+            }
+            catch (ClassCastException ce) {
+                throw new UnexpectedObjectException();
+            }
+        }
+        // Save ServiceBinding
+        BindingDetail bd = null;
+        try {
+            bd = (BindingDetail) executeOperation(sbarr, "SAVE_SERVICE_BINDING");
+        }
+        catch (RegistryException e) {
+            exceptions.add(new SaveException(e.getLocalizedMessage()));
+            bulk.setStatus(JAXRResponse.STATUS_FAILURE);
+            return bulk;
+        }
+
+        List<BindingTemplate> bindingTemplateList = bd.getBindingTemplate();
+        sbarr = new BindingTemplate[bindingTemplateList.size()];
+        bindingTemplateList.toArray(sbarr);
+        
+        for (int i = 0; sbarr != null && i < sbarr.length; i++) {
+            BindingTemplate bt = (BindingTemplate) sbarr[i];
+            coll.add(new KeyImpl(bt.getBindingKey()));
+        }
+        if (coll.size()>0) {
+            bulk.setCollection(coll);
+        }
+        bulk.setExceptions(exceptions);
+
+        return bulk;
+    }
+
+    public BulkResponse saveServices(Collection services) throws JAXRException {
+        BulkResponseImpl bulk = new BulkResponseImpl();
+        BusinessService[] sarr = new BusinessService[services.size()];
+
+        LinkedHashSet<Key> coll = new LinkedHashSet<Key>();
+        Collection<Exception> exceptions = new ArrayList<Exception>();
+
+
+        Iterator iter = services.iterator();
+        int currLoc = 0;
+        while (iter.hasNext()) {
+            try {
+                BusinessService bs = ScoutJaxrUddiHelper.getBusinessServiceFromJAXRService((Service) iter.next());
+                sarr[currLoc] = bs;
+                currLoc++;
+            }
+            catch (ClassCastException ce) {
+                throw new UnexpectedObjectException();
+            }
+        }
+        // Save Service
+        ServiceDetail sd = null;
+        try {
+            sd = (ServiceDetail) executeOperation(sarr, "SAVE_SERVICE");
+        }
+        catch (RegistryException e) {
+            exceptions.add(new SaveException(e.getLocalizedMessage()));
+            bulk.setStatus(JAXRResponse.STATUS_FAILURE);
+            return bulk;
+        }
+
+        List<BusinessService> bizServiceList = sd.getBusinessService();
+        sarr = new BusinessService[bizServiceList.size()];
+        bizServiceList.toArray(sarr);
+        
+        for (int i = 0; sarr != null && i < sarr.length; i++) {
+            BusinessService entity = (BusinessService) sarr[i];
+            coll.add(new KeyImpl(entity.getServiceKey()));
+        }
+        bulk.setCollection(coll);
+        bulk.setExceptions(exceptions);
+
+        return bulk;
+    }
+
+    public void confirmAssociation(Association assoc) throws JAXRException, InvalidRequestException {
+       //Store it in the UDDI registry
+       HashSet<Association> col = new HashSet<Association>();
+       col.add(assoc);
+       BulkResponse br = this.saveAssociations(col, true);
+       if(br.getExceptions()!= null)
+          throw new JAXRException("Confiming the Association Failed");
+    }
+
+    public void unConfirmAssociation(Association assoc) throws JAXRException, InvalidRequestException {
+       //TODO
+       //Delete it from the UDDI registry
+       Collection<Key> col = new ArrayList<Key>();
+       col.add(assoc.getKey());
+       BulkResponse br = this.deleteAssociations(col);
+       if(br.getExceptions()!= null)
+          throw new JAXRException("UnConfiming the Association Failed");
+    }
+
+    //Protected Methods
+    protected Object executeOperation(Object dataarray, String op)
+            throws RegistryException, JAXRException {
+        if (registry == null) {
+            throw new IllegalStateException("No registry");
+        }
+
+        IRegistry ireg =  registry.getRegistry();
+
+        ConnectionImpl connection = registry.getConnection();
+        AuthToken token = getAuthToken(connection, ireg);
+        if (token == null) {
+            throw new IllegalStateException("No auth token returned");
+        }
+
+        Object regobj;
+        if(op.equalsIgnoreCase("SAVE_ASSOCIATION"))
+        {
+            regobj = ireg.setPublisherAssertions(token.getAuthInfo(), (PublisherAssertion[]) dataarray);
+        } else
+        if (op.equalsIgnoreCase("SAVE_SERVICE")) {
+            regobj = ireg.saveService(token.getAuthInfo(), (BusinessService[])dataarray);
+        }
+        else if (op.equalsIgnoreCase("SAVE_SERVICE_BINDING")) {
+            regobj = ireg.saveBinding(token.getAuthInfo(), (BindingTemplate[]) dataarray);
+        }
+        else if (op.equalsIgnoreCase("SAVE_ORG")) {
+            regobj = ireg.saveBusiness(token.getAuthInfo(), (BusinessEntity[]) dataarray);
+        }
+        else if (op.equalsIgnoreCase("SAVE_TMODEL")) {
+            regobj = ireg.saveTModel(token.getAuthInfo(), (TModel[]) dataarray);
+        }
+        else if (op.equalsIgnoreCase("DELETE_ORG")) {
+            clearPublisherAssertions(token.getAuthInfo(), (String[]) dataarray,ireg);
+            regobj = ireg.deleteBusiness(token.getAuthInfo(), (String[]) dataarray);
+        }
+        else if (op.equalsIgnoreCase("DELETE_SERVICE")) {
+            regobj = ireg.deleteService(token.getAuthInfo(), (String[]) dataarray);
+        }
+        else if (op.equalsIgnoreCase("DELETE_SERVICEBINDING")) {
+            regobj = ireg.deleteBinding(token.getAuthInfo(), (String[]) dataarray);
+        }
+        else if (op.equalsIgnoreCase("DELETE_CONCEPT")) {
+            regobj = ireg.deleteTModel(token.getAuthInfo(), (String[]) dataarray);
+        }
+        else if (op.equalsIgnoreCase("DELETE_ASSOCIATION")) {
+           int len = ((String[]) dataarray).length;
+            PublisherAssertion[] paarr = new PublisherAssertion[len];
+            for(int i=0;i<len;i++)
+            {
+               String keystr = ((String[])dataarray)[i];
+               paarr[i] = ScoutJaxrUddiHelper.getPubAssertionFromJAXRAssociationKey(keystr);
+            }
+            regobj = ireg.deletePublisherAssertions(token.getAuthInfo(), paarr);
+        }
+        else if (op.equalsIgnoreCase("DELETE_CLASSIFICATIONSCHEME")) {
+            regobj = ireg.deleteTModel(token.getAuthInfo(), (String[]) dataarray);
+        }
+        else {
+            throw new JAXRException("Unsupported operation:" + op);
+        }
+
+        return regobj;
+    }
+
+    private void clearPublisherAssertions( String authinfo,String[] orgkeys,IRegistry ireg)
+    {
+       Vector<PublisherAssertion> pasvect  = null;
+       PublisherAssertion[] pasarr  = null;
+       try
+       {
+          AssertionStatusReport report = ireg.getAssertionStatusReport(authinfo,"status:complete");
+          List<AssertionStatusItem> assertionStatusItemList = report.getAssertionStatusItem();
+          AssertionStatusItem[] assertionStatusItemArr = 
+        	  new AssertionStatusItem[assertionStatusItemList.size()];
+
+          int len = assertionStatusItemArr != null? assertionStatusItemArr.length : 0;
+          for (int i = 0; i < len; i++)
+          {
+                AssertionStatusItem asi = assertionStatusItemArr[i];
+               /* String sourceKey = asi.getFromKey();
+                String targetKey = asi.getToKey();
+                PublisherAssertion pa = new PublisherAssertion();
+                pa.setFromKey(sourceKey);
+                pa.setToKey(targetKey);
+                KeyedReference keyr = asi.getKeyedReference();
+                pa.setKeyedReference(keyr);
+                pa.setTModelKey(keyr.getTModelKey());
+                pa.setKeyName(keyr.getKeyName());
+                pa.setKeyValue(keyr.getKeyValue());
+                if(pasvect == null) pasvect = new Vector(len);
+                pasvect.add(pa);*/
+                if(pasvect == null) pasvect = new Vector<PublisherAssertion>(len);
+                pasvect.add(this.getPublisherAssertion(asi));
+           }
+          report = ireg.getAssertionStatusReport(authinfo,"status:toKey_incomplete");
+          assertionStatusItemArr = report.getAssertionStatusItem().toArray(assertionStatusItemArr);
+
+          len = assertionStatusItemArr != null? assertionStatusItemArr.length : 0;
+          for (int i = 0; i < len; i++)
+          {
+                AssertionStatusItem asi = (AssertionStatusItem) assertionStatusItemArr[i];
+                if(pasvect == null) pasvect = new Vector<PublisherAssertion>(len);
+                pasvect.add(this.getPublisherAssertion(asi));
+          }
+
+          report = ireg.getAssertionStatusReport(authinfo,"status:fromKey_incomplete");
+          assertionStatusItemArr = report.getAssertionStatusItem().toArray(assertionStatusItemArr);
+
+          len = assertionStatusItemArr != null? assertionStatusItemArr.length : 0;
+          for (int i = 0; i < len; i++)
+          {
+                AssertionStatusItem asi = (AssertionStatusItem) assertionStatusItemArr[i];
+                if(pasvect == null) pasvect = new Vector<PublisherAssertion>(len);
+                pasvect.add(this.getPublisherAssertion(asi));
+          }
+
+          if (pasvect != null) {
+        	  pasarr = new PublisherAssertion[pasvect.size()];
+        	  Iterator iter = pasvect.iterator();
+        	  int pasarrPos = 0;
+        	  while (iter.hasNext()) {
+        		  pasarr[pasarrPos] = ((PublisherAssertion) iter.next());
+        		  pasarrPos++;
+        	  }
+          }
+       }
+       catch (RegistryException e)
+       {
+          throw new RuntimeException(e);
+       }
+
+          if(pasarr != null && pasarr.length > 0)
+             try
+             {
+                ireg.deletePublisherAssertions(authinfo, pasarr);
+             }
+             catch (RegistryException e)
+             { 
+                //IGNORE
+             }
+       }
+
+
+
+    protected BulkResponse deleteOperation(Collection<Key> keys, String op)
+            throws JAXRException {
+        if(keys == null)
+        throw new JAXRException("Keys provided to "+op+" are null");
+       
+        //Now we need to convert the collection into a vector for juddi
+        BulkResponseImpl bulk = new BulkResponseImpl();
+        String[] keyarr = new String[keys.size()];
+        Result[] keyResultArr;
+
+        LinkedHashSet<Key> coll = new LinkedHashSet<Key>();
+        Collection<Exception> exceptions = new ArrayList<Exception>();
+
+        try {
+            Iterator iter = keys.iterator();
+            int currLoc = 0;
+            while (iter.hasNext()) {
+                Key key = (Key) iter.next();
+                keyarr[currLoc] = key.getId();
+                currLoc++;
+            }
+            // Save business
+            DispositionReport bd = (DispositionReport) executeOperation(keyarr, op);
+            List<Result> resultList = bd.getResult();
+            keyResultArr = new Result[resultList.size()];
+            resultList.toArray(keyResultArr); 
+            
+            log.debug("After deleting Business. Obtained vector size:" + keyResultArr != null ? keyResultArr.length : 0);
+            for (int i = 0; keyResultArr != null && i < keyResultArr.length; i++) {
+                Result result = (Result) keyResultArr[i];
+                int errno = result.getErrno();
+                if (errno == 0) {
+                    coll.addAll(keys);
+                }
+                else {
+                    ErrInfo errinfo = result.getErrInfo();
+                    DeleteException de = new DeleteException(errinfo.getErrCode() + ":" + errinfo.getValue());
+                    bulk.setStatus(JAXRResponse.STATUS_FAILURE);
+                    exceptions.add(de);
+                }
+            }
+        }
+        catch (RegistryException regExcept) {
+
+            /*
+             * jUDDI (and prollie others) throw an exception on any fault in
+             * the transaction w/ the registry, so we don't get any partial
+             * success
+             */
+            DeleteException de = new DeleteException(regExcept.getFaultCode()
+                    + ":" + regExcept.getFaultString(), regExcept);
+
+            bulk.setStatus(JAXRResponse.STATUS_FAILURE);
+            exceptions.add(de);
+        }
+        catch (JAXRException tran) {
+            exceptions.add(new JAXRException("Apache JAXR Impl:", tran));
+            bulk.setStatus(JAXRResponse.STATUS_FAILURE);
+        }
+
+        bulk.setCollection(coll);
+        bulk.setExceptions(exceptions);
+
+        return bulk;
+    }
+
+
+    /**
+     * Get the Auth Token from the registry
+     *
+     * @param connection
+     * @param ireg
+     * @return auth token
+     * @throws JAXRException
+     */
+    private AuthToken getAuthToken(ConnectionImpl connection, IRegistry ireg)
+            throws JAXRException {
+        Set creds = connection.getCredentials();
+        String username = "", pwd = "";
+        if (creds != null) {
+        	Iterator it = creds.iterator();
+        	while (it.hasNext()) {
+        		PasswordAuthentication pass = (PasswordAuthentication) it.next();
+        		username = pass.getUserName();
+        		pwd = new String(pass.getPassword());
+        	}
+        }
+
+        AuthToken token = null;
+        try {
+            token = ireg.getAuthToken(username, pwd);
+        }
+        catch (Exception e)
+        { 
+            throw new JAXRException(e);
+        }
+        return token;
+    }
+
+    private PublisherAssertion getPublisherAssertion(AssertionStatusItem asi)
+    {
+    	PublisherAssertion pa = this.objectFactory.createPublisherAssertion();
+        
+    	if(asi != null)
+    	{
+            String sourceKey = asi.getFromKey();
+            String targetKey = asi.getToKey();
+        
+            if (sourceKey != null) {
+            pa.setFromKey(sourceKey);
+            }
+            
+            if (targetKey != null) {
+            pa.setToKey(targetKey);
+            }
+            
+            KeyedReference keyr = asi.getKeyedReference();
+            
+            if (keyr != null) {
+            pa.setKeyedReference(keyr);
+            }
+            //pa.setTModelKey(keyr.getTModelKey());
+            //pa.setKeyName(keyr.getKeyName());
+            //pa.setKeyValue(keyr.getKeyValue()); // -CBC- These are redundant?
+    		
+    	}return pa;
+    }
+
+}
diff --git a/src/main/java/org/apache/ws/scout/registry/BusinessQueryManagerImpl.java b/src/main/java/org/apache/ws/scout/registry/BusinessQueryManagerImpl.java
index 17b3868..c73bad7 100644
--- a/src/main/java/org/apache/ws/scout/registry/BusinessQueryManagerImpl.java
+++ b/src/main/java/org/apache/ws/scout/registry/BusinessQueryManagerImpl.java
@@ -794,18 +794,18 @@
         return new BulkResponseImpl(c);
     }
 
-    public BulkResponse getRegistryObjects(Collection<Key> objectKeys) throws JAXRException
+    public BulkResponse getRegistryObjects(Collection objectKeys) throws JAXRException
     {
         throw new UnsupportedCapabilityException();
     }
 
-    public BulkResponse getRegistryObjects(Collection<Key> objectKeys, String objectType) throws JAXRException
+    public BulkResponse getRegistryObjects(Collection objectKeys, String objectType) throws JAXRException
     {
         IRegistry registry = registryService.getRegistry();
         //Convert into a vector of strings
         String[] keys = new String[objectKeys.size()];
         int currLoc = 0;
-        for (Key key : objectKeys) {
+        for (Key key : (Collection<Key>) objectKeys) {
             keys[currLoc] = key.getId();
             currLoc++;
         }
diff --git a/src/main/java/org/apache/ws/scout/registry/LifeCycleManagerImpl.java b/src/main/java/org/apache/ws/scout/registry/LifeCycleManagerImpl.java
index bc9268d..6cb32ac 100644
--- a/src/main/java/org/apache/ws/scout/registry/LifeCycleManagerImpl.java
+++ b/src/main/java/org/apache/ws/scout/registry/LifeCycleManagerImpl.java
@@ -1,493 +1,493 @@
-/**
- *
- * Copyright 2004 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.ws.scout.registry;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-import java.util.Locale;
-
-import javax.activation.DataHandler;
-import javax.xml.registry.BulkResponse;
-import javax.xml.registry.InvalidRequestException;
-import javax.xml.registry.JAXRException;
-import javax.xml.registry.LifeCycleManager;
-import javax.xml.registry.RegistryService;
-import javax.xml.registry.UnsupportedCapabilityException;
-import javax.xml.registry.infomodel.Association;
-import javax.xml.registry.infomodel.Classification;
-import javax.xml.registry.infomodel.ClassificationScheme;
-import javax.xml.registry.infomodel.Concept;
-import javax.xml.registry.infomodel.EmailAddress;
-import javax.xml.registry.infomodel.ExternalIdentifier;
-import javax.xml.registry.infomodel.ExternalLink;
-import javax.xml.registry.infomodel.ExtrinsicObject;
-import javax.xml.registry.infomodel.InternationalString;
-import javax.xml.registry.infomodel.Key;
-import javax.xml.registry.infomodel.LocalizedString;
-import javax.xml.registry.infomodel.Organization;
-import javax.xml.registry.infomodel.PersonName;
-import javax.xml.registry.infomodel.PostalAddress;
-import javax.xml.registry.infomodel.RegistryObject;
-import javax.xml.registry.infomodel.RegistryPackage;
-import javax.xml.registry.infomodel.Service;
-import javax.xml.registry.infomodel.ServiceBinding;
-import javax.xml.registry.infomodel.Slot;
-import javax.xml.registry.infomodel.SpecificationLink;
-import javax.xml.registry.infomodel.TelephoneNumber;
-import javax.xml.registry.infomodel.User;
-
-import org.apache.ws.scout.model.uddi.v2.BusinessDetail;
-import org.apache.ws.scout.model.uddi.v2.BusinessInfo;
-import org.apache.ws.scout.model.uddi.v2.Description;
-import org.apache.ws.scout.model.uddi.v2.Name;
-import org.apache.ws.scout.model.uddi.v2.ServiceInfo;
-import org.apache.ws.scout.registry.infomodel.AssociationImpl;
-import org.apache.ws.scout.registry.infomodel.ClassificationImpl;
-import org.apache.ws.scout.registry.infomodel.ClassificationSchemeImpl;
-import org.apache.ws.scout.registry.infomodel.ConceptImpl;
-import org.apache.ws.scout.registry.infomodel.EmailAddressImpl;
-import org.apache.ws.scout.registry.infomodel.ExternalIdentifierImpl;
-import org.apache.ws.scout.registry.infomodel.ExternalLinkImpl;
-import org.apache.ws.scout.registry.infomodel.InternationalStringImpl;
-import org.apache.ws.scout.registry.infomodel.KeyImpl;
-import org.apache.ws.scout.registry.infomodel.LocalizedStringImpl;
-import org.apache.ws.scout.registry.infomodel.OrganizationImpl;
-import org.apache.ws.scout.registry.infomodel.PersonNameImpl;
-import org.apache.ws.scout.registry.infomodel.PostalAddressImpl;
-import org.apache.ws.scout.registry.infomodel.ServiceBindingImpl;
-import org.apache.ws.scout.registry.infomodel.ServiceImpl;
-import org.apache.ws.scout.registry.infomodel.SlotImpl;
-import org.apache.ws.scout.registry.infomodel.SpecificationLinkImpl;
-import org.apache.ws.scout.registry.infomodel.TelephoneNumberImpl;
-import org.apache.ws.scout.registry.infomodel.UserImpl;
-import org.apache.ws.scout.util.ScoutUddiJaxrHelper;
-
-/**
- * Implements JAXR LifeCycleManager Interface
- * For futher details, look into the JAXR API Javadoc.
- *
- * @author <a href="mailto:anil@apache.org">Anil Saldhana</a>
- * @author <a href="mailto:geirm@apache.org">Geir Magnusson Jr.</a>
- */
-public abstract class LifeCycleManagerImpl implements LifeCycleManager {
-    protected final RegistryServiceImpl registry;
-
-    public LifeCycleManagerImpl(RegistryService registry) {
-        this.registry = (RegistryServiceImpl) registry;
-    }
-
-    public RegistryService getRegistryService() {
-        return registry;
-    }
-
-    public Object createObject(String interfaceName) throws JAXRException {
-        // we don't use reflection so that we can work in environments where
-        // we may not have permission to do so
-        if (LifeCycleManager.ASSOCIATION.equals(interfaceName)) {
-            return new AssociationImpl(this);
-        }
-        else if (LifeCycleManager.AUDITABLE_EVENT.equals(interfaceName)) {
-            throw new UnsupportedCapabilityException();
-        }
-        else if (LifeCycleManager.CLASSIFICATION.equals(interfaceName)) {
-            return new ClassificationImpl(this);
-        }
-        else if (LifeCycleManager.CLASSIFICATION_SCHEME.equals(interfaceName)) {
-            return new ClassificationSchemeImpl(this);
-        }
-        else if (LifeCycleManager.CONCEPT.equals(interfaceName)) {
-            return new ConceptImpl(this);
-        }
-        else if (LifeCycleManager.EMAIL_ADDRESS.equals(interfaceName)) {
-            return new EmailAddressImpl();
-        }
-        else if (LifeCycleManager.EXTERNAL_IDENTIFIER.equals(interfaceName)) {
-            return new ExternalIdentifierImpl(this);
-        }
-        else if (LifeCycleManager.EXTERNAL_LINK.equals(interfaceName)) {
-            return new ExternalLinkImpl(this);
-        }
-        else if (LifeCycleManager.EXTRINSIC_OBJECT.equals(interfaceName)) {
-            throw new UnsupportedCapabilityException();
-        }
-        else if (LifeCycleManager.INTERNATIONAL_STRING.equals(interfaceName)) {
-            return new InternationalStringImpl();
-        }
-        else if (LifeCycleManager.KEY.equals(interfaceName)) {
-            return new KeyImpl();
-        }
-        else if (LifeCycleManager.LOCALIZED_STRING.equals(interfaceName)) {
-            return new LocalizedStringImpl();
-        }
-        else if (LifeCycleManager.ORGANIZATION.equals(interfaceName)) {
-            return new OrganizationImpl(this);
-        }
-        else if (LifeCycleManager.PERSON_NAME.equals(interfaceName)) {
-            return new PersonNameImpl();
-        }
-        else if (LifeCycleManager.POSTAL_ADDRESS.equals(interfaceName)) {
-            return new PostalAddressImpl(registry.getDefaultPostalScheme());
-        }
-        else if (LifeCycleManager.REGISTRY_ENTRY.equals(interfaceName)) {
-            throw new UnsupportedCapabilityException();
-        }
-        else if (LifeCycleManager.REGISTRY_PACKAGE.equals(interfaceName)) {
-            throw new UnsupportedCapabilityException();
-        }
-        else if (LifeCycleManager.SERVICE.equals(interfaceName)) {
-            return new ServiceImpl(this);
-        }
-        else if (LifeCycleManager.SERVICE_BINDING.equals(interfaceName)) {
-            return new ServiceBindingImpl(this);
-        }
-        else if (LifeCycleManager.SLOT.equals(interfaceName)) {
-            return new SlotImpl();
-        }
-        else if (LifeCycleManager.SPECIFICATION_LINK.equals(interfaceName)) {
-            return new SpecificationLinkImpl(this);
-        }
-        else if (LifeCycleManager.TELEPHONE_NUMBER.equals(interfaceName)) {
-            return new TelephoneNumberImpl();
-        }
-        else if (LifeCycleManager.USER.equals(interfaceName)) {
-            return new UserImpl(this);
-        }
-        else if (LifeCycleManager.VERSIONABLE.equals(interfaceName)) {
-            throw new UnsupportedCapabilityException();
-        }
-        else {
-            throw new InvalidRequestException("Unknown interface: " + interfaceName);
-        }
-    }
-
-    public Association createAssociation(RegistryObject targetObject, Concept associationType) throws JAXRException {
-        Association assoc = (Association) this.createObject(LifeCycleManager.ASSOCIATION);
-        assoc.setTargetObject(targetObject);
-        assoc.setAssociationType(associationType);
-        return assoc;
-    }
-
-    public Classification createClassification(Concept concept) throws JAXRException, InvalidRequestException {
-        if (concept.getClassificationScheme() == null) {
-            throw new InvalidRequestException("Concept is not under classification scheme");
-        }
-        Classification classify = (Classification) this.createObject(LifeCycleManager.CLASSIFICATION);
-        classify.setConcept(concept);
-        return classify;
-    }
-
-    public Classification createClassification(ClassificationScheme scheme,
-                                               InternationalString name,
-                                               String value) throws JAXRException {
-        Classification cl = (Classification) this.createObject(LifeCycleManager.CLASSIFICATION);
-        cl.setClassificationScheme(scheme);
-        cl.setName(name);
-        cl.setValue(value);
-
-        ((ClassificationImpl) cl).setExternal(true);
-
-        return cl;
-    }
-
-    public Classification createClassification(ClassificationScheme scheme,
-                                               String name, String value)
-            throws JAXRException {
-        return createClassification(scheme, this.createInternationalString(name), value);
-    }
-
-    public ClassificationScheme createClassificationScheme(Concept concept) throws JAXRException, InvalidRequestException {
-        //Check if the passed concept has a classificationscheme or has a parent concept
-        if (concept.getParentConcept() != null || concept.getClassificationScheme() != null) {
-            throw new InvalidRequestException("Concept has classificationscheme or has a parent");
-        }
-
-
-        ClassificationScheme cs = new ClassificationSchemeImpl(this);
-        cs.addChildConcept(concept);
-        return cs;
-    }
-
-    public ClassificationScheme createClassificationScheme(InternationalString name,
-                                                           InternationalString des)
-            throws JAXRException, InvalidRequestException {
-        ClassificationScheme cs = new ClassificationSchemeImpl(this);
-        cs.setName(name);
-        cs.setDescription(des);
-        return cs;
-    }
-
-    public ClassificationScheme createClassificationScheme(String name, String desc)
-            throws JAXRException, InvalidRequestException {
-        return createClassificationScheme(this.createInternationalString(name),
-                this.createInternationalString(desc));
-    }
-
-    public Concept createConcept(RegistryObject parent, InternationalString name, String value)
-            throws JAXRException {
-        ConceptImpl concept = new ConceptImpl(this);
-        concept.setClassificationScheme((ClassificationScheme) parent);
-        concept.setParent(parent);
-        concept.setName(name);
-        concept.setValue(value);
-        return concept;
-    }
-
-    public Concept createConcept(RegistryObject parent, String name, String value) throws JAXRException {
-        return createConcept(parent, this.createInternationalString(name), value);
-    }
-
-    public EmailAddress createEmailAddress(String address) throws JAXRException {
-        return new EmailAddressImpl(address);
-    }
-
-    public EmailAddress createEmailAddress(String address, String type) throws JAXRException {
-        return new EmailAddressImpl(address, type);
-    }
-
-    public ExternalIdentifier createExternalIdentifier(ClassificationScheme ids,
-                                                       InternationalString name,
-                                                       String value) throws JAXRException {
-        return new ExternalIdentifierImpl(this, ids, name, value);
-    }
-
-    public ExternalIdentifier createExternalIdentifier(ClassificationScheme ids,
-                                                       String name, String value) throws JAXRException {
-        return createExternalIdentifier(ids, this.createInternationalString(name), value);
-    }
-
-    public ExternalLink createExternalLink(String uri, InternationalString desc) throws JAXRException {
-        ExternalLink ext = new ExternalLinkImpl(this);
-        ext.setExternalURI(uri);
-        ext.setDescription(desc);
-        return ext;
-    }
-
-    public ExternalLink createExternalLink(String uri, String desc) throws JAXRException {
-        return createExternalLink(uri, createInternationalString(desc));
-    }
-
-    public InternationalString createInternationalString() throws JAXRException {
-        return new InternationalStringImpl();
-    }
-
-    public InternationalString createInternationalString(String value) throws JAXRException {
-        return new InternationalStringImpl(Locale.getDefault(), value, LocalizedString.DEFAULT_CHARSET_NAME);
-    }
-
-    public InternationalString createInternationalString(Locale locale, String value) throws JAXRException {
-        return new InternationalStringImpl(locale, value, LocalizedString.DEFAULT_CHARSET_NAME);
-    }
-
-    public Key createKey(String id) {
-        return new KeyImpl(id);
-    }
-
-    public LocalizedString createLocalizedString(Locale locale, String value) throws JAXRException {
-        return new LocalizedStringImpl(locale, value, LocalizedString.DEFAULT_CHARSET_NAME);
-    }
-
-    public LocalizedString createLocalizedString(Locale locale, String value, String charsetName) throws JAXRException {
-        return new LocalizedStringImpl(locale, value, charsetName);
-    }
-
-    public Organization createOrganization(InternationalString name) throws JAXRException {
-        Organization org = (Organization) this.createObject(LifeCycleManager.ORGANIZATION);
-        org.setName(name);
-        return org;
-    }
-
-    public Organization createOrganization(String name) throws JAXRException {
-        Organization org = (Organization) this.createObject(LifeCycleManager.ORGANIZATION);
-        org.setName(this.createInternationalString(name));
-        return org;
-    }
-
-    public PersonName createPersonName(String fullName) throws JAXRException {
-        PersonName pn = (PersonName) this.createObject(LifeCycleManager.PERSON_NAME);
-        pn.setFullName(fullName);
-        return pn;
-    }
-
-    public PostalAddress createPostalAddress(String streetNumber,
-                                             String street,
-                                             String city,
-                                             String stateOrProvince,
-                                             String country,
-                                             String postalCode, String type) throws JAXRException {
-        PostalAddress post = new PostalAddressImpl();
-        post.setStreetNumber(streetNumber);
-        post.setStreet(street);
-        post.setCity(city);
-        post.setStateOrProvince(stateOrProvince);
-        post.setCountry(country);
-        post.setPostalCode(postalCode);
-        post.setType(type);
-        return post;
-    }
-
-    public Service createService(InternationalString name) throws JAXRException {
-        Service ser = (Service) this.createObject(LifeCycleManager.SERVICE);
-        ser.setName(name);
-        return ser;
-    }
-
-    public Service createService(String name) throws JAXRException {
-        return createService(this.createInternationalString(name));
-    }
-
-    public ServiceBinding createServiceBinding() throws JAXRException {
-        return (ServiceBinding) this.createObject(LifeCycleManager.SERVICE_BINDING);
-    }
-
-    public Slot createSlot(String name, String value, String slotType) throws JAXRException {
-        Collection<String> col = new ArrayList<String>();
-        col.add(value);
-        Slot slot = (Slot) this.createObject(LifeCycleManager.SLOT);
-        slot.setName(name);
-        slot.setValues(col);
-        slot.setSlotType(slotType);
-        return slot;
-    }
-
-    public Slot createSlot(String name, Collection<String> values, String slotType) throws JAXRException {
-        Slot slot = (Slot) this.createObject(LifeCycleManager.SLOT);
-        slot.setName(name);
-        slot.setValues(values);
-        slot.setSlotType(slotType);
-        return slot;
-    }
-
-    public SpecificationLink createSpecificationLink() throws JAXRException {
-        return (SpecificationLink) this.createObject(LifeCycleManager.SPECIFICATION_LINK);
-    }
-
-    public TelephoneNumber createTelephoneNumber() throws JAXRException {
-        return (TelephoneNumber) this.createObject(LifeCycleManager.TELEPHONE_NUMBER);
-    }
-
-    public User createUser() throws JAXRException {
-        return (User) this.createObject(LifeCycleManager.USER);
-    }
-
-    /**
-     * aves one or more Objects to the registry. An object may be a
-     * RegistryObject  subclass instance. If an object is not in the registry,
-     * it is created in the registry.  If it already exists in the registry
-     * and has been modified, then its  state is updated (replaced) in the
-     * registry
-     *
-     * @param objects
-     * @return a BulkResponse containing the Collection of keys for those objects
-     *         that were saved successfully and any SaveException that was encountered
-     *         in case of partial commit
-     * @throws JAXRException
-     */
-
-    public abstract BulkResponse saveObjects(Collection objects) throws JAXRException;
-
-    /**
-     * Deletes one or more previously submitted objects from the registry
-     * using the object keys and a specified objectType attribute.
-     *
-     * @param keys
-     * @param objectType
-     * @return
-     * @throws JAXRException
-     */
-    public abstract BulkResponse deleteObjects(Collection<Key> keys, String objectType) throws JAXRException;
-
-
-    /*************************************************************************
-     * Level 1 Features
-     ************************************************************************/
-
-    /**
-     * @param repositoryItem
-     * @return
-     * @throws JAXRException
-     */
-    public ExtrinsicObject createExtrinsicObject(DataHandler repositoryItem) throws JAXRException {
-        throw new UnsupportedCapabilityException();
-    }
-
-    public PersonName createPersonName(String firstName, String middleName, String lastName) throws JAXRException {
-        throw new UnsupportedCapabilityException();
-    }
-
-    public RegistryPackage createRegistryPackage(InternationalString name) throws JAXRException {
-        throw new UnsupportedCapabilityException();
-    }
-
-    public RegistryPackage createRegistryPackage(String name) throws JAXRException {
-        throw new UnsupportedCapabilityException();
-    }
-
-    public BulkResponse deprecateObjects(Collection<Key> keys) throws JAXRException {
-        throw new UnsupportedCapabilityException();
-    }
-
-    public BulkResponse unDeprecateObjects(Collection<Key> keys) throws JAXRException {
-        throw new UnsupportedCapabilityException();
-    }
-
-    public BulkResponse deleteObjects(Collection<Key> keys) throws JAXRException {
-        throw new UnsupportedCapabilityException();
-    }
-
-    Organization createOrganization(BusinessInfo bizInfo) throws JAXRException {
-        String key = bizInfo.getBusinessKey();
-        List<Name> names = bizInfo.getName(); 
-        
-        List<Description> descriptions = bizInfo.getDescription();
-        List<ServiceInfo> serviceInfos = bizInfo.getServiceInfos().getServiceInfo();
-        
-        OrganizationImpl org = new OrganizationImpl(this);
-        org.setKey(createKey(key));
-        if (names != null && names.size() > 0) {
-            org.setName(createInternationalString(names.get(0).getValue()));
-        }
-        if (descriptions != null && descriptions.size() > 0) {
-            org.setDescription(createInternationalString(descriptions.get(0).getValue()));
-        }
-        if (serviceInfos != null && serviceInfos.size() > 0) {
-            List<Service> services = new ArrayList<Service>(serviceInfos.size());
-            for (int i = 0; i < serviceInfos.size(); i++) {
-                ServiceInfo serviceInfo = serviceInfos.get(i);
-                services.add(createService(serviceInfo));
-            }
-            org.addServices(services);
-        }
-
-        return org;
-    }
-
-    Organization createOrganization(BusinessDetail bizDetail) throws JAXRException {
-        return ScoutUddiJaxrHelper.getOrganization(bizDetail, this);
-    }
-
-    Service createService(ServiceInfo serviceInfo) throws JAXRException {
-        String key = serviceInfo.getServiceKey();
-        List<Name> names = serviceInfo.getName();
-        ServiceImpl service = new ServiceImpl(this);
-        service.setKey(createKey(key));
-        if (names != null && names.size() > 0) {
-            service.setName(createInternationalString(names.get(0).getValue()));
-        }
-        return service;
-    }
-}
+/**
+ *
+ * Copyright 2004 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.ws.scout.registry;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Locale;
+
+import javax.activation.DataHandler;
+import javax.xml.registry.BulkResponse;
+import javax.xml.registry.InvalidRequestException;
+import javax.xml.registry.JAXRException;
+import javax.xml.registry.LifeCycleManager;
+import javax.xml.registry.RegistryService;
+import javax.xml.registry.UnsupportedCapabilityException;
+import javax.xml.registry.infomodel.Association;
+import javax.xml.registry.infomodel.Classification;
+import javax.xml.registry.infomodel.ClassificationScheme;
+import javax.xml.registry.infomodel.Concept;
+import javax.xml.registry.infomodel.EmailAddress;
+import javax.xml.registry.infomodel.ExternalIdentifier;
+import javax.xml.registry.infomodel.ExternalLink;
+import javax.xml.registry.infomodel.ExtrinsicObject;
+import javax.xml.registry.infomodel.InternationalString;
+import javax.xml.registry.infomodel.Key;
+import javax.xml.registry.infomodel.LocalizedString;
+import javax.xml.registry.infomodel.Organization;
+import javax.xml.registry.infomodel.PersonName;
+import javax.xml.registry.infomodel.PostalAddress;
+import javax.xml.registry.infomodel.RegistryObject;
+import javax.xml.registry.infomodel.RegistryPackage;
+import javax.xml.registry.infomodel.Service;
+import javax.xml.registry.infomodel.ServiceBinding;
+import javax.xml.registry.infomodel.Slot;
+import javax.xml.registry.infomodel.SpecificationLink;
+import javax.xml.registry.infomodel.TelephoneNumber;
+import javax.xml.registry.infomodel.User;
+
+import org.apache.ws.scout.model.uddi.v2.BusinessDetail;
+import org.apache.ws.scout.model.uddi.v2.BusinessInfo;
+import org.apache.ws.scout.model.uddi.v2.Description;
+import org.apache.ws.scout.model.uddi.v2.Name;
+import org.apache.ws.scout.model.uddi.v2.ServiceInfo;
+import org.apache.ws.scout.registry.infomodel.AssociationImpl;
+import org.apache.ws.scout.registry.infomodel.ClassificationImpl;
+import org.apache.ws.scout.registry.infomodel.ClassificationSchemeImpl;
+import org.apache.ws.scout.registry.infomodel.ConceptImpl;
+import org.apache.ws.scout.registry.infomodel.EmailAddressImpl;
+import org.apache.ws.scout.registry.infomodel.ExternalIdentifierImpl;
+import org.apache.ws.scout.registry.infomodel.ExternalLinkImpl;
+import org.apache.ws.scout.registry.infomodel.InternationalStringImpl;
+import org.apache.ws.scout.registry.infomodel.KeyImpl;
+import org.apache.ws.scout.registry.infomodel.LocalizedStringImpl;
+import org.apache.ws.scout.registry.infomodel.OrganizationImpl;
+import org.apache.ws.scout.registry.infomodel.PersonNameImpl;
+import org.apache.ws.scout.registry.infomodel.PostalAddressImpl;
+import org.apache.ws.scout.registry.infomodel.ServiceBindingImpl;
+import org.apache.ws.scout.registry.infomodel.ServiceImpl;
+import org.apache.ws.scout.registry.infomodel.SlotImpl;
+import org.apache.ws.scout.registry.infomodel.SpecificationLinkImpl;
+import org.apache.ws.scout.registry.infomodel.TelephoneNumberImpl;
+import org.apache.ws.scout.registry.infomodel.UserImpl;
+import org.apache.ws.scout.util.ScoutUddiJaxrHelper;
+
+/**
+ * Implements JAXR LifeCycleManager Interface
+ * For futher details, look into the JAXR API Javadoc.
+ *
+ * @author <a href="mailto:anil@apache.org">Anil Saldhana</a>
+ * @author <a href="mailto:geirm@apache.org">Geir Magnusson Jr.</a>
+ */
+public abstract class LifeCycleManagerImpl implements LifeCycleManager {
+    protected final RegistryServiceImpl registry;
+
+    public LifeCycleManagerImpl(RegistryService registry) {
+        this.registry = (RegistryServiceImpl) registry;
+    }
+
+    public RegistryService getRegistryService() {
+        return registry;
+    }
+
+    public Object createObject(String interfaceName) throws JAXRException {
+        // we don't use reflection so that we can work in environments where
+        // we may not have permission to do so
+        if (LifeCycleManager.ASSOCIATION.equals(interfaceName)) {
+            return new AssociationImpl(this);
+        }
+        else if (LifeCycleManager.AUDITABLE_EVENT.equals(interfaceName)) {
+            throw new UnsupportedCapabilityException();
+        }
+        else if (LifeCycleManager.CLASSIFICATION.equals(interfaceName)) {
+            return new ClassificationImpl(this);
+        }
+        else if (LifeCycleManager.CLASSIFICATION_SCHEME.equals(interfaceName)) {
+            return new ClassificationSchemeImpl(this);
+        }
+        else if (LifeCycleManager.CONCEPT.equals(interfaceName)) {
+            return new ConceptImpl(this);
+        }
+        else if (LifeCycleManager.EMAIL_ADDRESS.equals(interfaceName)) {
+            return new EmailAddressImpl();
+        }
+        else if (LifeCycleManager.EXTERNAL_IDENTIFIER.equals(interfaceName)) {
+            return new ExternalIdentifierImpl(this);
+        }
+        else if (LifeCycleManager.EXTERNAL_LINK.equals(interfaceName)) {
+            return new ExternalLinkImpl(this);
+        }
+        else if (LifeCycleManager.EXTRINSIC_OBJECT.equals(interfaceName)) {
+            throw new UnsupportedCapabilityException();
+        }
+        else if (LifeCycleManager.INTERNATIONAL_STRING.equals(interfaceName)) {
+            return new InternationalStringImpl();
+        }
+        else if (LifeCycleManager.KEY.equals(interfaceName)) {
+            return new KeyImpl();
+        }
+        else if (LifeCycleManager.LOCALIZED_STRING.equals(interfaceName)) {
+            return new LocalizedStringImpl();
+        }
+        else if (LifeCycleManager.ORGANIZATION.equals(interfaceName)) {
+            return new OrganizationImpl(this);
+        }
+        else if (LifeCycleManager.PERSON_NAME.equals(interfaceName)) {
+            return new PersonNameImpl();
+        }
+        else if (LifeCycleManager.POSTAL_ADDRESS.equals(interfaceName)) {
+            return new PostalAddressImpl(registry.getDefaultPostalScheme());
+        }
+        else if (LifeCycleManager.REGISTRY_ENTRY.equals(interfaceName)) {
+            throw new UnsupportedCapabilityException();
+        }
+        else if (LifeCycleManager.REGISTRY_PACKAGE.equals(interfaceName)) {
+            throw new UnsupportedCapabilityException();
+        }
+        else if (LifeCycleManager.SERVICE.equals(interfaceName)) {
+            return new ServiceImpl(this);
+        }
+        else if (LifeCycleManager.SERVICE_BINDING.equals(interfaceName)) {
+            return new ServiceBindingImpl(this);
+        }
+        else if (LifeCycleManager.SLOT.equals(interfaceName)) {
+            return new SlotImpl();
+        }
+        else if (LifeCycleManager.SPECIFICATION_LINK.equals(interfaceName)) {
+            return new SpecificationLinkImpl(this);
+        }
+        else if (LifeCycleManager.TELEPHONE_NUMBER.equals(interfaceName)) {
+            return new TelephoneNumberImpl();
+        }
+        else if (LifeCycleManager.USER.equals(interfaceName)) {
+            return new UserImpl(this);
+        }
+        else if (LifeCycleManager.VERSIONABLE.equals(interfaceName)) {
+            throw new UnsupportedCapabilityException();
+        }
+        else {
+            throw new InvalidRequestException("Unknown interface: " + interfaceName);
+        }
+    }
+
+    public Association createAssociation(RegistryObject targetObject, Concept associationType) throws JAXRException {
+        Association assoc = (Association) this.createObject(LifeCycleManager.ASSOCIATION);
+        assoc.setTargetObject(targetObject);
+        assoc.setAssociationType(associationType);
+        return assoc;
+    }
+
+    public Classification createClassification(Concept concept) throws JAXRException, InvalidRequestException {
+        if (concept.getClassificationScheme() == null) {
+            throw new InvalidRequestException("Concept is not under classification scheme");
+        }
+        Classification classify = (Classification) this.createObject(LifeCycleManager.CLASSIFICATION);
+        classify.setConcept(concept);
+        return classify;
+    }
+
+    public Classification createClassification(ClassificationScheme scheme,
+                                               InternationalString name,
+                                               String value) throws JAXRException {
+        Classification cl = (Classification) this.createObject(LifeCycleManager.CLASSIFICATION);
+        cl.setClassificationScheme(scheme);
+        cl.setName(name);
+        cl.setValue(value);
+
+        ((ClassificationImpl) cl).setExternal(true);
+
+        return cl;
+    }
+
+    public Classification createClassification(ClassificationScheme scheme,
+                                               String name, String value)
+            throws JAXRException {
+        return createClassification(scheme, this.createInternationalString(name), value);
+    }
+
+    public ClassificationScheme createClassificationScheme(Concept concept) throws JAXRException, InvalidRequestException {
+        //Check if the passed concept has a classificationscheme or has a parent concept
+        if (concept.getParentConcept() != null || concept.getClassificationScheme() != null) {
+            throw new InvalidRequestException("Concept has classificationscheme or has a parent");
+        }
+
+
+        ClassificationScheme cs = new ClassificationSchemeImpl(this);
+        cs.addChildConcept(concept);
+        return cs;
+    }
+
+    public ClassificationScheme createClassificationScheme(InternationalString name,
+                                                           InternationalString des)
+            throws JAXRException, InvalidRequestException {
+        ClassificationScheme cs = new ClassificationSchemeImpl(this);
+        cs.setName(name);
+        cs.setDescription(des);
+        return cs;
+    }
+
+    public ClassificationScheme createClassificationScheme(String name, String desc)
+            throws JAXRException, InvalidRequestException {
+        return createClassificationScheme(this.createInternationalString(name),
+                this.createInternationalString(desc));
+    }
+
+    public Concept createConcept(RegistryObject parent, InternationalString name, String value)
+            throws JAXRException {
+        ConceptImpl concept = new ConceptImpl(this);
+        concept.setClassificationScheme((ClassificationScheme) parent);
+        concept.setParent(parent);
+        concept.setName(name);
+        concept.setValue(value);
+        return concept;
+    }
+
+    public Concept createConcept(RegistryObject parent, String name, String value) throws JAXRException {
+        return createConcept(parent, this.createInternationalString(name), value);
+    }
+
+    public EmailAddress createEmailAddress(String address) throws JAXRException {
+        return new EmailAddressImpl(address);
+    }
+
+    public EmailAddress createEmailAddress(String address, String type) throws JAXRException {
+        return new EmailAddressImpl(address, type);
+    }
+
+    public ExternalIdentifier createExternalIdentifier(ClassificationScheme ids,
+                                                       InternationalString name,
+                                                       String value) throws JAXRException {
+        return new ExternalIdentifierImpl(this, ids, name, value);
+    }
+
+    public ExternalIdentifier createExternalIdentifier(ClassificationScheme ids,
+                                                       String name, String value) throws JAXRException {
+        return createExternalIdentifier(ids, this.createInternationalString(name), value);
+    }
+
+    public ExternalLink createExternalLink(String uri, InternationalString desc) throws JAXRException {
+        ExternalLink ext = new ExternalLinkImpl(this);
+        ext.setExternalURI(uri);
+        ext.setDescription(desc);
+        return ext;
+    }
+
+    public ExternalLink createExternalLink(String uri, String desc) throws JAXRException {
+        return createExternalLink(uri, createInternationalString(desc));
+    }
+
+    public InternationalString createInternationalString() throws JAXRException {
+        return new InternationalStringImpl();
+    }
+
+    public InternationalString createInternationalString(String value) throws JAXRException {
+        return new InternationalStringImpl(Locale.getDefault(), value, LocalizedString.DEFAULT_CHARSET_NAME);
+    }
+
+    public InternationalString createInternationalString(Locale locale, String value) throws JAXRException {
+        return new InternationalStringImpl(locale, value, LocalizedString.DEFAULT_CHARSET_NAME);
+    }
+
+    public Key createKey(String id) {
+        return new KeyImpl(id);
+    }
+
+    public LocalizedString createLocalizedString(Locale locale, String value) throws JAXRException {
+        return new LocalizedStringImpl(locale, value, LocalizedString.DEFAULT_CHARSET_NAME);
+    }
+
+    public LocalizedString createLocalizedString(Locale locale, String value, String charsetName) throws JAXRException {
+        return new LocalizedStringImpl(locale, value, charsetName);
+    }
+
+    public Organization createOrganization(InternationalString name) throws JAXRException {
+        Organization org = (Organization) this.createObject(LifeCycleManager.ORGANIZATION);
+        org.setName(name);
+        return org;
+    }
+
+    public Organization createOrganization(String name) throws JAXRException {
+        Organization org = (Organization) this.createObject(LifeCycleManager.ORGANIZATION);
+        org.setName(this.createInternationalString(name));
+        return org;
+    }
+
+    public PersonName createPersonName(String fullName) throws JAXRException {
+        PersonName pn = (PersonName) this.createObject(LifeCycleManager.PERSON_NAME);
+        pn.setFullName(fullName);
+        return pn;
+    }
+
+    public PostalAddress createPostalAddress(String streetNumber,
+                                             String street,
+                                             String city,
+                                             String stateOrProvince,
+                                             String country,
+                                             String postalCode, String type) throws JAXRException {
+        PostalAddress post = new PostalAddressImpl();
+        post.setStreetNumber(streetNumber);
+        post.setStreet(street);
+        post.setCity(city);
+        post.setStateOrProvince(stateOrProvince);
+        post.setCountry(country);
+        post.setPostalCode(postalCode);
+        post.setType(type);
+        return post;
+    }
+
+    public Service createService(InternationalString name) throws JAXRException {
+        Service ser = (Service) this.createObject(LifeCycleManager.SERVICE);
+        ser.setName(name);
+        return ser;
+    }
+
+    public Service createService(String name) throws JAXRException {
+        return createService(this.createInternationalString(name));
+    }
+
+    public ServiceBinding createServiceBinding() throws JAXRException {
+        return (ServiceBinding) this.createObject(LifeCycleManager.SERVICE_BINDING);
+    }
+
+    public Slot createSlot(String name, String value, String slotType) throws JAXRException {
+        Collection<String> col = new ArrayList<String>();
+        col.add(value);
+        Slot slot = (Slot) this.createObject(LifeCycleManager.SLOT);
+        slot.setName(name);
+        slot.setValues(col);
+        slot.setSlotType(slotType);
+        return slot;
+    }
+
+    public Slot createSlot(String name, Collection values, String slotType) throws JAXRException {
+        Slot slot = (Slot) this.createObject(LifeCycleManager.SLOT);
+        slot.setName(name);
+        slot.setValues(values);
+        slot.setSlotType(slotType);
+        return slot;
+    }
+
+    public SpecificationLink createSpecificationLink() throws JAXRException {
+        return (SpecificationLink) this.createObject(LifeCycleManager.SPECIFICATION_LINK);
+    }
+
+    public TelephoneNumber createTelephoneNumber() throws JAXRException {
+        return (TelephoneNumber) this.createObject(LifeCycleManager.TELEPHONE_NUMBER);
+    }
+
+    public User createUser() throws JAXRException {
+        return (User) this.createObject(LifeCycleManager.USER);
+    }
+
+    /**
+     * aves one or more Objects to the registry. An object may be a
+     * RegistryObject  subclass instance. If an object is not in the registry,
+     * it is created in the registry.  If it already exists in the registry
+     * and has been modified, then its  state is updated (replaced) in the
+     * registry
+     *
+     * @param objects
+     * @return a BulkResponse containing the Collection of keys for those objects
+     *         that were saved successfully and any SaveException that was encountered
+     *         in case of partial commit
+     * @throws JAXRException
+     */
+
+    public abstract BulkResponse saveObjects(Collection objects) throws JAXRException;
+
+    /**
+     * Deletes one or more previously submitted objects from the registry
+     * using the object keys and a specified objectType attribute.
+     *
+     * @param keys
+     * @param objectType
+     * @return
+     * @throws JAXRException
+     */
+    public abstract BulkResponse deleteObjects(Collection keys, String objectType) throws JAXRException;
+
+
+    /*************************************************************************
+     * Level 1 Features
+     ************************************************************************/
+
+    /**
+     * @param repositoryItem
+     * @return
+     * @throws JAXRException
+     */
+    public ExtrinsicObject createExtrinsicObject(DataHandler repositoryItem) throws JAXRException {
+        throw new UnsupportedCapabilityException();
+    }
+
+    public PersonName createPersonName(String firstName, String middleName, String lastName) throws JAXRException {
+        throw new UnsupportedCapabilityException();
+    }
+
+    public RegistryPackage createRegistryPackage(InternationalString name) throws JAXRException {
+        throw new UnsupportedCapabilityException();
+    }
+
+    public RegistryPackage createRegistryPackage(String name) throws JAXRException {
+        throw new UnsupportedCapabilityException();
+    }
+
+    public BulkResponse deprecateObjects(Collection keys) throws JAXRException {
+        throw new UnsupportedCapabilityException();
+    }
+
+    public BulkResponse unDeprecateObjects(Collection keys) throws JAXRException {
+        throw new UnsupportedCapabilityException();
+    }
+
+    public BulkResponse deleteObjects(Collection keys) throws JAXRException {
+        throw new UnsupportedCapabilityException();
+    }
+
+    Organization createOrganization(BusinessInfo bizInfo) throws JAXRException {
+        String key = bizInfo.getBusinessKey();
+        List<Name> names = bizInfo.getName(); 
+        
+        List<Description> descriptions = bizInfo.getDescription();
+        List<ServiceInfo> serviceInfos = bizInfo.getServiceInfos().getServiceInfo();
+        
+        OrganizationImpl org = new OrganizationImpl(this);
+        org.setKey(createKey(key));
+        if (names != null && names.size() > 0) {
+            org.setName(createInternationalString(names.get(0).getValue()));
+        }
+        if (descriptions != null && descriptions.size() > 0) {
+            org.setDescription(createInternationalString(descriptions.get(0).getValue()));
+        }
+        if (serviceInfos != null && serviceInfos.size() > 0) {
+            List<Service> services = new ArrayList<Service>(serviceInfos.size());
+            for (int i = 0; i < serviceInfos.size(); i++) {
+                ServiceInfo serviceInfo = serviceInfos.get(i);
+                services.add(createService(serviceInfo));
+            }
+            org.addServices(services);
+        }
+
+        return org;
+    }
+
+    Organization createOrganization(BusinessDetail bizDetail) throws JAXRException {
+        return ScoutUddiJaxrHelper.getOrganization(bizDetail, this);
+    }
+
+    Service createService(ServiceInfo serviceInfo) throws JAXRException {
+        String key = serviceInfo.getServiceKey();
+        List<Name> names = serviceInfo.getName();
+        ServiceImpl service = new ServiceImpl(this);
+        service.setKey(createKey(key));
+        if (names != null && names.size() > 0) {
+            service.setName(createInternationalString(names.get(0).getValue()));
+        }
+        return service;
+    }
+}
diff --git a/src/main/java/org/apache/ws/scout/registry/infomodel/ClassificationSchemeImpl.java b/src/main/java/org/apache/ws/scout/registry/infomodel/ClassificationSchemeImpl.java
index 90a6f2a..feeae2e 100644
--- a/src/main/java/org/apache/ws/scout/registry/infomodel/ClassificationSchemeImpl.java
+++ b/src/main/java/org/apache/ws/scout/registry/infomodel/ClassificationSchemeImpl.java
@@ -58,7 +58,7 @@
         childConcepts.add(concept);
     }
 
-    public void addChildConcepts(Collection<Concept> collection)
+    public void addChildConcepts(Collection collection)
             throws JAXRException
     {
         childConcepts.addAll(collection);
diff --git a/src/main/java/org/apache/ws/scout/registry/infomodel/ConceptImpl.java b/src/main/java/org/apache/ws/scout/registry/infomodel/ConceptImpl.java
index f6e0e6b..f8eedfc 100644
--- a/src/main/java/org/apache/ws/scout/registry/infomodel/ConceptImpl.java
+++ b/src/main/java/org/apache/ws/scout/registry/infomodel/ConceptImpl.java
@@ -1,175 +1,172 @@
-/*
- * Copyright 2001-2004 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.ws.scout.registry.infomodel;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Iterator;
-
-import javax.xml.registry.JAXRException;
-import javax.xml.registry.LifeCycleManager;
-import javax.xml.registry.infomodel.ClassificationScheme;
-import javax.xml.registry.infomodel.Concept;
-import javax.xml.registry.infomodel.RegistryObject;
-
-/**
- * Implements JAXR Interface.
- * For futher details, look into the JAXR API Javadoc.
- *
- * @author Anil Saldhana  <anil@apache.org>
- */
-public class ConceptImpl extends RegistryObjectImpl implements Concept
-{
-    private String value = new String();
-
-    private RegistryObject parent = null;
-    private Concept parentconcept = null;
-
-    private ClassificationScheme scheme = null;
-    private Collection<Concept> childconcepts = new ArrayList<Concept>();
-
-    /**
-     * Creates a new instance of ConceptImpl
-     */
-    public ConceptImpl(LifeCycleManager lifeCycleManager)
-    {
-        super(lifeCycleManager);
-    }
-
-    public void addChildConcept(Concept concept)
-    {
-        this.childconcepts.add(concept);
-        ((ConceptImpl)concept).setParentconcept(this);
-    }
-
-    public void addChildConcepts(Collection<Concept> collection)
-    {
-        Iterator iter = collection.iterator();
-        while(iter.hasNext())
-        {
-            Concept c = (Concept)iter.next();
-            ((ConceptImpl)c).setParentconcept(this);
-            childconcepts.add(c);
-        }
-
-    }
-
-    public int getChildConceptCount()
-    {
-        return this.childconcepts.size();
-    }
-
-    public Collection<Concept> getChildrenConcepts()
-    {
-        return this.childconcepts;
-    }
-
-    public ClassificationScheme getClassificationScheme()
-    {
-        return scheme;
-    }
-
-    public Collection<Concept> getDescendantConcepts()
-    {
-        Collection<Concept> coll = new ArrayList<Concept>();
-        Iterator iter = childconcepts.iterator();
-        while(iter != null && iter.hasNext())
-        {
-            ConceptImpl c = (ConceptImpl)iter.next();
-            coll.add(c);
-            coll.addAll(c.getDescendantConcepts());
-        }
-        return coll;
-    }
-
-    public RegistryObject getParent()
-    {
-        return parent;
-    }
-
-    public Concept getParentConcept()
-    {
-        return parentconcept;
-    }
-
-    public String getPath()
-    {
-        return null;
-    }
-
-    public String getValue() throws JAXRException
-    {
-        return value;
-    }
-
-    public void removeChildConcept(Concept c)
-    {
-        ((ConceptImpl)c).setParentconcept(null);
-        childconcepts.remove(c);
-    }
-
-    public void removeChildConcepts(Collection collection)
-    {
-        Iterator iter = collection.iterator();
-        while(iter.hasNext())
-        {
-            Concept c = (Concept)iter.next();
-            ((ConceptImpl)c).setParentconcept(null);
-            childconcepts.add(c);
-        }
-    }
-
-    public void setValue(String str)
-    {
-        value = str;
-    }
-
-    public void setParent(RegistryObject parent)
-    {
-        this.parent = parent;
-    }
-
-    public void setParentconcept(Concept parentconcept)
-    {
-        this.parentconcept = parentconcept;
-        parent = null; //We deal with concept as parent
-    }
-
-    public void setScheme(ClassificationSchemeImpl scheme)
-    {
-        this.scheme = scheme;
-    }
-
-    public void setChildconcepts(Collection<Concept> childconcepts)
-    {
-        this.childconcepts.clear();
-        Iterator iter = childconcepts.iterator();
-        while(iter.hasNext())
-        {
-            Concept c = (Concept)iter.next();
-            ((ConceptImpl)c).setParentconcept(this);
-            childconcepts.add(c);
-        }
-    }
-
-    //Specific API
-    public void setClassificationScheme(ClassificationScheme sc)
-    {
-        scheme = sc;
-        parent = sc;
-    }
-}
+/*
+ * Copyright 2001-2004 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.ws.scout.registry.infomodel;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+
+import javax.xml.registry.JAXRException;
+import javax.xml.registry.LifeCycleManager;
+import javax.xml.registry.infomodel.ClassificationScheme;
+import javax.xml.registry.infomodel.Concept;
+import javax.xml.registry.infomodel.RegistryObject;
+
+/**
+ * Implements JAXR Interface.
+ * For futher details, look into the JAXR API Javadoc.
+ *
+ * @author Anil Saldhana  <anil@apache.org>
+ */
+public class ConceptImpl extends RegistryObjectImpl implements Concept
+{
+    private String value = new String();
+
+    private RegistryObject parent = null;
+    private Concept parentconcept = null;
+
+    private ClassificationScheme scheme = null;
+    private Collection<Concept> childconcepts = new ArrayList<Concept>();
+
+    /**
+     * Creates a new instance of ConceptImpl
+     */
+    public ConceptImpl(LifeCycleManager lifeCycleManager)
+    {
+        super(lifeCycleManager);
+    }
+
+    public void addChildConcept(Concept concept)
+    {
+        this.childconcepts.add(concept);
+        ((ConceptImpl)concept).setParentconcept(this);
+    }
+
+    public void addChildConcepts(Collection collection)
+    {
+        for (Object c : collection) {
+            ((ConceptImpl) c).setParentconcept(this);
+            childconcepts.add((Concept) c);
+        }
+
+    }
+
+    public int getChildConceptCount()
+    {
+        return this.childconcepts.size();                                                                                                           
+    }
+
+    public Collection<Concept> getChildrenConcepts()
+    {
+        return this.childconcepts;
+    }
+
+    public ClassificationScheme getClassificationScheme()
+    {
+        return scheme;
+    }
+
+    public Collection<Concept> getDescendantConcepts()
+    {
+        Collection<Concept> coll = new ArrayList<Concept>();
+        Iterator iter = childconcepts.iterator();
+        while(iter != null && iter.hasNext())
+        {
+            ConceptImpl c = (ConceptImpl)iter.next();
+            coll.add(c);
+            coll.addAll(c.getDescendantConcepts());
+        }
+        return coll;
+    }
+
+    public RegistryObject getParent()
+    {
+        return parent;
+    }
+
+    public Concept getParentConcept()
+    {
+        return parentconcept;
+    }
+
+    public String getPath()
+    {
+        return null;
+    }
+
+    public String getValue() throws JAXRException
+    {
+        return value;
+    }
+
+    public void removeChildConcept(Concept c)
+    {
+        ((ConceptImpl)c).setParentconcept(null);
+        childconcepts.remove(c);
+    }
+
+    public void removeChildConcepts(Collection collection)
+    {
+        Iterator iter = collection.iterator();
+        while(iter.hasNext())
+        {
+            Concept c = (Concept)iter.next();
+            ((ConceptImpl)c).setParentconcept(null);
+            childconcepts.add(c);
+        }
+    }
+
+    public void setValue(String str)
+    {
+        value = str;
+    }
+
+    public void setParent(RegistryObject parent)
+    {
+        this.parent = parent;
+    }
+
+    public void setParentconcept(Concept parentconcept)
+    {
+        this.parentconcept = parentconcept;
+        parent = null; //We deal with concept as parent
+    }
+
+    public void setScheme(ClassificationSchemeImpl scheme)
+    {
+        this.scheme = scheme;
+    }
+
+    public void setChildconcepts(Collection<Concept> childconcepts)
+    {
+        this.childconcepts.clear();
+        Iterator iter = childconcepts.iterator();
+        while(iter.hasNext())
+        {
+            Concept c = (Concept)iter.next();
+            ((ConceptImpl)c).setParentconcept(this);
+            childconcepts.add(c);
+        }
+    }
+
+    //Specific API
+    public void setClassificationScheme(ClassificationScheme sc)
+    {
+        scheme = sc;
+        parent = sc;
+    }
+}
diff --git a/src/main/java/org/apache/ws/scout/registry/infomodel/ExtensibleObjectImpl.java b/src/main/java/org/apache/ws/scout/registry/infomodel/ExtensibleObjectImpl.java
index c4869b8..8f4784a 100644
--- a/src/main/java/org/apache/ws/scout/registry/infomodel/ExtensibleObjectImpl.java
+++ b/src/main/java/org/apache/ws/scout/registry/infomodel/ExtensibleObjectImpl.java
@@ -1,69 +1,68 @@
-/*
- * Copyright 2001-2004 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.ws.scout.registry.infomodel;
-
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-
-import javax.xml.registry.JAXRException;
-import javax.xml.registry.infomodel.ExtensibleObject;
-import javax.xml.registry.infomodel.Slot;
-
-/**
- * Implements JAXR Interface.
- * For futher details, look into the JAXR API Javadoc.
- *
- * @author Anil Saldhana  <anil@apache.org>
- */
-public class ExtensibleObjectImpl implements ExtensibleObject
-{
-    private Map<String,Slot> slots = new HashMap<String,Slot>();
-
-    public void addSlot(Slot slot) throws JAXRException
-    {
-        slots.put(slot.getName(), slot);
-    }
-
-    public void addSlots(Collection slots) throws JAXRException
-    {
-        for (Iterator i = slots.iterator(); i.hasNext();)
-        {
-            addSlot((Slot) i.next());
-        }
-    }
-
-    public Slot getSlot(String slotName)
-    {
-        return (Slot) slots.get(slotName);
-    }
-
-    public Collection<Slot> getSlots()
-    {
-        return slots.values();
-    }
-
-    public void removeSlot(String slotName)
-    {
-        slots.remove(slotName);
-    }
-
-    public void removeSlots(Collection<String> slotNames)
-    {
-        slots.keySet().removeAll(slotNames);
-    }
-}
+/*
+ * Copyright 2001-2004 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.ws.scout.registry.infomodel;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import javax.xml.registry.JAXRException;
+import javax.xml.registry.infomodel.ExtensibleObject;
+import javax.xml.registry.infomodel.Slot;
+
+/**
+ * Implements JAXR Interface.
+ * For futher details, look into the JAXR API Javadoc.
+ *
+ * @author Anil Saldhana  <anil@apache.org>
+ */
+public class ExtensibleObjectImpl implements ExtensibleObject
+{
+    private Map<String,Slot> slots = new HashMap<String,Slot>();
+
+    public void addSlot(Slot slot) throws JAXRException
+    {
+        slots.put(slot.getName(), slot);
+    }
+
+    public void addSlots(Collection slots) throws JAXRException
+    {
+        for (Object slot : slots) {
+            addSlot((Slot) slot);
+        }
+    }
+
+    public Slot getSlot(String slotName)
+    {
+        return (Slot) slots.get(slotName);
+    }
+
+    public Collection<Slot> getSlots()
+    {
+        return slots.values();
+    }
+
+    public void removeSlot(String slotName)
+    {
+        slots.remove(slotName);
+    }
+
+    public void removeSlots(Collection slotNames)
+    {
+        slots.keySet().removeAll(slotNames);
+    }
+}
diff --git a/src/main/java/org/apache/ws/scout/registry/infomodel/OrganizationImpl.java b/src/main/java/org/apache/ws/scout/registry/infomodel/OrganizationImpl.java
index dcfbe97..d74608d 100644
--- a/src/main/java/org/apache/ws/scout/registry/infomodel/OrganizationImpl.java
+++ b/src/main/java/org/apache/ws/scout/registry/infomodel/OrganizationImpl.java
@@ -1,283 +1,281 @@
-/*
- * Copyright 2001-2004 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.ws.scout.registry.infomodel;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Set;
-
-import javax.xml.registry.JAXRException;
-import javax.xml.registry.LifeCycleManager;
-import javax.xml.registry.UnsupportedCapabilityException;
-import javax.xml.registry.infomodel.Organization;
-import javax.xml.registry.infomodel.PostalAddress;
-import javax.xml.registry.infomodel.Service;
-import javax.xml.registry.infomodel.TelephoneNumber;
-import javax.xml.registry.infomodel.User;
-
-/**
- * Organization Interface
- * * Implements JAXR Interface.
- * For futher details, look into the JAXR API Javadoc.
- *
- * @author <a href="mailto:anil@apache.org">Anil Saldhana</a>
- * @author <a href="mailto:geirm@apache.org">Geir Magnusson Jr.</a>
- */
-public class OrganizationImpl extends RegistryObjectImpl implements Organization
-{
-    private User primaryContact;
-    private Set<User> users = new HashSet<User>();
-    private Set<TelephoneNumber> telephoneNumbers = new HashSet<TelephoneNumber>();
-    private Collection<Service> services = new ArrayList<Service>();
-
-    public OrganizationImpl(LifeCycleManager lifeCycleManager)
-    {
-        super(lifeCycleManager);
-    }
-
-    public User getPrimaryContact() throws JAXRException
-    {
-        //TODO: How do we fix this? Run JAXRQueryTest and you will hit this problem.
-        //
-        //  gmj : I think I fixed w/ primary contact hack...
-        //
-        //if (primaryContact == null) {
-        //    throw new IllegalStateException("primaryContact is null and the spec says we cannot return a null value");
-        //}
-        return primaryContact;
-    }
-
-    public void setPrimaryContact(User user) throws JAXRException
-    {
-        if (user == null)
-        {
-            throw new IllegalArgumentException("primaryContact must not be null");
-        }
-
-        /*
-         * first check to see if user already exists in user set
-         */
-
-        primaryContact = user;
-
-        if (!users.contains(user)) {
-            addUser(user);
-        }
-    }
-
-    public void addUser(User user) throws JAXRException
-    {
-        doPrimaryContactHack(user);
-
-        users.add(user);
-        ((UserImpl) user).setOrganization(this);
-    }
-
-    /**
-     *
-     *  to solve the getPrimaryContactProblem(), if we have no defined
-     *  primaryContact, we'll designate the first user as such
-     *
-     * @param user
-     */
-    private void doPrimaryContactHack(User user) {
-
-        if (primaryContact == null && users.size() == 0) {
-            primaryContact = user;
-        }
-    }
-
-    public void addUsers(Collection collection) throws JAXRException
-    {
-        // do this by hand to ensure all members are actually instances of User
-        for (Iterator iterator = collection.iterator(); iterator.hasNext();)
-        {
-            User user = (User) iterator.next();
-            addUser(user);
-        }
-    }
-
-    public Collection<User> getUsers() throws JAXRException
-    {
-        return users;
-    }
-
-    public void removeUser(User user) throws JAXRException
-    {
-        if (user != null) {
-            users.remove(user);
-        }
-
-        /*
-         * more primaryContact hakiness - nothing says that you can't
-         * remove the user that is the PC...
-         */
-
-        if (!users.contains(primaryContact)) {
-            primaryContact = null;
-        }
-    }
-
-    public void removeUsers(Collection collection) throws JAXRException
-    {
-        if (collection != null) {
-            users.removeAll(collection);
-        }
-
-        /*
-         * more primaryContact hakiness - nothing says that you can't
-         * remove the user that is the PC...
-         */
-
-        if (!users.contains(primaryContact)) {
-            primaryContact = null;
-        }
-
-    }
-
-    public Collection<TelephoneNumber> getTelephoneNumbers(String phoneType) throws JAXRException
-    {
-        Set<TelephoneNumber> filteredNumbers;
-        if (phoneType == null)
-        {
-            filteredNumbers = telephoneNumbers;
-        } else
-        {
-            filteredNumbers = new HashSet<TelephoneNumber>(telephoneNumbers.size());
-            for (Iterator i = telephoneNumbers.iterator(); i.hasNext();)
-            {
-                TelephoneNumber number = (TelephoneNumber) i.next();
-                if (phoneType.equals(number.getType()))
-                {
-                    filteredNumbers.add(number);
-                }
-            }
-        }
-        return filteredNumbers;
-    }
-
-    public void setTelephoneNumbers(Collection<TelephoneNumber> collection) throws JAXRException
-    {
-        // do this by hand to ensure all members are actually instances of TelephoneNumber
-        Set<TelephoneNumber> numbers = new HashSet<TelephoneNumber>(collection.size());
-        for (Iterator i = collection.iterator(); i.hasNext();)
-        {
-            TelephoneNumber number = (TelephoneNumber) i.next();
-            numbers.add(number);
-        }
-        this.telephoneNumbers = numbers;
-    }
-
-    public void addService(Service service) throws JAXRException
-    {
-        services.add(service);
-
-        /*
-         * we need to tell the service who it's organization is so
-         * we can set the UDDI Business Key...
-         */
-
-        service.setProvidingOrganization(this);
-    }
-
-    public void addServices(Collection collection) throws JAXRException
-    {
-        // do this by hand to ensure all members are actually instances of Service
-        for (Iterator iterator = collection.iterator(); iterator.hasNext();)
-        {
-            Service service = (Service) iterator.next();
-
-            addService(service);
-        }
-    }
-
-    public Collection<Service> getServices() throws JAXRException
-    {
-        return services;
-    }
-
-    public void removeService(Service service) throws JAXRException
-    {
-    	services.remove(service);
-    }
-
-    public void removeServices(Collection collection) throws JAXRException
-    {
-        services.removeAll(collection);
-    }
-
-    ///////////////////////////////////////////////////////////////////////////
-    // Level 1 features must throw exceptions
-    ///////////////////////////////////////////////////////////////////////////
-
-    public Organization getParentOrganization() throws JAXRException
-    {
-        throw new UnsupportedCapabilityException("Level 1 feature");
-    }
-
-    public Collection<Organization> getDescendantOrganizations() throws JAXRException
-    {
-        throw new UnsupportedCapabilityException("Level 1 feature");
-    }
-
-    public Organization getRootOrganization() throws JAXRException
-    {
-        throw new UnsupportedCapabilityException("Level 1 feature");
-    }
-
-    public void addChildOrganization(Organization organization) throws JAXRException
-    {
-        throw new UnsupportedCapabilityException("Level 1 feature");
-    }
-
-    public void addChildOrganizations(Collection collection) throws JAXRException
-    {
-        throw new UnsupportedCapabilityException("Level 1 feature");
-    }
-
-    public int getChildOrganizationCount() throws JAXRException
-    {
-        throw new UnsupportedCapabilityException("Level 1 feature");
-    }
-
-    public Collection<Organization> getChildOrganizations() throws JAXRException
-    {
-        throw new UnsupportedCapabilityException("Level 1 feature");
-    }
-
-    public void removeChildOrganization(Organization organization) throws JAXRException
-    {
-        throw new UnsupportedCapabilityException("Level 1 feature");
-    }
-
-    public void removeChildOrganizations(Collection collection) throws JAXRException
-    {
-        throw new UnsupportedCapabilityException("Level 1 feature");
-    }
-
-    public PostalAddress getPostalAddress() throws JAXRException
-    {
-        throw new UnsupportedCapabilityException("Level 1 feature");
-    }
-
-    public void setPostalAddress(PostalAddress postalAddress) throws JAXRException
-    {
-        throw new UnsupportedCapabilityException("Level 1 feature");
-    }
-}
+/*
+ * Copyright 2001-2004 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.ws.scout.registry.infomodel;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+
+import javax.xml.registry.JAXRException;
+import javax.xml.registry.LifeCycleManager;
+import javax.xml.registry.UnsupportedCapabilityException;
+import javax.xml.registry.infomodel.Organization;
+import javax.xml.registry.infomodel.PostalAddress;
+import javax.xml.registry.infomodel.Service;
+import javax.xml.registry.infomodel.TelephoneNumber;
+import javax.xml.registry.infomodel.User;
+
+/**
+ * Organization Interface
+ * * Implements JAXR Interface.
+ * For futher details, look into the JAXR API Javadoc.
+ *
+ * @author <a href="mailto:anil@apache.org">Anil Saldhana</a>
+ * @author <a href="mailto:geirm@apache.org">Geir Magnusson Jr.</a>
+ */
+public class OrganizationImpl extends RegistryObjectImpl implements Organization
+{
+    private User primaryContact;
+    private Set<User> users = new HashSet<User>();
+    private Set<TelephoneNumber> telephoneNumbers = new HashSet<TelephoneNumber>();
+    private Collection<Service> services = new ArrayList<Service>();
+
+    public OrganizationImpl(LifeCycleManager lifeCycleManager)
+    {
+        super(lifeCycleManager);
+    }
+
+    public User getPrimaryContact() throws JAXRException
+    {
+        //TODO: How do we fix this? Run JAXRQueryTest and you will hit this problem.
+        //
+        //  gmj : I think I fixed w/ primary contact hack...
+        //
+        //if (primaryContact == null) {
+        //    throw new IllegalStateException("primaryContact is null and the spec says we cannot return a null value");
+        //}
+        return primaryContact;
+    }
+
+    public void setPrimaryContact(User user) throws JAXRException
+    {
+        if (user == null)
+        {
+            throw new IllegalArgumentException("primaryContact must not be null");
+        }
+
+        /*
+         * first check to see if user already exists in user set
+         */
+
+        primaryContact = user;
+
+        if (!users.contains(user)) {
+            addUser(user);
+        }
+    }
+
+    public void addUser(User user) throws JAXRException
+    {
+        doPrimaryContactHack(user);
+
+        users.add(user);
+        ((UserImpl) user).setOrganization(this);
+    }
+
+    /**
+     *
+     *  to solve the getPrimaryContactProblem(), if we have no defined
+     *  primaryContact, we'll designate the first user as such
+     *
+     * @param user
+     */
+    private void doPrimaryContactHack(User user) {
+
+        if (primaryContact == null && users.size() == 0) {
+            primaryContact = user;
+        }
+    }
+
+    public void addUsers(Collection collection) throws JAXRException
+    {
+        // do this by hand to ensure all members are actually instances of User
+        for (Iterator iterator = collection.iterator(); iterator.hasNext();)
+        {
+            User user = (User) iterator.next();
+            addUser(user);
+        }
+    }
+
+    public Collection<User> getUsers() throws JAXRException
+    {
+        return users;
+    }
+
+    public void removeUser(User user) throws JAXRException
+    {
+        if (user != null) {
+            users.remove(user);
+        }
+
+        /*
+         * more primaryContact hakiness - nothing says that you can't
+         * remove the user that is the PC...
+         */
+
+        if (!users.contains(primaryContact)) {
+            primaryContact = null;
+        }
+    }
+
+    public void removeUsers(Collection collection) throws JAXRException
+    {
+        if (collection != null) {
+            users.removeAll(collection);
+        }
+
+        /*
+         * more primaryContact hakiness - nothing says that you can't
+         * remove the user that is the PC...
+         */
+
+        if (!users.contains(primaryContact)) {
+            primaryContact = null;
+        }
+
+    }
+
+    public Collection<TelephoneNumber> getTelephoneNumbers(String phoneType) throws JAXRException
+    {
+        Set<TelephoneNumber> filteredNumbers;
+        if (phoneType == null)
+        {
+            filteredNumbers = telephoneNumbers;
+        } else
+        {
+            filteredNumbers = new HashSet<TelephoneNumber>(telephoneNumbers.size());
+            for (Iterator i = telephoneNumbers.iterator(); i.hasNext();)
+            {
+                TelephoneNumber number = (TelephoneNumber) i.next();
+                if (phoneType.equals(number.getType()))
+                {
+                    filteredNumbers.add(number);
+                }
+            }
+        }
+        return filteredNumbers;
+    }
+
+    public void setTelephoneNumbers(Collection collection) throws JAXRException
+    {
+        // do this by hand to ensure all members are actually instances of TelephoneNumber
+        Set<TelephoneNumber> numbers = new HashSet<TelephoneNumber>(collection.size());
+        for (Object number : collection) {
+            numbers.add((TelephoneNumber) number);
+        }
+        this.telephoneNumbers = numbers;
+    }
+
+    public void addService(Service service) throws JAXRException
+    {
+        services.add(service);
+
+        /*
+         * we need to tell the service who it's organization is so
+         * we can set the UDDI Business Key...
+         */
+
+        service.setProvidingOrganization(this);
+    }
+
+    public void addServices(Collection collection) throws JAXRException
+    {
+        // do this by hand to ensure all members are actually instances of Service
+        for (Iterator iterator = collection.iterator(); iterator.hasNext();)
+        {
+            Service service = (Service) iterator.next();
+
+            addService(service);
+        }
+    }
+
+    public Collection<Service> getServices() throws JAXRException
+    {
+        return services;
+    }
+
+    public void removeService(Service service) throws JAXRException
+    {
+    	services.remove(service);
+    }
+
+    public void removeServices(Collection collection) throws JAXRException
+    {
+        services.removeAll(collection);
+    }
+
+    ///////////////////////////////////////////////////////////////////////////
+    // Level 1 features must throw exceptions
+    ///////////////////////////////////////////////////////////////////////////
+
+    public Organization getParentOrganization() throws JAXRException
+    {
+        throw new UnsupportedCapabilityException("Level 1 feature");
+    }
+
+    public Collection<Organization> getDescendantOrganizations() throws JAXRException
+    {
+        throw new UnsupportedCapabilityException("Level 1 feature");
+    }
+
+    public Organization getRootOrganization() throws JAXRException
+    {
+        throw new UnsupportedCapabilityException("Level 1 feature");
+    }
+
+    public void addChildOrganization(Organization organization) throws JAXRException
+    {
+        throw new UnsupportedCapabilityException("Level 1 feature");
+    }
+
+    public void addChildOrganizations(Collection collection) throws JAXRException
+    {
+        throw new UnsupportedCapabilityException("Level 1 feature");
+    }
+
+    public int getChildOrganizationCount() throws JAXRException
+    {
+        throw new UnsupportedCapabilityException("Level 1 feature");
+    }
+
+    public Collection<Organization> getChildOrganizations() throws JAXRException
+    {
+        throw new UnsupportedCapabilityException("Level 1 feature");
+    }
+
+    public void removeChildOrganization(Organization organization) throws JAXRException
+    {
+        throw new UnsupportedCapabilityException("Level 1 feature");
+    }
+
+    public void removeChildOrganizations(Collection collection) throws JAXRException
+    {
+        throw new UnsupportedCapabilityException("Level 1 feature");
+    }
+
+    public PostalAddress getPostalAddress() throws JAXRException
+    {
+        throw new UnsupportedCapabilityException("Level 1 feature");
+    }
+
+    public void setPostalAddress(PostalAddress postalAddress) throws JAXRException
+    {
+        throw new UnsupportedCapabilityException("Level 1 feature");
+    }
+}
diff --git a/src/main/java/org/apache/ws/scout/registry/infomodel/RegistryObjectImpl.java b/src/main/java/org/apache/ws/scout/registry/infomodel/RegistryObjectImpl.java
index 8035c31..1f67665 100644
--- a/src/main/java/org/apache/ws/scout/registry/infomodel/RegistryObjectImpl.java
+++ b/src/main/java/org/apache/ws/scout/registry/infomodel/RegistryObjectImpl.java
@@ -1,355 +1,339 @@
-/*
- * Copyright 2001-2004 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.ws.scout.registry.infomodel;
-
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Set;
-
-import javax.xml.registry.JAXRException;
-import javax.xml.registry.LifeCycleManager;
-import javax.xml.registry.UnsupportedCapabilityException;
-import javax.xml.registry.infomodel.Association;
-import javax.xml.registry.infomodel.Classification;
-import javax.xml.registry.infomodel.Concept;
-import javax.xml.registry.infomodel.ExternalIdentifier;
-import javax.xml.registry.infomodel.ExternalLink;
-import javax.xml.registry.infomodel.InternationalString;
-import javax.xml.registry.infomodel.Key;
-import javax.xml.registry.infomodel.Organization;
-import javax.xml.registry.infomodel.RegistryObject;
-
-/**
- * Implements  RegistryObject Interface
- * Implements JAXR Interface.
- * For futher details, look into the JAXR API Javadoc.
- *
- * @author <a href="mailto:anil@apache.org">Anil Saldhana</a>
- * @author <a href="mailto:geirm@apache.org">Geir Magnusson Jr.</a>
- */
-public class RegistryObjectImpl extends ExtensibleObjectImpl implements RegistryObject
-{
-    private final LifeCycleManager lifeCycleManager;
-    private Key key;
-    private InternationalString name = new InternationalStringImpl();
-    private InternationalString desc = new InternationalStringImpl();
-
-    private Set<Classification> classifications = new HashSet<Classification>();
-    private Set<Association> associations = new HashSet<Association>();
-    private Set<ExternalIdentifier> externalIds = new HashSet<ExternalIdentifier>();
-    private Set<ExternalLink> externalLinks = new HashSet<ExternalLink>();
-
-    private OrganizationImpl submittingOrganization;
-
-    public RegistryObjectImpl(LifeCycleManager lifeCycleManager)
-    {
-        this.lifeCycleManager = lifeCycleManager;
-    }
-
-    public RegistryObjectImpl(LifeCycleManager lifeCycleManager, InternationalString n)
-    {
-        this.lifeCycleManager = lifeCycleManager;
-        name = n;
-    }
-
-    public Key getKey()
-    {
-        return key;
-    }
-
-    public InternationalString getDescription()
-    {
-        return desc;
-    }
-
-    public void setDescription(InternationalString description)
-    {
-        this.desc = description;
-    }
-
-    public InternationalString getName()
-    {
-        return name;
-    }
-
-    public void setName(InternationalString name)
-    {
-        this.name = name;
-    }
-
-    public void setKey(Key k)
-    {
-        key = k;
-    }
-
-    public String toXML() throws JAXRException
-    {
-        throw new UnsupportedCapabilityException("toXML is not supported");
-    }
-
-    public void addClassification(Classification classification)
-    {
-        classifications.add(classification);
-    }
-
-    public void addClassifications(Collection collection)
-    {
-        if (collection!=null) {
-            for (Iterator i = collection.iterator(); i.hasNext();)
-            {
-                Classification classification = (Classification) i.next();
-                classifications.add(classification);
-            }
-        }
-    }
-
-    public void removeClassification(Classification classification)
-    {
-        classifications.remove(classification);
-    }
-
-    public void removeClassifications(Collection<Classification> collection)
-    {
-        classifications.removeAll(collection);
-    }
-
-    public Collection getClassifications()
-    {
-        return Collections.unmodifiableSet(classifications);
-    }
-
-    public void setClassifications(Collection<Classification> collection)
-    {
-        Set<Classification> newClassifications = new HashSet<Classification>(collection.size());
-        for (Iterator i = collection.iterator(); i.hasNext();)
-        {
-            Classification classification = (Classification) i.next();
-            newClassifications.add(classification);
-        }
-        classifications = newClassifications;
-    }
-
-    /**
-     *  Adds specified Association to use this object as source.
-     *  Silently replaces the sourceObject in Association with
-     *  reference to this object.
-     *
-     * @param association
-     * @throws JAXRException
-     */
-    public void addAssociation(Association association)
-        throws JAXRException
-    {
-        associations.add(association);
-
-        association.setSourceObject(this);
-    }
-
-    public void addAssociations(Collection collection) throws JAXRException
-    {
-        for (Iterator i = collection.iterator(); i.hasNext();)
-        {
-            Association association = (Association) i.next();
-
-            addAssociation(association);
-        }
-    }
-
-    public Collection<Association> getAssociations() throws JAXRException
-    {
-        return Collections.unmodifiableSet(associations);
-    }
-
-    public void setAssociations(Collection collection)
-    {
-        Set<Association> newAssociations = new HashSet<Association>(collection.size());
-        for (Iterator i = collection.iterator(); i.hasNext();)
-        {
-            Association association = (Association) i.next();
-            newAssociations.add(association);
-        }
-        associations = newAssociations;
-    }
-
-    public void removeAssociation(Association association)
-    {
-        associations.remove(association);
-    }
-
-    public void removeAssociations(Collection collection)
-    {
-        associations.removeAll(collection);
-    }
-
-    public void addExternalIdentifier(ExternalIdentifier externalIdentifier)
-    {
-        externalIds.add(externalIdentifier);
-        ((ExternalIdentifierImpl) externalIdentifier).setRegistryObject(this);
-    }
-
-    public void addExternalIdentifiers(Collection<ExternalIdentifier> collection)
-    {
-        if (collection!=null) {
-            for (Iterator i = collection.iterator(); i.hasNext();)
-            {
-                ExternalIdentifier externalId = (ExternalIdentifier) i.next();
-                externalIds.add(externalId);
-                ((ExternalIdentifierImpl) externalId).setRegistryObject(this);
-            }
-        }
-    }
-
-    public void removeExternalIdentifier(ExternalIdentifier externalIdentifier)
-    {
-        externalIds.remove(externalIdentifier);
-        ((ExternalIdentifierImpl) externalIdentifier).setRegistryObject(null);
-    }
-
-    public void removeExternalIdentifiers(Collection collection)
-    {
-        //Lets clear out the reference to this in the ext id
-        Iterator iter = collection.iterator();
-        while (iter != null && iter.hasNext())
-        {
-            ExternalIdentifier externalId = (ExternalIdentifier) iter.next();
-            ((ExternalIdentifierImpl) externalId).setRegistryObject(null);
-        }
-        externalIds.removeAll(collection);
-    }
-
-    public Collection<ExternalIdentifier> getExternalIdentifiers()
-    {
-        return Collections.unmodifiableSet(externalIds);
-    }
-
-    public void setExternalIdentifiers(Collection<ExternalIdentifier> collection)
-    {
-        Set<ExternalIdentifier> newExternalIds = new HashSet<ExternalIdentifier>(collection.size());
-        for (Iterator i = collection.iterator(); i.hasNext();)
-        {
-            ExternalIdentifier externalId = (ExternalIdentifier) i.next();
-            newExternalIds.add(externalId);
-        }
-        externalIds = newExternalIds;
-    }
-
-    public void addExternalLink(ExternalLink externalLink)
-    {
-        externalLinks.add(externalLink);
-        ((ExternalLinkImpl) externalLink).addLinkedObject(this);
-    }
-
-    public void addExternalLinks(Collection<ExternalLink> collection)
-    {
-        for (Iterator i = collection.iterator(); i.hasNext();)
-        {
-            ExternalLink externalLink = (ExternalLink) i.next();
-            externalLinks.add(externalLink);
-            ((ExternalLinkImpl) externalLink).addLinkedObject(this);
-        }
-    }
-
-    public void removeExternalLink(ExternalLink externalLink)
-    {
-        ((ExternalLinkImpl) externalLink).removeLinkedObject(this);
-        externalLinks.remove(externalLink);
-    }
-
-    public void removeExternalLinks(Collection collection)
-    {
-        Iterator iter = collection.iterator();
-        while (iter != null && iter.hasNext())
-        {
-            ExternalLink externalLink = (ExternalLink) iter.next();
-            ((ExternalLinkImpl) externalLink).removeLinkedObject(this);
-        }
-        externalLinks.removeAll(collection);
-    }
-
-    public Collection<ExternalLink> getExternalLinks()
-    {
-        return Collections.unmodifiableSet(externalLinks);
-    }
-
-    public void setExternalLinks(Collection<ExternalLink> collection)
-    {
-        Set<ExternalLink> newExternalLinks = new HashSet<ExternalLink>(collection.size());
-        for (Iterator i = collection.iterator(); i.hasNext();)
-        {
-            ExternalLink externalLink = (ExternalLink) i.next();
-            newExternalLinks.add(externalLink);
-        }
-        externalLinks = newExternalLinks;
-    }
-
-    public Organization getSubmittingOrganization()
-    {
-        return submittingOrganization;
-    }
-
-    public LifeCycleManager getLifeCycleManager()
-    {
-        return lifeCycleManager;
-    }
-
-    /**
-     * The spec does not define how equality is defined for RegistryObject's.
-     * We choose to define it as having the same class and key value; if the
-     * key is null then the objects are not equal.
-     *
-     * @param obj the object to compare to
-     * @return true if the other object is of the same class and has the same key value
-     */
-    public boolean equals(Object obj)
-    {
-        if (obj == this) return true;
-        if (obj == null || !this.getClass().equals(obj.getClass())) return false;
-        final RegistryObjectImpl other = (RegistryObjectImpl) obj;
-        return this.key != null && key.equals(other.key);
-    }
-
-    public int hashCode()
-    {
-        return key == null ? 0 : key.hashCode();
-    }
-
-    ///////////////////////////////////////////////////////////////////////////
-    // Level 1 features must throw exceptions
-    ///////////////////////////////////////////////////////////////////////////
-
-    public Collection getAuditTrail() throws JAXRException
-    {
-        throw new UnsupportedCapabilityException("Level 1 feature");
-    }
-
-    public Collection getAssociatedObjects() throws JAXRException
-    {
-        throw new UnsupportedCapabilityException("Level 1 feature");
-    }
-
-    public Concept getObjectType() throws JAXRException
-    {
-        throw new UnsupportedCapabilityException("Level 1 feature");
-    }
-
-    public Collection getRegistryPackages() throws JAXRException
-    {
-        throw new UnsupportedCapabilityException("Level 1 feature");
-    }
-}
+/*
+ * Copyright 2001-2004 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.ws.scout.registry.infomodel;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+
+import javax.xml.registry.JAXRException;
+import javax.xml.registry.LifeCycleManager;
+import javax.xml.registry.UnsupportedCapabilityException;
+import javax.xml.registry.infomodel.Association;
+import javax.xml.registry.infomodel.Classification;
+import javax.xml.registry.infomodel.Concept;
+import javax.xml.registry.infomodel.ExternalIdentifier;
+import javax.xml.registry.infomodel.ExternalLink;
+import javax.xml.registry.infomodel.InternationalString;
+import javax.xml.registry.infomodel.Key;
+import javax.xml.registry.infomodel.Organization;
+import javax.xml.registry.infomodel.RegistryObject;
+
+/**
+ * Implements  RegistryObject Interface
+ * Implements JAXR Interface.
+ * For futher details, look into the JAXR API Javadoc.
+ *
+ * @author <a href="mailto:anil@apache.org">Anil Saldhana</a>
+ * @author <a href="mailto:geirm@apache.org">Geir Magnusson Jr.</a>
+ */
+public class RegistryObjectImpl extends ExtensibleObjectImpl implements RegistryObject
+{
+    private final LifeCycleManager lifeCycleManager;
+    private Key key;
+    private InternationalString name = new InternationalStringImpl();
+    private InternationalString desc = new InternationalStringImpl();
+
+    private Set<Classification> classifications = new HashSet<Classification>();
+    private Set<Association> associations = new HashSet<Association>();
+    private Set<ExternalIdentifier> externalIds = new HashSet<ExternalIdentifier>();
+    private Set<ExternalLink> externalLinks = new HashSet<ExternalLink>();
+
+    //TODO never assigned
+    private OrganizationImpl submittingOrganization;
+
+    public RegistryObjectImpl(LifeCycleManager lifeCycleManager)
+    {
+        this.lifeCycleManager = lifeCycleManager;
+    }
+
+    public RegistryObjectImpl(LifeCycleManager lifeCycleManager, InternationalString n)
+    {
+        this.lifeCycleManager = lifeCycleManager;
+        name = n;
+    }
+
+    public Key getKey()
+    {
+        return key;
+    }
+
+    public InternationalString getDescription()
+    {
+        return desc;
+    }
+
+    public void setDescription(InternationalString description)
+    {
+        this.desc = description;
+    }
+
+    public InternationalString getName()
+    {
+        return name;
+    }
+
+    public void setName(InternationalString name)
+    {
+        this.name = name;
+    }
+
+    public void setKey(Key k)
+    {
+        key = k;
+    }
+
+    public String toXML() throws JAXRException
+    {
+        throw new UnsupportedCapabilityException("toXML is not supported");
+    }
+
+    public void addClassification(Classification classification)
+    {
+        classifications.add(classification);
+    }
+
+    public void addClassifications(Collection collection)
+    {
+        if (collection!=null) {
+            for (Object classification : collection) {
+                classifications.add((Classification)classification);
+            }
+        }
+    }
+
+    public void removeClassification(Classification classification)
+    {
+        classifications.remove(classification);
+    }
+
+    public void removeClassifications(Collection collection)
+    {
+        classifications.removeAll(collection);
+    }
+
+    public Collection getClassifications()
+    {
+        return Collections.unmodifiableSet(classifications);
+    }
+
+    public void setClassifications(Collection collection)
+    {
+        Set<Classification> newClassifications = new HashSet<Classification>(collection.size());
+        for (Object classification : collection) {
+            newClassifications.add((Classification) classification);
+        }
+        classifications = newClassifications;
+    }
+
+    /**
+     *  Adds specified Association to use this object as source.
+     *  Silently replaces the sourceObject in Association with
+     *  reference to this object.
+     *
+     * @param association association to add
+     * @throws JAXRException
+     */
+    public void addAssociation(Association association)
+        throws JAXRException
+    {
+        associations.add(association);
+
+        association.setSourceObject(this);
+    }
+
+    public void addAssociations(Collection collection) throws JAXRException
+    {
+        for (Object association : collection) {
+            addAssociation((Association) association);
+        }
+    }
+
+    public Collection<Association> getAssociations() throws JAXRException
+    {
+        return Collections.unmodifiableSet(associations);
+    }
+
+    public void setAssociations(Collection collection)
+    {
+        Set<Association> newAssociations = new HashSet<Association>(collection.size());
+        for (Object association : collection) {
+            newAssociations.add((Association) association);
+        }
+        associations = newAssociations;
+    }
+
+    public void removeAssociation(Association association)
+    {
+        associations.remove(association);
+    }
+
+    public void removeAssociations(Collection collection)
+    {
+        associations.removeAll(collection);
+    }
+
+    public void addExternalIdentifier(ExternalIdentifier externalIdentifier)
+    {
+        externalIds.add(externalIdentifier);
+        ((ExternalIdentifierImpl) externalIdentifier).setRegistryObject(this);
+    }
+
+    public void addExternalIdentifiers(Collection collection)
+    {
+        if (collection!=null) {
+            for (Object externalId : collection) {
+                externalIds.add((ExternalIdentifier) externalId);
+                ((ExternalIdentifierImpl) externalId).setRegistryObject(this);
+            }
+        }
+    }
+
+    public void removeExternalIdentifier(ExternalIdentifier externalIdentifier)
+    {
+        externalIds.remove(externalIdentifier);
+        ((ExternalIdentifierImpl) externalIdentifier).setRegistryObject(null);
+    }
+
+    public void removeExternalIdentifiers(Collection collection)
+    {
+        //Lets clear out the reference to this in the ext id
+        Iterator iter = collection.iterator();
+        while (iter != null && iter.hasNext())
+        {
+            ExternalIdentifier externalId = (ExternalIdentifier) iter.next();
+            ((ExternalIdentifierImpl) externalId).setRegistryObject(null);
+        }
+        externalIds.removeAll(collection);
+    }
+
+    public Collection<ExternalIdentifier> getExternalIdentifiers()
+    {
+        return Collections.unmodifiableSet(externalIds);
+    }
+
+    public void setExternalIdentifiers(Collection collection)
+    {
+        Set<ExternalIdentifier> newExternalIds = new HashSet<ExternalIdentifier>(collection.size());
+        for (Object externalId : collection) {
+            newExternalIds.add((ExternalIdentifier) externalId);
+        }
+        externalIds = newExternalIds;
+    }
+
+    public void addExternalLink(ExternalLink externalLink)
+    {
+        externalLinks.add(externalLink);
+        ((ExternalLinkImpl) externalLink).addLinkedObject(this);
+    }
+
+    public void addExternalLinks(Collection collection)
+    {
+        for (Object externalLink : collection) {
+            externalLinks.add((ExternalLink) externalLink);
+            ((ExternalLinkImpl) externalLink).addLinkedObject(this);
+        }
+    }
+
+    public void removeExternalLink(ExternalLink externalLink)
+    {
+        ((ExternalLinkImpl) externalLink).removeLinkedObject(this);
+        externalLinks.remove(externalLink);
+    }
+
+    public void removeExternalLinks(Collection collection)
+    {
+        Iterator iter = collection.iterator();
+        while (iter != null && iter.hasNext())
+        {
+            ExternalLink externalLink = (ExternalLink) iter.next();
+            ((ExternalLinkImpl) externalLink).removeLinkedObject(this);
+        }
+        externalLinks.removeAll(collection);
+    }
+
+    public Collection<ExternalLink> getExternalLinks()
+    {
+        return Collections.unmodifiableSet(externalLinks);
+    }
+
+    public void setExternalLinks(Collection collection)
+    {
+        Set<ExternalLink> newExternalLinks = new HashSet<ExternalLink>(collection.size());
+        for (Object externalLink : collection) {
+            newExternalLinks.add((ExternalLink) externalLink);
+        }
+        externalLinks = newExternalLinks;
+    }
+
+    public Organization getSubmittingOrganization()
+    {
+        return submittingOrganization;
+    }
+
+    public LifeCycleManager getLifeCycleManager()
+    {
+        return lifeCycleManager;
+    }
+
+    /**
+     * The spec does not define how equality is defined for RegistryObject's.
+     * We choose to define it as having the same class and key value; if the
+     * key is null then the objects are not equal.
+     *
+     * @param obj the object to compare to
+     * @return true if the other object is of the same class and has the same key value
+     */
+    public boolean equals(Object obj)
+    {
+        if (obj == this) return true;
+        if (obj == null || !this.getClass().equals(obj.getClass())) return false;
+        final RegistryObjectImpl other = (RegistryObjectImpl) obj;
+        return this.key != null && key.equals(other.key);
+    }
+
+    public int hashCode()
+    {
+        return key == null ? 0 : key.hashCode();
+    }
+
+    ///////////////////////////////////////////////////////////////////////////
+    // Level 1 features must throw exceptions
+    ///////////////////////////////////////////////////////////////////////////
+
+    public Collection getAuditTrail() throws JAXRException
+    {
+        throw new UnsupportedCapabilityException("Level 1 feature");
+    }
+
+    public Collection getAssociatedObjects() throws JAXRException
+    {
+        throw new UnsupportedCapabilityException("Level 1 feature");
+    }
+
+    public Concept getObjectType() throws JAXRException
+    {
+        throw new UnsupportedCapabilityException("Level 1 feature");
+    }
+
+    public Collection getRegistryPackages() throws JAXRException
+    {
+        throw new UnsupportedCapabilityException("Level 1 feature");
+    }
+}
diff --git a/src/main/java/org/apache/ws/scout/registry/infomodel/ServiceBindingImpl.java b/src/main/java/org/apache/ws/scout/registry/infomodel/ServiceBindingImpl.java
index 37dbbd4..42f957f 100644
--- a/src/main/java/org/apache/ws/scout/registry/infomodel/ServiceBindingImpl.java
+++ b/src/main/java/org/apache/ws/scout/registry/infomodel/ServiceBindingImpl.java
@@ -98,7 +98,7 @@
         links.remove(link);
     }
 
-    public void removeSpecificationLinks(Collection<SpecificationLink> col) throws JAXRException
+    public void removeSpecificationLinks(Collection col) throws JAXRException
     {
         links.removeAll(col);
     }
diff --git a/src/main/java/org/apache/ws/scout/registry/infomodel/SlotImpl.java b/src/main/java/org/apache/ws/scout/registry/infomodel/SlotImpl.java
index 767098e..9781268 100644
--- a/src/main/java/org/apache/ws/scout/registry/infomodel/SlotImpl.java
+++ b/src/main/java/org/apache/ws/scout/registry/infomodel/SlotImpl.java
@@ -66,7 +66,7 @@
         slotType = s;
     }
 
-    public void setValues(Collection<String> collection) throws JAXRException
+    public void setValues(Collection collection) throws JAXRException
     {
         if (collection == null)
         {
diff --git a/src/main/java/org/apache/ws/scout/util/ScoutJaxrUddiHelper.java b/src/main/java/org/apache/ws/scout/util/ScoutJaxrUddiHelper.java
index 255aee7..9ffc7dd 100644
--- a/src/main/java/org/apache/ws/scout/util/ScoutJaxrUddiHelper.java
+++ b/src/main/java/org/apache/ws/scout/util/ScoutJaxrUddiHelper.java
@@ -16,10 +16,7 @@
  */
 package org.apache.ws.scout.util;
 
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.StringTokenizer;
+import java.util.*;
 
 import javax.xml.registry.JAXRException;
 import javax.xml.registry.infomodel.Association;
@@ -195,16 +192,9 @@
               bt.setServiceKey(svc.getKey().getId());
            }
 			
-			InternationalString idesc = ((RegistryObject) serviceBinding).getDescription();
+			InternationalString idesc = serviceBinding.getDescription();
             
-            if (idesc != null) {
-                for (LocalizedString locName : idesc.getLocalizedStrings()) {
-                    Description desc = objectFactory.createDescription();
-                    bt.getDescription().add(desc);
-                    desc.setValue(locName.getValue());
-                    desc.setLang(locName.getLocale().getLanguage());                
-                }
-            }
+            addDescriptions(bt.getDescription(), idesc);
 
 			// SpecificationLink
            Collection<SpecificationLink> slcol = serviceBinding.getSpecificationLinks();
@@ -221,7 +211,8 @@
 					if (specificationObject.getKey() != null && specificationObject.getKey().getId() != null) {
 						emptyTInfo.setTModelKey(specificationObject.getKey().getId());
                         if (specificationObject.getDescription()!=null) {
-                            for (LocalizedString locDesc : specificationObject.getDescription().getLocalizedStrings()) {
+                            for (Object o : specificationObject.getDescription().getLocalizedStrings()) {
+                                LocalizedString locDesc = (LocalizedString) o;
                                 Description description = objectFactory.createDescription();
                                 emptyTInfo.getDescription().add(description);
                                 description.setValue(locDesc.getValue());
@@ -332,25 +323,13 @@
 			Service service) throws JAXRException {
 		BusinessService bs = objectFactory.createBusinessService();
 		try {
-			InternationalString iname = ((RegistryObject) service).getName();
+			InternationalString iname = service.getName();
 						
-			for (LocalizedString locName : iname.getLocalizedStrings()) {
-			    Name name = objectFactory.createName();
-			    bs.getName().add(name);
-			    name.setValue(locName.getValue());
-			    name.setLang(locName.getLocale().getLanguage());                
-			}
+			addNames(bs.getName(), iname);
 	         
-            InternationalString idesc = ((RegistryObject) service).getDescription();
+            InternationalString idesc = service.getDescription();
     
-            if (idesc != null) {
-                for (LocalizedString locName : idesc.getLocalizedStrings()) {
-                    Description desc = objectFactory.createDescription();
-                    bs.getDescription().add(desc);
-                    desc.setValue(locName.getValue());
-                    desc.setLang(locName.getLocale().getLanguage());                
-                }
-            }
+           addDescriptions(bs.getDescription(), idesc);
 
             Organization o = service.getProvidingOrganization();
 
@@ -428,25 +407,13 @@
                 tm.setOperator(s.getName());
             }
 
-			InternationalString iname = ((RegistryObject) classificationScheme).getName();
+			InternationalString iname = classificationScheme.getName();
 			 
-			for (LocalizedString locName : iname.getLocalizedStrings()) {
-			    Name name = objectFactory.createName();
-			    tm.setName(name);
-			    name.setValue(locName.getValue());
-			    name.setLang(locName.getLocale().getLanguage());                
-			}
-	         
-			InternationalString idesc = ((RegistryObject) classificationScheme).getDescription();
+            tm.setName(getFirstName(iname));
+
+			InternationalString idesc = classificationScheme.getDescription();
 			
-			if (idesc != null) {
-			    for (LocalizedString locName : idesc.getLocalizedStrings()) {
-			        Description desc = objectFactory.createDescription();
-			        tm.getDescription().add(desc);
-			        desc.setValue(locName.getValue());
-	                desc.setLang(locName.getLocale().getLanguage());                
-	            }
-			}
+		    addDescriptions(tm.getDescription(), idesc);
 
             IdentifierBag idBag = getIdentifierBagFromExternalIdentifiers(classificationScheme.getExternalIdentifiers());
             if (idBag!=null) {
@@ -481,26 +448,15 @@
 			if (sl2 != null && sl2.getName() != null)
 				tm.setOperator(sl2.getName());
 
-			InternationalString iname = ((RegistryObject) concept).getName();
+			InternationalString iname = concept.getName();
+
+            tm.setName(getFirstName(iname));
+
+            InternationalString idesc = concept.getDescription();
 			
-			for (LocalizedString locName : iname.getLocalizedStrings()) {
-			    Name name = objectFactory.createName();
-			    tm.setName(name);
-			    name.setValue(locName.getValue());
-			    name.setLang(locName.getLocale().getLanguage());			    
-			}
-			
-			InternationalString idesc = ((RegistryObject) concept).getDescription();
-			
-            if (idesc != null) {
-                for (LocalizedString locName : idesc.getLocalizedStrings()) {
-                    Description desc = objectFactory.createDescription();
-                    tm.getDescription().add(desc);
-                    desc.setValue(locName.getValue());
-                    desc.setLang(locName.getLocale().getLanguage());
-                }
-            }
-//          External Links 
+            addDescriptions(tm.getDescription(), idesc);
+
+//          External Links
             Collection<ExternalLink> externalLinks = concept.getExternalLinks(); 
             if(externalLinks != null && externalLinks.size() > 0)
             {
@@ -521,7 +477,39 @@
         }
         return tm;
     }
-    
+
+    private static void addDescriptions(List<Description> descripions, InternationalString idesc) throws JAXRException {
+        if (idesc != null) {
+            for (Object o : idesc.getLocalizedStrings()) {
+                LocalizedString locName = (LocalizedString) o;
+                Description desc = objectFactory.createDescription();
+                descripions.add(desc);
+                desc.setValue(locName.getValue());
+                desc.setLang(locName.getLocale().getLanguage());
+            }
+        }
+    }
+
+    private static Name getFirstName(InternationalString iname) throws JAXRException {
+        for (Object o : iname.getLocalizedStrings()) {
+            LocalizedString locName = (LocalizedString) o;
+            Name name = objectFactory.createName();
+            name.setValue(locName.getValue());
+            name.setLang(locName.getLocale().getLanguage());
+            return name;
+        }
+        return null;
+    }
+    private static void addNames(List<Name> names, InternationalString iname) throws JAXRException {
+        for (Object o : iname.getLocalizedStrings()) {
+            LocalizedString locName = (LocalizedString) o;
+            Name name = objectFactory.createName();
+            name.setValue(locName.getValue());
+            name.setLang(locName.getLocale().getLanguage());
+            names.add(name);
+        }
+    }
+
     public static BusinessEntity getBusinessEntityFromJAXROrg(Organization organization)
 			throws JAXRException {
 		BusinessEntity biz = objectFactory.createBusinessEntity();
@@ -540,26 +528,14 @@
 			
 			InternationalString iname = organization.getName();
 			
-			if (iname != null) {    
-			    for (LocalizedString locName : iname.getLocalizedStrings()) {
-			        Name name = objectFactory.createName();
-			        biz.getName().add(name);
-			        name.setValue(locName.getValue());
-			        name.setLang(locName.getLocale().getLanguage());                
-			    }
+			if (iname != null) {
+                addNames(biz.getName(), iname);
 			}
 			
 			InternationalString idesc = organization.getDescription();
 			
-			if (idesc != null) {
-			    for (LocalizedString locName : idesc.getLocalizedStrings()) {
-			        Description desc = objectFactory.createDescription();
-			        biz.getDescription().add(desc);
-			        desc.setValue(locName.getValue());
-			        desc.setLang(locName.getLocale().getLanguage());                
-			    }
-			}
-			
+            addDescriptions(biz.getDescription(), idesc);
+
 			if (organization.getPrimaryContact() != null && 
 				organization.getPrimaryContact().getPersonName()!= null &&
 				organization.getPrimaryContact().getPersonName().getFullName() != null) {
@@ -802,8 +778,7 @@
      * These KeyedReferences optionally refer to a tModel that identifies the type of category (translates to the ClassificationScheme key).  If
      * this is set and the tModel doesn't exist in the UDDI registry, then an invalid key error will occur when trying to save the object.
      * 
-     * @param regObj
-     * @param destinationObj
+     * @param classifications classifications to turn into categories
      * @throws JAXRException
      */
 	public static CategoryBag getCategoryBagFromClassifications(Collection classifications) throws JAXRException {
@@ -901,8 +876,7 @@
 	/**
      * Adds the objects identifiers from JAXR's external identifier collection
      * 
-     * @param identifiers
-     * @param ibag
+     * @param identifiers external identifiers to turn into identifiers
      * @throws JAXRException
      */
 	public static IdentifierBag getIdentifierBagFromExternalIdentifiers(Collection identifiers) throws JAXRException {
@@ -977,5 +951,5 @@
             }
         }
         return bt; 
-    } 
+    }
 }
