/** \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                                                   */
/* ----------------------------------------------------------------------- */

using namespace std;
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() ) {
      if (!fs.isUntouchedFSValue(f) ) {
      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);
        icu::UnicodeString us;
        icu::UnicodeString av(attr->value.c_str());
        normalize( av, us );
        os << " " << attr->name << "=\"" << us << "\"";
      }
      //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++) {
            icu::UnicodeString us;
            icu::UnicodeString av(values->at(v).c_str());
            normalize( av, us );
            strcontent << " <" << ite->first 
              << ">" << us
              << "</" << 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);
      icu::UnicodeString us;
      icu::UnicodeString av(attr->value.c_str());
      normalize( av, us );
      os << " " << attr->name << "=\"" << us << "\"";
    }
    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++) {
	        icu::UnicodeString us;
			icu::UnicodeString av(values->at(v).c_str());
			normalize( av, us );
          os << " <" << ite->first << ">";
          os << us;
          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                                                    */
/* ----------------------------------------------------------------------- */


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








