/** \file xmlwriter.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.

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

   Description:

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


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


/* ----------------------------------------------------------------------- */
/*       Include dependencies                                              */
/* ----------------------------------------------------------------------- */
#include "uima/pragmas.hpp"

#include "uima/xmiwriter.hpp"
#include "uima/arrayfs.hpp"
#include "uima/listfs.hpp"
#include "uima/lowlevel_indexrepository.hpp"
#include "uima/lowlevel_indexiterator.hpp"
#include "uima/internal_casimpl.hpp"
#include "uima/internal_fspromoter.hpp"
#include "uima/fsindexrepository.hpp"

#include "uima/resmgr.hpp"
#include "uima/location.hpp"
#include <sstream>

/* ----------------------------------------------------------------------- */
/*       Constants                                                         */
/* ----------------------------------------------------------------------- */
//#define TAB_INCREMENT 0

/* ----------------------------------------------------------------------- */
/*       Forward declarations                                              */
/* ----------------------------------------------------------------------- */

/* ----------------------------------------------------------------------- */
/*       Types / Classes                                                   */
/* ----------------------------------------------------------------------- */


namespace uima {

  ////////////////////////////////////////////////////////////////////////
  // XmiWriter

  XmiWriter::XmiWriter(CAS const & cas, bool addDocument)
      : XMLWriterABase(cas, addDocument),  sharedData(0),
      iv_stringType( cas.getTypeSystem().getType(uima::CAS::TYPE_NAME_STRING) ),
      iv_integerType( cas.getTypeSystem().getType(uima::CAS::TYPE_NAME_INTEGER) ),
      iv_floatType( cas.getTypeSystem().getType(uima::CAS::TYPE_NAME_FLOAT) ),
      iv_byteType( cas.getTypeSystem().getType(uima::CAS::TYPE_NAME_BYTE) ),
      iv_booleanType( cas.getTypeSystem().getType(uima::CAS::TYPE_NAME_BOOLEAN) ),
      iv_shortType( cas.getTypeSystem().getType(uima::CAS::TYPE_NAME_SHORT) ),
      iv_longType( cas.getTypeSystem().getType(uima::CAS::TYPE_NAME_LONG) ),
      iv_doubleType( cas.getTypeSystem().getType(uima::CAS::TYPE_NAME_DOUBLE) ),
      iv_arrayType( cas.getTypeSystem().getType(uima::CAS::TYPE_NAME_ARRAY_BASE) ),
      iv_stringArrayType( cas.getTypeSystem().getType(uima::CAS::TYPE_NAME_STRING_ARRAY) ),
      iv_intArrayType( cas.getTypeSystem().getType(uima::CAS::TYPE_NAME_INTEGER_ARRAY) ),
      iv_floatArrayType( cas.getTypeSystem().getType(uima::CAS::TYPE_NAME_FLOAT_ARRAY) ),
      iv_byteArrayType( cas.getTypeSystem().getType(uima::CAS::TYPE_NAME_BYTE_ARRAY) ),
      iv_booleanArrayType( cas.getTypeSystem().getType(uima::CAS::TYPE_NAME_BOOLEAN_ARRAY) ),
      iv_shortArrayType( cas.getTypeSystem().getType(uima::CAS::TYPE_NAME_SHORT_ARRAY) ),
      iv_longArrayType( cas.getTypeSystem().getType(uima::CAS::TYPE_NAME_LONG_ARRAY) ),
      iv_doubleArrayType( cas.getTypeSystem().getType(uima::CAS::TYPE_NAME_DOUBLE_ARRAY) ),
      iv_sofaType( cas.getTypeSystem().getType(uima::CAS::TYPE_NAME_SOFA) ) {
    assert( iv_stringType.isValid());
    assert( iv_integerType.isValid());
    assert( iv_floatType.isValid());
    assert( iv_byteType.isValid());
    assert( iv_booleanType.isValid());
    assert( iv_shortType.isValid());
    assert( iv_longType.isValid());
    assert( iv_doubleType.isValid());
    assert( iv_stringArrayType.isValid() );
    assert( iv_arrayType.isValid() );
    assert( iv_intArrayType.isValid());
    assert( iv_floatArrayType.isValid());
    assert( iv_byteArrayType.isValid());
    assert( iv_booleanArrayType.isValid());
    assert( iv_shortArrayType.isValid());
    assert( iv_longArrayType.isValid());
    assert( iv_doubleArrayType.isValid());
    assert( iv_sofaType.isValid());
  }

  XmiWriter::XmiWriter(CAS const & cas, bool addDocument, XmiSerializationSharedData * serdata)
      : XMLWriterABase(cas, addDocument),  sharedData(serdata),
      iv_stringType( cas.getTypeSystem().getType(uima::CAS::TYPE_NAME_STRING) ),
      iv_integerType( cas.getTypeSystem().getType(uima::CAS::TYPE_NAME_INTEGER) ),
      iv_floatType( cas.getTypeSystem().getType(uima::CAS::TYPE_NAME_FLOAT) ),
      iv_byteType( cas.getTypeSystem().getType(uima::CAS::TYPE_NAME_BYTE) ),
      iv_booleanType( cas.getTypeSystem().getType(uima::CAS::TYPE_NAME_BOOLEAN) ),
      iv_shortType( cas.getTypeSystem().getType(uima::CAS::TYPE_NAME_SHORT) ),
      iv_longType( cas.getTypeSystem().getType(uima::CAS::TYPE_NAME_LONG) ),
      iv_doubleType( cas.getTypeSystem().getType(uima::CAS::TYPE_NAME_DOUBLE) ),
      iv_arrayType( cas.getTypeSystem().getType(uima::CAS::TYPE_NAME_ARRAY_BASE) ),
      iv_stringArrayType( cas.getTypeSystem().getType(uima::CAS::TYPE_NAME_STRING_ARRAY) ),
      iv_intArrayType( cas.getTypeSystem().getType(uima::CAS::TYPE_NAME_INTEGER_ARRAY) ),
      iv_floatArrayType( cas.getTypeSystem().getType(uima::CAS::TYPE_NAME_FLOAT_ARRAY) ),
      iv_byteArrayType( cas.getTypeSystem().getType(uima::CAS::TYPE_NAME_BYTE_ARRAY) ),
      iv_booleanArrayType( cas.getTypeSystem().getType(uima::CAS::TYPE_NAME_BOOLEAN_ARRAY) ),
      iv_shortArrayType( cas.getTypeSystem().getType(uima::CAS::TYPE_NAME_SHORT_ARRAY) ),
      iv_longArrayType( cas.getTypeSystem().getType(uima::CAS::TYPE_NAME_LONG_ARRAY) ),
      iv_doubleArrayType( cas.getTypeSystem().getType(uima::CAS::TYPE_NAME_DOUBLE_ARRAY) ),
      iv_sofaType( cas.getTypeSystem().getType(uima::CAS::TYPE_NAME_SOFA) ) {
    assert( iv_stringType.isValid());
    assert( iv_integerType.isValid());
    assert( iv_floatType.isValid());
    assert( iv_byteType.isValid());
    assert( iv_booleanType.isValid());
    assert( iv_shortType.isValid());
    assert( iv_longType.isValid());
    assert( iv_doubleType.isValid());
    assert( iv_stringArrayType.isValid() );
    assert( iv_arrayType.isValid() );
    assert( iv_intArrayType.isValid());
    assert( iv_floatArrayType.isValid());
    assert( iv_byteArrayType.isValid());
    assert( iv_booleanArrayType.isValid());
    assert( iv_shortArrayType.isValid());
    assert( iv_longArrayType.isValid());
    assert( iv_doubleArrayType.isValid());
    assert( iv_sofaType.isValid());
  }

  XmiWriter::~XmiWriter() {
    for (size_t i = 0; i < enqueuedFS.size(); i++) {
      vector<int> * indexes = (vector<int>*) enqueuedFS[i];
      if (indexes != 0)
        delete indexes;
    }
    for (size_t i = 0; i < xmiTypeNames.size(); i++) {
      if (xmiTypeNames.at(i) != 0) {
        delete xmiTypeNames.at(i);
      }
    }
  }

 /**
  * Populates nsUriToPrefixMap and xmiTypeNames structures based on CAS type system.
  */
 void XmiWriter::initTypeAndNamespaceMappings() {
   nsUriToPrefixMap[XMI_NS_URI] = XMI_NS_PREFIX;

   //Add any namespace prefix mappings used by out of type system data.
   //Need to do this before the in-typesystem namespaces so that the prefix
   //used here are reserved and won't be reused for any in-typesystem namespaces.
   if (this->sharedData !=  NULL) {
     vector<OotsElementData*> & ootsElements = this->sharedData->getOutOfTypeSystemElements();
     for(size_t i=0;i<ootsElements.size();i++) {
       OotsElementData * oed = ootsElements.at(i);
       string nsUri = oed->elementName->nsUri;
       string qname = oed->elementName->qualifiedName;
       string localName = oed->elementName->shortName;
       string prefix = qname.substr(0, oed->elementName->qualifiedName.find_first_of(":"));
       nsUriToPrefixMap[nsUri] = prefix;
       nsPrefixesUsed.insert(prefix);
     }
   }

   vector<Type>  allTypes;
   iv_cas.getTypeSystem().getAllTypes(allTypes);
   xmiTypeNames.resize(allTypes.size() + 1);
   //leave out 0th element.
   XmlElementName * invalidType = new XmlElementName("INVALID_TYPE",
     "INVALID_TYPE",
     "INVALID_TYPE");

   xmiTypeNames[0] = invalidType;

   for (size_t i = 0; i < allTypes.size() ; i++) {
     Type type = allTypes.at(i);
     lowlevel::TyFSType typecode = uima::internal::FSPromoter::demoteType(type);
     //cout << "Mapping " << type.getName() << endl;
     UnicodeStringRef name = type.getName();
     xmiTypeNames[typecode] = uimaTypeName2XmiElementName(name);
     // this also populats the nsUriToPrefix map
   }
 }

 /**
 * Converts a UIMA-style dotted type name to the element name that should be used in the XMI
 * serialization. The XMI element name consists of three parts - the Namespace URI, the Local
 * Name, and the QName (qualified name).
 *
 * @param uimaTypeName
 *          a UIMA-style dotted type name
 * @return a data structure holding the three components of the XML element name
 */
 XmlElementName * XmiWriter::uimaTypeName2XmiElementName(UnicodeStringRef & uimaTypeName) {
   // split uima type name into namespace and short name
   string nameSpace;
   string shortName;
   string nsUri;
   string qName;
   string typeName = uimaTypeName.asUTF8();
   int lastDotIndex = typeName.find_last_of(".");

   if (lastDotIndex == -1) // no namespace
   {
     shortName = typeName;
     nsUri = DEFAULT_NAMESPACE_URI;
   } else {
     nameSpace = typeName.substr(0, lastDotIndex);
     shortName = typeName.substr(lastDotIndex + 1);
     nsUri = "http:///";
     nsUri.append(nameSpace);
     std::replace(nsUri.begin(), nsUri.end(), '.', '/');
     nsUri.append(".ecore");
     //cout << nsUri << endl;
   }

   // determine what namespace prefix to use
   map<string, string>::iterator ite = nsUriToPrefixMap.find(nsUri);
   string prefix;
   if  (ite != nsUriToPrefixMap.end()) {
     prefix =  ite->second;
   }

   //create a prefix and associate nameSpace with prefix
   if (prefix.length() == 0) {
     if (nameSpace.length() != 0) {
       int secondLastDotIndex = nameSpace.find_last_of(".");
       //cout << nameSpace << " secondlastdot " << secondLastDotIndex << endl;
       prefix = nameSpace.substr(secondLastDotIndex + 1);
     } else {
       prefix = "noNamespace";
     }
     //cout << "prefix " << prefix << endl;
     // make sure this prefix hasn't already been used for some other namespace
     set<string>::iterator prefixIte = nsPrefixesUsed.find(prefix);
     int num=1;
     while (prefixIte != nsPrefixesUsed.end()) {
       num++;
       stringstream basePrefix;
       basePrefix << prefix << num << endl;
       prefixIte = nsPrefixesUsed.find(basePrefix.str());
       if (prefixIte == nsPrefixesUsed.end() ) {
         prefix = basePrefix.str();
         break;
       }
     }
     nsPrefixesUsed.insert(prefix);
     nsUriToPrefixMap[nsUri] = prefix;
   }
   qName = prefix;
   qName.append(":");
   qName.append(shortName);
   return new XmlElementName(nsUri, shortName, qName);

 }

 void XmiWriter::writeViews(ostream & os, CAS const & cas)  {
   // Get indexes for each SofaFS in the CAS
   int numViews = cas.iv_baseCas->iv_sofaCount; 
   //const CAS * baseCas = cas.getBaseCas();
   int sofaXmiId=0;
   lowlevel::TyFS  sofaAddr;

   for (int sofaNum = 1; sofaNum <= numViews; sofaNum++) {
     vector<lowlevel::TyFS> indexedFS;
     SofaFS sofa = cas.iv_baseCas->getSofa(sofaNum); 

     lowlevel::IndexRepository * loopIR = cas.iv_baseCas->iv_sofa2indexMap[sofaNum];

     if (sofaNum != 1 || cas.iv_baseCas->isInitialSofaCreated()) {
       sofaAddr = internal::FSPromoter::demoteFS(sofa);
       sofaXmiId = this->getXmiId(sofaAddr);
     }
     if (loopIR != NULL) { 
       loopIR->getIndexedFSs(indexedFS);
       writeView(os, sofaXmiId, indexedFS);
     }
   }
 }

 void XmiWriter::writeView(ostream & os,int sofaXmiId, vector<lowlevel::TyFS>& members) {
   UnicodeString viewType(UnicodeString("uima.cas.View"));
   UnicodeStringRef uref(viewType.getBuffer(), viewType.length());
   XmlElementName * elemName = uimaTypeName2XmiElementName(uref);

   stringstream membersString;
   for (size_t i = 0; i < members.size(); i++) {
     membersString << getXmiId(members.at(i)) << " ";
   }

   //check for out-of-typesystem members
   if (this->sharedData != NULL) {
     vector<int> ootsMembers;
     this->sharedData->getOutOfTypeSystemViewMembers(sofaXmiId, ootsMembers);
     if (ootsMembers.size() != 0) {
       for (size_t i=0; i < ootsMembers.size(); i++) {
         membersString << ootsMembers.at(i) << " ";
       }
     }
   }

   //remove leading and trailing blanks
   string outstr = membersString.str();
   size_t startpos = outstr.find_first_not_of(" ");
   size_t endpos = outstr.find_last_not_of(" ");
   if (string::npos != startpos && string::npos != endpos) {
     outstr = outstr.substr(startpos, endpos-startpos+1);
   } 

   if (sofaXmiId !=0 || outstr.size() > 0) {
     os << "<" << elemName->qualifiedName;
     if (sofaXmiId != 0) {
       os << " sofa=\"" << sofaXmiId << "\"";
     }
     if (outstr.size() > 0) {
       os << " members=\"" << outstr << "\"";
     }
     os << "/>";
   }   
     delete elemName;
 }

  bool XmiWriter::isReferenceType(Type const & t) const {
    return !( t.getTypeSystem().isPrimitive(uima::internal::FSPromoter::demoteType(t)) );
  }

  void XmiWriter::writeFeatureValue(ostream & os, FeatureStructure const & fs, Feature const & f) {
    assert( fs.isValid() );
    assert( f.isValid() );
    Type t;
    f.getRangeType(t); 
    assert( t.isValid() );
    if ( t == iv_stringType || t.isStringSubType() ) {
      UnicodeStringRef ref = fs.getStringValue(f);
      if (ref.getBuffer() != NULL) {
        icu::UnicodeString us;
        normalize( ref, us );
        os << " " << f.getName() << "=\"";
        os << us << "\"";
      }
    } else if (t == iv_integerType) {
      os << " " << f.getName() << "=\"";
      os << fs.getIntValue(f) << "\"";
    } else if (t == iv_floatType) {
      os << " " << f.getName() << "=\"";
      os << fs.getFloatValue(f) << "\"";
    } else if (t == iv_byteType) {
      os << " " << f.getName() << "=\"";
      int val = fs.getByteValue(f);
      os << val << "\"";
    } else if (t == iv_booleanType) {
      os << " " << f.getName() << "=\"";
      if (fs.getBooleanValue(f))
        os << "true" << "\"";
      else 
        os << "false" << "\"";
    } else if (t == iv_shortType) {
      os << " " << f.getName() << "=\"";
      os << fs.getShortValue(f) << "\"";
    } else if (t == iv_longType) {
      os << " " << f.getName() << "=\"";
      os << fs.getLongValue(f) << "\"";
    } else if (t == iv_doubleType) {
      os << " " << f.getName() << "=\"";
      stringstream s;
      s << fs.getDoubleValue(f);
      os << s.str() << "\"";
    } else {
     
      FeatureStructure referencedFS = fs.getFSValue(f);
      uima::lowlevel::TyFS lolFS = uima::internal::FSPromoter::demoteFS(referencedFS);
      if (lolFS != uima::lowlevel::FSHeap::INVALID_FS) {
        os << " " ;
        os << f.getName() << "=\"";
        //ptrdiff_t val = uima::internal::CASImpl::promoteCAS(iv_cas).getHeap().getUniqueID(lolFS);
        int val = getXmiId(lolFS);
        os << val << "\"";
      }
    }
  }

  template<class Array>
  void writeArray(ostream & os, Array const & array, char const * tag, int xmiid) {
    size_t i;
    if (array.size() > 0) {
      //XCAS os << " size=\"" << array.size() << "\">" << endl;
      os << " <" << tag;
            os << " " << XmiWriter::ID_ATTR_NAME << "=\"" << xmiid << "\"";
      os << " elements=\"" ;
      os << arrayToString(array, tag);    
      os << "\"/>" << endl;
    } else {
      //XCAS os << " size=\"0\"/>" << endl;
    }
  }

  void XmiWriter::writeArray(ostream & os, 
                            FeatureStructure const & array, 
                            char const * tag, int xmiid) { 
      os << " <" << tag;
      os << " " << ID_ATTR_NAME << "=\"" << xmiid << "\"";
      os << " elements=\"" ;
      os << arrayToString(array, tag);
      os << "\"/>" << endl;
  }

 string XmiWriter::arrayToString(FeatureStructure const & fs, char const * tag) {  
   stringstream str;

   int typecode = internal::FSPromoter::demoteType(fs.getType());
   switch (typecode) {
      case internal::gs_tyIntArrayType: {
        IntArrayFS arrayfs(fs);
        size_t n = arrayfs.size();
        for (size_t i=0; i < n;i++) {
          str << arrayfs.get(i);
          if (i+1 < n) {         
            str << " ";
          }
        }         
        break;
                                        }
      case internal::gs_tyFloatArrayType: {
        FloatArrayFS arrayfs(fs);
        size_t n = arrayfs.size();
        for (size_t i=0; i < n;i++) {
          str << arrayfs.get(i);
          if (i+1 < n) {         
            str << " ";
          }
        }         
        break;
                                          }
      case internal::gs_tyBooleanArrayType: {
        BooleanArrayFS arrayfs(fs);
        size_t n = arrayfs.size();
        for (size_t i=0; i < n;i++) {
          if (arrayfs.get(i)) {
            str << "true";
          } else {
            str << "false";
          }
          if (i+1 < n) {         
            str << " ";
          }
        }         
        break;
                                            }
      case internal::gs_tyByteArrayType: {
        ByteArrayFS arrayfs(fs);
        size_t n = arrayfs.size();
                char * out = new char[3];
                memset(out,0,3);
        for (size_t i=0; i < n;i++) {      
          sprintf(out,"%02X",0xFF & arrayfs.get(i)); 
          //printf ("itoahexadecimal: %d %d\n",i, arrayfs.get(i));
          str << out[0] << out[1];            
        }         
            delete[] out;
        break;
                                         }
      case internal::gs_tyShortArrayType: {
        ShortArrayFS arrayfs(fs);
        size_t n = arrayfs.size();
        for (size_t i=0; i < n;i++) {
          str << arrayfs.get(i);
          if (i+1 < n) {         
            str << " ";
          }
        }         
        break;
                                          }
      case internal::gs_tyLongArrayType: {
        LongArrayFS arrayfs(fs);
        size_t n = arrayfs.size();
        for (size_t i=0; i < n;i++) {
          str << arrayfs.get(i);
          if (i+1 < n) {         
            str << " ";
          }
        }         
        break;
                                         }
      case internal::gs_tyDoubleArrayType: {
        DoubleArrayFS arrayfs(fs);
        size_t n = arrayfs.size();
        for (size_t i=0; i < n;i++) {
          str << arrayfs.get(i);
          if (i+1 < n) {         
            str << " ";
          }
        }         
        break;
                                           }
      case internal::gs_tyFSArrayType: {
        ArrayFS arrayfs(fs);
        size_t size = arrayfs.size();

        vector<XmiArrayElement*> * ootsList = NULL;
        if (this->sharedData != NULL) {
          ootsList = this->sharedData->getOutOfTypeSystemArrayElements(internal::FSPromoter::demoteFS(arrayfs));
        }
        size_t ootsIndex = 0;
        for (size_t j=0; j < size; j++) {
          int xmiId = getXmiId(uima::internal::FSPromoter::demoteFS(arrayfs.get(j)));//convert to xmiid; 0 if not set
          if (xmiId == 0) {  //if 0 check if its an Oots FS 
            // However, this null array element might have been a reference to an 
            //out-of-typesystem FS, so check the ootsArrayElementsList
            if (ootsList != NULL) {
              while (ootsIndex < ootsList->size()) {
                XmiArrayElement * arel = ootsList->at(ootsIndex++);
                if (arel->index == j) {
                  str << arel->xmiId;
                  break;
                }                
              }
            }
          } else {
            str << xmiId;
          }
          if (j+1 < size) {         
            str << " ";
          }
        }         
        break;
                                       }
      case internal::gs_tyStringArrayType: {
        StringArrayFS arrayfs(fs);
        size_t n = arrayfs.size();
         UnicodeString ustr;       
        for (size_t i=0; i < n;i++) {
          ustr.setTo("");
          normalize( arrayfs.get(i), ustr );
          str << "<" << tag << ">" << ustr << "</" << tag << ">";
         
        }         
        break;
                                           }
      default: {
        cerr << "arrayToString() type not supported " << typecode << endl;
        ErrorInfo errInfo;
        errInfo.setErrorId((TyErrorId)UIMA_ERR_RESOURCE_CORRUPTED);
        ErrorMessage msg(UIMA_MSG_ID_EXC_XML_SAXPARSE_FATALERROR);
        msg.addParam("arrayToString() type not supported.");
        msg.addParam(typecode);
        errInfo.setMessage(msg);
        errInfo.setSeverity(ErrorInfo::unrecoverable);
        ExcIllFormedInputError exc(errInfo);
        throw exc; 
      }
    }
    return str.str();
  }

  void XmiWriter::writeBooleanArray(ostream & os, BooleanArrayFS const & array, char const * tag, int xmiid) {
    
    if (array.size() > 0) {
      os << " <" << tag;
      os << " " << ID_ATTR_NAME << "=\"" << xmiid << "\"";
      os << " elements=\"" ;
        os << arrayToString(array, tag).c_str();
        os << "\"/>" << endl;
    } 
  }

  void XmiWriter::writeStringArray(ostream & os, StringArrayFS const & array, char const * tag, int xmiid) {
    if (array.size() > 0) {
      //XCAS os << " size=\"" << array.size() << "\">" << endl;
      os << " <" << tag;
      os << " " << ID_ATTR_NAME << "=\"" << xmiid << "\">";
        os << arrayToString(array, "elements").c_str();
        os << "</" << tag << ">" << endl;
    } 
  }

  void XmiWriter::writeFSFlat(ostream & os,
                               FeatureStructure const & fs,
                               vector<int>* indexInfo) {
    uima::internal::CASImpl const & crCASImpl = uima::internal::CASImpl::promoteCAS(iv_cas);
    assert( fs.isValid() );
    Type t = fs.getType();
    lowlevel::TyFSType  typecode = uima::internal::FSPromoter::demoteType(t);
    XmlElementName * xmlElementName = xmiTypeNames[typecode];
    bool insidelist = fs.getCAS().getTypeSystem().isListType(typecode);
    int xmiId = /**crCASImpl.getHeap().getUniqueID**/
      getXmiId( uima::internal::FSPromoter::demoteFS(fs) );
   
    // if array
    if ( iv_arrayType.subsumes(t) ) {
      const CAS* ccasp = &iv_cas;
      CAS* casp = const_cast<CAS*> (ccasp);
        if (casp->getHeap()->getArraySize(internal::FSPromoter::demoteFS(fs)) >0) {
            if ( t == iv_intArrayType ) {
                writeArray( os, IntArrayFS(fs), xmlElementName->qualifiedName.c_str(), xmiId);
            } else if ( t == iv_floatArrayType ) {
                writeArray( os, FloatArrayFS(fs), xmlElementName->qualifiedName.c_str(), xmiId);
            } else if ( t == iv_stringArrayType ) {
                //cout << "got a string array " << endl;
                writeStringArray( os, StringArrayFS(fs), xmlElementName->qualifiedName.c_str(), xmiId);
            } else if ( t == iv_byteArrayType ) {
                writeArray(os, ByteArrayFS(fs), xmlElementName->qualifiedName.c_str(), xmiId);
            } else if ( t == iv_booleanArrayType ) {
                writeArray( os, BooleanArrayFS(fs), xmlElementName->qualifiedName.c_str(), xmiId);
            } else if ( t == iv_shortArrayType ) {
                writeArray( os, ShortArrayFS(fs),xmlElementName->qualifiedName.c_str(), xmiId );
            } else if ( t == iv_longArrayType ) {
                writeArray( os, LongArrayFS(fs), xmlElementName->qualifiedName.c_str(), xmiId);
            } else if ( t == iv_doubleArrayType ) {
                writeArray( os, DoubleArrayFS(fs), xmlElementName->qualifiedName.c_str(), xmiId);
            } else {
                assert( t == iv_cas.getTypeSystem().getType(uima::CAS::TYPE_NAME_FS_ARRAY) );
                if (internal::FSPromoter::demoteType(t) == internal::gs_tyFSArrayType) {
                    writeArray( os, ArrayFS(fs), xmlElementName->qualifiedName.c_str(), xmiId);
                } else {
                    cerr << "writeFSFlat unknown array type " << t.getName() << endl;
                }
            }
        }
    } else {
      vector<Feature> features;
      fs.getType().getAppropriateFeatures(features);
      size_t i;
        stringstream strcontent;
        os << " <" << xmlElementName->qualifiedName;
        os << " " << ID_ATTR_NAME << "=\"" << getXmiId( uima::internal::FSPromoter::demoteFS(fs) ) << "\"";
      bool containsElements=false;
        for (i=0; i<features.size(); ++i) {
        uima::Feature const & f = features[i];
        Type range;
        f.getRangeType(range); 
            int typecode = internal::FSPromoter::demoteType(range);
            //cout << "writeFSFlat() " << range.getName() << endl;
        switch (typecode) {
        case internal::gs_tyBooleanType:
        case internal::gs_tyByteType:
        case internal::gs_tyIntegerType:
        case internal::gs_tyFloatType:
        case internal::gs_tyStringType:
        case internal::gs_tyShortType:
        case internal::gs_tyLongType:
        case internal::gs_tyDoubleType: {
          writeFeatureValue(os, fs, f);
          break;
        }
        case internal::gs_tyStringArrayType: {
          if (f.isMultipleReferencesAllowed() ) {
            writeFeatureValue(os, fs, f);
          } else {
            StringArrayFS arrayFS = fs.getStringArrayFSValue(f);
            if (arrayFS.isValid() && arrayFS.size() > 0) {
              strcontent << arrayToString(arrayFS, f.getName().asUTF8().c_str());
            }
          }
          break;                             
        }
        case internal::gs_tyIntArrayType:
        case internal::gs_tyFloatArrayType:
        case internal::gs_tyByteArrayType:
        case internal::gs_tyBooleanArrayType:
        case internal::gs_tyShortArrayType:
        case internal::gs_tyLongArrayType:
        case internal::gs_tyDoubleArrayType:
        case internal::gs_tyFSArrayType:   {
          if (f.isMultipleReferencesAllowed() ) {
            writeFeatureValue(os, fs, f);
          } else {
            if (fs.getFSValue(f).isValid()) {
              string str = arrayToString(fs.getFSValue(f), f.getName().asUTF8().c_str());          
              os << " " << f.getName() << "=\"" << str << "\" ";
            }
          }
          break;                               
        }
        case internal::gs_tyIntListType:
        case internal::gs_tyEIntListType:
        case internal::gs_tyNEIntListType:
        case internal::gs_tyFloatListType:
        case internal::gs_tyEFloatListType:
        case internal::gs_tyNEFloatListType:
        case internal::gs_tyFSListType:  {
          if (f.isMultipleReferencesAllowed() || insidelist) {
            writeFeatureValue(os, fs, f);
          } else {
            if (fs.getFSValue(f).isValid()) {
              string str = listToString(fs.getFSValue(f), f.getName().asUTF8().c_str());                  
              os << " " << f.getName() << "=\"" << str << "\" ";  
              //cout << "   " << range.getName() << str << endl;
            }
          }
          break;
        }
        case internal::gs_tyStringListType:
        case internal::gs_tyEStringListType:
        case internal::gs_tyNEStringListType: {
          FeatureStructure listFS = fs.getFSValue(f);
          if (listFS.isValid()) {
            if (f.isMultipleReferencesAllowed() ) {
              writeFeatureValue(os, fs, f);
            } else {
              if (fs.getFSValue(f).isValid()) {
                string str = listToString(fs.getFSValue(f), f.getName().asUTF8().c_str());          
                if (listFS.isValid() && str.length() > 0) {
                  strcontent << str;
                }
              }
            }
          }
          break;
        }
        default: { 
          writeFeatureValue(os, fs, f);
          break;
        }
     }      
    }
      
  //add out-of-typesystem features, if any
  if (this->sharedData != NULL) {
    int fsaddr = internal::FSPromoter::demoteFS(fs);
    OotsElementData * oed = this->sharedData->getOutOfTypeSystemFeatures(fsaddr);
    if (oed != NULL) {
      //attributes
      for (size_t a=0; a < oed->attributes.size(); a++) {
        XmlAttribute * attr = oed->attributes.at(a);
        os << " " << attr->name << "=\"" << attr->value << "\"";
      }
      //child elements
      map<string,vector<string>*>::iterator ite ;
      for (ite = oed->childElements.begin();
        ite != oed->childElements.end(); ite++) {
          vector<string> * values = ite->second;
          for (size_t v=0; v < values->size();v++) {
            strcontent << " <" << ite->first 
              << ">" << values->at(v) 
              << "</" << ite->first << ">";
          }
        }
      }
    }
    // write stringArray and/or stringList Features if any
    if (strcontent.str().length() > 0) {
      os << ">" << strcontent.str();
      os << "</" << xmlElementName->qualifiedName << ">" << endl;
      strcontent.clear();
    } else {
      os << "/>" << endl;
    } 
  } 
}


void XmiWriter::findReferencedFSs(FeatureStructure const & fs, bool check) {
    

    if (! fs.isValid() ) {
      return;
    }
    if (check) {
      if (! enqueueUnindexed(fs)) {
        // already been processed
        return;
      }
    }
    Type t = fs.getType();
    //cout << "findReferencedFSs() " << t.getName() << endl;
    int tcode = internal::FSPromoter::demoteType(t);
    bool insideListNode=fs.getCAS().getTypeSystem().isListType(tcode);
    assert( t.isValid() );
    size_t i;
    if ( iv_arrayType.subsumes(t) ) {
      if ( t == iv_cas.getTypeSystem().getType(uima::CAS::TYPE_NAME_FS_ARRAY) ) {
        ArrayFS array(fs);
        for (i=0; i<array.size(); ++i) {
          findReferencedFSs(array.get(i));
        }
      }
    } 
    else {
      vector<Feature> features;
      fs.getType().getAppropriateFeatures(features);

      for (i=0; i<features.size(); ++i) {
        uima::Feature const & f = features[i];
        Type range;
        f.getRangeType(range); 
        if (isReferenceType(range)) {
          //cout << __LINE__ << "a referenced feature " <<
                //  f.getName() << endl;
                int typecode = internal::FSPromoter::demoteType(range);
                switch (typecode) {
                    case internal::gs_tyFSArrayType:  {
                      findReferencedFSs(fs.getFSValue(f));
                      break;
                  }
          case internal::gs_tyFSListType:  {
            // we only enqueue lists as first-class objects if the feature has
            // multipleReferencesAllowed = true
            // OR if we're already inside a list node (this handles the tail feature correctly)
            if (f.isMultipleReferencesAllowed() || insideListNode) {
              findReferencedFSs(fs.getFSValue(f));
            } else  {
              // enqueue any FSs reachable from an FSList
              enqueueFSListElements(fs.getFSValue(f));
            }
            break;
          }
                  case internal::gs_tyBooleanArrayType:
                  case internal::gs_tyByteArrayType:
                  case internal::gs_tyIntArrayType:
                  case internal::gs_tyFloatArrayType:
                  case internal::gs_tyStringArrayType:
                  case internal::gs_tyShortArrayType:
                  case internal::gs_tyLongArrayType:
                  case internal::gs_tyDoubleArrayType: {
                      if (f.isMultipleReferencesAllowed ()) {
                          findReferencedFSs(fs.getFSValue(f));
                    }
                      break;
                  }
                  case internal::gs_tyIntListType:
                  case internal::gs_tyFloatListType:
                  case internal::gs_tyStringListType:   {
                    if (f.isMultipleReferencesAllowed () || insideListNode) {
                          findReferencedFSs(fs.getFSValue(f));
                    }
                      break;
                  }
                  default: { //FS Ref
                      findReferencedFSs(fs.getFSValue(f));
                  }
            }
      }
    }
  }
}

void XmiWriter::write(ostream & os) {

  //build xmlTypeNames and nsUri to prefix mapping
  initTypeAndNamespaceMappings();
  //enqueue every FS that was deserialized into this CAS
  enqueueIncoming();
  const uima::lowlevel::IndexRepository * ixRep;
  const CAS* ccasp = &iv_cas;
  CAS* casp = const_cast<CAS*> (ccasp);
  CAS* tcas;
  uima::internal::CASImpl const & crCASImpl = uima::internal::CASImpl::promoteCAS(*casp->getBaseCas());
  ixRep = &crCASImpl.getIndexRepository();

  int numViews = casp->getNumViews();
  set<FeatureStructure> referencedFSs;
  for (int view=0; view<=numViews; view++) {
    if (view==0) {
      // First time through is for base CAS
      sofa = 0;
    } else {
      // for all Sofa found in the CAS, get new IndexRepository
      tcas = casp->getViewBySofaNum(view);
      sofa = tcas->getSofaNum();
      uima::internal::CASImpl & crTCASImpl = uima::internal::CASImpl::promoteCAS(*tcas);
      ixRep = &crTCASImpl.getIndexRepository();
    }

    // enqueue indexed FSs in known indexes
    vector<FeatureStructure> indexedFSs;
    vector<icu::UnicodeString> indexIDs = ixRep->getAllIndexIDs();
    size_t i;
    for (i=0; i<indexIDs.size(); ++i) {
      Type t = ixRep->getTypeForIndex(indexIDs[i]);
      FSIndex ix = ixRep->getIndex(indexIDs[i], t);
      FSIterator it = ix.iterator();
      for (it.moveToFirst(); it.isValid(); it.moveToNext()) {
        FeatureStructure fs = it.get();
        enqueueIndexed(fs, sofa);
      }
    }

    // enqueue the undefined index FSs
    for (size_t i=0;i < ixRep->iv_undefinedindex.size(); i++ ) {
      FeatureStructure fs = internal::FSPromoter::promoteFS(ixRep->iv_undefinedindex[i], iv_cas);
      enqueueIndexed(fs, sofa);
    }
  }

  os << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
  /////XCAS os << "<CAS>" << endl;
  os  << "<xmi:XMI " ;
  //write nsURI and prefix
  map<string, string>::iterator ite;
  for (ite=nsUriToPrefixMap.begin(); ite !=  nsUriToPrefixMap.end(); ite++) {
    os << "xmlns:" << ite->second << "=\"" << ite->first << "\" " ;
  }
  os << " xmi:version=\"2.0\">";
  // TODO: add schemaLocation if specified

  //Write a special instance of dummy type uima.cas.NULL, having xmi:id=0.
  //This is needed to represent nulls in multi-valued references, which 
  //aren't natively supported in Ecore.
  //?? XmlElementName * nullElement = uimaTypeName2XmiElementName("uima.cas.NULL"); //?
  os << "<cas:NULL xmi:id=\"0\"/>";

  // write out all enqueued FS
  map<int, vector<int>*>::iterator it;
  for (it = enqueuedFS.begin(); it != enqueuedFS.end(); it++) {
    FeatureStructure fs = internal::FSPromoter::promoteFS((*it).first, iv_cas);
    writeFSFlat(os, fs, (*it).second);
  }
  serializeOutOfTypeSystemElements(os); //encodes sharedData.getOutOfTypeSystemElements().size() elements
  writeViews(os,iv_cas);
  os << "</xmi:XMI>" << endl;
}

  // return true if the fs was not previously enqueued
  bool XmiWriter::enqueueUnindexed(FeatureStructure const &fs) {
    
    vector<int> * indexes;
    size_t tyfs = uima::internal::FSPromoter::demoteFS(fs);
    indexes = enqueuedFS[tyfs];
    if (NULL != indexes) {
      return false;
    }
    //cout << "enqueue new fs " << tyfs << " " << fs.getType().getName() << endl;
    // new FS, enqueue it
    indexes = new vector<int>;
    enqueuedFS[tyfs] = indexes;
    return true;
  }
  

  // return true if the fs was not previously enqueued
  bool XmiWriter::enqueueUnindexed(int id) {
    
    vector<int> * indexes;
    indexes = enqueuedFS[id];
    if (NULL != indexes) {
      return false;
    }
    //cout << "enqueue new fs " << tyfs << " " << fs.getType().getName() << endl;
    // new FS, enqueue it
    indexes = new vector<int>;
    enqueuedFS[id] = indexes;
    return true;
  }

  // return true if the fs was not previously enqueued
  bool XmiWriter::enqueueIndexed(FeatureStructure const &fs, int sofa) {
    vector<int> * indexes;
    size_t tyfs = uima::internal::FSPromoter::demoteFS(fs);
    indexes = enqueuedFS[tyfs];
    if (NULL != indexes) {
      for (size_t i=0; i<indexes->size(); i++) {
        if (sofa == indexes->at(i)) {
          return false;
        }
      }
      indexes->push_back(sofa);
      enqueuedFS[tyfs] = indexes;
      // and look for references
      // currently this is done for every FS.
      // This could be done more efficiently 
      // when enqueueing the incoming FS.
      findReferencedFSs(fs, false);
      return false;
    }
    // new FS, enqueue it and note the indexed Sofa
    indexes = new vector<int>;
    indexes->push_back(sofa);
    enqueuedFS[tyfs] = indexes;
    // and look for references
    findReferencedFSs(fs, false);
    return true;
  }

  /**
  * Enqueues all FS that are stored in the XmiSerializationSharedData's id map.
  * This map is populated during the previous deserialization.  This method
  * is used to make sure that all incoming FS are echoed in the next
  * serialization.
  */
  void XmiWriter::enqueueIncoming() {
    if (this->sharedData == NULL)
      return;
    vector<int> fsAddrs;
    this->sharedData->getAllFsAddressesInIdMap(fsAddrs);
    for (size_t i = 0; i < fsAddrs.size(); i++) {
      enqueueUnindexed(fsAddrs.at(i));
    }
  }

  /**
  * Get the XMI ID to use for an FS.
  * 
  * @param addr
  *          address of FS
  * @return XMI ID. If addr == CASImpl.NULL, returns null
  */
  int XmiWriter::getXmiId(int addr) {

    if (addr == 0) return 0;
    if (sharedData != NULL) {
      return this->sharedData->getXmiId(addr);
    } else {
      return addr;    // in the absence of outside information, just use the FS address
    }   
  }

  void XmiWriter::enqueueFSListElements(FeatureStructure const & fs) {
    if (!fs.isValid()) {
      return;
    }

    ListFS curNode(fs);
    map<int,int> visited;
    while (!curNode.isEmpty()) { 
      int addr = internal::FSPromoter::demoteFS(curNode);
      if (visited[addr] == addr) {
        cerr << "Found Cycle truncating " << endl;
        ResourceManager::getInstance().getLogger().logWarning("Found cycle in FSlist. Truncating.");
        break;
      }
      visited[addr] = addr;
      FeatureStructure head = curNode.getHead();
      if (head.isValid()) {
        this->findReferencedFSs(head);
      }

      curNode = curNode.getTail();        
    }
  }


  string XmiWriter::listToString(FeatureStructure const & fs, char const * tag) {
    stringstream str;
    map<int,int> visited;
    if (!fs.isValid()) { 
      return str.str();
    }
    int typecode = internal::FSPromoter::demoteType(fs.getType());
    //cout << __LINE__ << " listToString() " << fs.getType().getName() << endl;
    switch (typecode) {
    case internal::gs_tyNEIntListType: {
      IntListFS curNode(fs);
      while (!curNode.isEmpty()) { 
        int head = curNode.getHead();
        str << head;
        curNode = curNode.getTail();
        int addr = internal::FSPromoter::demoteFS(curNode);
        if (visited[addr] == addr) {
          cerr << "Found Cycle truncating " << endl;
          ResourceManager::getInstance().getLogger().logWarning("Found cycle in Intlist. Truncating.");
          break;
        }
        visited[addr] = addr;
        if ( !curNode.isEmpty() ) {
          str << " " ;
        }
      }
      //cout << "intList contents " << str.str() << endl;
      break;
                                       }
    case internal::gs_tyNEFloatListType: {
      FloatListFS curNode(fs);
      while (!curNode.isEmpty()) { 
        str << curNode.getHead();
        curNode = curNode.getTail();
        int addr = internal::FSPromoter::demoteFS(curNode);
        if (visited[addr] == addr) {
          cerr << "Found Cycle truncating " << endl;
          ResourceManager::getInstance().getLogger().logWarning("Found cycle in FloatListFS. Truncating.");
          break;
        }
        visited[addr] = addr;
        if ( !curNode.isEmpty() ) {
          str << " " ;
        }
      }
      break;
                                         }
    case internal::gs_tyEListType: {
      //cout << "listToString() Empty FSList SKIP"  << endl;
      break;
                                   }
    case internal::gs_tyFSListType: {
      //cout << "listToString() FSList SKIP"  << endl;
      break;
                                    }
    case internal::gs_tyNEListType: {
      //cout << "listToString() NonEmpty FSList"  << endl;
      ListFS curNode(fs);
      while (!curNode.isEmpty()) { 
        int head = internal::FSPromoter::demoteFS(curNode.getHead());
        if (head == 0) {
          //null value in list.  Represent with "0".
          // this may be null because the element was originally a reference to an 
          // out-of-typesystem FS, so chck the XmiSerializationSharedData
          if (sharedData != NULL) {
            int addr = internal::FSPromoter::demoteFS(curNode);
            OotsElementData * oed = sharedData->getOutOfTypeSystemFeatures(addr);
            if (oed != NULL) {
              assert(oed->attributes.size() == 1); //only the head feature can possibly be here
              XmlAttribute *  attr = oed->attributes.at(0);
              assert(attr->name.compare(CAS::FEATURE_BASE_NAME_HEAD)==0);
              str << attr->value;
            }
          } else {
            str << head;
          }
        } else {
          int addr = internal::FSPromoter::demoteFS(curNode);
          if (visited[addr] == addr) {
            cerr << "Found Cycle truncating " << endl;
            ResourceManager::getInstance().getLogger().logWarning("Found cycle in NEListFS. Truncating.");
            break;
          }
          visited[addr] = addr;
          str << getXmiId(head);
        }

        curNode = curNode.getTail();
        if ( !curNode.isEmpty() ) {
          str << " " ;
        }
      }
      //cout << "FSListType  content " << str.str() << endl;
      break;
                                    }
    case internal::gs_tyNEStringListType:  {
      StringListFS curNode(fs);
      UnicodeString ustr;
      while (!curNode.isEmpty()) { 
        ///string head = curNode.getHead().asUTF8();
        ustr.setTo("");
        normalize(curNode.getHead(), ustr);
        str << "<" << tag << ">" << ustr << "</" << tag << ">";
        curNode = curNode.getTail();
        int addr = internal::FSPromoter::demoteFS(curNode);
        if (visited[addr] == addr) {
          cerr << "Found Cycle truncating " << endl;
          ResourceManager::getInstance().getLogger().logWarning("Found cycle in StringListFS. Truncating.");
          break;
        }
        visited[addr] = addr;
        if ( !curNode.isEmpty() ) {
          str << " " ;
        }
      }
      break;
                                           }
    default: {
      cerr << "listToString() Invalid type " << fs.getType().getName() << endl;
      ErrorInfo errInfo;
      errInfo.setErrorId((TyErrorId)UIMA_ERR_RESOURCE_CORRUPTED);
      ErrorMessage msg(UIMA_MSG_ID_EXC_XML_SAXPARSE_FATALERROR);
      msg.addParam("listToString Invalid List type.");
      msg.addParam(tag);
      errInfo.setMessage(msg);
      errInfo.setSeverity(ErrorInfo::unrecoverable);
      ExcIllFormedInputError exc(errInfo);
      throw exc; 
    }
  }
  return str.str();
}


  /**
     * Serializes all of the out-of-typesystem elements that were recorded
     * in the XmiSerializationSharedData during the last deserialization.
     */
void XmiWriter::serializeOutOfTypeSystemElements(ostream & os)  {
  if (this->sharedData == NULL)
    return;
  vector<OotsElementData*> & ootsList = this->sharedData->getOutOfTypeSystemElements();
  for (size_t i=0; i < ootsList.size();i++) {
    OotsElementData * oed = ootsList.at(i);
    os << " <" << oed->elementName->qualifiedName;
    os << " " << ID_ATTR_NAME << "=\"" << oed->xmiId << "\"";
    // Add other attributes
    for (size_t a=0; a < oed->attributes.size();a++) {
      XmlAttribute * attr = oed->attributes.at(a);
      os << " " << attr->name << "=\"" << attr->value << "\"";
    }
    if (oed->childElements.size() > 0) {
      os << ">";
      //serialize features encoded as child elements
      map<string, vector<string>*>::iterator ite;
      for (ite = oed->childElements.begin(); ite != oed->childElements.end();ite++ ) {
        vector<string> * values = ite->second;
        for (size_t v=0; v < values->size(); v++) {
          os << " <" << ite->first << ">";
          os << values->at(v); 
          os << "</" << ite->first << ">";
        }
      }
      os << "</" << oed->elementName->qualifiedName << ">";
    } else {
      os << "/>";
    }
  }

}

char const *  XmiWriter::XMI_NS_URI =     "http://www.omg.org/XMI";
char const *  XmiWriter::XMI_NS_PREFIX = "xmi";
char const *  XmiWriter::DEFAULT_NAMESPACE_URI = "http:///uima/noNamespace.ecore";

char const *  XmiWriter::XSI_NS_URI= "http://www.w3.org/2001/XMLSchema-instance";
char const *  XmiWriter::XMI_TAG_LOCAL_NAME = "XMI";
char const *  XmiWriter::XMI_TAG_QNAME = "xmi:XMI";
char const *  XmiWriter::INDEXED_ATTR_NAME = "_indexed";
char const *  XmiWriter::ID_ATTR_NAME = "xmi:id";
char const *  XmiWriter::XMI_VERSION_LOCAL_NAME = "version";
char const *  XmiWriter::XMI_VERSION_QNAME = "xmi:version";
char const *  XmiWriter::XMI_VERSION_VALUE = "2.0";

}


/* ----------------------------------------------------------------------- */
/*       Implementation                                                    */
/* ----------------------------------------------------------------------- */


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








