/** @name xmideserializer_handler.cpp
-----------------------------------------------------------------------------

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

-----------------------------------------------------------------------------


   10/18/2005  Initial creation

-------------------------------------------------------------------------- */

//TODO support multiple indexed FS

// ---------------------------------------------------------------------------
//  Includes
// ---------------------------------------------------------------------------

#include "uima/pragmas.hpp"
#include <iostream>
#include <sstream>
#include <algorithm>
using namespace std;

#include "xercesc/sax2/Attributes.hpp"
#include "xercesc/sax/SAXParseException.hpp"
#include "xercesc/sax/SAXException.hpp"
#include "uima/msg.h"
#include "uima/exceptions.hpp"
#include "uima/lowlevel_typesystem.hpp"
#include "uima/lowlevel_indexrepository.hpp"

#include "uima/xmideserializer_handler.hpp"
#include "uima/internal_fspromoter.hpp"
#include "uima/internal_typeshortcuts.hpp"
#include "uima/internal_casimpl.hpp"
#include "uima/fsindexrepository.hpp"
#include "uima/arrayfs.hpp"
#include "uima/listfs.hpp"
#include "uima/annotator_context.hpp"
#include "uima/resmgr.hpp"


namespace uima {

// ---------------------------------------------------------------------------
//  XmiDeserialiserHandler: Constructors and Destructor
// ---------------------------------------------------------------------------

	XmiDeserializerHandler::XmiDeserializerHandler(CAS & cas,
		XmiSerializationSharedData * xmiSharedData) : iv_cas(cas.getBaseCas() ),
		iv_locator(NULL), iv_casimpl( uima::internal::CASImpl::promoteCAS(*iv_cas)),
		sharedData(xmiSharedData), ownsSharedData(false), lenient(false), outOfTypeSystemElement(NULL) {
			if (this->sharedData==NULL) {
				this->sharedData = new XmiSerializationSharedData();
				ownsSharedData=true;
			} else {
				lenient=true;
			}
			//cout << " XmiDeserializerHandler::constructor " << endl;
			currentContentFeat.append(DEFAULT_CONTENT_FEATURE);
			sofaTypeCode = uima::internal::gs_tySofaType;
			FSIndexRepository * fsidx = &iv_cas->getBaseIndexRepository();
			indexRepositories.push_back((lowlevel::IndexRepository*)fsidx);
			// There should always be another index for the Initial View
			fsidx = &iv_cas->getView(CAS::NAME_DEFAULT_SOFA)->getIndexRepository();
			indexRepositories.push_back((lowlevel::IndexRepository*)fsidx);

			// get temp heap handle for checking if an FS is an annotation
			lowlevel::FSHeap const & crHeap = iv_casimpl.getHeap();
			//       uima::lowlevel::FSHeap::TyFSHeap const & tyTempHeap = crHeap.iv_clTemporaryHeap;
			iv_typesystem = &crHeap.getTypeSystem();

			ignoreDepth=0;
			nextSofaNum=2;
		}

		XmiDeserializerHandler::~XmiDeserializerHandler()   {
			//cout << " XmiDeserializerHandler::destructor " << endl;

			if (ownsSharedData)  {
				delete sharedData;
			}
			//cout << " XmiDeserializerHandler::destructor done " << endl;
		}


// ---------------------------------------------------------------------------
//  XmiDeserializerHandler: Implementation of the SAX2 ContentHandler interface
// ---------------------------------------------------------------------------

  void  XmiDeserializerHandler::setDocumentLocator(const Locator* const locator) {
    //cout << " XmiDeserializerHandler::setDocumentLocator() " << endl;
    iv_locator = locator;
  }

  void XmiDeserializerHandler::startDocument() {
    //cout << " XmiDeserializerHandler::startDocument() " << endl;
    iv_state = DOC_STATE;
  }

	void XmiDeserializerHandler::startElement(const   XMLCh* const    uri,
		const   XMLCh* const    localname,
		const   XMLCh* const    qname,
		const Attributes & attrs) {
			//cout << " XmiDeserializerHandler::startElement() qname " << UnicodeString((UChar*)qname, XMLString::stringLen(qname)) << endl;
			//cout << "startElement localname " << UnicodeString(localname) << " uri " << UnicodeString(uri) << endl;
			//cout << "startElement attrs " << attrs.getLength() << endl;


			assert(sizeof(XMLCh) == sizeof(UChar));

			icu::UnicodeString qualifiedName(qname);
			buffer.remove(); 

			switch (iv_state) {
		case DOC_STATE: {
			//cout << "startElement DOC_STATE " <<  attrs.getLength() << endl;
			// allow any root element name
			// extract xmlns:prefix=uri attributes into a map, which we can use to
			// resolve the prefixes even with a non-namespace-aware parser
			if (attrs.getLength() != 0) {
				for (size_t i = 0; i < attrs.getLength(); i++) {
					UnicodeString attrName(attrs.getQName(i));
					//cout << "xmlns attrName " << attrName << endl;
					if (attrName.indexOf("xmlns:") > -1 ) {
						UnicodeString prefix;
						attrName.extract(6, attrName.length()-6, prefix);
						UnicodeString uri(attrs.getValue(i));
						nsPrefixToUriMap[prefix]= uri;
					}
				}
			}
			iv_state = FS_STATE;
			break;
										}
		case FS_STATE: {
			// ignore elements with XMI prefix (such as XMI annotations)  
			if (qualifiedName.indexOf("xmi") > 0) {
				this->iv_state = IGNORING_XMI_ELEMENTS_STATE;
				this->ignoreDepth++;
				return;
			}

			UnicodeString unsuri(uri);
			UnicodeString ulocalname(localname);
			// parser not namespace-enabled, so try to resolve NS ourselves
			// TODO test with non namespace-enabled
			/**
			int colonIndex = qualifiedName.indexOf(":");
			if (colonIndex != -1) {
			UnicodeString prefix;
			qualifiedName.extract(0, colonIndex,prefix);
			map<UnicodeString,UnicodeString>::iterator uriite = nsPrefixToUriMap.find(prefix);
			if (uriite != nsPrefixToUriMap.end()) { 
			nameSpaceURI = uriite->second;
			} else {
			// unbound namespace. Rather than failing, just assume a reasonable default.
			nameSpaceURI.append("http:///");
			nameSpaceURI.append(prefix);
			nameSpaceURI.append(".ecore");
			}
			colonIndex++;
			qualifiedName.extract(colonIndex, qualifiedName.length()-colonIndex,localName );
			} else { // no prefix. Use default URI 
			nameSpaceURI = DEFAULT_NAMESPACE_URI;
			}
			**/
			//cout << "startElement FS_STATE calling readFS " << typeName << endl; 
			//readFS(typeName, attrs);
			readFS(unsuri, ulocalname, qualifiedName, attrs);

			map<UnicodeString, vector<UnicodeString>*>::iterator mite;
            for (mite=multiValuedFeatures.begin();
				mite != multiValuedFeatures.end(); mite++) {
					if (mite->second != NULL) {
						delete mite->second;
					}
			}
			multiValuedFeatures.clear();
			iv_state = FEAT_STATE;
			break;	   
									 }
		case FEAT_STATE: {
			iv_state = FEAT_CONTENT_STATE;
			break;				 
										 }
		case IGNORING_XMI_ELEMENTS_STATE: {
			ignoreDepth++;
			break;								 
																			}
		default: {
			// If we're not in an element expecting state, raise an error.
			ErrorInfo errInfo;
			errInfo.setErrorId((TyErrorId)UIMA_ERR_RESOURCE_CORRUPTED);
			ErrorMessage msg(UIMA_MSG_ID_EXC_XML_SAXPARSE_FATALERROR);
			assertWithMsg(sizeof(XMLCh) == sizeof(UChar), "Port required");
			msg.addParam( qualifiedName );
			errInfo.setMessage(msg);
			errInfo.setSeverity(ErrorInfo::unrecoverable);
			ExcIllFormedInputError exc(errInfo);
			throw exc;
						 }
			} //switch
		}

	void XmiDeserializerHandler::characters(
					const   XMLCh* const  cpwsz,
					const unsigned int    uiLength) {
		assert(sizeof(XMLCh) == sizeof(UChar));

		if (this->iv_state == FEAT_CONTENT_STATE) {
			buffer.append( (UChar const *) cpwsz, 0, uiLength );
		}
		/**
		switch (this->iv_state)  {
			case FEAT_CONTENT_STATE:
				buffer.append( (UChar const *) cpwsz, 0, uiLength );
				break;
			default:
				break;
		}**/
	}

	void XmiDeserializerHandler::endElement(const XMLCh* const nsuri,
						const XMLCh* const localname,
						const XMLCh* const qname) {
		/**
		cout << " XmiDeserializerHandler::endElement() qname " 
		<< UnicodeString( (UChar*) qname, XMLString::stringLen(qname) ) << endl;
		cout << " XmiDeserializerHandler::endElement() uri " 
		<< UnicodeString( (UChar*) nsuri, XMLString::stringLen(nsuri) ) << endl;
		**/

		assert(sizeof(XMLCh) == sizeof(UChar));
		UnicodeString qualifiedName( (UChar const *) qname, XMLString::stringLen(qname));
		//cout << "endElement qualifiedname " << qualifiedName << endl;
		switch (iv_state) {
		case DOC_STATE: {
			// Do nothing.
			break; 
		}
		case FS_STATE: {
			iv_state = DOC_STATE;
			break;
		}
		case FEAT_CONTENT_STATE: {
			// We have just processed one of possibly many values for a feature.
			// Store this value in the multiValuedFeatures map for later use.
			//cout << "endELement FEAT_CONTENT_STATE " << buffer << endl;
			map<UnicodeString, vector<UnicodeString>*>::iterator ite =
				multiValuedFeatures.find(qualifiedName);
			vector<UnicodeString> * valuesList=0; 
			if (ite == multiValuedFeatures.end()) {
				valuesList = new vector<UnicodeString>;
				multiValuedFeatures[qualifiedName] = valuesList;
			} else {
				valuesList = ite->second;
			}
			if (valuesList==0) {
				cout << "endELement()FEAT_CONTENT_STATE valuesList not created" << endl;
			}
			else valuesList->push_back(buffer);

			// go back to the state where we're expecting a feature
			iv_state = FEAT_STATE;
			break;
		}
		case FEAT_STATE: {
			// end of FS. Process multi-valued features or array elements that were
			// encoded as subelements
			if (this->outOfTypeSystemElement != NULL) {
				if (this->multiValuedFeatures.size() > 0) {
					map<UnicodeString,vector<UnicodeString>*>::iterator ite;
					for (ite=multiValuedFeatures.begin(); ite != multiValuedFeatures.end();ite++) {
						UnicodeString featName = ite->first;
						vector<UnicodeString>* featVals = ite->second;
						addOutOfTypeSystemFeature(outOfTypeSystemElement, featName, *featVals);
					}
				}
				this->outOfTypeSystemElement = NULL;
			}
			//process the multivalued feature or array elements that 
			//were encoded as subelements.
			//cout << "endElement FEAT_STATE " << qualifiedName << endl;
			else if (currentType.isValid()) {
				int typecode = internal::FSPromoter::demoteType(currentType);
				if ( iv_cas->getTypeSystem().isArrayType(typecode) && 
					typecode != internal::gs_tyByteArrayType) {
						// create the array now. elements may have been provided either as
						// attributes or child elements, but not both.
						// BUT - not byte arrays! They are created immediately, to avoid
						// the overhead of parsing into a String array first
						vector<string> featVals;
						// cout << "endElement FEAT_STATE currentArrayElements " <<
						//	    currentArrayElements.length() << endl;
						if (currentArrayElements.length()==0) // were not specified as attributes
						{
							map<UnicodeString, vector<UnicodeString>*>::iterator ite =
								multiValuedFeatures.find(UnicodeString("elements"));
							if (ite != multiValuedFeatures.end()) {
								vector<UnicodeString>* vals = ite->second;
								for (size_t i=0; i<vals->size(); i++) {
									featVals.push_back( ((UnicodeStringRef)vals->at(i)).asUTF8()); 
								}
							}
						} else {
							tokenize(currentArrayElements,featVals);
						}         
						createArray(internal::FSPromoter::demoteType(currentType), featVals, currentArrayId);
					} else {
						map<UnicodeString,vector<UnicodeString>*>::iterator ite;
						for (ite=multiValuedFeatures.begin(); ite != multiValuedFeatures.end();ite++) {
							UnicodeString featName = ite->first;
							vector<UnicodeString>* featVals = ite->second;
							vector<string> stringList;
							for (size_t i=0; i< featVals->size();i++) {
								stringList.push_back( ((UnicodeStringRef)featVals->at(i)).asUTF8());
							}
							handleFeature(currentAddr, featName, stringList);
						}
					}
			}
			iv_state = FS_STATE;
			break;
		} 
		case IGNORING_XMI_ELEMENTS_STATE: {
			ignoreDepth--;
			if (ignoreDepth == 0) {
				iv_state = FS_STATE;
			}
			break;
		}
	}
}


	void XmiDeserializerHandler::endDocument() {

		//cout << " XmiDeserializerHandler::endDocument() " << endl;

		//fix up deserialized FSs
		for (size_t i = 0; i < this->deserializedFsAddrs.size(); i++) {
			//cout << "finalize fs " << deserializedFsAddrs.at(i) << endl;
			finalizeFS(deserializedFsAddrs.at(i));
		}

		//fix up lists
		for (size_t i = 0; i < fsListNodesFromMultivaluedProperties.size(); i++) {
			this->remapFSListHeads(fsListNodesFromMultivaluedProperties.at(i));
		}

		//cout << " XmiDeserializerHandler::endDocument() tcasInstance " << endl;
		//update document annotation info in tcas
		for (size_t i = 0; i < tcasInstances.size(); i++) {
			CAS * tcas = (CAS *) tcasInstances[i];
			if (tcas != 0) {
				tcas->pickupDocumentAnnotation();
			}
		}
		//cout << " XmiDeserializerHandler::endDocument() " << endl;
	}


  void XmiDeserializerHandler::ignorableWhitespace(const  XMLCh* const cpwsz,
      const unsigned int length) {
    //cout << " XmiDeserializerHandler::ignorableWhitespace() " << endl;
  }


/**
   * Converts an XMI element name to a UIMA-style dotted type name.
   * 
   */
	UnicodeString XmiDeserializerHandler::xmiElementName2uimaTypeName(UnicodeString& nsUri, UnicodeString& localName) {
		// check map first to see if we've already computed the namespace mapping
		map<UnicodeString,UnicodeString>::iterator ite = xmiNamespaceToUimaNamespaceMap.find(nsUri);
		UnicodeString uimaNamespace;
		if (ite != xmiNamespaceToUimaNamespaceMap.end()) {
			uimaNamespace = ite->second;
		} else {
			// check for the special "no-namespace" URI, which is used for UIMA types with no namespace
			if (nsUri.compare(DEFAULT_NAMESPACE_URI) == 0) {
				//uimaNamespace = "";
			} else {
				// Our convention is that the UIMA namespace is the URI path format e.g:
				// http:///uima/cas.ecore.
				// remove http:/// and trailing .ecore
				// replace remaining slashes with dot.
				nsUri.extractBetween(8, nsUri.length()-6, uimaNamespace); 
				//cout << "uimanamespace " << uimaNamespace << endl;
				uimaNamespace.findAndReplace("/", ".");
				uimaNamespace.append("."); // include trailing dot for convenience
			}
			xmiNamespaceToUimaNamespaceMap[nsUri]= uimaNamespace;
		}
		//cout << "uimaNamespace final " << uimaNamespace << endl;
		uimaNamespace.append(localName);
		return uimaNamespace;
	}


// Create a new FS.
	void XmiDeserializerHandler::readFS(UnicodeString & nsUri, UnicodeString & localName,
		UnicodeString & qualifiedName, const Attributes & attrs) {
			UnicodeString typeName = xmiElementName2uimaTypeName(nsUri, localName);
			Type type = iv_cas->getTypeSystem().getType(typeName);
			currentType=type;
			
			if (!type.isValid()) {
				if (typeName.compare(UnicodeString("uima.cas.NULL"))==0) {
					//cout << "readFS ignore " << typeName << endl;
					return; //ignore
				}
				if (typeName.compare(UnicodeString("uima.cas.View"))==0) {
					//cout << "readFS  " << typeName << endl;
					UnicodeString attrName; 
					int sofaXmiId=0;
					UnicodeString members;
					for (size_t i = 0; i < attrs.getLength(); i++) {
						attrName =  attrs.getQName(i);
						if (attrName.compare(CAS::FEATURE_BASE_NAME_SOFA) == 0) {
							UnicodeString ustr(attrs.getValue(i));
							sofaXmiId = atoi( ((UnicodeStringRef)ustr).asUTF8().c_str());
						} else if (attrName.compare("members") == 0) {
							members = attrs.getValue(i);
						} 
					}
					processView(sofaXmiId, members);
					return;
				} 
				// type is not in our type system
				if (!lenient) {
					ErrorInfo errInfo;
					errInfo.setErrorId((TyErrorId)UIMA_ERR_RESOURCE_CORRUPTED);
					ErrorMessage msg(UIMA_MSG_ID_EXC_XML_SAXPARSE_FATALERROR);
					assertWithMsg(sizeof(XMLCh) == sizeof(UChar), "Port required");
					msg.addParam(typeName);
					errInfo.setMessage(msg);
					errInfo.setSeverity(ErrorInfo::unrecoverable);
					ExcIllFormedInputError exc(errInfo);
					throw exc; 
				} else {
					this->addToOutOfTypeSystemData(
						new XmlElementName( ((UnicodeStringRef)nsUri).asUTF8(),
						((UnicodeStringRef)localName).asUTF8(),
						((UnicodeStringRef)qualifiedName).asUTF8()), attrs );   
					return;
				}
			} else if (iv_cas->getTypeSystem().isArrayType(internal::FSPromoter::demoteType(type)) ) {
				
        UnicodeString attrName; 
				int xmiId=0;
				UnicodeString elements;
				for (size_t i = 0; i < attrs.getLength(); i++) {
						attrName =  attrs.getQName(i);
						if (attrName.compare(XMI_ID_ATTR_NAME) == 0) {
							UnicodeString ustr(attrs.getValue(i));
							currentArrayId = atoi( ((UnicodeStringRef)ustr).asUTF8().c_str());
						} else if (attrName.compare("elements") == 0) {
							currentArrayElements = attrs.getValue(i);
						} 
				}

        //cout << "xmiId " << currentArrayId << " type=" << typeName << " elements=" << currentArrayElements << endl;
				if (internal::FSPromoter::demoteType(type) == internal::gs_tyByteArrayType) {
					int addr = createByteArray(currentArrayElements, currentArrayId);
				} 

			} else {
				//cout << "readFS() create FS and read attributes " << typeName << endl;
				uima::lowlevel::TyFS addr = uima::internal::FSPromoter::demoteFS(iv_cas->createFS(type));
				readFS(addr, attrs, true);
			}

		}



	/**
	* Handles the processing of a cas:View element in the XMI. The cas:View element encodes indexed
	* FSs.
	* 
	* @param sofa
	*          xmi:id of the sofa for this view, null indicates base CAS "view"
	* @param membersString
	*          whitespace-separated string of FS addresses. Each FS is to be added to the specified
	*          sofa's index repository
	*/
	void XmiDeserializerHandler::processView(int sofaXmiId, UnicodeString & members) {
		// TODO: this requires View to come AFTER all of its members
		//cout << "processView start " << sofaXmiId << "members=" << membersString << endl;
		if (members.length() > 0) { 
			// a view with no Sofa will be added to the 1st, _InitialView, index
			int sofaNum = 1;
			if (sofaXmiId != 0) {
				// translate sofa's xmi:id into its sofanum
				//cout << __LINE__ << " calling getFsAddrForXmiId " << sofaXmiId << endl;
				int sofaAddr = getFsAddrForXmiId(sofaXmiId);

				sofaNum = iv_cas->getHeap()->getIntValue(sofaAddr, internal::gs_tySofaNumFeature);
			}
			lowlevel::IndexRepository * indexRep =  indexRepositories.at(sofaNum);

			vector<string> memberList;
			tokenize(members, memberList);

			for (size_t i = 0; i < memberList.size(); i++) {
				// have to map each ID to its "real" address
				int addr=0;
        int amember = atoi(memberList.at(i).c_str());
				try {
					//cout << __LINE__ << " calling getFsAddrForXmiId " << members.at(i) << endl;
					addr = getFsAddrForXmiId(amember);
					indexRep->addFS(internal::FSPromoter::promoteFS(addr,*iv_cas));
				} catch (Exception e) {
					if (!lenient) {
						throw e;
					}
					else {
						//unknown view member may be an OutOfTypeSystem FS
						//cout << "calling sharedData->addOutOfTypeSystemViewMember" << endl;
						this->sharedData->addOutOfTypeSystemViewMember(sofaXmiId, amember);
					}
				}
			}
		}
	}


	int XmiDeserializerHandler::createByteArray(UnicodeString& currentArrayElements, int currentArrayId) {
		string elemStr = ( (UnicodeStringRef) currentArrayElements).asUTF8();
		int arrayLen = elemStr.length() / 2;
		ByteArrayFS fs = iv_cas->createByteArrayFS(arrayLen);
		size_t j=0;
		for (int i = 0; i < arrayLen; i++) {
			char hex[5], *stop;
			hex[0] = '0';
			hex[1] = 'x';
			if (j < elemStr.length() ) {
				hex[2] = elemStr.at(j++);
				if (j < elemStr.length()) {
					hex[3] = elemStr.at(j++);
					hex[4] = 0;
					char val = strtol(hex, &stop, 16);
					fs.set(i,val);
				}
			}
		}  
		int arrayAddr = internal::FSPromoter::demoteFS(fs);
		deserializedFsAddrs.push_back(arrayAddr);
		if (currentArrayId > 0) {
			sharedData->addIdMapping(arrayAddr,currentArrayId);
		}

		return arrayAddr;
	}

	void XmiDeserializerHandler::readFS(lowlevel::TyFS addr, const Attributes  & attrs, bool toIndex) {
		// Hang on address for setting content feature
		currentAddr = addr;

		int id = -1;
		//       int sofaRef = -1; // 0 ==> baseCas indexRepository
		////vector<int>* sofaRef = new vector<int>;
		UnicodeString attrName;
		UnicodeString attrValue;
		bool nameMapping = false;
		UChar ubuff[256];
		UErrorCode errorCode = U_ZERO_ERROR;
		int thisSofaNum;
		lowlevel::TyFS heapValue = iv_casimpl.getHeap().getType(addr);


		if (sofaTypeCode == heapValue) {
			int extsz = UnicodeString(CAS::FEATURE_BASE_NAME_SOFAID).extract(ubuff, 256, errorCode);
			if (extsz > 256) {
				cout << "ACK!" << endl;
			}
			const UChar* sofaID = attrs.getValue(ubuff);

			if (0==UnicodeStringRef(sofaID).compare(UnicodeString("_DefaultTextSofaName"))) {  
				// initial view Sofa always has sofaNum = 1
				thisSofaNum = 1;
			} else if (0==UnicodeStringRef(sofaID).compare(UnicodeString(CAS::NAME_DEFAULT_SOFA))) {   
				thisSofaNum = 1;
			}  else {
				thisSofaNum = this->nextSofaNum++;
			}
		}

		Type type = uima::internal::FSPromoter::promoteType(heapValue, iv_cas->getTypeSystem().getLowlevelTypeSystem());
		for (size_t i = 0; i < attrs.getLength(); i++) {
			assertWithMsg( sizeof(XMLCh) == sizeof(UChar), "Port required!");
			attrName = (UChar*)attrs.getQName(i);
			attrValue = (UChar*)attrs.getValue(i);

			if (attrName.compare(UnicodeString(XMI_ID_ATTR_NAME)) == 0) {
				id = atoi(UnicodeStringRef(attrValue).asUTF8().c_str());
				//cout << "got " << XMI_ID_ATTR_NAME << " " << id << endl;
			} else {       
				if (sofaTypeCode == heapValue && attrName.compare(CAS::FEATURE_BASE_NAME_SOFAID)==0) {
					if (attrValue.compare(UnicodeString("_DefaultTextSofaName"))==0 ) {
						// First change old default Sofa name into the new one
						attrValue = UnicodeString(CAS::NAME_DEFAULT_SOFA);
					}
				} else if (sofaTypeCode == heapValue 
					&& attrName.compare(UnicodeString(CAS::FEATURE_BASE_NAME_SOFANUM))==0) {
						stringstream str;
						str << thisSofaNum << endl;
						attrValue = UnicodeString(str.str().c_str());
					}
					//cout << "readFS calling handleFeature " << attrName << " attrvalue= "
					//	<< attrValue << endl;
					handleFeature(addr, attrName, attrValue, true);
			}
		}

		if (sofaTypeCode == heapValue) {
			// If a Sofa, create CAS view to get new indexRepository
			SofaFS sofa = (SofaFS) uima::internal::FSPromoter::promoteFS(addr, *iv_cas);
			//also add to indexes so we can retrieve the Sofa later
			iv_cas->getBaseIndexRepository().addFS(sofa);
			CAS * tcas = iv_cas->getView(sofa);
			assert ( EXISTS(tcas) );
			if (sofa.getSofaRef() == 1) {
				iv_cas->registerInitialSofa();
			} else {
				// add indexRepo for views other than the initial view
				lowlevel::IndexRepository * indexRep = iv_cas->getIndexRepositoryForSofa(sofa);
				assert ( EXISTS(indexRep) );
				indexRepositories.push_back(indexRep);
			}
			tcasInstances.push_back(tcas);
		}

		deserializedFsAddrs.push_back(addr);
		if (id > 0) {
			sharedData->addIdMapping(addr, id);
		}

	}

  

  
  void XmiDeserializerHandler::addArrayElement(lowlevel::TyFS addr,
											lowlevel::TyFSType arrayType, 
											int arrayPos, 
											string & buffer) {

    if (arrayPos >= (int) iv_casimpl.getHeap().getArraySize(addr) ) {
      ErrorInfo errInfo;
      errInfo.setErrorId((TyErrorId)UIMA_ERR_RESOURCE_CORRUPTED);
      ErrorMessage msg(UIMA_MSG_ID_EXC_XML_SAXPARSE_FATALERROR);
      assertWithMsg(sizeof(XMLCh) == sizeof(UChar), "Port required");
      msg.addParam("Invalid array FS in the CAS" );
      errInfo.setMessage(msg);
      errInfo.setSeverity(ErrorInfo::unrecoverable);
      ExcIllFormedInputError exc(errInfo);
      throw exc;
    }

    FeatureStructure fs = uima::internal::FSPromoter::promoteFS(addr, *iv_cas);

    switch (arrayType) {
    case internal::gs_tyIntArrayType: {
		//cout << "add intarray element at " << arrayPos << " " << buffer << endl;
        int val = atoi(buffer.c_str());
        IntArrayFS intFS(fs);
        intFS.set( (size_t) arrayPos, val);
        break;
      }
    case internal::gs_tyFloatArrayType: {
        float val = atof(buffer.c_str());
        FloatArrayFS floatFS(fs);
        floatFS.set( (size_t) arrayPos, val);
        break;
      }
    case internal::gs_tyStringArrayType: {
        //add the striug
				StringArrayFS strFS(fs);
				UnicodeString strval(buffer.c_str());
				strFS.set( (size_t) arrayPos,strval);
				break;
    }
    case internal::gs_tyByteArrayType: {
        short intval = atoi(buffer.c_str());
        char charval[2];
        sprintf(charval,"%c",intval);
        ByteArrayFS byteFS(fs);
        byteFS.set( (size_t) arrayPos, charval[0]);
        break;
    }
    case internal::gs_tyBooleanArrayType: {
        BooleanArrayFS booleanFS(fs);
        if (buffer.compare("true") == 0)  {
          booleanFS.set( (size_t) arrayPos, true);
          //cout << "bool buffer " << buffer << " val= " << val << "set " << true << endl;
        } else {
          booleanFS.set ( (size_t) arrayPos, false);
          //cout << arrayPos << " bool buffer " << buffer << " val= " << val << "set " << false << endl;
        }
        break;
      }
    case internal::gs_tyShortArrayType: {
        short val;
        //string strval;
        //UnicodeStringRef(buffer).extractUTF8(strval);
        stringstream s;
        s << buffer.c_str();
        s >> val;
        ShortArrayFS shortFS(fs);
        shortFS.set( (size_t) arrayPos, val);
        break;
      }
    case internal::gs_tyLongArrayType: {
        INT64 val;
        stringstream s;
        s << buffer;
        s >> val;
        LongArrayFS longFS(fs);
        longFS.set( (size_t) arrayPos, val);
        break;
      }
    case internal::gs_tyDoubleArrayType: {
        DoubleArrayFS doubleFS(fs);
        stringstream s;
        s << buffer;
        long double doubleval;
        s >> doubleval;
        doubleFS.set((size_t) arrayPos, doubleval);
        break;
      }
    default: {    //array of FSs
      lowlevel::TyFS fsid = atoi(buffer.c_str());
      FeatureStructure fsitem(fsid, *iv_cas);
      ArrayFS fsArrayfs(fs);
      fsArrayfs.set((size_t) arrayPos, fsitem);
    }
    } //swithch
  }



	// Create a feature value from a string representation.
	void XmiDeserializerHandler::handleFeature(lowlevel::TyFS addr, UnicodeString & featName, UnicodeString & featVal, bool lenient) {
		lowlevel::TyFSType fstype = iv_casimpl.getHeap().getType(addr);
		Type type = uima::internal::FSPromoter::promoteType(fstype, iv_cas->getTypeSystem().getLowlevelTypeSystem());
		Feature feat = type.getFeatureByBaseName(featName);
		if (!feat.isValid()) {
			if (!lenient) {
				ErrorInfo errInfo;
				errInfo.setErrorId((TyErrorId)UIMA_ERR_RESOURCE_CORRUPTED);
				ErrorMessage msg(UIMA_MSG_ID_EXC_XML_SAXPARSE_FATALERROR);
				assertWithMsg(sizeof(XMLCh) == sizeof(UChar), "Port required");
				msg.addParam("Unknown Feature");
				msg.addParam(featName);
				errInfo.setMessage(msg);
				errInfo.setSeverity(ErrorInfo::unrecoverable);
				ExcIllFormedInputError exc(errInfo);
				throw exc; 
			}
			else {
				sharedData->addOutOfTypeSystemAttribute(addr, featName, featVal);
			}
			return;
		}

		lowlevel::TyFSFeature featCode = internal::FSPromoter::demoteFeature(feat);
		handleFeature(type, addr, featCode, featVal, lenient);
	}

  void XmiDeserializerHandler::handleFeature(Type & type, 
    lowlevel::TyFS addr,
    lowlevel::TyFSFeature featCode, 
    UnicodeString & featVal,
    bool lenient) {

    FeatureStructure fs = uima::internal::FSPromoter::promoteFS(addr, *iv_cas);
    if (!fs.isValid() ) {
      cerr << "handle feature of Invalid FS " << type.getName() << endl;
      ErrorInfo errInfo;
      errInfo.setErrorId((TyErrorId)UIMA_ERR_RESOURCE_CORRUPTED);
      ErrorMessage msg(UIMA_MSG_ID_EXC_XML_SAXPARSE_FATALERROR);
      assertWithMsg(sizeof(XMLCh) == sizeof(UChar), "Port required");
      msg.addParam("Invalid FeatureStructure");
      msg.addParam(type.getName());
      errInfo.setMessage(msg);
      errInfo.setSeverity(ErrorInfo::unrecoverable);
      ExcIllFormedInputError exc(errInfo);
      throw exc; 
    }

    ///Feature feat = type.getFeatureByBaseName(featName);
	  Feature feat =  internal::FSPromoter::promoteFeature(featCode, *iv_typesystem);

    Type rtype;
    feat.getRangeType(rtype);
    lowlevel::TyFSType rangeType = uima::internal::FSPromoter::demoteType(rtype);
    switch (rangeType) {
      case internal::gs_tyIntegerType: {
        if (featVal.length()>0) {
          if (featCode == internal::gs_tySofaRefFeature) {
            // special handling for "sofa" feature of annotation. Need to change
            // it from a sofa reference into a sofa number
            int sofaXmiId = atoi(UnicodeStringRef(featVal).asUTF8().c_str());
            //cout << __LINE__ << " calling getFsAddrForXmiId " << sofaXmiId << endl; 
            int sofaAddr = getFsAddrForXmiId(sofaXmiId); 
            int sofaNum = iv_cas->getHeap()->getFSValue(sofaAddr, internal::gs_tySofaNumFeature);
            iv_cas->getHeap()->setFSValue(addr,featCode,sofaNum);

          } else {             
            fs.setIntValue(feat, atoi(UnicodeStringRef(featVal).asUTF8().c_str()));
          }
        }
        break;
      }
      case internal::gs_tyFloatType: { 
        if ( featVal.length() > 0)  {
          fs.setFloatValue(feat, atof(UnicodeStringRef(featVal).asUTF8().c_str()));
        }
        break;
      }
      case internal::gs_tyStringType: {
        if (featVal.length() > 0) {
          fs.setStringValue(feat, featVal);
        }
        break;
      }
      case internal::gs_tyByteType: {
        if (featVal.length() > 0) {
          string val = UnicodeStringRef(featVal).asUTF8();
          short intval = atoi(val.c_str());
          char charval[2];
          sprintf(charval,"%c",intval);
          fs.setByteValue(feat, charval[0] );
        }
        break;
      }
      case internal::gs_tyBooleanType: {
        if (featVal.length() > 0) {
          string val = UnicodeStringRef(featVal).asUTF8();
          if (val.compare("1")==0 || val.compare("true") == 0)
            fs.setBooleanValue(feat, true );
          else fs.setBooleanValue(feat, false);
        }
        break;
      }
      case internal::gs_tyShortType: {
        if (featVal.length() > 0) {
          string strval = UnicodeStringRef(featVal).asUTF8();
          short shortval;
          stringstream s;
          s << strval.c_str();
          s >> shortval;
          fs.setShortValue(feat, shortval);
        }
        break;
      }
      case internal::gs_tyLongType: {
        if (featVal.length() > 0) {
          string strval = UnicodeStringRef(featVal).asUTF8();
          INT64 longval;
          stringstream s;
          s << strval.c_str();
          s >> longval;
          fs.setLongValue(feat, longval);
        }
        break;
      }
      case internal::gs_tyDoubleType: {
        if (featVal.length() > 0) {
          string strval = UnicodeStringRef(featVal).asUTF8();
          long double doubleval;
          stringstream s;
          s << strval.c_str();
          s >> doubleval;
          fs.setDoubleValue(feat, doubleval );
        }
        break;
      }	  
      case internal::gs_tyBooleanArrayType:
      case internal::gs_tyByteArrayType:
      case internal::gs_tyIntArrayType: 
      case internal::gs_tyFloatArrayType: 
      case internal::gs_tyStringArrayType: 
      case internal::gs_tyLongArrayType:
      case internal::gs_tyShortArrayType:
      case internal::gs_tyDoubleArrayType: 
      case internal::gs_tyFSArrayType: {
        //cout << "handleFeature " << feat.getName() << " " << featVal << endl;
        if (feat.isMultipleReferencesAllowed()) {
          // do the usual FS deserialization
          //cout << "  multiplerefsallowed " << endl;
          if (featVal.length() > 0) {
            int val = atoi(UnicodeStringRef(featVal).asUTF8().c_str());
            //cout << " setting fsvalue " << "fsaddr " << addr << " value "<< val << endl;
            iv_cas->getHeap()->setFeatureInternal(addr,featCode,val);
          }
        } else {
          // Do the multivalued property deserialization.
          // However, byte arrays have a special serialization (as hex digits)
          //cout << " not multiplerefsallowed " << endl;
          if (rangeType == internal::gs_tyByteArrayType) {
            int arrayAddr = createByteArray(featVal, -1);
            iv_cas->getHeap()->setFSValue(addr,featCode,arrayAddr);
          } else {
            //cout << "tokenizing array values " << endl;
            vector<string> stringList;
            tokenize(featVal, stringList);
            handleFeature(addr, featCode, rangeType, stringList);
          }
        }
        break;
      }
      case internal::gs_tyFloatListType:
      case internal::gs_tyIntListType:
      case internal::gs_tyStringListType: 
      case internal::gs_tyFSListType: {
        //cout << "GOT A LIST FEATURE " << endl;
        if (feat.isMultipleReferencesAllowed()) {
          // do the usual FS deserialization
          if (featVal.length() > 0) {
            int val = atoi(UnicodeStringRef(featVal).asUTF8().c_str());
            iv_cas->getHeap()->setFeatureInternal(addr,featCode,val);
          }
        } else {
          // Do the multivalued property deserialization.
          ////handleFeature(addr,featCode,featVal);
          vector<string> stringList;
          tokenize(featVal, stringList);
          handleFeature(addr, featCode, rangeType, stringList);
        }
        break;
      }
      default: {
        if (rtype.isStringSubType()) {
          if (featVal.length() > 0) {
            fs.setStringValue(feat, featVal);
          }
        } else if (featVal.length() > 0) {
          lowlevel::TyFS val = (lowlevel::TyFS) atoi(UnicodeStringRef(featVal).asUTF8().c_str());
          iv_casimpl.getHeap().setFeatureInternal(addr, uima::internal::FSPromoter::demoteFeature(feat), val);
        }
        break;
      }
    }
  }
 
  void XmiDeserializerHandler::handleFeature(lowlevel::TyFS addr, 
                          UnicodeString & featName,
                          vector<string> & featVal) {
    lowlevel::TyFSType fstype = iv_casimpl.getHeap().getType(addr);
    Type type = uima::internal::FSPromoter::promoteType(fstype, iv_cas->getTypeSystem().getLowlevelTypeSystem());
    Feature feat = type.getFeatureByBaseName(featName);
    if (!feat.isValid()) {
      if (!lenient) {
        ErrorInfo errInfo;
        errInfo.setErrorId((TyErrorId)UIMA_ERR_RESOURCE_CORRUPTED);
        ErrorMessage msg(UIMA_MSG_ID_EXC_XML_SAXPARSE_FATALERROR);
        assertWithMsg(sizeof(XMLCh) == sizeof(UChar), "Port required");
        msg.addParam("Unknown Feature");
        msg.addParam(featName);
        errInfo.setMessage(msg);
        errInfo.setSeverity(ErrorInfo::unrecoverable);
        ExcIllFormedInputError exc(errInfo);
        throw exc; 
      }
      else {
        sharedData->addOutOfTypeSystemChildElements(addr, ( (UnicodeStringRef)featName).asUTF8(), featVal);
      }
      return;
    }
    lowlevel::TyFSFeature featCode = internal::FSPromoter::demoteFeature(feat);
    Type rtype;
    feat.getRangeType(rtype);
    handleFeature(addr, featCode,internal::FSPromoter::demoteType(rtype), featVal);
}

void XmiDeserializerHandler::handleFeature(lowlevel::TyFS addr, 
		                lowlevel::TyFSFeature featCode,
					          lowlevel::TyFSType rangeTypeCode,
					          vector<string> & featVals)  {
    //cout << "handleFeature array/list  " << featVals.size() << endl;
	 switch(rangeTypeCode) {
	   case internal::gs_tyBooleanArrayType:
	   case internal::gs_tyByteArrayType:
	   case internal::gs_tyIntArrayType: 
	   case internal::gs_tyFloatArrayType: 
	   case internal::gs_tyLongArrayType:
	   case internal::gs_tyShortArrayType:
	   case internal::gs_tyDoubleArrayType:
	   case internal::gs_tyFSArrayType: {
		   int arrayFS = createArray(rangeTypeCode, featVals, -1);  
		   iv_cas->getHeap()->setFSValue(addr,featCode,arrayFS);
		   break;
	   }
	   case internal::gs_tyStringArrayType: {
		   //cout << "handleFeature of type string array" << endl;
		   int arrayFS = createArray(rangeTypeCode, featVals, -1);  
		   iv_cas->getHeap()->setFSValue(addr,featCode,arrayFS);
		   break;
	   }
	   case internal::gs_tyIntListType: {
		   int arrayFS = createIntList(featVals);
           iv_cas->getHeap()->setFSValue(addr,featCode,arrayFS);
		   break;
	   }
	   case internal::gs_tyFloatListType: {
		   int arrayFS = createFloatList(featVals);
           iv_cas->getHeap()->setFSValue(addr,featCode,arrayFS);
		   break;
	   }
	   case internal::gs_tyStringListType: {
		   int arrayFS = createStringList(featVals);
           iv_cas->getHeap()->setFSValue(addr,featCode,arrayFS);
		   break;
	   }
	   case internal::gs_tyFSListType: {
		   int arrayFS = createFSList(featVals);
           iv_cas->getHeap()->setFSValue(addr,featCode,arrayFS);
		   break;
	   }   
	   default: {
		//scalar and FS type
		   if (featVals.size() != 1) {
				 //TODO log
			   cerr << "one feature value expected " << endl;
		   } else {
			   Type type = internal::FSPromoter::promoteType(rangeTypeCode,
				   iv_cas->getTypeSystem().getLowlevelTypeSystem());
				 UnicodeString val(featVals.at(0).c_str());
			   handleFeature(type,		   
				   addr, featCode,val, true);
		   }
	  	break;	
	   }
	  }
  }

  void XmiDeserializerHandler::tokenize(UnicodeString & ustr, vector<string> & stringList ) {

	  string str = (UnicodeStringRef(ustr)).asUTF8();
	  string::size_type lastPos = str.find_first_not_of(" ", 0); 
	  string::size_type pos = str.find_first_of(" ",lastPos);
    
	  while (string::npos != pos || string::npos != lastPos) {
        // Found a token, add it to the vector.
        stringList.push_back(str.substr(lastPos, pos - lastPos));
        // Skip blanks and find next non blank
        lastPos = str.find_first_not_of(" ", pos);
        // Find next blank
        pos = str.find_first_of(" ",lastPos);
    }
  }


  int XmiDeserializerHandler::createArray(  lowlevel::TyFSType typeCode,
		               vector<string>& stringList,
					          int xmiId)		{
    int arrayAddr;
  
	  switch (typeCode) {
      case internal::gs_tyBooleanArrayType:
	    case internal::gs_tyByteArrayType:
	    case internal::gs_tyIntArrayType: 
	    case internal::gs_tyFloatArrayType: 
	    case internal::gs_tyLongArrayType:
	    case internal::gs_tyShortArrayType:
	    case internal::gs_tyDoubleArrayType:
	    case internal::gs_tyStringArrayType:
	    case internal::gs_tyFSArrayType: {
	      //cout << "createArray() type " << typeCode << " size " << stringList.size() << endl;
		    arrayAddr = iv_cas->getHeap()->createArrayFS(typeCode, stringList.size());
		    //cout << "created array FS now adding element values at address " << arrayAddr << endl;
		    for (size_t i=0; i < stringList.size();i++) {		
			    addArrayElement(arrayAddr, typeCode,i,stringList.at(i));
		    }		 
		    break;
		  }        
	    default: {
	      cerr << "Invalid Array type" << endl;
		    ErrorInfo errInfo;
		    errInfo.setErrorId((TyErrorId)UIMA_ERR_RESOURCE_CORRUPTED);
		    ErrorMessage msg(UIMA_MSG_ID_EXC_XML_SAXPARSE_FATALERROR);
		    assertWithMsg(sizeof(XMLCh) == sizeof(UChar), "Port required");
		    msg.addParam("createArray failed.");
		    stringstream str;
		    str << "xmiId=" << xmiId << " typecode= " << typeCode << endl;
		    msg.addParam(str.str().c_str());
		    errInfo.setMessage(msg);
		    errInfo.setSeverity(ErrorInfo::unrecoverable);
		    ExcIllFormedInputError exc(errInfo);
		    throw exc; 
		    break;
	    }
	  }
		//cout << "createArray " << xmiId << " addr=" << arrayAddr << endl;
	  deserializedFsAddrs.push_back(arrayAddr);
	  if (xmiId > 0) {
		  sharedData->addIdMapping(arrayAddr, xmiId);
	  }
	  return arrayAddr;
  }
    
  int XmiDeserializerHandler::createIntList(vector<string>& stringList)	{
	  IntListFS listFS =   iv_cas->createIntListFS();
    for (size_t i = 0; i < stringList.size(); i++ ) {
      int value = atoi (stringList.at(i).c_str()); 
	    listFS.addLast(value);
    }
	  return internal::FSPromoter::demoteFS(listFS);
  }

  int XmiDeserializerHandler::createFloatList(vector<string>& stringList)	{
	  FloatListFS listFS =   iv_cas->createFloatListFS();
    for (size_t i = 0; i < stringList.size(); i++ ) {
      float value = atof (stringList.at(i).c_str()); 
	    listFS.addLast(value);
    }
	  return internal::FSPromoter::demoteFS(listFS);
  }

  int XmiDeserializerHandler::createFSList(vector<string>& stringList)	{
	  int first = iv_cas->getHeap()->createFS(internal::gs_tyEListType);

	  size_t i = stringList.size();
	  for  (;i > 0;i--) {
		  int value = atoi(stringList.at(i-1).c_str());
		  int node = iv_cas->getHeap()->createFS(internal::gs_tyNEListType);
		  fsListNodesFromMultivaluedProperties.push_back(node);
		  iv_cas->getHeap()->setFeatureInternal(node, internal::gs_tyHeadFeature, value);
		  iv_cas->getHeap()->setFeatureInternal(node, internal::gs_tyTailFeature, first);
		  first = node;
	  }
	  return first;
  }

  int XmiDeserializerHandler::createStringList(vector<string>& stringList)	{   
    StringListFS listFS =   iv_cas->createStringListFS();
    for (size_t i = 0; i < stringList.size(); i++ ) {
      UnicodeString value(stringList.at(i).c_str()); //use xmiId to look up addr
	    listFS.addLast(value);
    }
	  return internal::FSPromoter::demoteFS(listFS);
  }

  void XmiDeserializerHandler::remapFSListHeads(int addr) {
    int type = iv_cas->getHeap()->getType(addr);
	  if (type != internal::gs_tyIntListType &&
		  type != internal::gs_tyFloatListType &&
		  type != internal::gs_tyStringListType &&
		  type != internal::gs_tyFSListType &&
		  type != internal::gs_tyNEListType) {
      return;
	  }

	  int headFeat = internal::gs_tyHeadFeature;
    int featVal = iv_cas->getHeap()->getFeatureInternal(addr, headFeat);
    if (featVal != 0) {
      int fsValAddr = 0;
	  	try {
		  	  //cout << __LINE__ << " remap calling getFsAddrForXmiId " << featVal << endl;
		  	  fsValAddr = getFsAddrForXmiId(featVal);
		  } catch (Exception e) {
			  if (!lenient) {
			    throw e;
			  } else {
				  stringstream str;
				  str << featVal;
				  this->sharedData->addOutOfTypeSystemAttribute(addr, CAS::FEATURE_BASE_NAME_HEAD, str.str());
			  }
		  }
		  iv_cas->getHeap()->setFeatureInternal(addr, headFeat, fsValAddr);
    }
  }


  void XmiDeserializerHandler::finalizeFS(int deserializedfsaddr) {
    lowlevel::TyFS addr = deserializedfsaddr; 
    FeatureStructure fs = uima::internal::FSPromoter::promoteFS(addr, *iv_cas);
    Type type = fs.getType();
    if (iv_cas->getTypeSystem().isArrayType(uima::internal::FSPromoter::demoteType(type)) ) {    
      finalizeArray(type, addr); 
      return;
    }

    //update heap value of features that are references to other FS.
    vector<Feature> feats;
    type.getAppropriateFeatures(feats);

    for (size_t i = 0; i < feats.size(); i++) {
      Feature feat = (Feature) feats[i];
      Type rangeType;
      feat.getRangeType(rangeType);
      if (rangeType.isValid()) {
        lowlevel::TyFSType  rangetypecode = uima::internal::FSPromoter::demoteType(rangeType);
        lowlevel::TyFSFeature featcode = uima::internal::FSPromoter::demoteFeature(feat);

        //if not primitive
        if (iv_cas->getTypeSystem().isFSType(rangetypecode)  ||
          (iv_cas->getTypeSystem().isArrayType(rangetypecode) && 
          feat.isMultipleReferencesAllowed() ) || 
          (iv_cas->getTypeSystem().isListType(rangetypecode) && 
          feat.isMultipleReferencesAllowed()) ) {
            //get the current feature value which is the id
            lowlevel::TyFS featVal = iv_casimpl.getHeap().getFeatureInternal(addr, featcode);
            if (featVal != 0) {
              int fsValAddr = 0;
              try {
                //cout << __LINE__ << feat.getName() << " calling getFsAddrForXmiId " << featVal << endl;
                fsValAddr = getFsAddrForXmiId(featVal);		 
              } catch (Exception e) {
                if (!lenient) {
                  throw e;
                }
                else {
                  //this may be a reference to an out-of-typesystem FS
                  stringstream str;
                  str << featVal;
                  this->sharedData->addOutOfTypeSystemAttribute(addr, 
                      ((UnicodeStringRef)feat.getName()).asUTF8(), str.str());
                }       
              }
              iv_casimpl.getHeap().setFSValue(addr, featcode, fsValAddr);
            }
         }
      }
    }
  }


  void XmiDeserializerHandler::finalizeArray(Type & type, lowlevel::TyFS addr) {

    lowlevel::TyFSType typecode = uima::internal::FSPromoter::demoteType(type);
    if (!iv_cas->getTypeSystem().isFSArrayType(typecode)) {
      return;
    }
    // *** WARNING ***  *** WARNING ***  *** WARNING ***  *** WARNING ***
    // if implementation of ArrayFS on the heap changes, this code will be invalid
    int size = (int)iv_cas->getHeap()->getHeap().getHeapValue(addr + 1);
	
    for (int i=0; i<size; i++) {
      lowlevel::TyFS arrayVal = iv_cas->getHeap()->getHeap().getHeapValue(addr + 2 + i);
      if (arrayVal != 0) {
        int arrayValAddr = 0;
        try {
          //cout << __LINE__ << " calling getFsAddrForXmiId " << arrayVal << endl;
          arrayValAddr = getFsAddrForXmiId(arrayVal);
        } catch (Exception e) {
          if (!lenient) {
            throw e;
          }
          else {  
            // the array element may be out of typesystem.  In that case set it
            // to null, but record the id so we can add it back on next serialization.
            this->sharedData->addOutOfTypeSystemArrayElement(addr, i, arrayVal);
          }
        }
        iv_cas->getHeap()->getHeap().setHeapValue(addr + 2 + i, arrayValAddr);
      }
    }
  }

   /**
     * Gets the FS address into which the XMI element with the given ID
     * was deserialized.  This method supports merging multiple XMI documents
     * into a single CAS, by checking the XmiSerializationSharedData
     * structure to get the address of elements that were skipped during this
     * deserialization but were deserialized during a previous deserialization.
     * 
     * @param xmiId
     * @return
     */
  int XmiDeserializerHandler::getFsAddrForXmiId(int xmiId) {
    int addr = sharedData->getFsAddrForXmiId(xmiId);
		//cout << "xmiid=" << xmiId << "fsaddr=" << addr << endl;
    if (addr > 0)
        return addr;
	   else {  
      //cerr << __FILE__<<__LINE__ <<  " throw exc No such xmiid " << xmiId << endl;
		  ErrorInfo errInfo;
		  errInfo.setErrorId((TyErrorId)UIMA_ERR_RESOURCE_CORRUPTED);
		  ErrorMessage msg(UIMA_MSG_ID_EXC_XML_SAXPARSE_FATALERROR);
		  assertWithMsg(sizeof(XMLCh) == sizeof(UChar), "Port required");
		  msg.addParam("getFsAddrForXmiId");
		  msg.addParam(xmiId);
		  errInfo.setMessage(msg);
		  errInfo.setSeverity(ErrorInfo::unrecoverable);
		  ExcIllFormedInputError exc(errInfo);
		  throw exc; 
	  }
  }

	/**
   * Adds a feature sturcture to the out-of-typesystem data.  Also sets the
   * this->outOfTypeSystemElement field, which is referred to later if we have to
   * handle features recorded as child elements.
   */
  void XmiDeserializerHandler::addToOutOfTypeSystemData(XmlElementName * xmlElementName, const Attributes & attrs) {
    this->outOfTypeSystemElement = new OotsElementData();
    //this->outOfTypeSystemElement->elementName = xmlElementName->qualifiedName;
	  this->outOfTypeSystemElement->elementName = xmlElementName;
    UnicodeString attrName;
	  UnicodeString attrValue;
    for (size_t i = 0; i < attrs.getLength(); i++) {
      attrName = attrs.getQName(i);
      attrValue = attrs.getValue(i);
      if (attrName.compare(UnicodeString(XMI_ID_ATTR_NAME))==0) {
		    UnicodeStringRef uref(attrValue);
        this->outOfTypeSystemElement->xmiId = atoi(uref.asUTF8().c_str());
      }
      else {
        this->outOfTypeSystemElement->attributes.push_back(
                  new XmlAttribute(attrName, attrValue));
      }
    }
    this->sharedData->addOutOfTypeSystemElement(this->outOfTypeSystemElement);
  }    

    /**
     * Adds a feature to the out-of-typesystem features list.
     * @param ootsElem object to which to add the feature
     * @param featName name of feature
     * @param featVals feature values, as a list of strings
     */
  void XmiDeserializerHandler::addOutOfTypeSystemFeature(OotsElementData * ootsElem, 
		UnicodeString & featName, 
		vector<UnicodeString> & featVals) {
	  vector<string> * pVals = new vector<string>;
    for (size_t i=0;i<featVals.size();i++) {
		  pVals->push_back(  ((UnicodeStringRef)featVals.at(i)).asUTF8());    
    }
	  ootsElem->childElements[ ((UnicodeStringRef)featName).asUTF8()] = pVals;
  } 
// ---------------------------------------------------------------------------
//  XmiDeserializerHandler: Overrides of the SAX ErrorHandler interface
// ---------------------------------------------------------------------------
  void XmiDeserializerHandler::error(const SAXParseException& e) {
    ErrorInfo errInfo;
    errInfo.setErrorId((TyErrorId)UIMA_ERR_RESOURCE_CORRUPTED);
    ErrorMessage msg(UIMA_MSG_ID_EXC_XML_SAXPARSE_ERROR);
    assertWithMsg(sizeof(XMLCh) == sizeof(UChar), "Port required");
    msg.addParam((UChar const *)e.getSystemId());
    msg.addParam(e.getLineNumber());
    msg.addParam(e.getColumnNumber());
    msg.addParam((UChar const *) e.getMessage());
    errInfo.setMessage(msg);
    errInfo.setSeverity(ErrorInfo::unrecoverable);
    ExcIllFormedInputError exc(errInfo);
    throw exc;
  }

  void XmiDeserializerHandler::fatalError(const SAXParseException& e) {
    ErrorInfo errInfo;
    errInfo.setErrorId((TyErrorId)UIMA_ERR_RESOURCE_CORRUPTED);
    ErrorMessage msg(UIMA_MSG_ID_EXC_XML_SAXPARSE_FATALERROR);
    assertWithMsg(sizeof(XMLCh) == sizeof(UChar), "Port required");
    msg.addParam((UChar const *)e.getSystemId());
    msg.addParam(e.getLineNumber());
    msg.addParam(e.getColumnNumber());
    msg.addParam((UChar const *) e.getMessage());
    errInfo.setMessage(msg);
    errInfo.setSeverity(ErrorInfo::unrecoverable);
    ExcIllFormedInputError exc(errInfo);
    throw exc;
  }

  void XmiDeserializerHandler::warning(const SAXParseException& e) {
    ErrorInfo errInfo;
    errInfo.setErrorId((TyErrorId)UIMA_ERR_RESOURCE_CORRUPTED);
    ErrorMessage msg(UIMA_MSG_ID_EXC_XML_SAXPARSE_WARNING);
    assertWithMsg(sizeof(XMLCh) == sizeof(UChar), "Port required");
    msg.addParam((UChar const *)e.getSystemId());
    msg.addParam(e.getLineNumber());
    msg.addParam(e.getColumnNumber());
    msg.addParam((UChar const *) e.getMessage());
    errInfo.setMessage(msg);
    errInfo.setSeverity(ErrorInfo::unrecoverable);
    ExcIllFormedInputError exc(errInfo);
    throw exc;
  }

  char const * XmiDeserializerHandler::XMI_ID_ATTR_NAME = "xmi:id";
  char const * XmiDeserializerHandler::TRUE_VALUE = "true";
  char const * XmiDeserializerHandler::DEFAULT_CONTENT_FEATURE = "value";
  char const * XmiDeserializerHandler::DEFAULT_NAMESPACE_URI = "http:///uima/noNamespace.ecore";


} // namespace uima



