]> git.proxmox.com Git - mirror_edk2.git/blobdiff - Tools/Source/GenBuild/org/tianocore/build/autogen/AutoGen.java
Fixed EDKT318
[mirror_edk2.git] / Tools / Source / GenBuild / org / tianocore / build / autogen / AutoGen.java
index 1b9c5a0e4a77de4f5a1dcb9731c3f1824edc7747..5b6620b50dfc8d5f3672bcb012fe825a4fd482ed 100644 (file)
@@ -3,13 +3,13 @@
 \r
  This class is to generate Autogen.h and Autogen.c according to module surface area\r
  or library surface area.\r
\r
+\r
  Copyright (c) 2006, Intel Corporation\r
  All rights reserved. This program and the accompanying materials\r
  are licensed and made available under the terms and conditions of the BSD License\r
  which accompanies this distribution.  The full text of the license may be found at\r
  http://opensource.org/licenses/bsd-license.php\r
\r
+\r
  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
 \r
 \r
 package org.tianocore.build.autogen;\r
 \r
-import org.tianocore.build.global.GlobalData;\r
-import org.tianocore.build.global.Spd;\r
-import org.tianocore.build.global.SurfaceAreaQuery;\r
-import org.tianocore.GuidsDocument;\r
-import org.tianocore.LibraryClassDocument.LibraryClass;\r
-import org.tianocore.PPIsDocument;\r
-import org.tianocore.ProtocolsDocument;\r
-import org.tianocore.build.pcd.action.PCDAutoGenAction;\r
-\r
-import org.apache.tools.ant.BuildException;\r
-import org.apache.xmlbeans.XmlObject;\r
-\r
 import java.io.File;\r
+import java.io.FileInputStream;\r
+import java.io.FileOutputStream;\r
 import java.io.FileReader;\r
 import java.io.FileWriter;\r
+import java.io.IOException;\r
 import java.util.ArrayList;\r
+import java.util.HashSet;\r
+import java.util.Iterator;\r
+import java.util.LinkedHashSet;\r
+import java.util.LinkedList;\r
 import java.util.List;\r
 import java.util.Map;\r
+import java.util.Set;\r
+\r
+import org.apache.tools.ant.BuildException;\r
+import org.apache.xmlbeans.XmlObject;\r
+import org.tianocore.build.exception.AutoGenException;\r
+import org.tianocore.build.global.GlobalData;\r
+import org.tianocore.build.global.SurfaceAreaQuery;\r
+import org.tianocore.build.id.ModuleIdentification;\r
+import org.tianocore.build.id.PackageIdentification;\r
+import org.tianocore.build.pcd.action.PCDAutoGenAction;\r
+import org.tianocore.common.definitions.ToolDefinitions;\r
+import org.tianocore.common.definitions.EdkDefinitions;\r
+import org.tianocore.common.exception.EdkException;\r
+import org.tianocore.common.logger.EdkLog;\r
 \r
 /**\r
   This class is to generate Autogen.h and Autogen.c according to module surface\r
@@ -46,10 +55,15 @@ public class AutoGen {
     ///\r
     private String outputPath;\r
 \r
+    ///\r
+    /// The name of FV directory\r
+    ///\r
+    private String fvDir;\r
+\r
     ///\r
     /// The base name of module or library.\r
     ///\r
-    private String baseName;\r
+    private ModuleIdentification moduleId;\r
 \r
     ///\r
     /// The build architecture\r
@@ -62,295 +76,354 @@ public class AutoGen {
     ///\r
     private PCDAutoGenAction myPcdAutogen;\r
 \r
+    ///\r
+    /// the one of type : NOT_PCD_DRIVER, PEI_PCD_DRIVER, DXE_PCD_DRIVER\r
+    /// \r
+    private CommonDefinition.PCD_DRIVER_TYPE pcdDriverType;\r
+\r
     ///\r
     /// The protocl list which records in module or library surface area and\r
     /// it's dependence on library instance surface area.\r
     ///\r
-    private List<String> mProtocolList = new ArrayList<String>();\r
+    private Set<String> mProtocolList = new HashSet<String>();\r
 \r
     ///\r
     /// The Ppi list which recorded in module or library surface area and its\r
     /// dependency on library instance surface area.\r
     ///\r
-    private List<String> mPpiList = new ArrayList<String>();\r
+    private Set<String> mPpiList = new HashSet<String>();\r
 \r
     ///\r
-    /// The Guid list which recoreded in module or library surface are and it's\r
+    /// The Guid list which recoreded in module or library surface area and it's\r
     /// dependence on library instance surface area.\r
     ///\r
-    private List<GuidsDocument.Guids.GuidEntry> mGuidList = new ArrayList<GuidsDocument.Guids.GuidEntry>();\r
+    private Set<String> mGuidList = new HashSet<String>();\r
+\r
+    ///\r
+    /// The dependence package list which recoreded in module or library surface\r
+    /// area and it's dependence on library instance surface area.\r
+    ///\r
+    private List<PackageIdentification> mDepPkgList = new LinkedList<PackageIdentification>();\r
+\r
+    ///\r
+    ///  For non library module, add its library instance's construct and destructor to\r
+    ///  list. String[0] recode LibConstructor name, String[1] recode Lib instance \r
+       ///  module type.\r
+    ///\r
+    private List<String[]> libConstructList = new ArrayList<String[]>();\r
+    private List<String[]> libDestructList = new ArrayList<String[]>();\r
+\r
+    ///\r
+    /// List to store SetVirtalAddressMapCallBack, ExitBootServiceCallBack\r
+    ///\r
+    private List<String> setVirtalAddList = new ArrayList<String>();\r
+    private List<String> exitBootServiceList = new ArrayList<String>();\r
+\r
+    private SurfaceAreaQuery saq = null;\r
+    \r
+    private ModuleIdentification parentId = null;\r
 \r
     /**\r
       Construct function\r
-      \r
+     \r
       This function mainly initialize some member variable.\r
       \r
-      @param outputPath    Output path of AutoGen file.\r
-      @param baseName      Module base name.\r
-      @param arch          Target architecture.\r
+      @param fvDir\r
+                 Absolute path of FV directory.\r
+      @param outputPath\r
+                 Output path of AutoGen file.\r
+      @param moduleId\r
+                 Module identification.\r
+      @param arch\r
+                 Target architecture.\r
     **/\r
-    public AutoGen(String outputPath, String baseName, String arch) {\r
+    public AutoGen(String fvDir, String outputPath, ModuleIdentification moduleId, String arch, SurfaceAreaQuery saq, ModuleIdentification parentId) {\r
         this.outputPath = outputPath;\r
-        this.baseName = baseName;\r
+        this.moduleId = moduleId;\r
         this.arch = arch;\r
-\r
+        this.fvDir = fvDir;\r
+        this.saq = saq;\r
+        this.parentId = parentId;\r
     }\r
 \r
     /**\r
       saveFile function\r
-      \r
+     \r
       This function save the content in stringBuffer to file.\r
-      \r
-      @param fileName      The name of file.\r
-      @param fileBuffer    The content of AutoGen file in buffer.\r
-      @return              "true" successful, "false" failed.\r
+     \r
+      @param fileName\r
+                 The name of file.\r
+      @param fileBuffer\r
+                 The content of AutoGen file in buffer.\r
+      @return boolean           \r
+                 "true"  successful\r
+                 "false" failed\r
     **/\r
     private boolean saveFile(String fileName, StringBuffer fileBuffer) {\r
-        try {\r
-            File autoGenH = new File(fileName);\r
+        \r
+        File autoGenH = new File(fileName);\r
 \r
             //\r
             // if the file exists, compare their content\r
             //\r
-            if (autoGenH.exists()) {\r
-                FileReader fIn = new FileReader(autoGenH);\r
-                char[] oldFileBuffer = new char[(int) autoGenH.length()];\r
-                fIn.read(oldFileBuffer, 0, (int) autoGenH.length());\r
+        if (autoGenH.exists()) {\r
+            char[] oldFileBuffer = new char[(int) autoGenH.length()];\r
+                       try {\r
+                               FileReader fIn = new FileReader(autoGenH);\r
+                               fIn.read(oldFileBuffer, 0, (int) autoGenH.length());\r
                 fIn.close();\r
+                       } catch (IOException e) {\r
+                               EdkLog.log(EdkLog.EDK_INFO, this.moduleId.getName() \r
+                                                               + "'s " \r
+                                                               + fileName \r
+                                                               + " is exist, but can't be open!!");\r
+                               return false;\r
+                       }\r
 \r
-                //\r
-                // if we got the same file, don't re-generate it to prevent\r
-                // sources depending on it from re-building\r
-                //\r
-                if (fileBuffer.toString().compareTo(new String(oldFileBuffer)) == 0) {\r
-                    return true;\r
-                }\r
+            //\r
+            // if we got the same file, don't re-generate it to prevent\r
+            // sources depending on it from re-building\r
+            //\r
+            if (fileBuffer.toString().compareTo(new String(oldFileBuffer)) == 0) {\r
+                return true;\r
             }\r
-            FileWriter fOut = new FileWriter(autoGenH);\r
+        }\r
+        \r
+               try {\r
+                       FileWriter fOut = new FileWriter(autoGenH);\r
             fOut.write(fileBuffer.toString());\r
+                       fOut.flush();\r
             fOut.close();\r
-        } catch (Exception e) {\r
-            return false;\r
-        }\r
+               } catch (IOException e) {\r
+                       EdkLog.log(EdkLog.EDK_INFO, this.moduleId.getName() \r
+                                                               + "'s " \r
+                                                               + fileName \r
+                                                               + " can't be create!!");\r
+                       return false;\r
+               } \r
         return true;\r
     }\r
 \r
     /**\r
       genAutogen function\r
-      \r
+     \r
       This function call libGenAutoGen or moduleGenAutogen function, which\r
       dependence on generate library autogen or module autogen.\r
-      \r
-      @throws BuildException    Failed to creat AutoGen.c & AutoGen.h.\r
+     \r
+      @throws BuildException\r
+                  Failed to creat AutoGen.c & AutoGen.h.\r
     **/\r
-    public void genAutogen() throws BuildException {\r
+    public void genAutogen() throws EdkException {\r
         try {\r
             //\r
             // If outputPath do not exist, create it.\r
             //\r
             File path = new File(outputPath);\r
             path.mkdirs();\r
-\r
-            //\r
-            // Check current is library or not, then call the corresponding\r
-            // function.\r
-            //\r
-            if (SurfaceAreaQuery.getComponentType().equalsIgnoreCase(\r
-                    CommonDefinition.LibraryStr)) {\r
-                libGenAutogen();\r
-            } else {\r
-                moduleGenAutogen();\r
-            }\r
-\r
-        } catch (Exception e) {\r
-            throw new BuildException(\r
-                    "Failed to create AutoGen.c & AutoGen.h!\n"\r
-                            + e.getMessage());\r
+               } catch (Exception e) {\r
+            throw new AutoGenException(\r
+                                    "Failed to create "\r
+                                    + outputPath + " directory");\r
         }\r
+            \r
+               //\r
+               // Check current is library or not, then call the corresponding\r
+               // function.\r
+               //\r
+               if (this.moduleId.isLibrary()) {\r
+                       libGenAutogen();\r
+               } else {\r
+                       moduleGenAutogen();\r
+               }\r
     }\r
 \r
-    /** \r
+    /**\r
       moduleGenAutogen function\r
-    \r
+     \r
       This function generates AutoGen.c & AutoGen.h for module.\r
      \r
-      @throws BuildException  Faile to create module AutoGen.c & AutoGen.h.\r
+      @throws BuildException\r
+                  Faile to create module AutoGen.c & AutoGen.h.\r
     **/\r
-    void moduleGenAutogen() throws BuildException {\r
-\r
-        try {\r
-            moduleGenAutogenC();\r
-            moduleGenAutogenH();\r
-        } catch (Exception e) {\r
-            throw new BuildException(\r
-                    "Faile to create module AutoGen.c & AutoGen.h!\n"\r
-                            + e.getMessage());\r
-        }\r
+    void moduleGenAutogen() throws EdkException {\r
+               collectLibInstanceInfo();\r
+               moduleGenAutogenC();\r
+               moduleGenAutogenH();\r
     }\r
 \r
     /**\r
       libGenAutogen function\r
-      \r
+     \r
       This function generates AutoGen.c & AutoGen.h for library.\r
-      \r
+     \r
       @throws BuildException\r
                   Faile to create library AutoGen.c & AutoGen.h\r
     **/\r
-    void libGenAutogen() throws BuildException {\r
-        try {\r
-            libGenAutogenC();\r
-            libGenAutogenH();\r
-        } catch (Exception e) {\r
-            throw new BuildException(\r
-                    "Faile to create library AutoGen.c & AutoGen.h!\n"\r
-                            + e.getMessage());\r
-        }\r
+    void libGenAutogen() throws EdkException {\r
+               libGenAutogenC();\r
+               libGenAutogenH();\r
     }\r
 \r
     /**\r
       moduleGenAutogenH\r
      \r
       This function generates AutoGen.h for module.\r
-      \r
+     \r
       @throws BuildException\r
                   Failed to generate AutoGen.h.\r
     **/\r
-    void moduleGenAutogenH() throws BuildException {\r
+    void moduleGenAutogenH() throws EdkException {\r
 \r
-        List<String> libClassIncludeH;\r
+        Set<String> libClassIncludeH;\r
         String moduleType;\r
+        // List<String> headerFileList;\r
         List<String> headerFileList;\r
-\r
+        Iterator item;\r
         StringBuffer fileBuffer = new StringBuffer(8192);\r
-        \r
+\r
         //\r
-        // Write Autogen.h header notation \r
+        // Write Autogen.h header notation\r
         //\r
-        fileBuffer.append(CommonDefinition.autogenHNotation);\r
-        \r
+        fileBuffer.append(CommonDefinition.AUTOGENHNOTATION);\r
+\r
         //\r
-        // Add #ifndef  ${BaseName}_AUTOGENH\r
-        //     #def     ${BseeName}_AUTOGENH\r
+        // Add #ifndef ${BaseName}_AUTOGENH\r
+        // #def ${BseeName}_AUTOGENH\r
         //\r
-        fileBuffer.append("#ifndef    " + this.baseName.toUpperCase() + "_AUTOGENH\r\n");\r
-        fileBuffer.append("#define    " + this.baseName.toUpperCase() + "_AUTOGENH\r\n\r\n");\r
-        \r
+        fileBuffer.append(CommonDefinition.IFNDEF \r
+                                     + CommonDefinition.AUTOGENH\r
+                                     + this.moduleId.getGuid().replaceAll("-", "_") \r
+                                     + ToolDefinitions.LINE_SEPARATOR);\r
+        fileBuffer.append(CommonDefinition.DEFINE \r
+                                     + CommonDefinition.AUTOGENH\r
+                                     + this.moduleId.getGuid().replaceAll("-", "_") \r
+                                     + ToolDefinitions.LINE_SEPARATOR \r
+                                     + ToolDefinitions.LINE_SEPARATOR);\r
+\r
         //\r
         // Write the specification version and release version at the begine\r
         // of autogen.h file.\r
         // Note: the specification version and release version should\r
-        // be got from module surface area instead of hard code by it's moduleType.\r
+        // be got from module surface area instead of hard code by it's\r
+        // moduleType.\r
         //\r
-        moduleType = SurfaceAreaQuery.getModuleType();\r
-        switch (CommonDefinition.getModuleType(moduleType)) {\r
-        case CommonDefinition.ModuleTypeDxeCore:\r
-        case CommonDefinition.ModuleTypeDxeDriver:\r
-        case CommonDefinition.ModuleTypeDxeRuntimeDriver:\r
-        case CommonDefinition.ModuleTypeDxeSmmDriver:\r
-        case CommonDefinition.ModuleTypeDxeSalDriver:\r
-        case CommonDefinition.ModuleTypeUefiDriver:\r
-        case CommonDefinition.ModuleTypeUefiApplication:\r
-            fileBuffer.append(CommonDefinition.autoGenHLine1);\r
-            break;\r
-        default:\r
-            fileBuffer.append(CommonDefinition.autoGenHVersionDefault);\r
-            break;\r
-        }\r
-        switch (CommonDefinition.getModuleType(moduleType)) {\r
-        case CommonDefinition.ModuleTypeUefiDriver:\r
-        case CommonDefinition.ModuleTypeUefiApplication:\r
-            fileBuffer.append(CommonDefinition.autoGenHReleaseDefault);\r
-            break;\r
-        default:\r
-            fileBuffer.append(CommonDefinition.autoGenHLine2);\r
-            break;\r
-        }\r
+        moduleType = saq.getModuleType();\r
 \r
         //\r
-        // Add "extern int __make_me_compile_correctly;" at begin of \r
+        // Add "extern int __make_me_compile_correctly;" at begin of\r
         // AutoGen.h.\r
         //\r
-        fileBuffer.append(CommonDefinition.autoGenHbegin);\r
+        fileBuffer.append(CommonDefinition.AUTOGENHBEGIN);\r
 \r
+        //\r
+        // Put EFI_SPECIFICATION_VERSION, and EDK_RELEASE_VERSION.\r
+        //\r
+        String[] specList = saq.getExternSpecificaiton();\r
+        for (int i = 0; i < specList.length; i++) {\r
+            fileBuffer.append(CommonDefinition.DEFINE + specList[i]\r
+                              + "\r\n");\r
+        }\r
         //\r
         // Write consumed package's mdouleInfo related .h file to autogen.h\r
         //\r
-        List<String> consumedPkgList = SurfaceAreaQuery\r
-                .getIncludePackageName(this.arch);\r
-        if (consumedPkgList != null) {\r
-            headerFileList = IncludesToAutogenH(consumedPkgList, moduleType);\r
-            for (int i = 0; i < headerFileList.size(); i++) {\r
-                fileBuffer.append(headerFileList.get(i));\r
+        // PackageIdentification[] consumedPkgIdList = SurfaceAreaQuery\r
+        // .getDependencePkg(this.arch);\r
+        PackageIdentification[] consumedPkgIdList = saq.getDependencePkg(this.arch);\r
+        if (consumedPkgIdList != null) {\r
+            headerFileList = depPkgToAutogenH(consumedPkgIdList, moduleType);\r
+            item = headerFileList.iterator();\r
+            while (item.hasNext()) {\r
+                fileBuffer.append(item.next().toString());\r
             }\r
         }\r
 \r
         //\r
         // Write library class's related *.h file to autogen.h.\r
         //\r
-        LibraryClass[] libClassList = SurfaceAreaQuery\r
-                .getLibraryClassArray(CommonDefinition.AlwaysConsumed);\r
+        String[] libClassList = saq.getLibraryClasses(CommonDefinition.ALWAYSCONSUMED,this.arch);\r
         if (libClassList != null) {\r
             libClassIncludeH = LibraryClassToAutogenH(libClassList);\r
-            for (int i = 0; i < libClassIncludeH.size(); i++) {\r
-                fileBuffer.append(libClassIncludeH.get(i));\r
+            item = libClassIncludeH.iterator();\r
+            while (item.hasNext()) {\r
+                fileBuffer.append(item.next().toString());\r
             }\r
         }\r
 \r
-        libClassList = SurfaceAreaQuery\r
-                .getLibraryClassArray(CommonDefinition.AlwaysProduced);\r
+        libClassList = saq.getLibraryClasses(CommonDefinition.ALWAYSPRODUCED, this.arch);\r
         if (libClassList != null) {\r
             libClassIncludeH = LibraryClassToAutogenH(libClassList);\r
-            for (int i = 0; i < libClassIncludeH.size(); i++) {\r
-                fileBuffer.append(libClassIncludeH.get(i));\r
+            item = libClassIncludeH.iterator();\r
+            while (item.hasNext()) {\r
+                fileBuffer.append(item.next().toString());\r
             }\r
         }\r
         fileBuffer.append("\r\n");\r
-        \r
+\r
         //\r
+        //  If is TianoR8FlashMap, copy {Fv_DIR}/FlashMap.h to\r
+        // {DEST_DIR_DRBUG}/FlashMap.h\r
+        //\r
+        if (saq.isHaveTianoR8FlashMap()) {\r
+            fileBuffer.append(CommonDefinition.INCLUDE);\r
+            fileBuffer.append("  <");\r
+            fileBuffer.append(CommonDefinition.TIANOR8PLASHMAPH + ">\r\n");\r
+            copyFlashMapHToDebugDir();\r
+        }\r
+\r
         // Write PCD autogen information to AutoGen.h.\r
         //\r
         if (this.myPcdAutogen != null) {\r
-            fileBuffer.append(this.myPcdAutogen.OutputH());\r
+            fileBuffer.append("\r\n");\r
+            fileBuffer.append(this.myPcdAutogen.getHAutoGenString());\r
         }\r
 \r
         //\r
         // Append the #endif at AutoGen.h\r
         //\r
         fileBuffer.append("#endif\r\n");\r
-        \r
+\r
         //\r
         // Save string buffer content in AutoGen.h.\r
         //\r
         if (!saveFile(outputPath + File.separatorChar + "AutoGen.h", fileBuffer)) {\r
-            throw new BuildException("Failed to generate AutoGen.h !!!");\r
+            throw new AutoGenException("Failed to generate AutoGen.h !!!");\r
         }\r
     }\r
-    \r
+\r
     /**\r
       moduleGenAutogenC\r
-   \r
+     \r
       This function generates AutoGen.c for module.\r
-    \r
+     \r
       @throws BuildException\r
-                Failed to generate AutoGen.c.\r
+                  Failed to generate AutoGen.c.\r
     **/\r
-    void moduleGenAutogenC() throws BuildException {\r
+    void moduleGenAutogenC() throws EdkException {\r
 \r
         StringBuffer fileBuffer = new StringBuffer(8192);\r
         //\r
-        // Write Autogen.c header notation \r
+        // Write Autogen.c header notation\r
         //\r
-        fileBuffer.append(CommonDefinition.autogenCNotation);\r
-        \r
+        fileBuffer.append(CommonDefinition.AUTOGENCNOTATION);\r
+\r
         //\r
         // Write #include <AutoGen.h> at beginning of AutoGen.c\r
         //\r
-        fileBuffer.append(CommonDefinition.includeAutogenH);\r
-        \r
+        fileBuffer.append(CommonDefinition.INCLUDEAUTOGENH);\r
+\r
         //\r
-        // Write DriverBinding/ComponentName/DriverConfiguration/DriverDialog\r
+        // Get the native MSA file infomation. Since before call autogen,\r
+        // the MSA native <Externs> information were overrided. So before\r
+        // process <Externs> it should be set the DOC as the Native MSA info.\r
+        //\r
+        Map<String, XmlObject> doc = GlobalData.getNativeMsa(this.moduleId);\r
+        saq.push(doc);\r
+        //\r
+        // Write <Extern>\r
+        // DriverBinding/ComponentName/DriverConfiguration/DriverDialog\r
         // to AutoGen.c\r
         //\r
+\r
         ExternsDriverBindingToAutoGenC(fileBuffer);\r
 \r
         //\r
@@ -362,26 +435,37 @@ public class AutoGen {
         //\r
         // Write EntryPoint to autgoGen.c\r
         //\r
-        String[] entryPointList = SurfaceAreaQuery.getModuleEntryPointArray();\r
-        if (entryPointList != null) {\r
-            EntryPointToAutoGen(entryPointList, fileBuffer);\r
-        }\r
+        String[] entryPointList = saq.getModuleEntryPointArray();\r
+               String[] unloadImageList = saq.getModuleUnloadImageArray();\r
+        EntryPointToAutoGen(CommonDefinition.remDupString(entryPointList), \r
+                                       CommonDefinition.remDupString(unloadImageList),\r
+                                       fileBuffer);\r
+\r
+        pcdDriverType = saq.getPcdDriverType();\r
+\r
+        //\r
+        // Restore the DOC which include the FPD module info.\r
+        //\r
+        saq.pop();\r
 \r
         //\r
         // Write Guid to autogen.c\r
         //\r
-        String guid = SurfaceAreaQuery.getModuleGuid();\r
+        String guid = CommonDefinition.formatGuidName(saq.getModuleGuid());\r
+\r
         fileBuffer\r
-                .append("GLOBAL_REMOVE_IF_UNREFERENCED EFI_GUID gEfiCallerIdGuid = {");\r
+        .append("GLOBAL_REMOVE_IF_UNREFERENCED EFI_GUID gEfiCallerIdGuid = {");\r
         if (guid == null) {\r
-            throw new BuildException("Guid value must set!\n");\r
+            throw new AutoGenException("Guid value must set!\n");\r
         }\r
 \r
         //\r
         // Formate Guid as ANSI c form.Example:\r
-        // {0xd2b2b828, 0x826, 0x48a7,{0xb3, 0xdf, 0x98, 0x3c, 0x0, 0x60, 0x24, 0xf0}}\r
+        // {0xd2b2b828, 0x826, 0x48a7,{0xb3, 0xdf, 0x98, 0x3c, 0x0, 0x60, 0x24,\r
+        // 0xf0}}\r
         //\r
-        fileBuffer.append(Spd.formatGuidName(guid));\r
+\r
+        fileBuffer.append(guid);\r
         fileBuffer.append("};\r\n");\r
 \r
         //\r
@@ -392,6 +476,17 @@ public class AutoGen {
         //\r
         LibInstanceToAutogenC(fileBuffer);\r
 \r
+        //\r
+        // Get module dependent Package identification.\r
+        //\r
+        PackageIdentification[] packages = saq.getDependencePkg(this.arch);\r
+        for (int i = 0; i < packages.length; i++) {\r
+            if (!this.mDepPkgList.contains(packages[i])) {\r
+                this.mDepPkgList.add(packages[i]);\r
+            }\r
+\r
+        }\r
+\r
         //\r
         // Write consumed ppi, guid, protocol to autogen.c\r
         //\r
@@ -400,278 +495,309 @@ public class AutoGen {
         GuidGuidToAutogenC(fileBuffer);\r
 \r
         //\r
-        // Call pcd autogen. PCDAutoGenAction tool only need module name and\r
-        // isPcdEmulatedDriver as parameter. Library inherits PCD and module's\r
-        // PCD information has been collected in FPDParser task by\r
-        // CollectPCDAction. \r
-        // Note : when PCD image tool ready,\r
-        // isPCDEmulatedDriver parameter will be removed.\r
+        // Call pcd autogen.\r
         //\r
-        try {\r
-            this.myPcdAutogen = new PCDAutoGenAction(baseName,\r
-                                                     null,\r
-                                                     null,\r
-                                                     null,\r
-                                                     this.arch,\r
-                                                     null,\r
-                                                     false,\r
-                                                     SurfaceAreaQuery.getModulePcdEntryNameArray());\r
-            this.myPcdAutogen.execute();\r
-        } catch (Exception e) {\r
-            throw new BuildException("PCD Autogen for module failed:" + e.getMessage());\r
-        }\r
-\r
+        this.myPcdAutogen = new PCDAutoGenAction(moduleId, \r
+                                                 arch, \r
+                                                 false, \r
+                                                 null,\r
+                                                 pcdDriverType, \r
+                                                 parentId);\r
+        \r
+        this.myPcdAutogen.execute();\r
         if (this.myPcdAutogen != null) {\r
-            fileBuffer.append(this.myPcdAutogen.OutputC());\r
+            fileBuffer.append("\r\n");\r
+            fileBuffer.append(this.myPcdAutogen.getCAutoGenString());\r
         }\r
 \r
         if (!saveFile(outputPath + File.separatorChar + "AutoGen.c", fileBuffer)) {\r
-            throw new BuildException("Failed to generate AutoGen.c !!!");\r
+            throw new AutoGenException("Failed to generate AutoGen.c !!!");\r
         }\r
 \r
     }\r
-    \r
+\r
     /**\r
       libGenAutogenH\r
-   \r
+     \r
       This function generates AutoGen.h for library.\r
-    \r
+     \r
       @throws BuildException\r
-                Failed to generate AutoGen.c.\r
+                  Failed to generate AutoGen.c.\r
     **/\r
-    void libGenAutogenH() throws BuildException {\r
+    void libGenAutogenH() throws EdkException {\r
 \r
-        List<String> libClassIncludeH;\r
+        Set<String> libClassIncludeH;\r
         String moduleType;\r
         List<String> headerFileList;\r
+        Iterator item;\r
         StringBuffer fileBuffer = new StringBuffer(10240);\r
 \r
         //\r
-        // Write Autogen.h header notation \r
+        // Write Autogen.h header notation\r
         //\r
-        fileBuffer.append(CommonDefinition.autogenHNotation);\r
-        \r
+        fileBuffer.append(CommonDefinition.AUTOGENHNOTATION);\r
+\r
         //\r
-        // Add #ifndef  ${BaseName}_AUTOGENH\r
-        //     #def     ${BseeName}_AUTOGENH\r
+        // Add #ifndef ${BaseName}_AUTOGENH\r
+        // #def ${BseeName}_AUTOGENH\r
         //\r
-        fileBuffer.append("#ifndef    " + this.baseName.toUpperCase() + "_AUTOGENH\r\n");\r
-        fileBuffer.append("#define    " + this.baseName.toUpperCase() + "_AUTOGENH\r\n\r\n");\r
-        \r
+        fileBuffer.append(CommonDefinition.IFNDEF \r
+                                     + CommonDefinition.AUTOGENH\r
+                                     + this.moduleId.getGuid().replaceAll("-", "_") \r
+                                     + ToolDefinitions.LINE_SEPARATOR);\r
+        fileBuffer.append(CommonDefinition.DEFINE \r
+                                     + CommonDefinition.AUTOGENH\r
+                                     + this.moduleId.getGuid().replaceAll("-", "_") \r
+                                     + ToolDefinitions.LINE_SEPARATOR \r
+                                     + ToolDefinitions.LINE_SEPARATOR);\r
+\r
         //\r
-        // Write EFI_SPECIFICATION_VERSION and EDK_RELEASE_VERSION \r
+        // Write EFI_SPECIFICATION_VERSION and EDK_RELEASE_VERSION\r
         // to autogen.h file.\r
         // Note: the specification version and release version should\r
         // be get from module surface area instead of hard code.\r
         //\r
-        fileBuffer.append(CommonDefinition.autoGenHbegin);\r
-        fileBuffer.append(CommonDefinition.autoGenHLine1);\r
-        fileBuffer.append(CommonDefinition.autoGenHLine2);\r
+        fileBuffer.append(CommonDefinition.AUTOGENHBEGIN);\r
+        String[] specList = saq.getExternSpecificaiton();\r
+        for (int i = 0; i < specList.length; i++) {\r
+            fileBuffer.append(CommonDefinition.DEFINE + specList[i]\r
+                              + "\r\n");\r
+        }\r
+        // fileBuffer.append(CommonDefinition.autoGenHLine1);\r
+        // fileBuffer.append(CommonDefinition.autoGenHLine2);\r
 \r
         //\r
         // Write consumed package's mdouleInfo related *.h file to autogen.h.\r
-        // \r
-        moduleType = SurfaceAreaQuery.getModuleType();\r
-        List<String> cosumedPkglist = SurfaceAreaQuery\r
-                .getIncludePackageName(this.arch);\r
-        headerFileList = IncludesToAutogenH(cosumedPkglist, moduleType);\r
-        for (int i = 0; i < headerFileList.size(); i++) {\r
-            fileBuffer.append(headerFileList.get(i));\r
+        //\r
+        moduleType = saq.getModuleType();\r
+        PackageIdentification[] cosumedPkglist = saq\r
+                                                 .getDependencePkg(this.arch);\r
+        headerFileList = depPkgToAutogenH(cosumedPkglist, moduleType);\r
+        item = headerFileList.iterator();\r
+        while (item.hasNext()) {\r
+            fileBuffer.append(item.next().toString());\r
         }\r
-\r
         //\r
         // Write library class's related *.h file to autogen.h\r
         //\r
-        LibraryClass[] libClassList = SurfaceAreaQuery\r
-                .getLibraryClassArray(CommonDefinition.AlwaysConsumed);\r
+        String[] libClassList = saq\r
+                                .getLibraryClasses(CommonDefinition.ALWAYSCONSUMED, this.arch);\r
         if (libClassList != null) {\r
             libClassIncludeH = LibraryClassToAutogenH(libClassList);\r
-            for (int i = 0; i < libClassIncludeH.size(); i++) {\r
-                fileBuffer.append(libClassIncludeH.get(i));\r
+            item = libClassIncludeH.iterator();\r
+            while (item.hasNext()) {\r
+                fileBuffer.append(item.next().toString());\r
             }\r
         }\r
 \r
-        libClassList = SurfaceAreaQuery\r
-                .getLibraryClassArray(CommonDefinition.AlwaysProduced);\r
+        libClassList = saq\r
+                       .getLibraryClasses(CommonDefinition.ALWAYSPRODUCED, this.arch);\r
         if (libClassList != null) {\r
             libClassIncludeH = LibraryClassToAutogenH(libClassList);\r
-            for (int i = 0; i < libClassIncludeH.size(); i++) {\r
-                fileBuffer.append(libClassIncludeH.get(i));\r
+            item = libClassIncludeH.iterator();\r
+            while (item.hasNext()) {\r
+                fileBuffer.append(item.next().toString());\r
             }\r
         }\r
-        fileBuffer.append("\r\n");\r
-        \r
+        fileBuffer.append(ToolDefinitions.LINE_SEPARATOR);\r
+\r
+        //\r
+        //  If is TianoR8FlashMap, copy {Fv_DIR}/FlashMap.h to\r
+        // {DEST_DIR_DRBUG}/FlashMap.h\r
+        //\r
+        if (saq.isHaveTianoR8FlashMap()) {\r
+            fileBuffer.append(CommonDefinition.INCLUDE);\r
+            fileBuffer.append("  <");\r
+            fileBuffer.append(CommonDefinition.TIANOR8PLASHMAPH + ">\r\n");\r
+            copyFlashMapHToDebugDir();\r
+        }\r
+\r
         //\r
         // Write PCD information to library AutoGen.h.\r
         //\r
         if (this.myPcdAutogen != null) {\r
-            fileBuffer.append(this.myPcdAutogen.OutputH());\r
+            fileBuffer.append("\r\n");\r
+            fileBuffer.append(this.myPcdAutogen.getHAutoGenString());\r
         }\r
 \r
         //\r
         // Append the #endif at AutoGen.h\r
         //\r
         fileBuffer.append("#endif\r\n");\r
-        \r
+\r
         //\r
         // Save content of string buffer to AutoGen.h file.\r
         //\r
         if (!saveFile(outputPath + File.separatorChar + "AutoGen.h", fileBuffer)) {\r
-            throw new BuildException("Failed to generate AutoGen.h !!!");\r
+            throw new AutoGenException("Failed to generate AutoGen.h !!!");\r
         }\r
     }\r
 \r
     /**\r
       libGenAutogenC\r
-   \r
+     \r
       This function generates AutoGen.h for library.\r
-    \r
+     \r
       @throws BuildException\r
-                Failed to generate AutoGen.c.\r
+                  Failed to generate AutoGen.c.\r
     **/\r
-    void libGenAutogenC() throws BuildException {\r
+    void libGenAutogenC() throws EdkException {\r
         StringBuffer fileBuffer = new StringBuffer(10240);\r
 \r
         //\r
-        // Write Autogen.c header notation \r
+        // Write Autogen.c header notation\r
         //\r
-        fileBuffer.append(CommonDefinition.autogenCNotation);\r
-        \r
-        fileBuffer.append(CommonDefinition.autoGenCLine1);\r
-        fileBuffer.append("\r\n");\r
+        fileBuffer.append(CommonDefinition.AUTOGENCNOTATION);\r
+\r
+        fileBuffer.append(ToolDefinitions.LINE_SEPARATOR);\r
+        fileBuffer.append(ToolDefinitions.LINE_SEPARATOR);\r
 \r
         //\r
-        // Call pcd autogen. PCDAutoGenAction tool only need module name and\r
-        // isPcdEmulatedDriver as parameter. Library inherit PCD and module's\r
-        // PCD information has been collected in FPDParser task by\r
-        // CollectPCDAction. \r
-        // Note : when PCD image tool ready,\r
-        // isPCDEmulatedDriver parameter will be removed.\r
+        // Call pcd autogen.\r
         //\r
-        try {\r
-            this.myPcdAutogen = new PCDAutoGenAction(baseName, \r
-                                                     null,\r
-                                                     null,\r
-                                                     null,\r
-                                                     this.arch,\r
-                                                     null,\r
-                                                     true,\r
-                                                     SurfaceAreaQuery.getModulePcdEntryNameArray());\r
-            this.myPcdAutogen.execute();\r
-        } catch (Exception e) {\r
-            throw new BuildException("Pcd Autogen for library failed! " + e.getMessage());\r
-        }\r
-\r
+        this.myPcdAutogen = new PCDAutoGenAction(moduleId,\r
+                                                 arch,\r
+                                                 true,\r
+                                                 saq.getModulePcdEntryNameArray(),\r
+                                                 pcdDriverType, \r
+                                                 parentId);\r
+        this.myPcdAutogen.execute();\r
         if (this.myPcdAutogen != null) {\r
-            fileBuffer.append(this.myPcdAutogen.OutputC());\r
+            fileBuffer.append(ToolDefinitions.LINE_SEPARATOR);\r
+            fileBuffer.append(this.myPcdAutogen.getCAutoGenString());\r
         }\r
 \r
         if (!saveFile(outputPath + File.separatorChar + "AutoGen.c", fileBuffer)) {\r
-            throw new BuildException("Failed to generate AutoGen.c !!!");\r
+            throw new AutoGenException("Failed to generate AutoGen.c !!!");\r
         }\r
     }\r
 \r
     /**\r
       LibraryClassToAutogenH\r
-      \r
-      This function returns *.h files declared by library classes which are \r
+     \r
+      This function returns *.h files declared by library classes which are\r
       consumed or produced by current build module or library.\r
-      \r
-      @param   libClassList     List of library class which consumed or produce\r
-                                by current build module or library.\r
-      @return  includeStrList   List of *.h file.             \r
+     \r
+      @param libClassList\r
+                 List of library class which consumed or produce by current\r
+                 build module or library.\r
+      @return includeStrList List of *.h file.\r
     **/\r
-    List<String> LibraryClassToAutogenH(LibraryClass[] libClassList) {\r
-        List<String> includStrList = new ArrayList<String>();\r
-        String includerName;\r
+    Set<String> LibraryClassToAutogenH(String[] libClassList)\r
+    throws EdkException {\r
+        Set<String> includeStrList = new LinkedHashSet<String>();\r
+        String includeName[];\r
         String str = "";\r
-       \r
+\r
         //\r
-        // Get include file from GlobalData's SPDTable according to \r
+        // Get include file from GlobalData's SPDTable according to\r
         // library class name.\r
         //\r
         for (int i = 0; i < libClassList.length; i++) {\r
-            includerName = GlobalData.getLibClassIncluder(getStringValue((XmlObject)libClassList[i]));\r
-            if (includerName != null) {\r
-                str = CommonDefinition.include + " " + "<";\r
-                str = str + includerName + ">\r\n";\r
-                includStrList.add(str);\r
-                includerName = null;\r
+            includeName = GlobalData.getLibraryClassHeaderFiles(\r
+                            saq.getDependencePkg(this.arch),\r
+                                                                libClassList[i]);\r
+            if (includeName == null) {\r
+                throw new AutoGenException("Can not find library class ["\r
+                                           + libClassList[i] + "] declaration in any SPD package. ");\r
+            }\r
+            for (int j = 0; j < includeName.length; j++) {\r
+                String includeNameStr = includeName[j];\r
+                if (includeNameStr != null) {\r
+                    str = CommonDefinition.INCLUDE + " " + "<";\r
+                    str = str + includeNameStr + ">\r\n";\r
+                    includeStrList.add(str);\r
+                    includeNameStr = null;\r
+                }\r
             }\r
         }\r
-        return includStrList;\r
+        return includeStrList;\r
     }\r
 \r
     /**\r
       IncludesToAutogenH\r
-      \r
+     \r
       This function add include file in AutoGen.h file.\r
-      @param   packageNameList   List of module depended package.\r
-      @param   moduleType        Module type.\r
-      @return \r
+     \r
+      @param packageNameList\r
+                 List of module depended package.\r
+      @param moduleType\r
+                 Module type.\r
+      @return\r
     **/\r
-    List<String> IncludesToAutogenH(List<String> packageNameList,\r
-            String moduleType) {\r
+    List<String> depPkgToAutogenH(PackageIdentification[] packageNameList,\r
+                                  String moduleType) throws AutoGenException {\r
 \r
-        List<String> includeStrList = new ArrayList<String>();\r
-        String packageName = "";\r
+        List<String> includeStrList = new LinkedList<String>();\r
+        String pkgHeader;\r
         String includeStr = "";\r
 \r
         //\r
         // Get include file from moduleInfo file\r
         //\r
-        for (int i = 0; i < packageNameList.size(); i++) {\r
-            packageName = packageNameList.get(i);\r
-            includeStr = GlobalData.getModuleInfoByPackageName(packageName,\r
-                    moduleType);\r
-            includeStrList.add(includeStr);\r
+        for (int i = 0; i < packageNameList.length; i++) {\r
+            pkgHeader = GlobalData.getPackageHeaderFiles(packageNameList[i],\r
+                                                         moduleType);\r
+            if (pkgHeader == null) {\r
+                throw new AutoGenException("Can not find package ["\r
+                                           + packageNameList[i]\r
+                                           + "] declaration in any SPD package. ");\r
+            } else if (!pkgHeader.equalsIgnoreCase("")) {\r
+                includeStr = CommonDefinition.INCLUDE + " <" + pkgHeader\r
+                             + ">\r\n";\r
+                includeStrList.add(includeStr);\r
+            }\r
         }\r
+\r
         return includeStrList;\r
     }\r
 \r
     /**\r
-      EntryPointToAutoGen \r
-      \r
-      This function convert <ModuleEntryPoint> & <ModuleUnloadImage> information\r
-      in mas to AutoGen.c\r
-      \r
-      @param  entryPointList    List of entry point.                            \r
-      @param  fileBuffer        String buffer fo AutoGen.c.\r
+      EntryPointToAutoGen\r
+     \r
+      This function convert <ModuleEntryPoint> & <ModuleUnloadImage>\r
+      information in mas to AutoGen.c\r
+     \r
+      @param entryPointList\r
+                 List of entry point.\r
+      @param fileBuffer\r
+                 String buffer fo AutoGen.c.\r
       @throws Exception\r
     **/\r
-    void EntryPointToAutoGen(String[] entryPointList, StringBuffer fileBuffer)\r
-            throws BuildException {\r
+    void EntryPointToAutoGen(String[] entryPointList, String[] unloadImageList, StringBuffer fileBuffer)\r
+    throws EdkException {\r
+\r
+        String typeStr = saq.getModuleType();\r
+               int unloadImageCount = 0;\r
+        int entryPointCount  = 0;\r
 \r
-        String typeStr = SurfaceAreaQuery.getModuleType();\r
-        \r
         //\r
         // The parameters and return value of entryPoint is difference\r
         // for difference module type.\r
         //\r
         switch (CommonDefinition.getModuleType(typeStr)) {\r
-\r
+        \r
         case CommonDefinition.ModuleTypePeiCore:\r
-            if (entryPointList.length != 1 || entryPointList[0].equals("")) {\r
-                throw new BuildException(\r
-                        "Module type = 'PEI_CORE', only have one module entry point!");\r
+            if (entryPointList == null ||entryPointList.length != 1 ) {\r
+                throw new AutoGenException(\r
+                                        "Module type = 'PEI_CORE', can have only one module entry point!");\r
             } else {\r
                 fileBuffer.append("EFI_STATUS\r\n");\r
-                fileBuffer.append("EFIAPI\r\n");\r
                 fileBuffer.append(entryPointList[0]);\r
                 fileBuffer.append(" (\r\n");\r
                 fileBuffer\r
-                        .append("  IN EFI_PEI_STARTUP_DESCRIPTOR  *PeiStartupDescriptor,\r\n");\r
+                .append("  IN EFI_PEI_STARTUP_DESCRIPTOR  *PeiStartupDescriptor,\r\n");\r
                 fileBuffer\r
-                        .append("  IN VOID                        *OldCoreData\r\n");\r
+                .append("  IN VOID                        *OldCoreData\r\n");\r
                 fileBuffer.append("  );\r\n\r\n");\r
 \r
                 fileBuffer.append("EFI_STATUS\r\n");\r
                 fileBuffer.append("EFIAPI\r\n");\r
                 fileBuffer.append("ProcessModuleEntryPointList (\r\n");\r
                 fileBuffer\r
-                        .append("  IN EFI_PEI_STARTUP_DESCRIPTOR  *PeiStartupDescriptor,\r\n");\r
+                .append("  IN EFI_PEI_STARTUP_DESCRIPTOR  *PeiStartupDescriptor,\r\n");\r
                 fileBuffer\r
-                        .append("  IN VOID                        *OldCoreData\r\n");\r
+                .append("  IN VOID                        *OldCoreData\r\n");\r
                 fileBuffer.append("  )\r\n\r\n");\r
                 fileBuffer.append("{\r\n");\r
                 fileBuffer.append("  return ");\r
@@ -683,13 +809,12 @@ public class AutoGen {
 \r
         case CommonDefinition.ModuleTypeDxeCore:\r
             fileBuffer.append("const UINT32 _gUefiDriverRevision = 0;\r\n");\r
-            if (entryPointList.length != 1 || entryPointList[0].equals("")) {\r
-                throw new BuildException(\r
-                        "Module type = 'DXE_CORE', only have one module entry point!");\r
+            if (entryPointList == null || entryPointList.length != 1) {\r
+                throw new AutoGenException(\r
+                                        "Module type = 'DXE_CORE', can have only one module entry point!");\r
             } else {\r
 \r
                 fileBuffer.append("VOID\r\n");\r
-                fileBuffer.append("EFIAPI\r\n");\r
                 fileBuffer.append(entryPointList[0]);\r
                 fileBuffer.append(" (\n");\r
                 fileBuffer.append("  IN VOID  *HobStart\r\n");\r
@@ -709,24 +834,32 @@ public class AutoGen {
             break;\r
 \r
         case CommonDefinition.ModuleTypePeim:\r
-            int entryPointCount = 0;\r
+            entryPointCount = 0;\r
             fileBuffer\r
-                    .append("GLOBAL_REMOVE_IF_UNREFERENCED const UINT32 _gPeimRevision = 0;\r\n");\r
+            .append("GLOBAL_REMOVE_IF_UNREFERENCED const UINT32 _gPeimRevision = 0;\r\n");\r
+            if (entryPointList == null || entryPointList.length == 0) {\r
+                fileBuffer.append("EFI_STATUS\r\n");\r
+                fileBuffer.append("EFIAPI\r\n");\r
+                fileBuffer.append("ProcessModuleEntryPointList (\r\n");\r
+                fileBuffer.append("  IN EFI_FFS_FILE_HEADER  *FfsHeader,\r\n");\r
+                fileBuffer.append("  IN EFI_PEI_SERVICES     **PeiServices\r\n");\r
+                fileBuffer.append("  )\r\n\r\n");\r
+                fileBuffer.append("{\r\n");\r
+                fileBuffer.append("  return EFI_SUCCESS;\r\n");\r
+                fileBuffer.append("}\r\n\r\n");\r
+                break;\r
+            }\r
             for (int i = 0; i < entryPointList.length; i++) {\r
-                if (!entryPointList[i].equals("")) {\r
-                    fileBuffer.append("EFI_STATUS\r\n");\r
-                    fileBuffer.append("EFIAPI\r\n");\r
-                    fileBuffer.append(entryPointList[i]);\r
-                    fileBuffer.append(" (\r\n");\r
-                    fileBuffer\r
-                            .append("  IN EFI_FFS_FILE_HEADER  *FfsHeader,\r\n");\r
-                    fileBuffer\r
-                            .append("  IN EFI_PEI_SERVICES     **PeiServices\r\n");\r
-                    fileBuffer.append("  );\r\n");\r
-                    entryPointCount++;\r
-                } else {\r
-                    break;\r
-                }\r
+                fileBuffer.append("EFI_STATUS\r\n");\r
+                fileBuffer.append(entryPointList[i]);\r
+                fileBuffer.append(" (\r\n");\r
+                fileBuffer\r
+                .append("  IN EFI_FFS_FILE_HEADER  *FfsHeader,\r\n");\r
+                fileBuffer\r
+                .append("  IN EFI_PEI_SERVICES     **PeiServices\r\n");\r
+                fileBuffer.append("  );\r\n");\r
+                entryPointCount++;\r
+\r
             }\r
 \r
             fileBuffer.append("EFI_STATUS\r\n");\r
@@ -736,10 +869,7 @@ public class AutoGen {
             fileBuffer.append("  IN EFI_PEI_SERVICES     **PeiServices\r\n");\r
             fileBuffer.append("  )\r\n\r\n");\r
             fileBuffer.append("{\r\n");\r
-\r
-            if (entryPointCount == 0) {\r
-                fileBuffer.append("  return EFI_SUCCESS;\r\n");\r
-            } else if (entryPointCount == 1) {\r
+            if (entryPointCount == 1) {\r
                 fileBuffer.append("  return ");\r
                 fileBuffer.append(entryPointList[0]);\r
                 fileBuffer.append(" (FfsHeader, PeiServices);\r\n");\r
@@ -753,7 +883,7 @@ public class AutoGen {
                         fileBuffer.append(entryPointList[i]);\r
                         fileBuffer.append(" (FfsHeader, PeiServices);\r\n");\r
                         fileBuffer\r
-                                .append("  if (!EFI_ERROR (Status) || EFI_ERROR (CombinedStatus)) {\r\n");\r
+                        .append("  if (!EFI_ERROR (Status) || EFI_ERROR (CombinedStatus)) {\r\n");\r
                         fileBuffer.append("    CombinedStatus = Status;\r\n");\r
                         fileBuffer.append("  }\r\n\r\n");\r
                     } else {\r
@@ -767,139 +897,139 @@ public class AutoGen {
 \r
         case CommonDefinition.ModuleTypeDxeSmmDriver:\r
             entryPointCount = 0;\r
-            for (int i = 0; i < entryPointList.length; i++) {\r
-                if (!entryPointList[i].equals("")) {\r
+            //\r
+            // If entryPoint is null, create an empty ProcessModuleEntryPointList\r
+            // function.\r
+            //\r
+            if (entryPointList == null || entryPointList.length == 0) {\r
+                fileBuffer\r
+                .append("GLOBAL_REMOVE_IF_UNREFERENCED  const UINT8  _gDriverEntryPointCount = ");\r
+                fileBuffer.append(Integer.toString(entryPointCount));\r
+                fileBuffer.append(";\r\n");\r
+                fileBuffer.append("EFI_STATUS\r\n");\r
+                fileBuffer.append("EFIAPI\r\n");\r
+                fileBuffer.append("ProcessModuleEntryPointList (\r\n");\r
+                fileBuffer.append("  IN EFI_HANDLE        ImageHandle,\r\n");\r
+                fileBuffer.append("  IN EFI_SYSTEM_TABLE  *SystemTable\r\n");\r
+                fileBuffer.append("  )\r\n\r\n");\r
+                fileBuffer.append("{\r\n");\r
+                fileBuffer.append("  return EFI_SUCCESS;\r\n");\r
+                fileBuffer.append("}\r\n\r\n");\r
+\r
+            } else {\r
+                for (int i = 0; i < entryPointList.length; i++) {\r
                     fileBuffer.append("EFI_STATUS\r\n");\r
-                    fileBuffer.append("EFIAPI\r\n");\r
                     fileBuffer.append(entryPointList[i]);\r
                     fileBuffer.append(" (\r\n");\r
-                    fileBuffer.append("  EFI_HANDLE        ImageHandle,\r\n");\r
-                    fileBuffer.append("  EFI_SYSTEM_TABLE  *SystemTable\r\n");\r
+                    fileBuffer.append("  IN EFI_HANDLE        ImageHandle,\r\n");\r
+                    fileBuffer.append("  IN EFI_SYSTEM_TABLE  *SystemTable\r\n");\r
                     fileBuffer.append("  );\r\n");\r
                     entryPointCount++;\r
-                } else {\r
-                    break;\r
                 }\r
-            }\r
-            fileBuffer\r
-                    .append("GLOBAL_REMOVE_IF_UNREFERENCED  const UINT8  _gDriverEntryPointCount = ");\r
-            fileBuffer.append(Integer.toString(entryPointCount));\r
-            fileBuffer.append(";\r\n");\r
-            fileBuffer\r
-                    .append("static BASE_LIBRARY_JUMP_BUFFER  mJumpContext;\r\n");\r
-            fileBuffer\r
-                    .append("static EFI_STATUS  mDriverEntryPointStatus = EFI_LOAD_ERROR;\r\n\r\n");\r
+                fileBuffer\r
+                .append("GLOBAL_REMOVE_IF_UNREFERENCED  const UINT8  _gDriverEntryPointCount = ");\r
+                fileBuffer.append(Integer.toString(entryPointCount));\r
+                fileBuffer.append(";\r\n");\r
+                fileBuffer\r
+                .append("static BASE_LIBRARY_JUMP_BUFFER  mJumpContext;\r\n");\r
+                fileBuffer\r
+                .append("static EFI_STATUS  mDriverEntryPointStatus = EFI_LOAD_ERROR;\r\n\r\n");\r
 \r
-            fileBuffer.append("EFI_STATUS\r\n");\r
-            fileBuffer.append("EFIAPI\r\n");\r
-            fileBuffer.append("ProcessModuleEntryPointList (\r\n");\r
-            fileBuffer.append("  EFI_HANDLE        ImageHandle,\r\n");\r
-            fileBuffer.append("  EFI_SYSTEM_TABLE  *SystemTable\r\n");\r
-            fileBuffer.append("  )\r\n\r\n");\r
-            fileBuffer.append("{\r\n");\r
+                fileBuffer.append("EFI_STATUS\r\n");\r
+                fileBuffer.append("EFIAPI\r\n");\r
+                fileBuffer.append("ProcessModuleEntryPointList (\r\n");\r
+                fileBuffer.append("  IN EFI_HANDLE        ImageHandle,\r\n");\r
+                fileBuffer.append("  IN EFI_SYSTEM_TABLE  *SystemTable\r\n");\r
+                fileBuffer.append("  )\r\n\r\n");\r
+                fileBuffer.append("{\r\n");\r
 \r
-            for (int i = 0; i < entryPointList.length; i++) {\r
-                if (!entryPointList[i].equals("")) {\r
+\r
+                for (int i = 0; i < entryPointList.length; i++) {\r
                     fileBuffer\r
-                            .append("  if (SetJump (&mJumpContext) == 0) {\r\n");\r
+                    .append("  if (SetJump (&mJumpContext) == 0) {\r\n");\r
                     fileBuffer.append("    ExitDriver (");\r
                     fileBuffer.append(entryPointList[i]);\r
                     fileBuffer.append(" (ImageHandle, SystemTable));\r\n");\r
                     fileBuffer.append("    ASSERT (FALSE);\r\n");\r
                     fileBuffer.append("  }\r\n");\r
-                } else {\r
-                    break;\r
+\r
                 }\r
+                fileBuffer.append("  return mDriverEntryPointStatus;\r\n");\r
+                fileBuffer.append("}\r\n\r\n");\r
+\r
+                fileBuffer.append("VOID\r\n");\r
+                fileBuffer.append("EFIAPI\r\n");\r
+                fileBuffer.append("ExitDriver (\r\n");\r
+                fileBuffer.append("  IN EFI_STATUS  Status\n");\r
+                fileBuffer.append("  )\r\n\r\n");\r
+                fileBuffer.append("{\r\n");\r
+                fileBuffer\r
+                .append("  if (!EFI_ERROR (Status) || EFI_ERROR (mDriverEntryPointStatus)) {\r\n");\r
+                fileBuffer.append("    mDriverEntryPointStatus = Status;\r\n");\r
+                fileBuffer.append("  }\r\n");\r
+                fileBuffer.append("  LongJump (&mJumpContext, (UINTN)-1);\r\n");\r
+                fileBuffer.append("  ASSERT (FALSE);\r\n");\r
+                fileBuffer.append("}\r\n\r\n");\r
+\r
             }\r
-            fileBuffer.append("  return mDriverEntryPointStatus;\r\n");\r
-            fileBuffer.append("}\r\n\r\n");\r
 \r
-            fileBuffer.append("VOID\r\n");\r
-            fileBuffer.append("EFIAPI\r\n");\r
-            fileBuffer.append("ExitDriver (\r\n");\r
-            fileBuffer.append("  IN EFI_STATUS  Status\n");\r
-            fileBuffer.append("  )\r\n\r\n");\r
-            fileBuffer.append("{\r\n");\r
-            fileBuffer\r
-                    .append("  if (!EFI_ERROR (Status) || EFI_ERROR (mDriverEntryPointStatus)) {\r\n");\r
-            fileBuffer.append("    mDriverEntryPointStatus = Status;\r\n");\r
-            fileBuffer.append("  }\r\n");\r
-            fileBuffer.append("  LongJump (&mJumpContext, (UINTN)-1);\r\n");\r
-            fileBuffer.append("  ASSERT (FALSE);\r\n");\r
-            fileBuffer.append("}\r\n\r\n");\r
 \r
             //\r
             // Add "ModuleUnloadImage" for DxeSmmDriver module type;\r
             //\r
-            entryPointList = SurfaceAreaQuery.getModuleUnloadImageArray();\r
-            entryPointCount = 0;\r
-            if (entryPointList != null) {\r
-                for (int i = 0; i < entryPointList.length; i++) {\r
-                    if (!entryPointList[i].equals("")) {\r
-                        fileBuffer.append("EFI_STATUS\r\n");\r
-                        fileBuffer.append("EFIAPI\r\n");\r
-                        fileBuffer.append(entryPointList[i]);\r
-                        fileBuffer.append(" (\r\n");\r
-                        fileBuffer\r
-                                .append("  EFI_HANDLE        ImageHandle\r\n");\r
-                        fileBuffer.append("  );\r\n");\r
-                        entryPointCount++;\r
-                    } else {\r
-                        break;\r
-                    }\r
+            //entryPointList = SurfaceAreaQuery.getModuleUnloadImageArray();\r
+            //entryPointList = CommonDefinition.remDupString(entryPointList);\r
+            //entryPointCount = 0;\r
+\r
+                       unloadImageCount = 0;\r
+            if (unloadImageList != null) {\r
+                for (int i = 0; i < unloadImageList.length; i++) {\r
+                    fileBuffer.append("EFI_STATUS\r\n");\r
+                    fileBuffer.append(unloadImageList[i]);\r
+                    fileBuffer.append(" (\r\n");\r
+                    fileBuffer\r
+                    .append("  IN EFI_HANDLE        ImageHandle\r\n");\r
+                    fileBuffer.append("  );\r\n");\r
+                    unloadImageCount++;\r
                 }\r
             }\r
 \r
             fileBuffer\r
-                    .append("GLOBAL_REMOVE_IF_UNREFERENCED const UINT8  _gDriverUnloadImageCount = ");\r
-            fileBuffer.append(Integer.toString(entryPointCount));\r
+            .append("GLOBAL_REMOVE_IF_UNREFERENCED const UINT8  _gDriverUnloadImageCount = ");\r
+            fileBuffer.append(Integer.toString(unloadImageCount));\r
             fileBuffer.append(";\r\n\r\n");\r
 \r
-            if (entryPointList != null) {\r
-                for (int i = 0; i < entryPointList.length; i++) {\r
-                    if (!entryPointList[i].equals("")) {\r
-                        fileBuffer.append("EFI_STATUS\r\n");\r
-                        fileBuffer.append("EFIAPI\r\n");\r
-                        fileBuffer.append(entryPointList[i]);\r
-                        fileBuffer.append(" (\r\n");\r
-                        fileBuffer\r
-                                .append("  EFI_HANDLE        ImageHandle\r\n");\r
-                        fileBuffer.append("  );\r\n");\r
-                    } else {\r
-                        break;\r
-                    }\r
-                }\r
-            }\r
-\r
             fileBuffer.append("EFI_STATUS\r\n");\r
             fileBuffer.append("EFIAPI\r\n");\r
             fileBuffer.append("ProcessModuleUnloadList (\r\n");\r
-            fileBuffer.append("  EFI_HANDLE  ImageHandle\r\n");\r
+            fileBuffer.append("  IN EFI_HANDLE  ImageHandle\r\n");\r
             fileBuffer.append("  )\r\n");\r
             fileBuffer.append("{\r\n");\r
 \r
-            if (entryPointCount == 0) {\r
+            if (unloadImageCount == 0) {\r
                 fileBuffer.append("  return EFI_SUCCESS;\r\n");\r
-            } else if (entryPointCount == 1) {\r
+            } else if (unloadImageCount == 1) {\r
                 fileBuffer.append("  return ");\r
-                fileBuffer.append(entryPointList[0]);\r
+                fileBuffer.append(unloadImageList[0]);\r
                 fileBuffer.append("(ImageHandle);\r\n");\r
             } else {\r
                 fileBuffer.append("  EFI_STATUS  Status;\r\n\r\n");\r
                 fileBuffer.append("  Status = EFI_SUCCESS;\r\n\r\n");\r
-                for (int i = 0; i < entryPointList.length; i++) {\r
-                    if (!entryPointList[i].equals("")) {\r
+                for (int i = 0; i < unloadImageList.length; i++) {\r
+                    if (i == 0) {\r
+                        fileBuffer.append("     Status = ");\r
+                        fileBuffer.append(unloadImageList[i]);\r
+                        fileBuffer.append("(ImageHandle);\r\n");\r
+                    } else {\r
                         fileBuffer.append("  if (EFI_ERROR (Status)) {\r\n");\r
                         fileBuffer.append("    ");\r
-                        fileBuffer.append(entryPointList[i]);\r
+                        fileBuffer.append(unloadImageList[i]);\r
                         fileBuffer.append("(ImageHandle);\r\n");\r
                         fileBuffer.append("  } else {\r\n");\r
                         fileBuffer.append("    Status = ");\r
-                        fileBuffer.append(entryPointList[i]);\r
+                        fileBuffer.append(unloadImageList[i]);\r
                         fileBuffer.append("(ImageHandle);\r\n");\r
                         fileBuffer.append("  }\r\n");\r
-                    } else {\r
-                        break;\r
                     }\r
                 }\r
                 fileBuffer.append("  return Status;\r\n");\r
@@ -914,160 +1044,160 @@ public class AutoGen {
         case CommonDefinition.ModuleTypeUefiApplication:\r
             entryPointCount = 0;\r
             fileBuffer.append("const UINT32 _gUefiDriverRevision = 0;\r\n");\r
-            for (int i = 0; i < entryPointList.length; i++) {\r
-                if (!entryPointList[i].equals("")) {\r
+            //\r
+            // If entry point is null, create a empty ProcessModuleEntryPointList function.\r
+            //\r
+            if (entryPointList == null || entryPointList.length == 0) {\r
+                fileBuffer\r
+                .append("GLOBAL_REMOVE_IF_UNREFERENCED const UINT8  _gDriverEntryPointCount = 0;\r\n");\r
+                fileBuffer.append("EFI_STATUS\r\n");\r
+                fileBuffer.append("EFIAPI\r\n");\r
+                fileBuffer.append("ProcessModuleEntryPointList (\r\n");\r
+                fileBuffer.append("  IN EFI_HANDLE        ImageHandle,\r\n");\r
+                fileBuffer.append("  IN EFI_SYSTEM_TABLE  *SystemTable\r\n");\r
+                fileBuffer.append("  )\r\n\r\n");\r
+                fileBuffer.append("{\r\n");\r
+                fileBuffer.append("  return EFI_SUCCESS;\r\n");\r
+                fileBuffer.append("}\r\n");\r
+\r
+            } else {\r
+                for (int i = 0; i < entryPointList.length; i++) {\r
+\r
                     fileBuffer.append("EFI_STATUS\r\n");\r
-                    fileBuffer.append("EFIAPI\r\n");\r
                     fileBuffer.append(entryPointList[i]);\r
                     fileBuffer.append(" (\r\n");\r
-                    fileBuffer.append("  EFI_HANDLE        ImageHandle,\r\n");\r
-                    fileBuffer.append("  EFI_SYSTEM_TABLE  *SystemTable\r\n");\r
+                    fileBuffer.append("  IN EFI_HANDLE        ImageHandle,\r\n");\r
+                    fileBuffer.append("  IN EFI_SYSTEM_TABLE  *SystemTable\r\n");\r
                     fileBuffer.append("  );\r\n");\r
                     entryPointCount++;\r
-                } else {\r
-                    break;\r
                 }\r
-            }\r
 \r
-            fileBuffer\r
-                    .append("GLOBAL_REMOVE_IF_UNREFERENCED const UINT8  _gDriverEntryPointCount = ");\r
-            fileBuffer.append(Integer.toString(entryPointCount));\r
-            fileBuffer.append(";\r\n");\r
-            if (entryPointCount > 1) {\r
                 fileBuffer\r
-                        .append("static BASE_LIBRARY_JUMP_BUFFER  mJumpContext;\r\n");\r
-                fileBuffer\r
-                        .append("static EFI_STATUS  mDriverEntryPointStatus = EFI_LOAD_ERROR;\r\n");\r
-            }\r
-            fileBuffer.append("\n");\r
+                .append("GLOBAL_REMOVE_IF_UNREFERENCED const UINT8  _gDriverEntryPointCount = ");\r
+                fileBuffer.append(Integer.toString(entryPointCount));\r
+                fileBuffer.append(";\r\n");\r
+                if (entryPointCount > 1) {\r
+                    fileBuffer\r
+                    .append("static BASE_LIBRARY_JUMP_BUFFER  mJumpContext;\r\n");\r
+                    fileBuffer\r
+                    .append("static EFI_STATUS  mDriverEntryPointStatus = EFI_LOAD_ERROR;\r\n");\r
+                }\r
+                fileBuffer.append("\n");\r
 \r
-            fileBuffer.append("EFI_STATUS\r\n");\r
-            fileBuffer.append("EFIAPI\r\n");\r
-            fileBuffer.append("ProcessModuleEntryPointList (\r\n");\r
-            fileBuffer.append("  EFI_HANDLE        ImageHandle,\r\n");\r
-            fileBuffer.append("  EFI_SYSTEM_TABLE  *SystemTable\r\n");\r
-            fileBuffer.append("  )\r\n\r\n");\r
-            fileBuffer.append("{\r\n");\r
+                fileBuffer.append("EFI_STATUS\r\n");\r
+                fileBuffer.append("EFIAPI\r\n");\r
+                fileBuffer.append("ProcessModuleEntryPointList (\r\n");\r
+                fileBuffer.append("  IN EFI_HANDLE        ImageHandle,\r\n");\r
+                fileBuffer.append("  IN EFI_SYSTEM_TABLE  *SystemTable\r\n");\r
+                fileBuffer.append("  )\r\n\r\n");\r
+                fileBuffer.append("{\r\n");\r
 \r
-            if (entryPointCount == 0) {\r
-                fileBuffer.append("  return EFI_SUCCESS;\r\n");\r
-            } else if (entryPointCount == 1) {\r
-                fileBuffer.append("  return (");\r
-                fileBuffer.append(entryPointList[0]);\r
-                fileBuffer.append(" (ImageHandle, SystemTable));\r\n");\r
-            } else {\r
-                for (int i = 0; i < entryPointList.length; i++) {\r
-                    if (!entryPointList[i].equals("")) {\r
-                        fileBuffer\r
-                                .append("  if (SetJump (&mJumpContext) == 0) {\r\n");\r
-                        fileBuffer.append("    ExitDriver (");\r
-                        fileBuffer.append(entryPointList[i]);\r
-                        fileBuffer.append(" (ImageHandle, SystemTable));\r\n");\r
-                        fileBuffer.append("    ASSERT (FALSE);\r\n");\r
-                        fileBuffer.append("  }\r\n");\r
-                    } else {\r
-                        break;\r
+                if (entryPointCount == 1) {\r
+                    fileBuffer.append("  return (");\r
+                    fileBuffer.append(entryPointList[0]);\r
+                    fileBuffer.append(" (ImageHandle, SystemTable));\r\n");\r
+                } else {\r
+                    for (int i = 0; i < entryPointList.length; i++) {\r
+                        if (!entryPointList[i].equals("")) {\r
+                            fileBuffer\r
+                            .append("  if (SetJump (&mJumpContext) == 0) {\r\n");\r
+                            fileBuffer.append("    ExitDriver (");\r
+                            fileBuffer.append(entryPointList[i]);\r
+                            fileBuffer.append(" (ImageHandle, SystemTable));\r\n");\r
+                            fileBuffer.append("    ASSERT (FALSE);\r\n");\r
+                            fileBuffer.append("  }\r\n");\r
+                        } else {\r
+                            break;\r
+                        }\r
                     }\r
+                    fileBuffer.append("  return mDriverEntryPointStatus;\r\n");\r
                 }\r
-                fileBuffer.append("  return mDriverEntryPointStatus;\r\n");\r
-            }\r
-            fileBuffer.append("}\r\n\r\n");\r
+                fileBuffer.append("}\r\n\r\n");\r
+\r
+                fileBuffer.append("VOID\r\n");\r
+                fileBuffer.append("EFIAPI\r\n");\r
+                fileBuffer.append("ExitDriver (\r\n");\r
+                fileBuffer.append("  IN EFI_STATUS  Status\r\n");\r
+                fileBuffer.append("  )\r\n\r\n");\r
+                fileBuffer.append("{\r\n");\r
+                if (entryPointCount <= 1) {\r
+                    fileBuffer.append("  if (EFI_ERROR (Status)) {\r\n");\r
+                    fileBuffer\r
+                    .append("    ProcessLibraryDestructorList (gImageHandle, gST);\r\n");\r
+                    fileBuffer.append("  }\r\n");\r
+                    fileBuffer\r
+                    .append("  gBS->Exit (gImageHandle, Status, 0, NULL);\r\n");\r
+                } else {\r
+                    fileBuffer\r
+                    .append("  if (!EFI_ERROR (Status) || EFI_ERROR (mDriverEntryPointStatus)) {\r\n");\r
+                    fileBuffer.append("    mDriverEntryPointStatus = Status;\r\n");\r
+                    fileBuffer.append("  }\r\n");\r
+                    fileBuffer.append("  LongJump (&mJumpContext, (UINTN)-1);\r\n");\r
+                    fileBuffer.append("  ASSERT (FALSE);\r\n");\r
+                }\r
+                fileBuffer.append("}\r\n\r\n");\r
 \r
-            fileBuffer.append("VOID\n");\r
-            fileBuffer.append("EFIAPI\n");\r
-            fileBuffer.append("ExitDriver (\r\n");\r
-            fileBuffer.append("  IN EFI_STATUS  Status\n");\r
-            fileBuffer.append("  )\r\n\r\n");\r
-            fileBuffer.append("{\r\n");\r
-            if (entryPointCount <= 1) {\r
-                fileBuffer.append("  if (EFI_ERROR (Status)) {\r\n");\r
-                fileBuffer\r
-                        .append("    ProcessLibraryDestructorList (gImageHandle, gST);\r\n");\r
-                fileBuffer.append("  }\r\n");\r
-                fileBuffer\r
-                        .append("  gBS->Exit (gImageHandle, Status, 0, NULL);\r\n");\r
-            } else {\r
-                fileBuffer\r
-                        .append("  if (!EFI_ERROR (Status) || EFI_ERROR (mDriverEntryPointStatus)) {\r\n");\r
-                fileBuffer.append("    mDriverEntryPointStatus = Status;\r\n");\r
-                fileBuffer.append("  }\r\n");\r
-                fileBuffer.append("  LongJump (&mJumpContext, (UINTN)-1);\r\n");\r
-                fileBuffer.append("  ASSERT (FALSE);\r\n");\r
             }\r
-            fileBuffer.append("}\r\n\r\n");\r
 \r
             //\r
             // Add ModuleUnloadImage for DxeDriver and UefiDriver module type.\r
             //\r
-            entryPointList = SurfaceAreaQuery.getModuleUnloadImageArray();\r
-            entryPointCount = 0;\r
-            if (entryPointList != null) {\r
-                for (int i = 0; i < entryPointList.length; i++) {\r
-                    if (!entryPointList[i].equals("")) {\r
-                        fileBuffer.append("EFI_STATUS\r\n");\r
-                        fileBuffer.append("EFIAPI\r\n");\r
-                        fileBuffer.append(entryPointList[i]);\r
-                        fileBuffer.append(" (\r\n");\r
-                        fileBuffer\r
-                                .append("  EFI_HANDLE        ImageHandle\r\n");\r
-                        fileBuffer.append("  );\r\n");\r
-                        entryPointCount++;\r
-                    } else {\r
-                        break;\r
-                    }\r
+            //entryPointList = SurfaceAreaQuery.getModuleUnloadImageArray();\r
+            //\r
+            // Remover duplicate unload entry point.\r
+            //\r
+            //entryPointList = CommonDefinition.remDupString(entryPointList);\r
+            //entryPointCount = 0;\r
+                       unloadImageCount = 0;\r
+            if (unloadImageList != null) {\r
+                for (int i = 0; i < unloadImageList.length; i++) {\r
+                    fileBuffer.append("EFI_STATUS\r\n");\r
+                    fileBuffer.append("EFIAPI\r\n");\r
+                    fileBuffer.append(unloadImageList[i]);\r
+                    fileBuffer.append(" (\r\n");\r
+                    fileBuffer\r
+                    .append("  IN EFI_HANDLE        ImageHandle\r\n");\r
+                    fileBuffer.append("  );\r\n");\r
+                    unloadImageCount++;\r
                 }\r
             }\r
 \r
             fileBuffer\r
-                    .append("GLOBAL_REMOVE_IF_UNREFERENCED const UINT8  _gDriverUnloadImageCount = ");\r
-            fileBuffer.append(Integer.toString(entryPointCount));\r
+            .append("GLOBAL_REMOVE_IF_UNREFERENCED const UINT8  _gDriverUnloadImageCount = ");\r
+            fileBuffer.append(Integer.toString(unloadImageCount));\r
             fileBuffer.append(";\r\n\r\n");\r
 \r
-            if (entryPointList != null) {\r
-                for (int i = 0; i < entryPointList.length; i++) {\r
-                    if (!entryPointList[i].equals("")) {\r
-                        fileBuffer.append("EFI_STATUS\r\n");\r
-                        fileBuffer.append("EFIAPI\r\n");\r
-                        fileBuffer.append(entryPointList[i]);\r
-                        fileBuffer.append(" (\r\n");\r
-                        fileBuffer\r
-                                .append("  EFI_HANDLE        ImageHandle\r\n");\r
-                        fileBuffer.append("  );\r\n");\r
-                    } else {\r
-                        break;\r
-                    }\r
-                }\r
-            }\r
-\r
             fileBuffer.append("EFI_STATUS\n");\r
-            fileBuffer.append("EFIAPI\n");\r
+            fileBuffer.append("EFIAPI\r\n");\r
             fileBuffer.append("ProcessModuleUnloadList (\r\n");\r
-            fileBuffer.append("  EFI_HANDLE  ImageHandle\r\n");\r
+            fileBuffer.append("  IN EFI_HANDLE  ImageHandle\r\n");\r
             fileBuffer.append("  )\r\n");\r
             fileBuffer.append("{\r\n");\r
 \r
-            if (entryPointCount == 0) {\r
+            if (unloadImageCount == 0) {\r
                 fileBuffer.append("  return EFI_SUCCESS;\r\n");\r
-            } else if (entryPointCount == 1) {\r
+            } else if (unloadImageCount == 1) {\r
                 fileBuffer.append("  return ");\r
-                fileBuffer.append(entryPointList[0]);\r
+                fileBuffer.append(unloadImageList[0]);\r
                 fileBuffer.append("(ImageHandle);\r\n");\r
             } else {\r
                 fileBuffer.append("  EFI_STATUS  Status;\r\n\r\n");\r
                 fileBuffer.append("  Status = EFI_SUCCESS;\r\n\r\n");\r
-                for (int i = 0; i < entryPointList.length; i++) {\r
-                    if (!entryPointList[i].equals("")) {\r
+                for (int i = 0; i < unloadImageList.length; i++) {\r
+                    if (i == 0) {\r
+                        fileBuffer.append("  Status = ");\r
+                        fileBuffer.append(unloadImageList[i]);\r
+                        fileBuffer.append("(ImageHandle);\r\n");\r
+                    } else {\r
                         fileBuffer.append("  if (EFI_ERROR (Status)) {\r\n");\r
                         fileBuffer.append("    ");\r
-                        fileBuffer.append(entryPointList[i]);\r
+                        fileBuffer.append(unloadImageList[i]);\r
                         fileBuffer.append("(ImageHandle);\r\n");\r
                         fileBuffer.append("  } else {\r\n");\r
                         fileBuffer.append("    Status = ");\r
-                        fileBuffer.append(entryPointList[i]);\r
+                        fileBuffer.append(unloadImageList[i]);\r
                         fileBuffer.append("(ImageHandle);\r\n");\r
                         fileBuffer.append("  }\r\n");\r
-                    } else {\r
-                        break;\r
                     }\r
                 }\r
                 fileBuffer.append("  return Status;\r\n");\r
@@ -1078,433 +1208,255 @@ public class AutoGen {
     }\r
 \r
     /**\r
-      PpiGuidToAutogenc \r
-    \r
-      This function gets GUIDs from SPD file accrodeing to <PPIs> information and \r
-      write those GUIDs to AutoGen.c.\r
-    \r
-      @param   fileBuffer         String Buffer for Autogen.c file.\r
-      @throws  BuildException     Guid must set value!\r
+      PpiGuidToAutogenc\r
+     \r
+      This function gets GUIDs from SPD file accrodeing to <PPIs> information\r
+      and write those GUIDs to AutoGen.c.\r
+     \r
+      @param fileBuffer\r
+                 String Buffer for Autogen.c file.\r
+      @throws BuildException\r
+                  Guid must set value!\r
     **/\r
-    void PpiGuidToAutogenC(StringBuffer fileBuffer) throws BuildException {\r
+    void PpiGuidToAutogenC(StringBuffer fileBuffer) throws AutoGenException {\r
         String[] cNameGuid = null;\r
-        boolean isEqual = false;\r
-\r
-        PPIsDocument.PPIs.Ppi[] ppiList = SurfaceAreaQuery.getPpiArray(null);\r
-        if (ppiList != null) {\r
-            for (int i = 0; i < ppiList.length; i++) {\r
-                isEqual = false;\r
-                String ppiName = getStringValue((XmlObject)ppiList[i]);\r
-                for (int j = 0; j < this.mPpiList.size(); j++) {\r
-                    if (this.mPpiList.get(j).equalsIgnoreCase(ppiName)) {\r
-                        isEqual = true;\r
-                    }\r
-                }\r
-                if (!isEqual) {\r
-                    this.mPpiList.add(ppiName);\r
-                }\r
-            }\r
+\r
+        //\r
+        // Get the all PPI adn PPI Notify from MSA file,\r
+        // then add those PPI ,and PPI Notify name to list.\r
+        //\r
+\r
+        String[] ppiList = saq.getPpiArray(this.arch);\r
+        for (int i = 0; i < ppiList.length; i++) {\r
+            this.mPpiList.add(ppiList[i]);\r
         }\r
 \r
-        PPIsDocument.PPIs.PpiNotify[] ppiNotifyList = SurfaceAreaQuery\r
-                .getPpiNotifyArray(null);\r
-        if (ppiNotifyList != null) {\r
-            for (int i = 0; i < ppiNotifyList.length; i++) {\r
-                isEqual = false;\r
-                String ppiNotifyName = getStringValue((XmlObject)ppiNotifyList[i]);\r
-                for (int j = 0; j < this.mPpiList.size(); j++) {\r
-                    if (this.mPpiList.get(j).equalsIgnoreCase(ppiNotifyName)) {\r
-                        isEqual = true;\r
-                    }\r
-                }\r
-                if (!isEqual) {\r
-                    this.mPpiList.add(ppiNotifyName);\r
-                }\r
-            }\r
+        String[] ppiNotifyList = saq.getPpiNotifyArray(this.arch);\r
+        for (int i = 0; i < ppiNotifyList.length; i++) {\r
+            this.mPpiList.add(ppiNotifyList[i]);\r
         }\r
 \r
-        for (int i = 0; i < this.mPpiList.size(); i++) {\r
-            if (this.mPpiList.get(i) != null) {\r
-                cNameGuid = GlobalData.getPpiInfoGuid(this.mPpiList.get(i));\r
-                if (cNameGuid != null) {\r
-                    fileBuffer\r
-                            .append("\r\nGLOBAL_REMOVE_IF_UNREFERENCED EFI_GUID ");\r
-                    fileBuffer.append(cNameGuid[0]);\r
-                    fileBuffer.append(" =     { ");\r
-                    fileBuffer.append(cNameGuid[1]);\r
-                    fileBuffer.append(" } ;");\r
-                }\r
+        //\r
+        // Find CNAME and GUID from dependence SPD file and write to Autogen.c\r
+        //\r
+        Iterator ppiIterator = this.mPpiList.iterator();\r
+        String ppiKeyWord = null;\r
+        while (ppiIterator.hasNext()) {\r
+            ppiKeyWord = ppiIterator.next().toString();\r
+            cNameGuid = GlobalData.getPpiGuid(this.mDepPkgList, ppiKeyWord);\r
+            if (cNameGuid != null) {\r
+                fileBuffer\r
+                .append("\r\nGLOBAL_REMOVE_IF_UNREFERENCED EFI_GUID ");\r
+                fileBuffer.append(cNameGuid[0]);\r
+                fileBuffer.append(" =     { ");\r
+                fileBuffer.append(CommonDefinition.formatGuidName(cNameGuid[1]));\r
+                fileBuffer.append(" } ;");\r
             } else {\r
-                throw new BuildException("Guid must set value!");\r
+                //\r
+                // If can't find Ppi GUID declaration in every package\r
+                //\r
+                throw new AutoGenException("Can not find Ppi GUID ["\r
+                                           + ppiKeyWord + "] declaration in any SPD package!");\r
             }\r
         }\r
     }\r
 \r
     /**\r
-      ProtocolGuidToAutogenc \r
-    \r
-      This function gets GUIDs from SPD file accrodeing to <Protocol> \r
+      ProtocolGuidToAutogenc\r
+     \r
+      This function gets GUIDs from SPD file accrodeing to <Protocol>\r
       information and write those GUIDs to AutoGen.c.\r
-    \r
-      @param   fileBuffer         String Buffer for Autogen.c file.\r
-      @throws  BuildException     Protocol name must set.\r
+     \r
+      @param fileBuffer\r
+                 String Buffer for Autogen.c file.\r
+      @throws BuildException\r
+                  Protocol name must set.\r
     **/\r
-    void ProtocolGuidToAutogenC(StringBuffer fileBuffer) throws BuildException {\r
+    void ProtocolGuidToAutogenC(StringBuffer fileBuffer) throws EdkException {\r
         String[] cNameGuid = null;\r
-        boolean isEqual = false;\r
-\r
-        ProtocolsDocument.Protocols.Protocol[] protocolList = SurfaceAreaQuery\r
-                .getProtocolArray(null);\r
-        if (protocolList != null) {\r
-            for (int i = 0; i < protocolList.length; i++) {\r
-                isEqual = false;\r
-                String protocolName = getStringValue((XmlObject)protocolList[i]);\r
-                for (int j = 0; j < this.mProtocolList.size(); j++) {\r
-                    if (this.mProtocolList.get(j).equalsIgnoreCase(protocolName)) {\r
-                        isEqual = true;\r
-                    }\r
-                }\r
-                if (!isEqual) {\r
-                    this.mProtocolList.add(protocolName);\r
 \r
-                }\r
-            }\r
+        String[] protocolList = saq.getProtocolArray(this.arch);\r
+\r
+        //\r
+        // Add result to Autogen global list.\r
+        //\r
+        for (int i = 0; i < protocolList.length; i++) {\r
+            this.mProtocolList.add(protocolList[i]);\r
         }\r
 \r
-        ProtocolsDocument.Protocols.ProtocolNotify[] protocolNotifyList = SurfaceAreaQuery\r
-                .getProtocolNotifyArray(null);\r
-        if (protocolNotifyList != null) {\r
-            for (int i = 0; i < protocolNotifyList.length; i++) {\r
-                isEqual = false;\r
-                String protocolNotifyName = getStringValue((XmlObject)protocolNotifyList[i]);\r
-                for (int j = 0; j < this.mProtocolList.size(); j++) {\r
-                    if (this.mProtocolList.get(j).equalsIgnoreCase(protocolNotifyName)) {\r
-                        isEqual = true;\r
-                    }\r
-                }\r
-                if (!isEqual) {\r
-                    this.mProtocolList.add(protocolNotifyName);\r
+        String[] protocolNotifyList = saq\r
+                                      .getProtocolNotifyArray(this.arch);\r
 \r
-                }\r
-            }\r
+        for (int i = 0; i < protocolNotifyList.length; i++) {\r
+            this.mProtocolList.add(protocolNotifyList[i]);\r
         }\r
-        if (this.mProtocolList.size() > 0) {\r
-            for (int i = 0; i < this.mProtocolList.size(); i++) {\r
-                if (this.mProtocolList.get(i) != null) {\r
-                    cNameGuid = GlobalData\r
-                            .getProtocolInfoGuid(this.mProtocolList.get(i));\r
-                    if (cNameGuid != null) {\r
-                        fileBuffer\r
-                                .append("\r\nGLOBAL_REMOVE_IF_UNREFERENCED EFI_GUID ");\r
-                        fileBuffer.append(cNameGuid[0]);\r
-                        fileBuffer.append(" =     { ");\r
-                        fileBuffer.append(cNameGuid[1]);\r
-                        fileBuffer.append(" } ;");\r
-                    }\r
-                } else {\r
-                    throw new BuildException("Protocol name must set!");\r
-                }\r
+\r
+        //\r
+        // Get the NAME and GUID from dependence SPD and write to Autogen.c\r
+        //\r
+        Iterator protocolIterator = this.mProtocolList.iterator();\r
+        String protocolKeyWord = null;\r
+\r
+\r
+        while (protocolIterator.hasNext()) {\r
+            protocolKeyWord = protocolIterator.next().toString();\r
+            cNameGuid = GlobalData.getProtocolGuid(this.mDepPkgList, protocolKeyWord);\r
+            if (cNameGuid != null) {\r
+                fileBuffer\r
+                .append("\r\nGLOBAL_REMOVE_IF_UNREFERENCED EFI_GUID ");\r
+                fileBuffer.append(cNameGuid[0]);\r
+                fileBuffer.append(" =     { ");\r
+                fileBuffer.append(CommonDefinition.formatGuidName(cNameGuid[1]));\r
+                fileBuffer.append(" } ;");\r
+            } else {\r
+                //\r
+                // If can't find protocol GUID declaration in every package\r
+                //\r
+                throw new AutoGenException("Can not find protocol Guid ["\r
+                                         + protocolKeyWord + "] declaration in any SPD package!");\r
             }\r
         }\r
     }\r
 \r
     /**\r
       GuidGuidToAutogenc\r
-    \r
+     \r
       This function gets GUIDs from SPD file accrodeing to <Guids> information\r
       and write those GUIDs to AutoGen.c.\r
-    \r
-      @param  fileBuffer       String Buffer for Autogen.c file.\r
-    \r
+     \r
+      @param fileBuffer\r
+                 String Buffer for Autogen.c file.\r
+     \r
     **/\r
-    void GuidGuidToAutogenC(StringBuffer fileBuffer) {\r
+    void GuidGuidToAutogenC(StringBuffer fileBuffer) throws AutoGenException {\r
         String[] cNameGuid = null;\r
-        boolean isEqual = false;\r
-        GuidsDocument.Guids.GuidEntry[] guidList = SurfaceAreaQuery\r
-                .getGuidEntryArray(null);\r
-\r
-        if (guidList != null) {\r
-            for (int i = 0; i < guidList.length; i++) {\r
-                for (int j = 0; j < this.mGuidList.size(); j++) {\r
-                    isEqual = false;\r
-                    if (this.mGuidList.get(j).getCName().equalsIgnoreCase(\r
-                            guidList[i].getCName().toString())) {\r
-                        isEqual = true;\r
-                        break;\r
-                    }\r
-                }\r
-                if (!isEqual) {\r
-                    this.mGuidList.add(guidList[i]);\r
-\r
-                }\r
+        String guidKeyWord = null;\r
 \r
-            }\r
-        }\r
+        String[] guidList = saq.getGuidEntryArray(this.arch);\r
 \r
-        for (int i = 0; i < this.mGuidList.size(); i++) {\r
-            if (this.mGuidList.get(i).getCName() != null) {\r
-                cNameGuid = GlobalData.getGuidInfoGuid(this.mGuidList.get(i)\r
-                        .getCName());\r
-                if (cNameGuid != null) {\r
-                    fileBuffer\r
-                            .append("\r\nGLOBAL_REMOVE_IF_UNREFERENCED EFI_GUID ");\r
-                    fileBuffer.append(cNameGuid[0]);\r
-                    fileBuffer.append(" =     { ");\r
-                    fileBuffer.append(cNameGuid[1]);\r
-                    fileBuffer.append("} ;");\r
-                }\r
-            }\r
+        for (int i = 0; i < guidList.length; i++) {\r
+            this.mGuidList.add(guidList[i]);\r
         }\r
-    }\r
-\r
-    /**\r
-      LibInstanceToAutogenC\r
-      \r
-      This function adds dependent library instance to autogen.c,which includeing \r
-      library's constructor, destructor, and library dependent ppi, protocol, guid,\r
-      pcd information.\r
-         \r
-      @param  fileBuffer              String buffer for AutoGen.c\r
-      @throws BuildException          \r
-    **/\r
-    void LibInstanceToAutogenC(StringBuffer fileBuffer) throws BuildException {\r
-        int index;\r
-        boolean isEqual = false;\r
-\r
-        String moduleType = SurfaceAreaQuery.getModuleType();\r
-        List<String> libConstructList = new ArrayList<String>();\r
-        List<String> libDestructList = new ArrayList<String>();\r
-\r
-        String libConstructName = null;\r
-        String libDestructName = null;\r
-        List<String> libraryList = SurfaceAreaQuery.getLibraryInstance(\r
-                this.arch, CommonDefinition.AlwaysConsumed);\r
-\r
-        try {\r
-            if (libraryList != null) {\r
-                //\r
-                // Reorder library instance sequence.\r
-                //\r
-                AutogenLibOrder libOrder = new AutogenLibOrder(libraryList);\r
-                List orderList = libOrder.orderLibInstance();\r
-                \r
-                if (orderList != null) {\r
-                    //\r
-                    // Process library instance one by one.\r
-                    //\r
-                    for (int i = 0; i < orderList.size(); i++) {\r
-                        \r
-                        //\r
-                        // Get library instance basename.\r
-                        //\r
-                        String libInstanceName = orderList.get(i).toString();\r
-                        \r
-                        //\r
-                        // Get override map\r
-                        //\r
-                        Map<String, XmlObject> libDoc = GlobalData\r
-                                .getDoc(libInstanceName);\r
-                        SurfaceAreaQuery.push(libDoc);\r
-                        \r
-                        //\r
-                        // Get <PPis>, <Protocols>, <Guids> list of this library\r
-                        // instance.\r
-                        //\r
-                        PPIsDocument.PPIs.Ppi[] ppiList = SurfaceAreaQuery\r
-                                .getPpiArray(null);\r
-                        PPIsDocument.PPIs.PpiNotify[] ppiNotifyList = SurfaceAreaQuery\r
-                                .getPpiNotifyArray(null);\r
-                        ProtocolsDocument.Protocols.Protocol[] protocolList = SurfaceAreaQuery\r
-                                .getProtocolArray(null);\r
-                        ProtocolsDocument.Protocols.ProtocolNotify[] protocolNotifyList = SurfaceAreaQuery\r
-                                .getProtocolNotifyArray(null);\r
-                        GuidsDocument.Guids.GuidEntry[] guidList = SurfaceAreaQuery\r
-                                .getGuidEntryArray(null);\r
-\r
-                        //\r
-                        // Add those ppi, protocol, guid in global ppi, protocol, guid\r
-                        // list.\r
-                        //\r
-                        if (ppiList != null) {\r
-                            for (index = 0; index < ppiList.length; index++) {\r
-                                isEqual = false;\r
-                                String name = getStringValue((XmlObject)ppiList[index]);\r
-                                for (int j = 0; j < this.mPpiList.size(); j++) {\r
-                                    if (this.mPpiList.get(j).equalsIgnoreCase(name)) {\r
-                                        isEqual = true;\r
-                                    }\r
-                                }\r
-                                if (!isEqual) {\r
-                                    this.mPpiList.add(name);\r
-                                }\r
-                            }\r
-                        }\r
-                        if (ppiNotifyList != null) {\r
-                            for (index = 0; index < ppiNotifyList.length; index++) {\r
-                                isEqual = false;\r
-                                String name = getStringValue((XmlObject)ppiNotifyList[index]);\r
-                                for (int j = 0; j < this.mPpiList.size(); j++) {\r
-                                    if (this.mPpiList.get(j).equalsIgnoreCase(name)) {\r
-                                        isEqual = true;\r
-                                    }\r
-                                }\r
-                                if (!isEqual) {\r
-                                    this.mPpiList.add(name);\r
-                                }\r
-                            }\r
-                        }\r
-                        if (protocolList != null) {\r
-                            for (index = 0; index < protocolList.length; index++) {\r
-                                isEqual = false;\r
-                                String name = getStringValue((XmlObject)protocolList[index]);\r
-                                for (int j = 0; j < this.mProtocolList.size(); j++) {\r
-                                    if (this.mProtocolList.get(j).equalsIgnoreCase(name)) {\r
-                                        isEqual = true;\r
-                                    }\r
-                                }\r
-                                if (!isEqual) {\r
-                                    this.mProtocolList.add(name);\r
-                                }\r
-                            }\r
-                        }\r
-                        if (protocolNotifyList != null) {\r
-                            for (index = 0; index < protocolNotifyList.length; index++) {\r
-                                isEqual = false;\r
-                                String name = getStringValue((XmlObject)protocolNotifyList[index]);\r
-                                for (int j = 0; j < this.mProtocolList.size(); j++) {\r
-                                    if (this.mProtocolList.get(j).equalsIgnoreCase(name)) {\r
-                                        isEqual = true;\r
-                                    }\r
-                                }\r
-                                if (!isEqual) {\r
-                                    this.mProtocolList.add(name);\r
-                                }\r
-                            }\r
-                        }\r
-                        if (guidList != null) {\r
-                            for (index = 0; index < guidList.length; index++) {\r
-                                isEqual = false;\r
-                                for (int j = 0; j < this.mGuidList.size(); j++) {\r
-                                    if (this.mGuidList.get(j).getCName()\r
-                                            .equalsIgnoreCase(\r
-                                                    guidList[index].getCName())) {\r
-                                        isEqual = true;\r
-                                    }\r
-                                }\r
-                                if (!isEqual) {\r
-                                    this.mGuidList.add(guidList[index]);\r
-                                }\r
-                            }\r
-                        }\r
 \r
-                        //\r
-                        // If not yet parse this library instance's constructor\r
-                        // element,parse it.\r
-                        //\r
-                        if (!GlobalData.isHaveLibInstance(libInstanceName)) {\r
-                            libConstructName = SurfaceAreaQuery\r
-                                    .getLibConstructorName();\r
-                            libDestructName = SurfaceAreaQuery\r
-                                    .getLibDestructorName();\r
-\r
-                            GlobalData.setLibInstanceInfo(libInstanceName,\r
-                                    libConstructName, libDestructName);\r
-                        } else {\r
-                            libConstructName = GlobalData\r
-                                    .getLibInstanceConstructor(libInstanceName);\r
-                            libDestructName = GlobalData\r
-                                    .getLibInstanceDestructor(libInstanceName);\r
-                        }\r
-                        SurfaceAreaQuery.pop();\r
-                        //\r
-                        // Add dependent library instance constructor function.\r
-                        //\r
-                        if (libConstructName != null) {\r
-                            libConstructList.add(libConstructName);\r
-                        }\r
-                        //\r
-                        // Add dependent library instance destructor fuction.\r
-                        //\r
-                        if (libDestructName != null) {\r
-                            libDestructList.add(libDestructName);\r
-                        }\r
-                    }\r
 \r
-                }\r
+        Iterator guidIterator = this.mGuidList.iterator();\r
+        while (guidIterator.hasNext()) {\r
+            guidKeyWord = guidIterator.next().toString();\r
+            cNameGuid = GlobalData.getGuid(this.mDepPkgList, guidKeyWord);\r
 \r
+            if (cNameGuid != null) {\r
+                fileBuffer\r
+                .append("\r\nGLOBAL_REMOVE_IF_UNREFERENCED EFI_GUID ");\r
+                fileBuffer.append(cNameGuid[0]);\r
+                fileBuffer.append(" =     { ");\r
+                fileBuffer.append(CommonDefinition.formatGuidName(cNameGuid[1]));\r
+                fileBuffer.append("} ;");\r
+            } else {\r
                 //\r
-                // Add library constructor to AutoGen.c\r
-                //\r
-                LibConstructorToAutogenC(libConstructList, moduleType,\r
-                        fileBuffer/* autogenC */);\r
-                //\r
-                // Add library destructor to AutoGen.c\r
+                // If can't find GUID declaration in every package\r
                 //\r
-                LibDestructorToAutogenC(libDestructList, moduleType,\r
-                        fileBuffer/* autogenC */);\r
+                throw new AutoGenException("Can not find Guid [" + guidKeyWord\r
+                                           + "] declaration in any SPD package. ");\r
             }\r
 \r
-        } catch (Exception e) {\r
-            throw new BuildException(e.getMessage());\r
         }\r
     }\r
 \r
\r
+    /**\r
+      LibInstanceToAutogenC\r
+     \r
+      This function adds dependent library instance to autogen.c,which\r
+      includeing library's constructor, destructor, and library dependent ppi,\r
+      protocol, guid, pcd information.\r
+     \r
+      @param fileBuffer\r
+                 String buffer for AutoGen.c\r
+      @throws BuildException\r
+    **/\r
+    void LibInstanceToAutogenC(StringBuffer fileBuffer) throws EdkException {\r
+               String moduleType = this.moduleId.getModuleType();\r
+               //\r
+               // Add library constructor to AutoGen.c\r
+               //\r
+               LibConstructorToAutogenC(libConstructList, moduleType,\r
+                                                                fileBuffer/* autogenC */);\r
+               //\r
+               // Add library destructor to AutoGen.c\r
+               //\r
+               LibDestructorToAutogenC(libDestructList, moduleType, fileBuffer/* autogenC */);\r
+    }\r
+\r
     /**\r
       LibConstructorToAutogenc\r
-    \r
-      This function writes library constructor list to AutoGen.c. The library \r
+     \r
+      This function writes library constructor list to AutoGen.c. The library\r
       constructor's parameter and return value depend on module type.\r
-    \r
-      @param  libInstanceList        List of library construct name.\r
-      @param  moduleType             Module type.\r
-      @param  fileBuffer             String buffer for AutoGen.c\r
-      @throws Exception              \r
+     \r
+      @param libInstanceList\r
+                 List of library construct name.\r
+      @param moduleType\r
+                 Module type.\r
+      @param fileBuffer\r
+                 String buffer for AutoGen.c\r
+      @throws Exception\r
     **/\r
-    void LibConstructorToAutogenC(List<String> libInstanceList,\r
-            String moduleType, StringBuffer fileBuffer) throws Exception {\r
+    void LibConstructorToAutogenC(List<String[]> libInstanceList,\r
+                                  String moduleType, StringBuffer fileBuffer) throws EdkException {\r
         boolean isFirst = true;\r
 \r
         //\r
-        // The library constructor's parameter and return value depend on \r
+        // The library constructor's parameter and return value depend on\r
         // module type.\r
         //\r
         for (int i = 0; i < libInstanceList.size(); i++) {\r
-            switch (CommonDefinition.getModuleType(moduleType)) {\r
-            case CommonDefinition.ModuleTypeBase:\r
-                fileBuffer.append("RETURN_STATUS\r\n");\r
-                fileBuffer.append(libInstanceList.get(i));\r
+                       if (libInstanceList.get(i)[1].equalsIgnoreCase(EdkDefinitions.MODULE_TYPE_BASE)) {\r
+                               fileBuffer.append("RETURN_STATUS\r\n");\r
+                fileBuffer.append("EFIAPI\r\n");\r
+                fileBuffer.append(libInstanceList.get(i)[0]);\r
                 fileBuffer.append(" (\r\n");\r
                 fileBuffer.append("  VOID\r\n");\r
                 fileBuffer.append("  );\r\n");\r
-                break;\r
-\r
-            case CommonDefinition.ModuleTypePeiCore:\r
-            case CommonDefinition.ModuleTypePeim:\r
-                fileBuffer.append("EFI_STATUS\r\n");\r
-                fileBuffer.append(libInstanceList.get(i));\r
-                fileBuffer.append(" (\r\n");\r
-                fileBuffer\r
-                        .append("  IN EFI_FFS_FILE_HEADER       *FfsHeader,\r\n");\r
-                fileBuffer\r
-                        .append("  IN EFI_PEI_SERVICES          **PeiServices\r\n");\r
-                fileBuffer.append("  );\r\n");\r
-                break;\r
+                       } else {\r
+                               switch (CommonDefinition.getModuleType(moduleType)) {\r
+                case CommonDefinition.ModuleTypeBase:\r
+                    fileBuffer.append("RETURN_STATUS\r\n");\r
+                    fileBuffer.append("EFIAPI\r\n");\r
+                    fileBuffer.append(libInstanceList.get(i)[0]);\r
+                    fileBuffer.append(" (\r\n");\r
+                    fileBuffer.append("  VOID\r\n");\r
+                    fileBuffer.append("  );\r\n");\r
+                    break;\r
 \r
-            case CommonDefinition.ModuleTypeDxeCore:\r
-            case CommonDefinition.ModuleTypeDxeDriver:\r
-            case CommonDefinition.ModuleTypeDxeRuntimeDriver:\r
-            case CommonDefinition.ModuleTypeDxeSmmDriver:\r
-            case CommonDefinition.ModuleTypeDxeSalDriver:\r
-            case CommonDefinition.ModuleTypeUefiDriver:\r
-            case CommonDefinition.ModuleTypeUefiApplication:\r
-                fileBuffer.append("EFI_STATUS\r\n");\r
-                fileBuffer.append(libInstanceList.get(i));\r
-                fileBuffer.append(" (\r\n");\r
-                fileBuffer.append("  IN EFI_HANDLE        ImageHandle,\r\n");\r
-                fileBuffer.append("  IN EFI_SYSTEM_TABLE  *SystemTable\r\n");\r
-                fileBuffer.append("  );\r\n");\r
-                break;\r
+                case CommonDefinition.ModuleTypePeiCore:\r
+                case CommonDefinition.ModuleTypePeim:\r
+                                       fileBuffer.append("EFI_STATUS\r\n");\r
+                                       fileBuffer.append("EFIAPI\r\n");\r
+                                       fileBuffer.append(libInstanceList.get(i)[0]);\r
+                                       fileBuffer.append(" (\r\n");\r
+                                       fileBuffer\r
+                                       .append("  IN EFI_FFS_FILE_HEADER       *FfsHeader,\r\n");\r
+                                       fileBuffer\r
+                                       .append("  IN EFI_PEI_SERVICES          **PeiServices\r\n");\r
+                                       fileBuffer.append("  );\r\n");\r
+                                       break;\r
+       \r
+                               case CommonDefinition.ModuleTypeDxeCore:\r
+                               case CommonDefinition.ModuleTypeDxeDriver:\r
+                               case CommonDefinition.ModuleTypeDxeRuntimeDriver:\r
+                               case CommonDefinition.ModuleTypeDxeSmmDriver:\r
+                               case CommonDefinition.ModuleTypeDxeSalDriver:\r
+                               case CommonDefinition.ModuleTypeUefiDriver:\r
+                               case CommonDefinition.ModuleTypeUefiApplication:\r
+                                       fileBuffer.append("EFI_STATUS\r\n");\r
+                                       fileBuffer.append("EFIAPI\r\n");\r
+                                       fileBuffer.append(libInstanceList.get(i)[0]);\r
+                                       fileBuffer.append(" (\r\n");\r
+                                       fileBuffer.append("  IN EFI_HANDLE        ImageHandle,\r\n");\r
+                                       fileBuffer.append("  IN EFI_SYSTEM_TABLE  *SystemTable\r\n");\r
+                                       fileBuffer.append("  );\r\n");\r
+                                       break;\r
+\r
+                           }\r
             }\r
         }\r
 \r
@@ -1512,6 +1464,7 @@ public class AutoGen {
         // Add ProcessLibraryConstructorList in AutoGen.c\r
         //\r
         fileBuffer.append("VOID\r\n");\r
+        fileBuffer.append("EFIAPI\r\n");\r
         fileBuffer.append("ProcessLibraryConstructorList (\r\n");\r
         switch (CommonDefinition.getModuleType(moduleType)) {\r
         case CommonDefinition.ModuleTypeBase:\r
@@ -1522,7 +1475,7 @@ public class AutoGen {
         case CommonDefinition.ModuleTypePeim:\r
             fileBuffer.append("  IN EFI_FFS_FILE_HEADER       *FfsHeader,\r\n");\r
             fileBuffer\r
-                    .append("  IN EFI_PEI_SERVICES          **PeiServices\r\n");\r
+            .append("  IN EFI_PEI_SERVICES          **PeiServices\r\n");\r
             break;\r
 \r
         case CommonDefinition.ModuleTypeDxeCore:\r
@@ -1539,37 +1492,53 @@ public class AutoGen {
 \r
         fileBuffer.append("  )\r\n");\r
         fileBuffer.append("{\r\n");\r
-\r
+        //\r
+        // If no constructor function, return EFI_SUCCESS.\r
+        //\r
+        //if (libInstanceList.size() == 0){\r
+        //   fileBuffer.append("  return EFI_SUCCESS;\r\n");\r
+        //}\r
         for (int i = 0; i < libInstanceList.size(); i++) {\r
             if (isFirst) {\r
                 fileBuffer.append("  EFI_STATUS  Status;\r\n");\r
+                fileBuffer.append("  Status = EFI_SUCCESS;\r\n");\r
                 fileBuffer.append("\r\n");\r
                 isFirst = false;\r
             }\r
-            switch (CommonDefinition.getModuleType(moduleType)) {\r
-            case CommonDefinition.ModuleTypeBase:\r
+                       if (libInstanceList.get(i)[1].equalsIgnoreCase(EdkDefinitions.MODULE_TYPE_BASE)) {\r
                 fileBuffer.append("  Status = ");\r
-                fileBuffer.append(libInstanceList.get(i));\r
+                fileBuffer.append(libInstanceList.get(i)[0]);\r
                 fileBuffer.append("();\r\n");\r
                 fileBuffer.append("  VOID\r\n");\r
-                break;\r
-            case CommonDefinition.ModuleTypePeiCore:\r
-            case CommonDefinition.ModuleTypePeim:\r
-                fileBuffer.append("  Status = ");\r
-                fileBuffer.append(libInstanceList.get(i));\r
-                fileBuffer.append(" (FfsHeader, PeiServices);\r\n");\r
-                break;\r
-            case CommonDefinition.ModuleTypeDxeCore:\r
-            case CommonDefinition.ModuleTypeDxeDriver:\r
-            case CommonDefinition.ModuleTypeDxeRuntimeDriver:\r
-            case CommonDefinition.ModuleTypeDxeSmmDriver:\r
-            case CommonDefinition.ModuleTypeDxeSalDriver:\r
-            case CommonDefinition.ModuleTypeUefiDriver:\r
-            case CommonDefinition.ModuleTypeUefiApplication:\r
-                fileBuffer.append("  Status = ");\r
-                fileBuffer.append(libInstanceList.get(i));\r
-                fileBuffer.append(" (ImageHandle, SystemTable);\r\n");\r
-                break;\r
+                       } else {\r
+                               switch (CommonDefinition.getModuleType(moduleType)) {\r
+                                       case CommonDefinition.ModuleTypeBase:\r
+                                               fileBuffer.append("  Status = ");\r
+                                               fileBuffer.append(libInstanceList.get(i)[0]);\r
+                                               fileBuffer.append("();\r\n");\r
+                                               fileBuffer.append("  VOID\r\n");\r
+                                               break;\r
+                                       case CommonDefinition.ModuleTypePeiCore:\r
+                                       case CommonDefinition.ModuleTypePeim:\r
+                                               fileBuffer.append("  Status = ");\r
+                                               fileBuffer.append(libInstanceList.get(i)[0]);\r
+                                               fileBuffer.append(" (FfsHeader, PeiServices);\r\n");\r
+                                               break;\r
+                                       case CommonDefinition.ModuleTypeDxeCore:\r
+                                       case CommonDefinition.ModuleTypeDxeDriver:\r
+                                       case CommonDefinition.ModuleTypeDxeRuntimeDriver:\r
+                                       case CommonDefinition.ModuleTypeDxeSmmDriver:\r
+                                       case CommonDefinition.ModuleTypeDxeSalDriver:\r
+                                       case CommonDefinition.ModuleTypeUefiDriver:\r
+                                       case CommonDefinition.ModuleTypeUefiApplication:\r
+                                               fileBuffer.append("  Status = ");\r
+                                               fileBuffer.append(libInstanceList.get(i)[0]);\r
+                                               fileBuffer.append(" (ImageHandle, SystemTable);\r\n");\r
+                                               break;\r
+                                       default:\r
+                                               EdkLog.log(EdkLog.EDK_INFO,"Autogen doesn't know how to deal with module type - " + moduleType + "!");\r
+                          }\r
+            \r
             }\r
             fileBuffer.append("  ASSERT_EFI_ERROR (Status);\r\n");\r
         }\r
@@ -1578,52 +1547,67 @@ public class AutoGen {
 \r
     /**\r
       LibDestructorToAutogenc\r
-    \r
-      This function writes library destructor list to AutoGen.c. The library \r
+     \r
+      This function writes library destructor list to AutoGen.c. The library\r
       destructor's parameter and return value depend on module type.\r
-    \r
-      @param  libInstanceList        List of library destructor name.\r
-      @param  moduleType             Module type.\r
-      @param  fileBuffer             String buffer for AutoGen.c\r
-      @throws Exception              \r
+     \r
+      @param libInstanceList\r
+                 List of library destructor name.\r
+      @param moduleType\r
+                 Module type.\r
+      @param fileBuffer\r
+                 String buffer for AutoGen.c\r
+      @throws Exception\r
     **/\r
-    void LibDestructorToAutogenC(List<String> libInstanceList,\r
-            String moduleType, StringBuffer fileBuffer) throws Exception {\r
+    void LibDestructorToAutogenC(List<String[]> libInstanceList,\r
+                                 String moduleType, StringBuffer fileBuffer) throws EdkException {\r
         boolean isFirst = true;\r
         for (int i = 0; i < libInstanceList.size(); i++) {\r
-            switch (CommonDefinition.getModuleType(moduleType)) {\r
-            case CommonDefinition.ModuleTypeBase:\r
-                fileBuffer.append("RETURN_STATUS\n");\r
-                fileBuffer.append(libInstanceList.get(i));\r
+                       if (libInstanceList.get(i)[1].equalsIgnoreCase(EdkDefinitions.MODULE_TYPE_BASE)) {\r
+                fileBuffer.append("RETURN_STATUS\r\n");\r
+                fileBuffer.append("EFIAPI\r\n");\r
+                fileBuffer.append(libInstanceList.get(i)[0]);\r
                 fileBuffer.append(" (\r\n");\r
                 fileBuffer.append("  VOID\r\n");\r
                 fileBuffer.append("  );\r\n");\r
-                break;\r
-            case CommonDefinition.ModuleTypePeiCore:\r
-            case CommonDefinition.ModuleTypePeim:\r
-                fileBuffer.append("EFI_STATUS\r\n");\r
-                fileBuffer.append(libInstanceList.get(i));\r
-                fileBuffer.append(" (\r\n");\r
-                fileBuffer\r
-                        .append("  IN EFI_FFS_FILE_HEADER       *FfsHeader,\r\n");\r
-                fileBuffer\r
-                        .append("  IN EFI_PEI_SERVICES          **PeiServices\r\n");\r
-                fileBuffer.append("  );\r\n");\r
-                break;\r
-            case CommonDefinition.ModuleTypeDxeCore:\r
-            case CommonDefinition.ModuleTypeDxeDriver:\r
-            case CommonDefinition.ModuleTypeDxeRuntimeDriver:\r
-            case CommonDefinition.ModuleTypeDxeSmmDriver:\r
-            case CommonDefinition.ModuleTypeDxeSalDriver:\r
-            case CommonDefinition.ModuleTypeUefiDriver:\r
-            case CommonDefinition.ModuleTypeUefiApplication:\r
-                fileBuffer.append("EFI_STATUS\r\n");\r
-                fileBuffer.append(libInstanceList.get(i));\r
-                fileBuffer.append(" (\r\n");\r
-                fileBuffer.append("  IN EFI_HANDLE        ImageHandle,\r\n");\r
-                fileBuffer.append("  IN EFI_SYSTEM_TABLE  *SystemTable\r\n");\r
-                fileBuffer.append("  );\r\n");\r
-                break;\r
+                       } else {\r
+                               switch (CommonDefinition.getModuleType(moduleType)) {\r
+                                       case CommonDefinition.ModuleTypeBase:\r
+                                               fileBuffer.append("RETURN_STATUS\r\n");\r
+                                               fileBuffer.append("EFIAPI\r\n");\r
+                                               fileBuffer.append(libInstanceList.get(i)[0]);\r
+                                               fileBuffer.append(" (\r\n");\r
+                                               fileBuffer.append("  VOID\r\n");\r
+                                               fileBuffer.append("  );\r\n");\r
+                                               break;\r
+                                       case CommonDefinition.ModuleTypePeiCore:\r
+                                       case CommonDefinition.ModuleTypePeim:\r
+                                               fileBuffer.append("EFI_STATUS\r\n");\r
+                                               fileBuffer.append("EFIAPI\r\n");\r
+                                               fileBuffer.append(libInstanceList.get(i)[0]);\r
+                                               fileBuffer.append(" (\r\n");\r
+                                               fileBuffer\r
+                                               .append("  IN EFI_FFS_FILE_HEADER       *FfsHeader,\r\n");\r
+                                               fileBuffer\r
+                                               .append("  IN EFI_PEI_SERVICES          **PeiServices\r\n");\r
+                                               fileBuffer.append("  );\r\n");\r
+                                               break;\r
+                                       case CommonDefinition.ModuleTypeDxeCore:\r
+                                       case CommonDefinition.ModuleTypeDxeDriver:\r
+                                       case CommonDefinition.ModuleTypeDxeRuntimeDriver:\r
+                                       case CommonDefinition.ModuleTypeDxeSmmDriver:\r
+                                       case CommonDefinition.ModuleTypeDxeSalDriver:\r
+                                       case CommonDefinition.ModuleTypeUefiDriver:\r
+                                       case CommonDefinition.ModuleTypeUefiApplication:\r
+                                               fileBuffer.append("EFI_STATUS\r\n");\r
+                                               fileBuffer.append("EFIAPI\r\n");\r
+                                               fileBuffer.append(libInstanceList.get(i)[0]);\r
+                                               fileBuffer.append(" (\r\n");\r
+                                               fileBuffer.append("  IN EFI_HANDLE        ImageHandle,\r\n");\r
+                                               fileBuffer.append("  IN EFI_SYSTEM_TABLE  *SystemTable\r\n");\r
+                                               fileBuffer.append("  );\r\n");\r
+                                               break;\r
+                           }\r
             }\r
         }\r
 \r
@@ -1643,22 +1627,34 @@ public class AutoGen {
         case CommonDefinition.ModuleTypeUefiDriver:\r
         case CommonDefinition.ModuleTypeUefiApplication:\r
             fileBuffer.append("VOID\r\n");\r
+            fileBuffer.append("EFIAPI\r\n");\r
             fileBuffer.append("ProcessLibraryDestructorList (\r\n");\r
             fileBuffer.append("  IN EFI_HANDLE        ImageHandle,\r\n");\r
             fileBuffer.append("  IN EFI_SYSTEM_TABLE  *SystemTable\r\n");\r
             fileBuffer.append("  )\r\n");\r
             fileBuffer.append("{\r\n");\r
+            //\r
+            // If no library destructor function, return EFI_SUCCESS.\r
+            //\r
 \r
             for (int i = 0; i < libInstanceList.size(); i++) {\r
                 if (isFirst) {\r
                     fileBuffer.append("  EFI_STATUS  Status;\r\n");\r
+                    fileBuffer.append("  Status = EFI_SUCCESS;\r\n");\r
                     fileBuffer.append("\r\n");\r
                     isFirst = false;\r
                 }\r
-                fileBuffer.append("  Status = ");\r
-                fileBuffer.append(libInstanceList.get(i));\r
-                fileBuffer.append("(ImageHandle, SystemTable);\r\n");\r
-                fileBuffer.append("  ASSERT_EFI_ERROR (Status);\r\n");\r
+                               if (libInstanceList.get(i)[1].equalsIgnoreCase(EdkDefinitions.MODULE_TYPE_BASE)) {\r
+                    fileBuffer.append("  Status = ");\r
+                    fileBuffer.append(libInstanceList.get(i)[0]);\r
+                    fileBuffer.append("();\r\n");\r
+                    fileBuffer.append("  VOID\r\n");\r
+                               } else {\r
+                                       fileBuffer.append("  Status = ");\r
+                                       fileBuffer.append(libInstanceList.get(i)[0]);\r
+                                       fileBuffer.append("(ImageHandle, SystemTable);\r\n");\r
+                                       fileBuffer.append("  ASSERT_EFI_ERROR (Status);\r\n");\r
+                               }\r
             }\r
             fileBuffer.append("}\r\n");\r
             break;\r
@@ -1667,103 +1663,92 @@ public class AutoGen {
 \r
     /**\r
       ExternsDriverBindingToAutoGenC\r
-      \r
-      This function is to write DRIVER_BINDING, COMPONENT_NAME, \r
+     \r
+      This function is to write DRIVER_BINDING, COMPONENT_NAME,\r
       DRIVER_CONFIGURATION, DRIVER_DIAGNOSTIC in AutoGen.c.\r
-      \r
-      @param  fileBuffer             String buffer for AutoGen.c\r
-     */\r
+     \r
+      @param fileBuffer\r
+                 String buffer for AutoGen.c\r
+    **/\r
     void ExternsDriverBindingToAutoGenC(StringBuffer fileBuffer)\r
-            throws BuildException {\r
+    throws EdkException {\r
 \r
         //\r
-        // Check what <extern> contains. And the number of following elements\r
-        // under <extern> should be same. 1. DRIVER_BINDING 2. COMPONENT_NAME\r
-        // 3.DRIVER_CONFIGURATION 4. DRIVER_DIAGNOSTIC\r
-        //\r
-        \r
-        String[] drvBindList = SurfaceAreaQuery.getDriverBindingArray();\r
-        \r
-        //\r
-        // If component name protocol,component configuration protocol,\r
-        // component diagnostic protocol is not null or empty, check \r
-        // if every one have the same number of the driver binding protocol.\r
-        //\r
-        if (drvBindList == null || drvBindList.length == 0) {\r
-            return;\r
-        }\r
-\r
-        String[] compNamList = SurfaceAreaQuery.getComponentNameArray();\r
-        String[] compConfList = SurfaceAreaQuery.getDriverConfigArray();\r
-        String[] compDiagList = SurfaceAreaQuery.getDriverDiagArray();\r
+        // Get the arry of extern. The driverBindingGroup is a 2 dimension array.\r
+               // The second dimension is include following element: DriverBinding, \r
+               // ComponentName, DriverConfiguration, DriverDiag;\r
+               // \r
+        String[][] driverBindingGroup = this.saq.getExternProtocolGroup();\r
 \r
+        //\r
+        // inital BitMask;\r
+               // \r
         int BitMask = 0;\r
 \r
         //\r
         // Write driver binding protocol extern to autogen.c\r
         //\r
-        for (int i = 0; i < drvBindList.length; i++) {\r
-            fileBuffer.append("extern EFI_DRIVER_BINDING_PROTOCOL ");\r
-            fileBuffer.append(drvBindList[i]);\r
-            fileBuffer.append(";\r\n");\r
+        for (int i = 0; i < driverBindingGroup.length; i++) {\r
+                       if (driverBindingGroup[i][0] != null) {\r
+                               fileBuffer.append("extern EFI_DRIVER_BINDING_PROTOCOL ");\r
+                fileBuffer.append(driverBindingGroup[i][0]);\r
+                fileBuffer.append(";\r\n");\r
+                       } \r
         }\r
 \r
         //\r
         // Write component name protocol extern to autogen.c\r
         //\r
-        if (compNamList != null && compNamList.length != 0) {\r
-            if (drvBindList.length != compNamList.length) {\r
-                throw new BuildException(\r
-                        "Different number of Driver Binding and Component Name protocols!");\r
-            }\r
-\r
-            BitMask |= 0x01;\r
-            for (int i = 0; i < compNamList.length; i++) {\r
-                fileBuffer.append("extern EFI_COMPONENT_NAME_PROTOCOL ");\r
-                fileBuffer.append(compNamList[i]);\r
-                fileBuffer.append(";\r\n");\r
-            }\r
-        }\r
+               for (int i = 0; i < driverBindingGroup.length; i++) {\r
+                       if (driverBindingGroup[i][1]!= null) {\r
+                               if (driverBindingGroup[i][0] != null) {\r
+                                       BitMask |= 0x01;\r
+                                   fileBuffer.append("extern EFI_COMPONENT_NAME_PROTOCOL ");\r
+                    fileBuffer.append(driverBindingGroup[i][1]);\r
+                    fileBuffer.append(";\r\n");\r
+                               } else {\r
+                    throw new AutoGenException("DriverBinding can't be empty!!");\r
+                               }\r
+                       }\r
+               }\r
 \r
         //\r
         // Write driver configration protocol extern to autogen.c\r
         //\r
-        if (compConfList != null && compConfList.length != 0) {\r
-            if (drvBindList.length != compConfList.length) {\r
-                throw new BuildException(\r
-                        "Different number of Driver Binding and Driver Configuration protocols!");\r
-            }\r
-\r
-            BitMask |= 0x02;\r
-            for (int i = 0; i < compConfList.length; i++) {\r
-                fileBuffer.append("extern EFI_DRIVER_CONFIGURATION_PROTOCOL ");\r
-                fileBuffer.append(compConfList[i]);\r
-                fileBuffer.append(";\r\n");\r
-            }\r
-        }\r
-\r
+               for (int i = 0; i < driverBindingGroup.length; i++) {\r
+                       if (driverBindingGroup[i][2] != null) {\r
+                               if (driverBindingGroup[i][0] != null) {\r
+                    BitMask |= 0x02;\r
+                                   fileBuffer.append("extern EFI_DRIVER_CONFIGURATION_PROTOCOL ");\r
+                    fileBuffer.append(driverBindingGroup[i][2]);\r
+                    fileBuffer.append(";\r\n");\r
+                               } else {\r
+                    throw new AutoGenException("DriverBinding can't be empty!!");\r
+                               }\r
+                       }\r
+               }\r
+        \r
         //\r
         // Write driver dignastic protocol extern to autogen.c\r
         //\r
-        if (compDiagList != null && compDiagList.length != 0) {\r
-            if (drvBindList.length != compDiagList.length) {\r
-                throw new BuildException(\r
-                        "Different number of Driver Binding and Driver Configuration protocols!");\r
-            }\r
-\r
-            BitMask |= 0x04;\r
-            for (int i = 0; i < compDiagList.length; i++) {\r
-                fileBuffer.append("extern EFI_DRIVER_DIAGNOSTICS_PROTOCOL ");\r
-                fileBuffer.append(compDiagList[i]);\r
-                fileBuffer.append(";\r\n");\r
-            }\r
-        }\r
-\r
+               for (int i = 0; i < driverBindingGroup.length; i++) {\r
+                       if (driverBindingGroup[i][3] != null) {\r
+                               if (driverBindingGroup[i][0] != null) {\r
+                    BitMask |= 0x04;\r
+                    fileBuffer.append("extern EFI_DRIVER_DIAGNOSTICS_PROTOCOL ");\r
+                    fileBuffer.append(driverBindingGroup[i][3]);\r
+                    fileBuffer.append(";\r\n");\r
+                               } else {\r
+                    throw new AutoGenException("DriverBinding can't be empty!!");\r
+                               }\r
+                       }\r
+               }\r
+      \r
         //\r
         // Write driver module protocol bitmask.\r
         //\r
         fileBuffer\r
-                .append("GLOBAL_REMOVE_IF_UNREFERENCED const UINT8  _gDriverModelProtocolBitmask = ");\r
+        .append("GLOBAL_REMOVE_IF_UNREFERENCED const UINT8  _gDriverModelProtocolBitmask = ");\r
         fileBuffer.append(Integer.toString(BitMask));\r
         fileBuffer.append(";\r\n");\r
 \r
@@ -1771,95 +1756,298 @@ public class AutoGen {
         // Write driver module protocol list entry\r
         //\r
         fileBuffer\r
-                .append("GLOBAL_REMOVE_IF_UNREFERENCED const UINTN  _gDriverModelProtocolListEntries = ");\r
+        .append("GLOBAL_REMOVE_IF_UNREFERENCED const UINTN  _gDriverModelProtocolListEntries = ");\r
 \r
-        fileBuffer.append(Integer.toString(drvBindList.length));\r
+        fileBuffer.append(Integer.toString(driverBindingGroup.length));\r
         fileBuffer.append(";\r\n");\r
 \r
         //\r
         // Write drive module protocol list to autogen.c\r
         //\r
-        fileBuffer\r
-                .append("GLOBAL_REMOVE_IF_UNREFERENCED const EFI_DRIVER_MODEL_PROTOCOL_LIST  _gDriverModelProtocolList[] = {");\r
-        for (int i = 0; i < drvBindList.length; i++) {\r
+               if (driverBindingGroup.length > 0) {\r
+                       fileBuffer\r
+        .append("GLOBAL_REMOVE_IF_UNREFERENCED const EFI_DRIVER_MODEL_PROTOCOL_LIST  _gDriverModelProtocolList[] = {");\r
+               }\r
+        \r
+               \r
+        for (int i = 0; i < driverBindingGroup.length; i++) {\r
             if (i != 0) {\r
                 fileBuffer.append(",");\r
             }\r
-            fileBuffer.append("\r\n {\r\n");\r
+                       \r
+                       fileBuffer.append("\r\n {\r\n");\r
             fileBuffer.append("  &");\r
-            fileBuffer.append(drvBindList[i]);\r
+            fileBuffer.append(driverBindingGroup[i][0]);\r
             fileBuffer.append(", \r\n");\r
+                       \r
 \r
-            if (compNamList != null) {\r
+            if (driverBindingGroup[i][1] != null) {\r
                 fileBuffer.append("  &");\r
-                fileBuffer.append(compNamList[i]);\r
+                fileBuffer.append(driverBindingGroup[i][1]);\r
                 fileBuffer.append(", \r\n");\r
             } else {\r
                 fileBuffer.append("  NULL, \r\n");\r
             }\r
 \r
-            if (compConfList != null) {\r
+            if (driverBindingGroup[i][2] != null) {\r
                 fileBuffer.append("  &");\r
-                fileBuffer.append(compConfList[i]);\r
+                fileBuffer.append(driverBindingGroup[i][2]);\r
                 fileBuffer.append(", \r\n");\r
             } else {\r
                 fileBuffer.append("  NULL, \r\n");\r
             }\r
 \r
-            if (compDiagList != null) {\r
+            if (driverBindingGroup[i][3] != null) {\r
                 fileBuffer.append("  &");\r
-                fileBuffer.append(compDiagList[i]);\r
+                fileBuffer.append(driverBindingGroup[i][3]);\r
                 fileBuffer.append(", \r\n");\r
             } else {\r
                 fileBuffer.append("  NULL, \r\n");\r
             }\r
             fileBuffer.append("  }");\r
         }\r
-        fileBuffer.append("\r\n};\r\n");\r
+\r
+               if (driverBindingGroup.length > 0) {\r
+                       fileBuffer.append("\r\n};\r\n");\r
+               }\r
     }\r
 \r
     /**\r
       ExternCallBackToAutoGenC\r
-    \r
-      This function adds <SetVirtualAddressMapCallBack> and <ExitBootServicesCallBack>\r
-      infomation to AutoGen.c\r
-    \r
-      @param  fileBuffer           String buffer for AutoGen.c\r
+     \r
+      This function adds <SetVirtualAddressMapCallBack> and\r
+      <ExitBootServicesCallBack> infomation to AutoGen.c\r
+     \r
+      @param fileBuffer\r
+                 String buffer for AutoGen.c\r
       @throws BuildException\r
     **/\r
     void ExternCallBackToAutoGenC(StringBuffer fileBuffer)\r
-            throws BuildException {\r
-        String[] setVirtualList = SurfaceAreaQuery\r
-                .getSetVirtualAddressMapCallBackArray();\r
-        String[] exitBootList = SurfaceAreaQuery\r
-                .getExitBootServicesCallBackArray();\r
-        String moduleType = SurfaceAreaQuery.getModuleType();\r
-        boolean UefiOrDxeModule = false;\r
-        int Count = 0;\r
-        int i;\r
-\r
+    throws EdkException {\r
+        //\r
+        // Collect module's <SetVirtualAddressMapCallBack> and\r
+        // <ExitBootServiceCallBack> and add to setVirtualAddList\r
+        //  exitBootServiceList.\r
+        //\r
+        String[] setVirtuals = saq.getSetVirtualAddressMapCallBackArray();\r
+        String[] exitBoots = saq.getExitBootServicesCallBackArray();\r
+        if (setVirtuals != null) {\r
+            for (int j = 0; j < setVirtuals.length; j++) {\r
+                this.setVirtalAddList.add(setVirtuals[j]);\r
+            }\r
+        }\r
+        if (exitBoots != null) {\r
+            for (int k = 0; k < exitBoots.length; k++) {\r
+                this.exitBootServiceList.add(exitBoots[k]);\r
+            }\r
+        }\r
+        //\r
+        //  Add c code in autogen.c which relate to <SetVirtualAddressMapCallBack>\r
+        //  and <ExitBootServicesCallBack>\r
+        //\r
+        String moduleType = this.moduleId.getModuleType();\r
         switch (CommonDefinition.getModuleType(moduleType)) {\r
         case CommonDefinition.ModuleTypeDxeDriver:\r
         case CommonDefinition.ModuleTypeDxeRuntimeDriver:\r
         case CommonDefinition.ModuleTypeDxeSalDriver:\r
         case CommonDefinition.ModuleTypeUefiDriver:\r
-        case CommonDefinition.ModuleTypeUefiApplication:\r
-            //\r
-            // Entry point lib for these module types needs to know the count\r
-            // of entryPoint.\r
-            //\r
-            UefiOrDxeModule = true;\r
-            fileBuffer\r
-                    .append("\r\nGLOBAL_REMOVE_IF_UNREFERENCED  const UINTN _gDriverSetVirtualAddressMapEventCount = ");\r
+               case CommonDefinition.ModuleTypeUefiApplication:\r
+                       //\r
+                       //  If moduleType is one of above, call setVirtualAddressToAutogenC,\r
+                       //  and setExitBootServiceToAutogenC.\r
+                       // \r
+            setVirtualAddressToAutogenC(fileBuffer);\r
+                       setExitBootServiceToAutogenC(fileBuffer);\r
+            break;\r
+        default:\r
+            break;\r
+        }\r
+    }\r
+\r
+    /**\r
+      copyFlashMapHToDebugDir\r
+      \r
+      This function is to copy the falshmap.h to debug directory and change \r
+      its name to TianoR8FlashMap.h\r
+      \r
+      @param \r
+      @return\r
+    **/\r
+    private void copyFlashMapHToDebugDir() throws  AutoGenException{\r
+\r
+        File inFile = new File(fvDir + File.separatorChar + CommonDefinition.FLASHMAPH);\r
+        int size = (int)inFile.length();\r
+        byte[] buffer = new byte[size];\r
+        File outFile = new File (this.outputPath + File.separatorChar + CommonDefinition.TIANOR8PLASHMAPH);\r
+        //\r
+        //  If TianoR8FlashMap.h existed and the flashMap.h don't change,\r
+        //  do nothing.\r
+        //\r
+        if ((!outFile.exists()) ||(inFile.lastModified() - outFile.lastModified()) >= 0) {\r
+                       if (inFile.exists()) {\r
+                               try{\r
+                                       FileInputStream fis = new FileInputStream (inFile);\r
+                                   fis.read(buffer);\r
+                                   FileOutputStream fos = new FileOutputStream(outFile);\r
+                                   fos.write(buffer);\r
+                                   fis.close();\r
+                                   fos.close();\r
+                               } catch (IOException e){\r
+                    throw new AutoGenException("The file, flashMap.h can't be open!");\r
+                               }\r
+                               \r
+                       } else {\r
+                               throw new AutoGenException("The file, flashMap.h doesn't exist!");\r
+                       }\r
+        }\r
+    }\r
+\r
+    /**\r
+      This function first order the library instances, then collect\r
+      library instance 's PPI, Protocol, GUID,\r
+      SetVirtalAddressMapCallBack, ExitBootServiceCallBack, and\r
+      Destructor, Constructor.\r
+      \r
+      @param\r
+      @return    \r
+    **/\r
+    private void collectLibInstanceInfo() throws EdkException{\r
+        int index;\r
+\r
+        String libConstructName = null;\r
+        String libDestructName = null;\r
+               String libModuleType   = null;\r
+        String[] setVirtuals = null;\r
+        String[] exitBoots = null;\r
+\r
+        ModuleIdentification[] libraryIdList = saq.getLibraryInstance(this.arch);\r
+\r
+               if (libraryIdList != null) {\r
+                       //\r
+                       // Reorder library instance sequence.\r
+                       //\r
+                       AutogenLibOrder libOrder = new AutogenLibOrder(libraryIdList,\r
+                                                                                                                  this.arch);\r
+                       List<ModuleIdentification> orderList = libOrder\r
+                                                                                                  .orderLibInstance();\r
+\r
+                       if (orderList != null) {\r
+                               //\r
+                               // Process library instance one by one.\r
+                               //\r
+                               for (int i = 0; i < orderList.size(); i++) {\r
+\r
+                                       //\r
+                                       // Get library instance basename.\r
+                                       //\r
+                                       ModuleIdentification libInstanceId = orderList.get(i);\r
+\r
+                                       //\r
+                                       // Get override map\r
+                                       //\r
+\r
+                                       Map<String, XmlObject> libDoc = GlobalData.getDoc(libInstanceId, this.arch);\r
+                                       saq.push(libDoc);\r
+                                       //\r
+                                       // Get <PPis>, <Protocols>, <Guids> list of this library\r
+                                       // instance.\r
+                                       //\r
+                                       String[] ppiList = saq.getPpiArray(this.arch);\r
+                                       String[] ppiNotifyList = saq.getPpiNotifyArray(this.arch);\r
+                                       String[] protocolList = saq.getProtocolArray(this.arch);\r
+                                       String[] protocolNotifyList = saq.getProtocolNotifyArray(this.arch);\r
+                                       String[] guidList = saq.getGuidEntryArray(this.arch);\r
+                                       PackageIdentification[] pkgList = saq.getDependencePkg(this.arch);\r
+\r
+                                       //\r
+                                       // Add those ppi, protocol, guid in global ppi,\r
+                                       // protocol, guid\r
+                                       // list.\r
+                                       //\r
+                                       for (index = 0; index < ppiList.length; index++) {\r
+                                               this.mPpiList.add(ppiList[index]);\r
+                                       }\r
+\r
+                                       for (index = 0; index < ppiNotifyList.length; index++) {\r
+                                               this.mPpiList.add(ppiNotifyList[index]);\r
+                                       }\r
+\r
+                                       for (index = 0; index < protocolList.length; index++) {\r
+                                               this.mProtocolList.add(protocolList[index]);\r
+                                       }\r
+\r
+                                       for (index = 0; index < protocolNotifyList.length; index++) {\r
+                                               this.mProtocolList.add(protocolNotifyList[index]);\r
+                                       }\r
+\r
+                                       for (index = 0; index < guidList.length; index++) {\r
+                                               this.mGuidList.add(guidList[index]);\r
+                                       }\r
+                                       for (index = 0; index < pkgList.length; index++) {\r
+                                               if (!this.mDepPkgList.contains(pkgList[index])) {\r
+                                                       this.mDepPkgList.add(pkgList[index]);\r
+                                               }\r
+                                       }\r
+\r
+                                       //\r
+                                       // If not yet parse this library instance's constructor\r
+                                       // element,parse it.\r
+                                       //\r
+                                       libConstructName = saq.getLibConstructorName();\r
+                                       libDestructName = saq.getLibDestructorName();\r
+                                       libModuleType = saq.getModuleType();\r
+\r
+                                       //\r
+                                       // Collect SetVirtualAddressMapCallBack and\r
+                                       // ExitBootServiceCallBack.\r
+                                       //\r
+                                       setVirtuals = saq.getSetVirtualAddressMapCallBackArray();\r
+                                       exitBoots = saq.getExitBootServicesCallBackArray();\r
+                                       if (setVirtuals != null) {\r
+                                               for (int j = 0; j < setVirtuals.length; j++) {\r
+                                                       this.setVirtalAddList.add(setVirtuals[j]);\r
+                                               }\r
+                                       }\r
+                                       if (exitBoots != null) {\r
+                                               for (int k = 0; k < exitBoots.length; k++) {\r
+                                                       this.exitBootServiceList.add(exitBoots[k]);\r
+                                               }\r
+                                       }\r
+                                       saq.pop();\r
+                                       //\r
+                                       // Add dependent library instance constructor function.\r
+                                       //\r
+                                       if (libConstructName != null) {\r
+                                               this.libConstructList.add(new String[] {libConstructName, libModuleType});\r
+                                       }\r
+                                       //\r
+                                       // Add dependent library instance destructor fuction.\r
+                                       //\r
+                                       if (libDestructName != null) {\r
+                                               this.libDestructList.add(new String[] {libDestructName, libModuleType});\r
+                                       }\r
+                               }\r
+                       }\r
+\r
+               }\r
+    }\r
+       private void setVirtualAddressToAutogenC(StringBuffer fileBuffer){\r
+        //\r
+        // Entry point lib for these module types needs to know the count\r
+        // of entryPoint.\r
+        //\r
+               fileBuffer\r
+            .append("\r\nGLOBAL_REMOVE_IF_UNREFERENCED  const UINTN _gDriverSetVirtualAddressMapEventCount = ");\r
 \r
             //\r
             // If the list is not valid or has no entries set count to zero else\r
             // set count to the number of valid entries\r
             //\r
-            Count = 0;\r
-            if (setVirtualList != null) {\r
-                for (i = 0; i < setVirtualList.length; i++) {\r
-                    if (setVirtualList[i].equalsIgnoreCase("")) {\r
+            int Count = 0;\r
+                       int i = 0;\r
+            if (this.setVirtalAddList != null) {\r
+                for (i = 0; i < this.setVirtalAddList.size(); i++) {\r
+                    if (this.setVirtalAddList.get(i).equalsIgnoreCase("")) {\r
                         break;\r
                     }\r
                 }\r
@@ -1868,110 +2056,102 @@ public class AutoGen {
 \r
             fileBuffer.append(Integer.toString(Count));\r
             fileBuffer.append(";\r\n\r\n");\r
-            break;\r
-        default:\r
-            break;\r
-        }\r
-\r
-        if (setVirtualList == null) {\r
-            if (UefiOrDxeModule) {\r
+            if (this.setVirtalAddList == null || this.setVirtalAddList.size() == 0) {\r
                 //\r
                 // No data so make a NULL list\r
                 //\r
                 fileBuffer\r
-                        .append("\r\nGLOBAL_REMOVE_IF_UNREFERENCED const EFI_EVENT_NOTIFY _gDriverSetVirtualAddressMapEvent[] = {\r\n");\r
+                .append("\r\nGLOBAL_REMOVE_IF_UNREFERENCED const EFI_EVENT_NOTIFY _gDriverSetVirtualAddressMapEvent[] = {\r\n");\r
                 fileBuffer.append("  NULL\r\n");\r
                 fileBuffer.append("};\r\n\r\n");\r
-            }\r
-        } else {\r
-            //\r
-            // Write SetVirtualAddressMap function definition.\r
-            //\r
-            for (i = 0; i < setVirtualList.length; i++) {\r
-                if (setVirtualList[i].equalsIgnoreCase("")) {\r
-                    break;\r
-                }\r
-                fileBuffer.append("VOID\r\n");\r
-                fileBuffer.append("EFIAPI\n");\r
-                fileBuffer.append(setVirtualList[i]);\r
-                fileBuffer.append(" (\r\n");\r
-                fileBuffer.append("  IN EFI_EVENT  Event,\r\n");\r
-                fileBuffer.append("  IN VOID       *Context\r\n");\r
-                fileBuffer.append("  );\r\n\r\n");\r
-            }\r
+            } else {\r
+                //\r
+                // Write SetVirtualAddressMap function definition.\r
+                //\r
+                for (i = 0; i < this.setVirtalAddList.size(); i++) {\r
+                    if (this.setVirtalAddList.get(i).equalsIgnoreCase("")) {\r
+                        break;\r
+                    }\r
+                    fileBuffer.append("VOID\r\n");\r
+                    fileBuffer.append("EFIAPI\r\n");\r
+                    fileBuffer.append(this.setVirtalAddList.get(i));\r
+                    fileBuffer.append(" (\r\n");\r
+                    fileBuffer.append("  IN EFI_EVENT  Event,\r\n");\r
+                    fileBuffer.append("  IN VOID       *Context\r\n");\r
+                    fileBuffer.append("  );\r\n\r\n");\r
+                 }\r
 \r
-            //\r
-            // Write SetVirtualAddressMap entry point array.\r
-            //\r
-            fileBuffer\r
-                    .append("\r\nGLOBAL_REMOVE_IF_UNREFERENCED const EFI_EVENT_NOTIFY _gDriverSetVirtualAddressMapEvent[] = {");\r
-            for (i = 0; i < setVirtualList.length; i++) {\r
-                if (setVirtualList[i].equalsIgnoreCase("")) {\r
-                    break;\r
-                }\r
+                //\r
+                // Write SetVirtualAddressMap entry point array.\r
+                //\r
+                fileBuffer\r
+                .append("\r\nGLOBAL_REMOVE_IF_UNREFERENCED const EFI_EVENT_NOTIFY _gDriverSetVirtualAddressMapEvent[] = {");\r
+                for (i = 0; i < this.setVirtalAddList.size(); i++) {\r
+                    if (this.setVirtalAddList.get(i).equalsIgnoreCase("")) {\r
+                        break;\r
+                    }\r
 \r
-                if (i == 0) {\r
-                    fileBuffer.append("\r\n  ");\r
-                } else {\r
-                    fileBuffer.append(",\r\n  ");\r
+                    if (i == 0) {\r
+                        fileBuffer.append("\r\n  ");\r
+                    } else {\r
+                        fileBuffer.append(",\r\n  ");\r
+                    }\r
+\r
+                    fileBuffer.append(this.setVirtalAddList.get(i));\r
                 }\r
+                //\r
+                // add the NULL at the end of _gDriverSetVirtualAddressMapEvent list.\r
+                //\r
+                fileBuffer.append(",\r\n  NULL");\r
+                fileBuffer.append("\r\n};\r\n\r\n");\r
+                       }\r
+       }\r
 \r
-                fileBuffer.append(setVirtualList[i]);\r
-            }\r
-            if (Count == 0) {\r
-                fileBuffer.append("\r\n  NULL");\r
-            }\r
-            fileBuffer.append("\r\n};\r\n\r\n");\r
-        }\r
 \r
-        if (UefiOrDxeModule) {\r
-            //\r
-            // Entry point lib for these module types needs to know the count.\r
-            //\r
-            fileBuffer\r
-                    .append("\r\nGLOBAL_REMOVE_IF_UNREFERENCED  const UINTN _gDriverExitBootServicesEventCount = ");\r
+       private void setExitBootServiceToAutogenC(StringBuffer fileBuffer){\r
+               //\r
+        // Entry point lib for these module types needs to know the count.\r
+        //\r
+        fileBuffer\r
+        .append("\r\nGLOBAL_REMOVE_IF_UNREFERENCED  const UINTN _gDriverExitBootServicesEventCount = ");\r
 \r
-            //\r
-            // If the list is not valid or has no entries set count to zero else\r
-            // set count to the number of valid entries.\r
-            //\r
-            Count = 0;\r
-            if (exitBootList != null) {\r
-                if (setVirtualList != null) {\r
-                    for (i = 0; i < exitBootList.length; i++) {\r
-                        if (exitBootList[i].equalsIgnoreCase("")) {\r
-                            break;\r
-                        }\r
-                    }\r
-                    Count = i;\r
+        //\r
+        // If the list is not valid or has no entries set count to zero else\r
+        // set count to the number of valid entries.\r
+        //\r
+        int Count = 0;\r
+               int i = 0; \r
+        if (this.exitBootServiceList != null) {\r
+            for (i = 0; i < this.exitBootServiceList.size(); i++) {\r
+                if (this.exitBootServiceList.get(i).equalsIgnoreCase("")) {\r
+                    break;\r
                 }\r
             }\r
-            fileBuffer.append(Integer.toString(Count));\r
-            fileBuffer.append(";\r\n\r\n");\r
+            Count = i;\r
         }\r
+        fileBuffer.append(Integer.toString(Count));\r
+        fileBuffer.append(";\r\n\r\n");\r
 \r
-        if (exitBootList == null) {\r
-            if (UefiOrDxeModule) {\r
-                //\r
-                // No data so make a NULL list.\r
-                //\r
-                fileBuffer\r
-                        .append("\r\nGLOBAL_REMOVE_IF_UNREFERENCED const EFI_EVENT_NOTIFY _gDriverExitBootServicesEvent[] = {\r\n");\r
-                fileBuffer.append("  NULL\r\n");\r
-                fileBuffer.append("};\r\n\r\n");\r
-            }\r
+               if (this.exitBootServiceList == null || this.exitBootServiceList.size() == 0) {\r
+            //      \r
+            // No data so make a NULL list.\r
+            //\r
+            fileBuffer\r
+            .append("\r\nGLOBAL_REMOVE_IF_UNREFERENCED const EFI_EVENT_NOTIFY _gDriverExitBootServicesEvent[] = {\r\n");\r
+            fileBuffer.append("  NULL\r\n");\r
+            fileBuffer.append("};\r\n\r\n");\r
         } else {\r
             //\r
             // Write DriverExitBootServices function definition.\r
             //\r
-            for (i = 0; i < exitBootList.length; i++) {\r
-                if (exitBootList[i].equalsIgnoreCase("")) {\r
+            for (i = 0; i < this.exitBootServiceList.size(); i++) {\r
+                if (this.exitBootServiceList.get(i).equalsIgnoreCase("")) {\r
                     break;\r
                 }\r
 \r
                 fileBuffer.append("VOID\r\n");\r
-                fileBuffer.append("EFIAPI\n");\r
-                fileBuffer.append(exitBootList[i]);\r
+                fileBuffer.append("EFIAPI\r\n");\r
+                fileBuffer.append(this.exitBootServiceList.get(i));\r
                 fileBuffer.append(" (\r\n");\r
                 fileBuffer.append("  IN EFI_EVENT  Event,\r\n");\r
                 fileBuffer.append("  IN VOID       *Context\r\n");\r
@@ -1982,9 +2162,9 @@ public class AutoGen {
             // Write DriverExitBootServices entry point array.\r
             //\r
             fileBuffer\r
-                    .append("\r\nGLOBAL_REMOVE_IF_UNREFERENCED const EFI_EVENT_NOTIFY _gDriverExitBootServicesEvent[] = {");\r
-            for (i = 0; i < exitBootList.length; i++) {\r
-                if (exitBootList[i].equalsIgnoreCase("")) {\r
+            .append("\r\nGLOBAL_REMOVE_IF_UNREFERENCED const EFI_EVENT_NOTIFY _gDriverExitBootServicesEvent[] = {");\r
+            for (i = 0; i < this.exitBootServiceList.size(); i++) {\r
+                if (this.exitBootServiceList.get(i).equalsIgnoreCase("")) {\r
                     break;\r
                 }\r
 \r
@@ -1993,17 +2173,13 @@ public class AutoGen {
                 } else {\r
                     fileBuffer.append(",\r\n  ");\r
                 }\r
-                fileBuffer.append(exitBootList[i]);\r
-            }\r
-            if (Count == 0) {\r
-                fileBuffer.append("\r\n  NULL");\r
+                fileBuffer.append(this.exitBootServiceList.get(i));\r
             }\r
+            \r
+            fileBuffer.append(",\r\n  NULL");\r
             fileBuffer.append("\r\n};\r\n\r\n");\r
         }\r
 \r
-    }\r
+       }\r
 \r
-    private String getStringValue(XmlObject xmlDoc) {\r
-        return xmlDoc.getDomNode().getFirstChild().getNodeValue();\r
-    }\r
 }\r