diff -ur icu-49.1.orig/source/layout/AlternateSubstSubtables.cpp icu-49.1/source/layout/AlternateSubstSubtables.cpp
--- icu-49.1.orig/source/layout/AlternateSubstSubtables.cpp	2012-03-21 18:38:08.000000000 +0100
+++ icu-49.1/source/layout/AlternateSubstSubtables.cpp	2012-03-22 10:16:50.000000000 +0100
@@ -27,13 +27,19 @@
             Offset alternateSetTableOffset = SWAPW(alternateSetTableOffsetArray[coverageIndex]);
             const AlternateSetTable *alternateSetTable =
                 (const AlternateSetTable *) ((char *) this + alternateSetTableOffset);
-            TTGlyphID alternate = SWAPW(alternateSetTable->alternateArray[0]);
+            le_int32 altIndex = glyphIterator->getFeatureParam();
 
-            if (filter == NULL || filter->accept(LE_SET_GLYPH(glyph, alternate))) {
-                glyphIterator->setCurrGlyphID(SWAPW(alternateSetTable->alternateArray[0]));
+            if (altIndex < SWAPW(alternateSetTable->glyphCount)) {
+	            TTGlyphID alternate = SWAPW(alternateSetTable->alternateArray[altIndex]);
+
+                if (filter == NULL || filter->accept(LE_SET_GLYPH(glyph, alternate))) {
+                    glyphIterator->setCurrGlyphID(alternate);
+                }
+
+                return 1;
             }
             
-            return 1;
+	    // feature param was out of range for the glyph
         }
 
         // XXXX If we get here, the table's mal-formed...
diff -ur icu-49.1.orig/source/layout/GlyphIterator.cpp icu-49.1/source/layout/GlyphIterator.cpp
--- icu-49.1.orig/source/layout/GlyphIterator.cpp	2012-03-21 18:38:08.000000000 +0100
+++ icu-49.1/source/layout/GlyphIterator.cpp	2012-03-22 10:16:50.000000000 +0100
@@ -19,7 +19,7 @@
                              FeatureMask theFeatureMask, const GlyphDefinitionTableHeader *theGlyphDefinitionTableHeader)
   : direction(1), position(-1), nextLimit(-1), prevLimit(-1),
     glyphStorage(theGlyphStorage), glyphPositionAdjustments(theGlyphPositionAdjustments),
-    srcIndex(-1), destIndex(-1), lookupFlags(theLookupFlags), featureMask(theFeatureMask), glyphGroup(0),
+    srcIndex(-1), destIndex(-1), lookupFlags(theLookupFlags), featureMask(theFeatureMask), featureParam(0), glyphGroup(0),
     glyphClassDefinitionTable(NULL), markAttachClassDefinitionTable(NULL)
 
 {
@@ -53,12 +53,13 @@
     destIndex = that.destIndex;
     lookupFlags = that.lookupFlags;
     featureMask = that.featureMask;
+    featureParam = that.featureParam;
     glyphGroup  = that.glyphGroup;
     glyphClassDefinitionTable = that.glyphClassDefinitionTable;
     markAttachClassDefinitionTable = that.markAttachClassDefinitionTable;
 }
 
-GlyphIterator::GlyphIterator(GlyphIterator &that, FeatureMask newFeatureMask)
+GlyphIterator::GlyphIterator(GlyphIterator &that, FeatureMask newFeatureMask, le_int32 newFeatureParam)
   : glyphStorage(that.glyphStorage)
 {
     direction    = that.direction;
@@ -71,6 +72,7 @@
     destIndex = that.destIndex;
     lookupFlags = that.lookupFlags;
     featureMask = newFeatureMask;
+    featureParam = newFeatureParam;
     glyphGroup  = 0;
     glyphClassDefinitionTable = that.glyphClassDefinitionTable;
     markAttachClassDefinitionTable = that.markAttachClassDefinitionTable;
@@ -89,6 +91,7 @@
     destIndex = that.destIndex;
     lookupFlags = newLookupFlags;
     featureMask = that.featureMask;
+    featureParam = that.featureParam;
     glyphGroup  = that.glyphGroup;
     glyphClassDefinitionTable = that.glyphClassDefinitionTable;
     markAttachClassDefinitionTable = that.markAttachClassDefinitionTable;
@@ -103,6 +106,7 @@
 {
     position     = prevLimit;
     featureMask  = newFeatureMask;
+    featureParam = 0;
     glyphGroup   = 0;
     lookupFlags  = newLookupFlags;
 }
@@ -130,6 +134,11 @@
     return position;
 }
 
+le_int32 GlyphIterator::getFeatureParam() const
+{
+    return featureParam;
+}
+
 le_bool GlyphIterator::isRightToLeft() const
 {
     return direction < 0;
@@ -400,8 +409,10 @@
     }
 }
 
-le_bool GlyphIterator::hasFeatureTag(le_bool matchGroup) const
+le_bool GlyphIterator::hasFeatureTag(le_bool matchGroup)
 {
+    featureParam = 0;
+
     if (featureMask == 0) {
         return TRUE;
     }
@@ -409,7 +420,20 @@
     LEErrorCode success = LE_NO_ERROR;
     FeatureMask fm = glyphStorage.getAuxData(position, success);
 
-    return ((fm & featureMask) == featureMask) && (!matchGroup || (le_int32)(fm & LE_GLYPH_GROUP_MASK) == glyphGroup);
+    if (((fm & featureMask) == featureMask) && (!matchGroup || (le_int32)(fm & LE_GLYPH_GROUP_MASK) == glyphGroup)) {
+        const le_int32 *paramList = (const le_int32 *) glyphStorage.getAuxParam(position, success);
+        if (paramList != NULL) {
+            fm = featureMask;
+            while ((fm & 0x80000000UL) == 0) {
+                ++paramList;
+                fm <<= 1;
+            }
+            featureParam = *paramList;
+        }
+        return TRUE;
+    }
+
+    return FALSE;
 }
 
 le_bool GlyphIterator::findFeatureTag()
diff -ur icu-49.1.orig/source/layout/GlyphIterator.h icu-49.1/source/layout/GlyphIterator.h
--- icu-49.1.orig/source/layout/GlyphIterator.h	2012-03-21 18:38:10.000000000 +0100
+++ icu-49.1/source/layout/GlyphIterator.h	2012-03-22 10:16:50.000000000 +0100
@@ -28,7 +28,7 @@
 
     GlyphIterator(GlyphIterator &that);
 
-    GlyphIterator(GlyphIterator &that, FeatureMask newFeatureMask);
+    GlyphIterator(GlyphIterator &that, FeatureMask newFeatureMask, le_int32 featureParam = 0);
 
     GlyphIterator(GlyphIterator &that, le_uint16 newLookupFlags);
 
@@ -51,6 +51,8 @@
     le_int32  getMarkComponent(le_int32 markPosition) const;
     le_bool   findMark2Glyph();
 
+    le_int32  getFeatureParam() const;
+
     void getCursiveEntryPoint(LEPoint &entryPoint) const;
     void getCursiveExitPoint(LEPoint &exitPoint) const;
 
@@ -74,7 +76,7 @@
 
 private:
     le_bool filterGlyph(le_uint32 index) const;
-    le_bool hasFeatureTag(le_bool matchGroup) const;
+    le_bool hasFeatureTag(le_bool matchGroup); /* not const because it updates the featureParam field */
     le_bool nextInternal(le_uint32 delta = 1);
     le_bool prevInternal(le_uint32 delta = 1);
 
@@ -90,6 +92,7 @@
     le_int32    destIndex;
     le_uint16   lookupFlags;
     FeatureMask featureMask;
+    le_int32    featureParam;
     le_int32    glyphGroup;
 
     const GlyphClassDefinitionTable *glyphClassDefinitionTable;
diff -ur icu-49.1.orig/source/layout/LEGlyphStorage.cpp icu-49.1/source/layout/LEGlyphStorage.cpp
--- icu-49.1.orig/source/layout/LEGlyphStorage.cpp	2012-03-21 18:38:10.000000000 +0100
+++ icu-49.1/source/layout/LEGlyphStorage.cpp	2012-03-22 10:16:50.000000000 +0100
@@ -20,7 +20,7 @@
 
 LEGlyphStorage::LEGlyphStorage()
     : fGlyphCount(0), fGlyphs(NULL), fCharIndices(NULL), fPositions(NULL),
-      fAuxData(NULL), fInsertionList(NULL), fSrcIndex(0), fDestIndex(0)
+      fAuxData(NULL), fAuxParam(NULL), fInsertionList(NULL), fSrcIndex(0), fDestIndex(0)
 {
     // nothing else to do!
 }
@@ -44,6 +44,11 @@
         fAuxData = NULL;
     }
 
+    if (fAuxParam != NULL) {
+        LE_DELETE_ARRAY(fAuxParam);
+        fAuxParam = NULL;
+    }
+
     if (fInsertionList != NULL) {
         delete fInsertionList;
         fInsertionList = NULL;
@@ -151,14 +156,15 @@
         return -1;
     }
 
-    if (fAuxData != NULL) {
+    if (fAuxData != NULL || fAuxParam != NULL) {
         success = LE_INTERNAL_ERROR;
         return -1;
     }
 
     fAuxData = LE_NEW_ARRAY(le_uint32, fGlyphCount);
+    fAuxParam = LE_NEW_ARRAY(void *, fGlyphCount);
 
-    if (fAuxData == NULL) {
+    if (fAuxData == NULL || fAuxParam == NULL) {
         success = LE_MEMORY_ALLOCATION_ERROR;
         return -1;
     }
@@ -365,13 +371,32 @@
     return fAuxData[glyphIndex];
 }
 
-void LEGlyphStorage::setAuxData(le_int32 glyphIndex, le_uint32 auxData, LEErrorCode &success)
+void *LEGlyphStorage::getAuxParam(le_int32 glyphIndex, LEErrorCode &success) const
+{
+    if (LE_FAILURE(success)) {
+        return NULL;
+    }
+
+    if (fAuxParam == NULL) {
+        success = LE_NO_LAYOUT_ERROR;
+        return NULL;
+    }
+    
+    if (glyphIndex < 0 || glyphIndex >= fGlyphCount) {
+        success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
+        return NULL;
+    }
+
+    return fAuxParam[glyphIndex];
+}
+
+void LEGlyphStorage::setAuxData(le_int32 glyphIndex, le_uint32 auxData, void *auxParam, LEErrorCode &success)
 {
     if (LE_FAILURE(success)) {
         return;
     }
 
-    if (fAuxData == NULL) {
+    if (fAuxData == NULL || fAuxParam == NULL) {
         success = LE_NO_LAYOUT_ERROR;
         return;
     }
@@ -382,6 +407,7 @@
     }
 
     fAuxData[glyphIndex] = auxData;
+    fAuxParam[glyphIndex] = auxParam;
 }
 
 void LEGlyphStorage::getGlyphPositions(float positions[], LEErrorCode &success) const
@@ -496,8 +522,14 @@
         LE_DELETE_ARRAY(fAuxData);
     }
 
+    if (fAuxParam != NULL) {
+        LE_DELETE_ARRAY(fAuxParam);
+    }
+
     fAuxData = from.fAuxData;
     from.fAuxData = NULL;
+    fAuxParam = from.fAuxParam;
+    from.fAuxParam = NULL;
 }
 
 void LEGlyphStorage::adoptGlyphCount(LEGlyphStorage &from)
@@ -588,6 +620,15 @@
         fAuxData = (le_uint32 *)newAuxData;
     }
 
+    if (fAuxParam != NULL) {	
+        void **newAuxParam = (void **) LE_GROW_ARRAY(fAuxParam, newGlyphCount); 
+        if (newAuxParam == NULL) { 
+            // could not grow the aux param array 
+            return fGlyphCount; 
+        } 
+        fAuxParam = (void **)newAuxParam;
+    }
+
     fSrcIndex  = fGlyphCount - 1;
     fDestIndex = newGlyphCount - 1;
 
@@ -640,6 +681,18 @@
         }
     }
 
+    if (fAuxParam != NULL) {
+        le_int32 src = fSrcIndex, dest = fDestIndex;
+
+        while (src > atPosition) {
+            fAuxParam[dest--] = fAuxParam[src--];
+        }
+
+        for (le_int32 i = count - 1; i >= 0; i -= 1) {
+            fAuxParam[dest--] = fAuxParam[atPosition];
+        }
+    }
+
     while (fSrcIndex > atPosition) {
         fGlyphs[fDestIndex]      = fGlyphs[fSrcIndex];
         fCharIndices[fDestIndex] = fCharIndices[fSrcIndex];
diff -ur icu-49.1.orig/source/layout/LEGlyphStorage.h icu-49.1/source/layout/LEGlyphStorage.h
--- icu-49.1.orig/source/layout/LEGlyphStorage.h	2012-03-21 18:38:08.000000000 +0100
+++ icu-49.1/source/layout/LEGlyphStorage.h	2012-03-22 10:16:50.000000000 +0100
@@ -63,12 +63,12 @@
     float     *fPositions;
 
     /**
-     * The auxillary data array.
+     * The auxiliary data arrays.
      *
      * @internal
      */
     le_uint32 *fAuxData;
-
+    void     **fAuxParam;
 
     /**
      * The insertion list, used to grow the above arrays.
@@ -299,6 +299,7 @@
      * @stable ICU 3.6
      */
     le_uint32 getAuxData(le_int32 glyphIndex, LEErrorCode &success) const;
+    void *getAuxParam(le_int32 glyphIndex, LEErrorCode &success) const;
 
     /**
      * This operator allows direct access to the glyph array
@@ -427,15 +428,20 @@
     void adjustPosition(le_int32 glyphIndex, float xAdjust, float yAdjust, LEErrorCode &success);
 
     /**
-     * Set the auxillary data for a particular glyph.
+     * Set the auxiliary data for a particular glyph.
      *
      * @param glyphIndex the index of the glyph
-     * @param auxData the new auxillary data
-     * @param success will be set to an error code if the auxillary data cannot be set.
+     * @param auxData the new auxiliary data
+     * @param auxParam the new secondary auxiliary data (parameter)
+     * @param success will be set to an error code if the auxiliary data cannot be set.
      *
-     * @stable ICU 3.6
+     * @stable ICU 3.6 - mod for XeTeX
+     */
+    void setAuxData(le_int32 glyphIndex, le_uint32 auxData, void *auxParam, LEErrorCode &success);
+    /**
+     * The common case when @param auxParam is <code>NULL</code>.
      */
-    void setAuxData(le_int32 glyphIndex, le_uint32 auxData, LEErrorCode &success);
+    inline void setAuxData(le_int32 glyphIndex, le_uint32 auxData, LEErrorCode &success);
 
     /**
      * Delete the glyph array and replace it with the one
@@ -540,6 +546,10 @@
     return fGlyphs[glyphIndex];
 }
 
+inline void LEGlyphStorage::setAuxData(le_int32 glyphIndex, le_uint32 auxData, LEErrorCode &success)
+{
+    setAuxData(glyphIndex, auxData, NULL, success);
+}
 
 U_NAMESPACE_END
 #endif
diff -ur icu-49.1.orig/source/layout/OpenTypeLayoutEngine.cpp icu-49.1/source/layout/OpenTypeLayoutEngine.cpp
--- icu-49.1.orig/source/layout/OpenTypeLayoutEngine.cpp	2012-03-21 18:38:08.000000000 +0100
+++ icu-49.1/source/layout/OpenTypeLayoutEngine.cpp	2012-03-22 10:16:50.000000000 +0100
@@ -78,7 +78,7 @@
 OpenTypeLayoutEngine::OpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode,
                         le_int32 typoFlags, const GlyphSubstitutionTableHeader *gsubTable, LEErrorCode &success)
     : LayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, success), fFeatureMask(minimalFeatures),
-      fFeatureMap(featureMap), fFeatureMapCount(featureMapCount), fFeatureOrder(FALSE),
+      fFeatureMap(featureMap), fFeatureParamList(NULL), fFeatureMapCount(featureMapCount), fFeatureOrder(FALSE),
       fGSUBTable(gsubTable), fGDEFTable(NULL), fGPOSTable(NULL), fSubstitutionFilter(NULL)
 {
     static const le_uint32 gdefTableTag = LE_GDEF_TABLE_TAG;
@@ -216,7 +216,7 @@
     glyphStorage.allocateAuxData(success);
 
     for (le_int32 i = 0; i < count; i += 1) {
-        glyphStorage.setAuxData(i, fFeatureMask, success);
+        glyphStorage.setAuxData(i, fFeatureMask, (void *) fFeatureParamList, success);
     }
 
     return count;
diff -ur icu-49.1.orig/source/layout/OpenTypeLayoutEngine.h icu-49.1/source/layout/OpenTypeLayoutEngine.h
--- icu-49.1.orig/source/layout/OpenTypeLayoutEngine.h	2012-03-21 18:38:08.000000000 +0100
+++ icu-49.1/source/layout/OpenTypeLayoutEngine.h	2012-03-22 10:16:50.000000000 +0100
@@ -194,6 +194,13 @@
     le_bool fFeatureOrder;
 
     /**
+     * The list of what? FIXME..
+     *
+     * @internal
+     */
+    const le_int32 *fFeatureParamList;
+
+    /**
      * The address of the GSUB table.
      *
      * @internal
