From a29c47e01d9689fad735bbeccfaef67676a425d1 Mon Sep 17 00:00:00 2001
From: wuyizhong <wuyizhong@6f19259b-4bc3-4df7-8a09-765794883524>
Date: Fri, 30 Jun 2006 18:17:09 +0000
Subject: [PATCH] Change to new XML Schema.

git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@687 6f19259b-4bc3-4df7-8a09-765794883524
---
 .../org/tianocore/build/ExpandTask.java       |   54 -
 .../org/tianocore/build/FfsProcess.java       |   50 +-
 .../org/tianocore/build/FileProcess.java      |  113 +-
 .../tianocore/build/FrameworkBuildTask.java   |  210 ++
 .../org/tianocore/build/GenBuildTask.java     | 1586 ++++-------
 .../build/ModuleBuildFileGenerator.java       |  591 +++++
 .../org/tianocore/build/OutputDirSetup.java   |  271 ++
 .../tianocore/build/OutputDirSetupTask.java   |  190 --
 .../org/tianocore/build/autogen/AutoGen.java  | 1090 ++++----
 .../build/autogen/AutogenLibOrder.java        |  122 +-
 .../build/autogen/CommonDefinition.java       |   86 +-
 .../build/exception/AutoGenException.java     |   39 +
 .../build/exception/EdkException.java         |   36 +
 .../build/exception/GenBuildException.java    |   40 +
 .../build/exception/PcdAutogenException.java  |   35 +
 .../build/exception/TianoToolsException.java  |   41 +
 .../build/exception/XmlParseException.java    |   35 +
 .../tianocore/build/fpd/FpdParserTask.java    |  948 +++----
 .../build/fpd/PlatformBuildFileGenerator.java |  479 ++++
 .../tianocore/build/global/GlobalData.java    | 1163 +++++----
 .../tianocore/build/global/GlobalShare.java   |  178 --
 .../build/global/LibBuildFileGenerator.java   |  412 ---
 .../build/global/ModuleIdentification.java    |   55 -
 .../tianocore/build/global/OutputManager.java |  276 +-
 .../build/global/OverrideProcess.java         |  361 ---
 .../org/tianocore/build/global/Spd.java       |  491 ++--
 .../build/global/SurfaceAreaParser.java       |  213 --
 .../build/global/SurfaceAreaQuery.java        | 2321 +++++++++++------
 .../{fpd => id}/FpdModuleIdentification.java  |   95 +-
 .../tianocore/build/id/Identification.java    |   74 +
 .../build/id/ModuleIdentification.java        |  124 +
 .../build/id/PackageIdentification.java       |   73 +
 .../build/id/PlatformIdentification.java      |   43 +
 .../build/toolchain/ConfigReader.java         |  172 +-
 .../build/toolchain/ToolChainAttribute.java   |   37 +
 .../build/toolchain/ToolChainConfig.java      |  142 +
 .../build/toolchain/ToolChainElement.java     |   35 +
 .../build/toolchain/ToolChainFactory.java     |  529 ----
 .../build/toolchain/ToolChainInfo.java        |  219 ++
 .../build/toolchain/ToolChainKey.java         |  177 ++
 .../build/toolchain/ToolChainMap.java         |  165 ++
 .../build/toolchain/ToolChainTask.java        |   17 +-
 42 files changed, 7170 insertions(+), 6218 deletions(-)
 delete mode 100644 Tools/Source/GenBuild/org/tianocore/build/ExpandTask.java
 create mode 100644 Tools/Source/GenBuild/org/tianocore/build/FrameworkBuildTask.java
 create mode 100644 Tools/Source/GenBuild/org/tianocore/build/ModuleBuildFileGenerator.java
 create mode 100644 Tools/Source/GenBuild/org/tianocore/build/OutputDirSetup.java
 delete mode 100644 Tools/Source/GenBuild/org/tianocore/build/OutputDirSetupTask.java
 create mode 100644 Tools/Source/GenBuild/org/tianocore/build/exception/AutoGenException.java
 create mode 100644 Tools/Source/GenBuild/org/tianocore/build/exception/EdkException.java
 create mode 100644 Tools/Source/GenBuild/org/tianocore/build/exception/GenBuildException.java
 create mode 100644 Tools/Source/GenBuild/org/tianocore/build/exception/PcdAutogenException.java
 create mode 100644 Tools/Source/GenBuild/org/tianocore/build/exception/TianoToolsException.java
 create mode 100644 Tools/Source/GenBuild/org/tianocore/build/exception/XmlParseException.java
 create mode 100644 Tools/Source/GenBuild/org/tianocore/build/fpd/PlatformBuildFileGenerator.java
 delete mode 100644 Tools/Source/GenBuild/org/tianocore/build/global/GlobalShare.java
 delete mode 100644 Tools/Source/GenBuild/org/tianocore/build/global/LibBuildFileGenerator.java
 delete mode 100644 Tools/Source/GenBuild/org/tianocore/build/global/ModuleIdentification.java
 delete mode 100644 Tools/Source/GenBuild/org/tianocore/build/global/OverrideProcess.java
 delete mode 100644 Tools/Source/GenBuild/org/tianocore/build/global/SurfaceAreaParser.java
 rename Tools/Source/GenBuild/org/tianocore/build/{fpd => id}/FpdModuleIdentification.java (57%)
 create mode 100644 Tools/Source/GenBuild/org/tianocore/build/id/Identification.java
 create mode 100644 Tools/Source/GenBuild/org/tianocore/build/id/ModuleIdentification.java
 create mode 100644 Tools/Source/GenBuild/org/tianocore/build/id/PackageIdentification.java
 create mode 100644 Tools/Source/GenBuild/org/tianocore/build/id/PlatformIdentification.java
 create mode 100644 Tools/Source/GenBuild/org/tianocore/build/toolchain/ToolChainAttribute.java
 create mode 100644 Tools/Source/GenBuild/org/tianocore/build/toolchain/ToolChainConfig.java
 create mode 100644 Tools/Source/GenBuild/org/tianocore/build/toolchain/ToolChainElement.java
 delete mode 100644 Tools/Source/GenBuild/org/tianocore/build/toolchain/ToolChainFactory.java
 create mode 100644 Tools/Source/GenBuild/org/tianocore/build/toolchain/ToolChainInfo.java
 create mode 100644 Tools/Source/GenBuild/org/tianocore/build/toolchain/ToolChainKey.java
 create mode 100644 Tools/Source/GenBuild/org/tianocore/build/toolchain/ToolChainMap.java

diff --git a/Tools/Source/GenBuild/org/tianocore/build/ExpandTask.java b/Tools/Source/GenBuild/org/tianocore/build/ExpandTask.java
deleted file mode 100644
index c4c53e04b9..0000000000
--- a/Tools/Source/GenBuild/org/tianocore/build/ExpandTask.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/** @file
-  This file is ANT task Expand. 
-  
-  Expand task is used to prepare ANT properties for further build. 
-
-Copyright (c) 2006, Intel Corporation
-All rights reserved. This program and the accompanying materials
-are licensed and made available under the terms and conditions of the BSD License
-which accompanies this distribution.  The full text of the license may be found at
-http://opensource.org/licenses/bsd-license.php
-
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
-
-**/
-package org.tianocore.build;
-
-import org.apache.tools.ant.BuildException;
-import org.apache.tools.ant.Task;
-
-import org.tianocore.build.global.GlobalData;
-
-/**
-  Expand task is used to prepare ANT properties for further build. 
-  <p>Current, prepare the dependent Library instance list for <code>LIBS</code></p>
- 
-  @since GenBuild 1.0
-**/
-public class ExpandTask extends Task {
-    
-    /**
-      Public construct method. It is necessary for ANT task.
-    **/
-    public ExpandTask () {
-    }
-    
-    /**
-      ANT task's entry point, will be called after init().
-      
-      Set <code>LIBS</code> for further build usage. 
-    **/
-    public void execute() throws BuildException {
-        String basename = getProject().getProperty("BASE_NAME");
-        String arch = getProject().getProperty("ARCH");
-        arch = arch.toUpperCase();
-        String[] libraries = GlobalData.getModuleLibrary(basename, arch);
-        String str = "";
-        for (int i = 0; i < libraries.length; i ++){
-            str += " " + GlobalData.getLibrary(libraries[i], arch);
-        }
-        getProject().setProperty("LIBS", str);
-       
-    }
-}
diff --git a/Tools/Source/GenBuild/org/tianocore/build/FfsProcess.java b/Tools/Source/GenBuild/org/tianocore/build/FfsProcess.java
index 267a50e4e3..02eca2abef 100644
--- a/Tools/Source/GenBuild/org/tianocore/build/FfsProcess.java
+++ b/Tools/Source/GenBuild/org/tianocore/build/FfsProcess.java
@@ -26,6 +26,10 @@ import org.apache.tools.ant.BuildException;
 import org.apache.tools.ant.Project;
 import org.apache.xmlbeans.XmlCursor;
 import org.apache.xmlbeans.XmlObject;
+import org.tianocore.BuildOptionsDocument;
+import org.tianocore.build.global.GlobalData;
+import org.tianocore.build.global.SurfaceAreaQuery;
+import org.tianocore.build.id.FpdModuleIdentification;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 import org.w3c.dom.NamedNodeMap;
@@ -60,6 +64,8 @@ public class FfsProcess {
     /// Xml Document Node for corresponding FFS layout
     ///
     private Node ffs;
+    
+    private BuildOptionsDocument.BuildOptions.Ffs ffsXmlObject;
 
     ///
     /// ANT script to call GenFfs
@@ -131,11 +137,31 @@ public class FfsProcess {
       @throws BuildException
               If specified COMMON_FILE XML file is not valide.
     **/
-    public boolean initSections(String buildType, Project project) throws BuildException {
+    public boolean initSections(String buildType, Project project, FpdModuleIdentification fpdModuleId) throws BuildException {
         //
-        // first try to sections defined in PLATFORM level
+        // Firstly, try to find in ModuleSA
         //
-
+//        BuildOptionsDocument.BuildOptions.Ffs[] ffsArray = SurfaceAreaQuery.getModuleFfs();
+//        for (int i = 0; i < ffsArray.length; i++) {
+//            if (isMatch(ffsArray[i].getFfsKey(), buildType)) {
+//                ffsXmlObject = ffsArray[i];
+//                return true;
+//            }
+//        }
+        
+        //
+        // secondly, try to sections defined in PLATFORM level
+        //
+        SurfaceAreaQuery.push(GlobalData.getFpdBuildOptions());
+        BuildOptionsDocument.BuildOptions.Ffs[] ffsArray = SurfaceAreaQuery.getFpdFfs();
+        SurfaceAreaQuery.pop();
+        for (int i = 0; i < ffsArray.length; i++) {
+            if (isMatch(ffsArray[i].getFfsKey(), buildType)) {
+                ffsXmlObject = ffsArray[i];
+                return true;
+            }
+        }
+        
         //
         // if module specify sections itself, it's okay
         // otherwise find sections from WORKSPACE default setting with
@@ -194,22 +220,30 @@ public class FfsProcess {
     **/
     public String[] getGenSectionElements(Document document, String basename, String guid, String targetFilename) {
         this.basename = basename;
-        if (ffs == null) {
+        if (ffs == null && ffsXmlObject == null) {
             return new String[0];
         }
         Vector<String> sectionList = new Vector<String>();
         XmlCursor cursor = null;
         try {
-            cursor = XmlObject.Factory.parse(ffs).newCursor();
+            if (ffsXmlObject == null) {
+                cursor = XmlObject.Factory.parse(ffs).newCursor();
+            }
+            else {
+                cursor = ffsXmlObject.newCursor();
+            }
         } catch (Exception e) {
             return null;
         }
         int mode = MODE_NONE;
         Element root = document.createElement("genffsfile");
         root.setAttribute("outputDir", "${BIN_DIR}");
+        root.setAttribute("moduleType", "${MODULE_TYPE}");
         root.setAttribute("BaseName", basename);
         root.setAttribute("fileGuid", guid);
-        cursor.toFirstChild();
+        if (ffsXmlObject == null) {
+            cursor.toFirstChild();
+        }
         if (cursor.toFirstChild()) {
             do {
                 if (cursor.getName().getLocalPart().equalsIgnoreCase("Attribute")) {
@@ -315,7 +349,7 @@ public class FfsProcess {
             // outputPath = "${DEST_DIR_OUTPUT}">
             //
             ele = doc.createElement("tool");
-            ele.setAttribute("toolName", "${WORKSPACE_DIR}" + File.separatorChar + "Tools" + File.separatorChar + "bin"
+            ele.setAttribute("toolName", "${WORKSPACE_DIR}" + File.separatorChar + "Tools" + File.separatorChar + "Bin"
                                          + File.separatorChar + "GenCRC32Section");
             ele.setAttribute("outputPath", "${DEST_DIR_OUTPUT}");
         }
@@ -365,7 +399,7 @@ public class FfsProcess {
     }
 
     /**
-       Get the corresponding section file suffix.
+      Get the corresponding section file suffix.
        
       @param type Section type
       @return Corresponding section file extension
diff --git a/Tools/Source/GenBuild/org/tianocore/build/FileProcess.java b/Tools/Source/GenBuild/org/tianocore/build/FileProcess.java
index 87650af827..e615802c00 100644
--- a/Tools/Source/GenBuild/org/tianocore/build/FileProcess.java
+++ b/Tools/Source/GenBuild/org/tianocore/build/FileProcess.java
@@ -16,6 +16,7 @@ package org.tianocore.build;
 import java.io.File;
 import java.util.Set;
 
+import org.apache.tools.ant.BuildException;
 import org.apache.tools.ant.Project;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
@@ -29,17 +30,24 @@ import org.w3c.dom.Node;
   by its extension. Following is the current supported extensions. </p>
   
   <pre>   
-          .c         |      C_Code
-          .asm       |      Assembly
-          .s         |      IPF_Assembly_Code
-          .h         |      Header
-          .lib       |      Static_Library
-          .i         |      IPF_PP_Code
-          .vfr       |      Vfr
-          .uni       |      Unicode
-          .dxs       |      Dependency_File
-          .bmp       |      Graphics
-          .efi       |      EFI
+ Source File Suffix     File Type       Description
+    .h                   CHeader      C header file
+    .c                   CCode        C source file
+    .inc                 ASMHeader    Assembly header file
+    .asm                 ASM          Assembly source file, usually for IA32 and X64 Arch and MSFT tool chain
+    .S                   ASM          Assembly source file, usually for IPF Arch
+    .s                   ASM          Assembly source file, usually for IA32 and X64 Arch and GCC tool chain
+    .uni                 UNI          Unicode file
+    .vfr                 VFR          Visual Forms Representation File
+    .fv                  FV           Firmware Volume
+    .SEC                 FFS          Firmware File System file
+    .PEI                 FFS          Firmware File System file
+    .DXE                 FFS          Firmware File System file
+    .APP                 FFS          Firmware File System file
+    .FVI                 FFS          Firmware File System file
+    .FFS                 FFS          Firmware File System file
+    .bmp                 BMP          Graphic File
+    .i                   PPCode       IPF PreProcessor Code
   </pre>
   
   @since GenBuild 1.0
@@ -48,13 +56,25 @@ public class FileProcess {
     ///
     ///  The mapping information about source suffix, result suffix, file type.
     ///
-    public final String[][] fileTypes = { { ".c", ".obj", "C_Code" }, { ".asm", ".obj", "Assembly" },
-                                         { ".s", ".obj", "IPF_Assembly_Code" }, { ".h", "", "Header" },
-                                         { ".lib", "", "Static_Library" }, { ".src", ".c", "" },
-                                         { ".i", ".obj", "IPF_PP_Code" }, { ".vfr", ".obj", "Vfr" },
-                                         { ".uni", "", "Unicode" }, { ".dxs", "", "Dependency_File" },
-                                         { ".bmp", "", "Graphics" }, { ".efi", "", "EFI" } };
-
+    public final String[][] fileTypes = { {".h", "", "CHeader" }, 
+                                          {".c", "", "CCode" },
+                                          {".inc", "", "ASMHeader" },
+                                          {".asm", "", "ASM" }, 
+                                          {".S", "", "ASM" },
+                                          {".s", "", "ASM" },
+                                          {".uni", "", "UNI" },
+                                          {".vfr", "", "VFR" },
+                                          {".dxs", "", "DPX"},
+                                          {".fv", "", "FV" },
+                                          {".efi", "", "EFI" },
+                                          {".SEC", "", "FFS" },
+                                          {".PEI", "", "FFS" },
+                                          {".DXE", "", "FFS" },
+                                          {".APP", "", "FFS" },
+                                          {".FYI", "", "FFS" },
+                                          {".FFS", "", "FFS" },
+                                          {".bmp", "", "BMP" },
+                                          {".i", "", "PPCode"}};
     ///
     /// Current ANT context. 
     ///
@@ -64,11 +84,6 @@ public class FileProcess {
     /// Current module's include pathes
     ///
     private Set<String> includes;
-
-    ///
-    /// Current source files. 
-    ///
-    private Set<String> sourceFiles;
     
     ///
     /// Xml Document.
@@ -93,11 +108,10 @@ public class FileProcess {
       @param sourceFiles Modules source files
       @param document XML document
     **/
-    public void init(Project project, Set<String> includes, Set<String> sourceFiles, Document document) {
+    public void init(Project project, Set<String> includes, Document document) {
         this.document = document;
         this.includes = includes;
         this.project = project;
-        this.sourceFiles = sourceFiles;
     }
 
     /**
@@ -140,16 +154,16 @@ public class FileProcess {
       @param filename Source file name
       @param root Root node
     **/
-    public synchronized void parseFile(String filename, Node root) {
+    public synchronized void parseFile(String filename, Node root) throws BuildException {
         boolean flag = false;
         for (int i = 0; i < fileTypes.length; i++) {
-            if (filename.toLowerCase().endsWith(fileTypes[i][0])) {
+            if (filename.endsWith(fileTypes[i][0])) {
                 flag = true;
                 parseFile(filename, fileTypes[i][2], root);
             }
         }
         if (!flag) {
-            System.out.println("Warning: File " + filename + " is not known from its suffix.");
+            throw new BuildException("File [" + filename + "] is not known from its suffix.");
         }
     }
 
@@ -167,31 +181,58 @@ public class FileProcess {
     **/
     public synchronized void parseFile(String filename, String filetype, Node root) {
         if (unicodeFirst) {
-            if ( ! filetype.equalsIgnoreCase("Unicode")){
+            if ( ! filetype.equalsIgnoreCase("UNI")){
                 return ;
             }
             unicodeExist= true;
         } else {
-            if (filetype.equalsIgnoreCase("Unicode")){
+            if (filetype.equalsIgnoreCase("UNI")){
                 return ;
             }
         }
-        sourceFiles.add(filename);
-        if (filetype.equalsIgnoreCase("Header")) {
+        
+        //
+        // If file is C or ASM header file, skip it
+        //
+        if (filetype.equalsIgnoreCase("CHeader") || filetype.equalsIgnoreCase("ASMHeader")) {
             return;
         }
-        if (filetype.equalsIgnoreCase("IPF_PP_Code")) {
+        
+        //
+        // If file is pre-processor file, skip it
+        // 
+        if (filetype.equalsIgnoreCase("PPCode")) {
             return;
         }
+        
+        //
+        // If define CC_EXT in tools_def.txt file, the source file with 
+        // different suffix is skipped
+        //
+        String toolsDefExtName = project.getProperty(filetype + "_EXT");
+        if (toolsDefExtName != null) {
+            String[] exts = toolsDefExtName.split(" ");
+            for (int i = 0; i < exts.length; i++) {
+                if ( ! filename.endsWith(exts[i])) {
+                    return ;
+                }
+            }
+        }
+        
         String module_path = project.getProperty("MODULE_DIR");
         File moduleFile = new File(module_path);
         File sourceFile = new File(filename);
+        
+        //
         // If source file is AutoGen.c, then Filepath is .
-        String sourceFilepath;
-        String sourceFilename;
+        //
+        String sourceFilepath = "";
+        String sourceFilename = "";
+        String sourceFileext = "";
         if (sourceFile.getPath().endsWith("AutoGen.c")) {
             sourceFilepath = ".";
             sourceFilename = "AutoGen";
+            sourceFileext = ".c";
             filetype = "AUTOGEN";
         } else {
             // sourceFile.
@@ -206,12 +247,14 @@ public class FileProcess {
             index = str.lastIndexOf('.');
             if (index > 0) {
                 sourceFilename = str.substring(0, index);
+                sourceFileext = str.substring(index);
             }
         }
         // <Build_filetype FILEPATH="" FILENAME="" />
         Element ele = document.createElement("Build_" + filetype);
         ele.setAttribute("FILEPATH", sourceFilepath);
         ele.setAttribute("FILENAME", sourceFilename);
+        ele.setAttribute("FILEEXT", sourceFileext.substring(1));
         String[] includePaths = includes.toArray(new String[includes.size()]);
         Element includesEle = document.createElement("EXTRA.INC");
         for (int i = 0; i < includePaths.length; i++) {
diff --git a/Tools/Source/GenBuild/org/tianocore/build/FrameworkBuildTask.java b/Tools/Source/GenBuild/org/tianocore/build/FrameworkBuildTask.java
new file mode 100644
index 0000000000..b9afc57bad
--- /dev/null
+++ b/Tools/Source/GenBuild/org/tianocore/build/FrameworkBuildTask.java
@@ -0,0 +1,210 @@
+package org.tianocore.build;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.InputStreamReader;
+import java.util.Iterator;
+import java.util.LinkedHashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Task;
+import org.tianocore.build.fpd.FpdParserTask;
+import org.tianocore.build.global.GlobalData;
+import org.tianocore.build.toolchain.ToolChainInfo;
+
+public class FrameworkBuildTask extends Task{
+
+    private Set<File> buildFiles = new LinkedHashSet<File>();
+    
+    private Set<File> fpdFiles = new LinkedHashSet<File>();
+    
+    private Set<File> msaFiles = new LinkedHashSet<File>();
+    
+    ///
+    /// there are three type: all (build), clean and cleanall
+    ///
+    private String type = "all";
+    
+    public void execute() throws BuildException {
+        //
+        // Seach build.xml -> .FPD -> .MSA file
+        //
+        try {
+            //
+            // Gen Current Working Directory
+            //
+            File dummyFile = new File(".");
+            File cwd = dummyFile.getCanonicalFile();
+            File[] files = cwd.listFiles();
+            for (int i = 0; i < files.length; i++) {
+                if (files[i].isFile()) {
+                    if (files[i].getName().equalsIgnoreCase("build.xml")) {
+                        //
+                        // First, search build.xml, if found, ANT call it
+                        //
+                        buildFiles.add(files[i]);
+
+                    } else if (files[i].getName().endsWith(".fpd")) {
+                        //
+                        // Second, search FPD file, if found, build it
+                        //
+                        fpdFiles.add(files[i]);
+                    } else if (files[i].getName().endsWith(".msa")) {
+                        //
+                        // Third, search MSA file, if found, build it
+                        //
+                        msaFiles.add(files[i]);
+                    }
+                }
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+            throw new BuildException(e.getMessage());
+        }
+        
+        //
+        // If there is no build files or FPD files or MSA files, stop build
+        //
+        if (fpdFiles.size() == 0 && msaFiles.size() == 0) {
+            throw new BuildException("Can't find any build.xml file or FPD files or MSA files in current directory. ");
+        }
+        
+        File buildFile = intercommuniteWithUser();
+        System.out.println("Start to build file [" + buildFile.getPath() + "] ..>> ");
+        
+        //
+        // Deal with all environment variable (Add them to properties)
+        //
+        backupSystemProperties();
+        
+        //
+        // Get ToolChain Info from environment
+        //
+        ToolChainInfo envToolChainInfo = new ToolChainInfo(); 
+        envToolChainInfo.addTargets(getProject().getProperty("TARGET")); 
+        envToolChainInfo.addTagnames(getProject().getProperty("TAGNAME")); 
+        envToolChainInfo.addArchs(getProject().getProperty("ARCH")); 
+        GlobalData.setToolChainEnvInfo(envToolChainInfo);
+        
+        //
+        // Global Data initialization
+        //
+        String toolsDefFilename = "tools_def.txt";
+        if (getProject().getProperty("TOOLS_DEF") != null) {
+            toolsDefFilename = getProject().getProperty("TOOLS_DEF");
+        }
+        
+        GlobalData.initInfo("Tools" + File.separatorChar + "Conf" + File.separatorChar + "FrameworkDatabase.db",
+                            getProject().getProperty("WORKSPACE_DIR"), toolsDefFilename);
+        
+        //
+        // Build every FPD files (PLATFORM build)
+        //
+        if (buildFile.getName().endsWith(".fpd")) {
+            FpdParserTask fpdParserTask = new FpdParserTask();
+            fpdParserTask.setType(type);
+            fpdParserTask.setProject(getProject());
+            fpdParserTask.setFpdFile(buildFile);
+            fpdParserTask.execute();
+        }
+        
+        //
+        // Build every MSA files (SINGLE MODULE BUILD)
+        //
+        else if (buildFile.getName().endsWith(".msa")) {
+            GenBuildTask genBuildTask = new GenBuildTask();
+            genBuildTask.setType(type);
+            genBuildTask.setProject(getProject());
+            genBuildTask.setMsaFile(buildFile);
+            genBuildTask.execute();
+        }
+    }
+    
+    /**
+      Transfer system environment variables to ANT properties. If system variable 
+      already exiests in ANT properties, skip it.
+      
+    **/
+    private void backupSystemProperties() {
+        Map<String, String> sysProperties = System.getenv();
+        Set<String> keys = sysProperties.keySet();
+        Iterator<String> iter = keys.iterator();
+        while (iter.hasNext()) {
+            String name = iter.next();
+            
+            //
+            // If system environment variable is not in ANT properties, add it
+            //
+            if (getProject().getProperty(name) == null) {
+                getProject().setProperty(name, sysProperties.get(name));
+            }
+        }
+    }
+
+    private File intercommuniteWithUser(){
+        File file = null;
+        if (fpdFiles.size() + msaFiles.size() > 1) {
+            File[] allFiles = new File[fpdFiles.size() + msaFiles.size()];
+            int index = 0;
+            Iterator<File> iter = fpdFiles.iterator();
+            while (iter.hasNext()) {
+                allFiles[index] = iter.next();
+                index++;
+            }
+            iter = msaFiles.iterator();
+            while (iter.hasNext()) {
+                allFiles[index] = iter.next();
+                index++;
+            }
+            System.out.println("Find " + allFiles.length + " FPD and MSA files: ");
+            for (int i = 0; i < allFiles.length; i++) {
+                System.out.println("[" + (i + 1) + "]: " + allFiles[i].getName());
+            }
+            
+            boolean flag = true;
+            System.out.print("Please select one file to build:[1] ");
+            do{
+                BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
+                try {
+                     String str = br.readLine();
+                     if (str.trim().length() == 0) {
+                         file = allFiles[0];
+                         flag = false;
+                         continue ;
+                     }
+                     int indexSelect = Integer.parseInt(str);
+                     if (indexSelect <=0 || indexSelect > allFiles.length) {
+                         System.out.print("Please enter a number between [1.." + allFiles.length + "]:[1] ");
+                         continue ;
+                     } else {
+                         file = allFiles[indexSelect - 1];
+                         flag = false;
+                         continue ;
+                     }
+                } catch (Exception e) {
+                    System.out.print("Please enter a valid number:[1] ");
+                    flag = true;
+                }
+            } while (flag);
+        }
+        else if (fpdFiles.size() == 1) {
+            file = fpdFiles.toArray(new File[1])[0];
+        }
+        else if (msaFiles.size() == 1) {
+            file = msaFiles.toArray(new File[1])[0];
+        }
+        return file;
+    }
+    
+    
+    public void setType(String type) {
+        if (type.equalsIgnoreCase("clean") || type.equalsIgnoreCase("cleanall")) {
+            this.type = type.toLowerCase();
+        }
+        else {
+            this.type = "all";
+        }
+    }
+}
diff --git a/Tools/Source/GenBuild/org/tianocore/build/GenBuildTask.java b/Tools/Source/GenBuild/org/tianocore/build/GenBuildTask.java
index 3127b8706d..0e807f8abb 100644
--- a/Tools/Source/GenBuild/org/tianocore/build/GenBuildTask.java
+++ b/Tools/Source/GenBuild/org/tianocore/build/GenBuildTask.java
@@ -16,56 +16,42 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 package org.tianocore.build;
 
 import java.io.File;
-import java.util.HashMap;
-import java.util.HashSet;
+import java.util.Hashtable;
 import java.util.Iterator;
 import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.Stack;
 import java.util.Vector;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.transform.OutputKeys;
-import javax.xml.transform.Result;
-import javax.xml.transform.Source;
-import javax.xml.transform.Transformer;
-import javax.xml.transform.TransformerFactory;
-import javax.xml.transform.dom.DOMSource;
-import javax.xml.transform.stream.StreamResult;
-
 import org.apache.tools.ant.BuildException;
-import org.apache.tools.ant.Project;
-import org.apache.tools.ant.Task;
 import org.apache.tools.ant.taskdefs.Ant;
+import org.apache.tools.ant.taskdefs.Property;
 import org.apache.xmlbeans.XmlObject;
-import org.w3c.dom.Comment;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
 
-import org.tianocore.build.autogen.AutoGen;
-import org.tianocore.build.autogen.CommonDefinition;
+import org.tianocore.build.exception.EdkException;
 import org.tianocore.build.fpd.FpdParserTask;
-import org.tianocore.build.global.GenBuildLogger;
 import org.tianocore.build.global.GlobalData;
 import org.tianocore.build.global.OutputManager;
 import org.tianocore.build.global.SurfaceAreaQuery;
-import org.tianocore.build.toolchain.ToolChainFactory;
-import org.tianocore.logger.EdkLog;
-import org.tianocore.FilenameDocument;
-import org.tianocore.MsaHeaderDocument;
-import org.tianocore.MsaLibHeaderDocument;
+import org.tianocore.build.id.FpdModuleIdentification;
+import org.tianocore.build.id.ModuleIdentification;
+import org.tianocore.build.id.PackageIdentification;
+import org.tianocore.build.id.PlatformIdentification;
+import org.tianocore.build.tools.ModuleItem;
 
 /**
   <p>
   <code>GenBuildTask</code> is an ANT task that can be used in ANT build
   system. The main function of this task is to parse module's surface area,
   then generate the corresponding <em>BaseName_build.xml</em> (the real ANT
-  build script) and call this to build the module.
+  build script) and call this to build the module. The whole process including:
+  1. generate AutoGen.c and AutoGen.h; 2. build all dependent library instances; 
+  3. build all source files inlcude AutoGen.c; 4. generate sections;
+  5. generate FFS file if it is driver module while LIB file if it is Library module. 
   </p>
   
   <p>
@@ -73,11 +59,16 @@ import org.tianocore.MsaLibHeaderDocument;
   </p>
   
   <pre>
-   &lt;GenBuild baseName=&quot;HelloWorld&quot; 
-             mbdFilename=&quot;${MODULE_DIR}/HelloWorld.mbd&quot; 
-             msaFilename=&quot;${MODULE_DIR}/HelloWorld.msa&quot;/&gt;
+   &lt;GenBuild  
+             msaFilename=&quot;HelloWorld.msa&quot;/&gt; 
+             processTo=&quot;ALL&quot;/&gt;
   </pre>
   
+  <p><code>processTo</code> provides a way to customize the whole build process. 
+  processTo can be one value of ALL, AUTOGEN, FILES, LIBRARYINSTANCES, SECTIONS, NONE. 
+  Default is ALL, means whole 
+  </p>
+  
   <p>
   This task calls <code>AutoGen</code> to generate <em>AutoGen.c</em> and
   <em>AutoGen.h</em>. The task also parses the development environment
@@ -88,85 +79,30 @@ import org.tianocore.MsaLibHeaderDocument;
   
   @since GenBuild 1.0
 **/
-public class GenBuildTask extends Task {
-
+public class GenBuildTask extends Ant {
+    
     ///
     /// Module surface area file.
     ///
-    File msaFilename;
+    File msaFile;
 
     ///
-    /// Module build description file.
-    ///
-    File mbdFilename;
-
-    ///
-    /// Module surface area information after overrided.
-    ///
-    public Map<String, XmlObject> map = new HashMap<String, XmlObject>();
-
-    ///
-    /// Module's base name.
-    ///
-    private String baseName;
-
-    ///
-    /// Current build Arch, such as IA32, X64, IPF and so on.
-    ///
-    private String arch;
-
-    ///
-    /// Module's GUID (Globally Unique Identifier).
-    ///
-    private String guid;
-
-    ///
-    /// Module's component type, such as SEC, LIBRARY, BS_DRIVER and so on.
-    ///
-    private String componentType;
-
-    ///
-    /// This value is used in build time. Override module's component type. When
-    /// search FFS (Sections information) in common file, buildtype instead of
-    /// component type.
-    ///
-    private String buildType;
-
-    ///
-    /// List all required includes for current build module.
-    ///
-    public Set<String> includes = new LinkedHashSet<String>();
-
-    ///
-    /// List all libraries for current build module.
-    ///
-    public Set<String> libraries = new LinkedHashSet<String>();
-
-    ///
-    /// List all source files for current build module.
-    ///
-    public Set<String> sourceFiles = new LinkedHashSet<String>();
-
-    ///
-    /// Flag to identify what surface area files are specified. Current value is
-    /// <em>NO_SA</em>, <em>ONLY_MSA</em>, <em>ONLY_LIBMSA</em>,
-    /// <em>MSA_AND_MBD</em> or <em>LIBMSA_AND_LIBMBD</em>.
     /// 
-    /// @see org.tianocore.build.global.GlobaData
     ///
-    private int flag = GlobalData.NO_SA;
-
-    ///
-    /// The information at the header of <em>build.xml</em>.
-    ///
-    private String info = "====================================================================\n"
-                        + "DO NOT EDIT \n"
-                        + "File auto-generated by build utility\n"
-                        + "\n"
-                        + "Abstract:\n"
-                        + "Auto-generated ANT build file for building of EFI Modules/Platforms\n"
-                        + "=====================================================================";
+    private String type = "all"; // = "build";
+    
+    ///
+    /// Module's Identification.
+    ///
+    private ModuleIdentification moduleId;
 
+    private Vector<Property> properties = new Vector<Property>();
+    
+    private static Stack<Hashtable> backupPropertiesStack = new Stack<Hashtable>();
+    
+    
+    private static Hashtable backupProperties;
+    
     /**
       Public construct method. It is necessary for ANT task.
     **/
@@ -174,945 +110,537 @@ public class GenBuildTask extends Task {
     }
 
     /**
-      ANT task's entry point, will be called after init(). The main steps is described
-      as following: 
-      <ul>
-      <li> Judge current build mode (MODULE | PACKAGE | PLATFORM). This step will execute
-      only once in whole build process; </li>
-      <li> Initialize global information (Framework DB, SPD files and all MSA files 
-      listed in SPD). This step will execute only once in whole build process; </li>
-      <li> Restore some important ANT property. If current build is single module 
-      build, here will set many default values; </li>
-      <li> Get the current module's overridded surface area information from 
-      global data; </li> 
-      <li> Set up the output directories, including BIN_DIR, DEST_DIR_OUTPUT and
-      DEST_DIR_DEBUG; </li>
-      <li> Get module dependent library instances and include pathes; </li>
-      <li> Judge whether current module is built. If yes, skip it; </li>
-      <li> Call AutoGen and PCD to generate AutoGen.c & AutoGen.h </li>
-      <li> Set up the compile flags; </li>
-      <li> Generate BaseName_build.xml; </li>
-      <li> Call to BaseName_build.xml, and build the current module. </li>
-      </ul>
-      
-      <p>Build is dependent on BuildMacro.xml which define many macro. </p> 
-      
+  
       @throws BuildException
               From module build, exception from module surface area invalid.
     **/
     public void execute() throws BuildException {
-        System.out.println("Module [" + baseName + "] start.");
+        try{
+        pushProperties();
         //
-        // Inital GenBuild log  method 
+        // Enable all specified properties
         //
-        GenBuildLogger logger = new GenBuildLogger(getProject());
-        EdkLog.setLogger(logger);
-        EdkLog.setLogLevel(1);
-        
-        OutputManager.update(getProject());
-        GlobalData.initInfo("Tools" + File.separatorChar + "Conf" + File.separatorChar + "FrameworkDatabase.db",
-                            getProject().getProperty("WORKSPACE_DIR"));
-        recallFixedProperties();
-        arch = getProject().getProperty("ARCH");
-        arch = arch.toUpperCase();
-        map = GlobalData.getDoc(baseName);
-        //
-        // Initialize SurfaceAreaQuery
-        //
-        SurfaceAreaQuery.setDoc(map);
-        //
-        // Setup Output Management
-        //
-        String[] outdir = SurfaceAreaQuery.getOutputDirectory();
-        OutputManager.update(getProject(), outdir[1], outdir[0]);
-
-        updateIncludesAndLibraries();
-
-        if (GlobalData.isModuleBuilt(baseName, arch)) {
-            return;
-        } else {
-            GlobalData.registerBuiltModule(baseName, arch);
+        Iterator<Property> iter = properties.iterator();
+        while (iter.hasNext()) {
+            Property item = iter.next();
+            getProject().setProperty(item.getName(), item.getValue());
         }
+        
         //
-        // Call AutoGen
+        // GenBuild should specify either msaFile or moduleGuid & packageGuid
         //
-        AutoGen autogen = new AutoGen(getProject().getProperty("DEST_DIR_DEBUG"), baseName, arch);
-        autogen.genAutogen();
+        if (msaFile == null ) {
+            String moduleGuid = getProject().getProperty("MODULE_GUID");
+            String moduleVersion = getProject().getProperty("MODULE_VERSION");
+            String packageGuid = getProject().getProperty("PACKAGE_GUID");
+            String packageVersion = getProject().getProperty("PACKAGE_VERSION");
+            if (moduleGuid == null || packageGuid == null) {
+                throw new BuildException("GenBuild parameters error. ");
+            }
+            PackageIdentification packageId = new PackageIdentification(packageGuid, packageVersion);
+            moduleId = new ModuleIdentification(moduleGuid, moduleVersion);
+            moduleId.setPackage(packageId);
+            Map<String, XmlObject> doc = GlobalData.getNativeMsa(moduleId);
+            SurfaceAreaQuery.setDoc(doc);
+            moduleId = SurfaceAreaQuery.getMsaHeader();
+        }
+        else {
+            Map<String, XmlObject> doc = GlobalData.getNativeMsa(msaFile);
+            SurfaceAreaQuery.setDoc(doc);
+            moduleId = SurfaceAreaQuery.getMsaHeader();
+        }
+        String[] producedLibraryClasses = SurfaceAreaQuery.getLibraryClasses("ALWAYS_PRODUCED");
+        if (producedLibraryClasses.length == 0) {
+            moduleId.setLibrary(false);
+        }
+        else {
+            moduleId.setLibrary(true);
+        }
+        
         //
-        // Update parameters
+        // Judge whether it is single module build or not
         //
-        updateParameters();
+        if (getProject().getProperty("PLATFORM") == null) {
+            //
+            // Single Module build
+            //
+            prepareSingleModuleBuild();
+        }
+        else {
+            //
+            // Platform build. Restore the platform related info
+            //
+            String platformName = getProject().getProperty("PLATFORM");
+            PlatformIdentification platformId = GlobalData.getPlatform(platformName);
+            getProject().setProperty("PLATFORM_DIR", platformId.getFpdFile().getParent().replaceAll("(\\\\)", "/"));
+            getProject().setProperty("PLATFORM_RELATIVE_DIR", platformId.getPlatformRelativeDir().replaceAll("(\\\\)", "/"));
+            
+            String packageGuid = getProject().getProperty("PACKAGE_GUID");
+            String packageVersion = getProject().getProperty("PACKAGE_VERSION");
+            PackageIdentification packageId = new PackageIdentification(packageGuid, packageVersion);
+            moduleId.setPackage(packageId);
+        }
+        
         //
-        // Update flags like CC_FLAGS, LIB_FLAGS etc.
+        // If single module : intersection MSA supported ARCHs and tools def!!
+        // else, get arch from pass down
         //
-        flagsSetup();
-        GlobalData.addLibrary(baseName, arch, getProject().getProperty("BIN_DIR") + File.separatorChar + baseName + ".lib");
-        GlobalData.addModuleLibrary(baseName, arch, libraries);
+        String[] archList = new String[0];
+        if ( getProject().getProperty("ARCH") != null ) {
+            archList = getProject().getProperty("ARCH").split(" ");
+        }
+        else {
+            archList = GlobalData.getToolChainInfo().getArchs();
+        }
+        
+        
         //
-        // If ComponentType is USER_DEFINED,
+        // Judge if arch is all supported by current module. If not, throw Exception.
+        //
+        List moduleSupportedArchs = SurfaceAreaQuery.getModuleSupportedArchs();
+        if (moduleSupportedArchs != null) {
+            for (int k = 0; k < archList.length; k++) {
+                if ( ! moduleSupportedArchs.contains(archList[k])) {
+                    throw new BuildException("ARCH [" + archList[k] + "] is not supported by " + moduleId + ". " + moduleId + " only supports [" + moduleSupportedArchs + "].");
+                }
+            }
+        }
+        
+        for (int k = 0; k < archList.length; k++) {
+            getProject().setProperty("ARCH", archList[k]);
+            
+            FpdModuleIdentification fpdModuleId = new FpdModuleIdentification(moduleId, archList[k]);
+            
+            //
+            // Whether the module is built before
+            //
+            if (GlobalData.isModuleBuilt(fpdModuleId)) {
+                return ;
+            }
+            else {
+                GlobalData.registerBuiltModule(fpdModuleId);
+            }
+            
+            //
+            // For Every TOOLCHAIN, TARGET
+            //
+            String[] targetList =  GlobalData.getToolChainInfo().getTargets();
+            for (int i = 0; i < targetList.length; i ++){
+                //
+                // Prepare for target related common properties
+                // TARGET
+                //
+                getProject().setProperty("TARGET", targetList[i]);
+                String[] toolchainList = GlobalData.getToolChainInfo().getTagnames();
+                for(int j = 0; j < toolchainList.length; j ++){
+                    //
+                    // Prepare for toolchain related common properties
+                    // TOOLCHAIN
+                    //
+                    getProject().setProperty("TOOLCHAIN", toolchainList[j]);
+
+                    System.out.println("Build " + moduleId + " start >>>");
+                    System.out.println("Target: " + targetList[i] + " Tagname: " + toolchainList[j] + " Arch: " + archList[k]);
+                    SurfaceAreaQuery.setDoc(GlobalData.getDoc(fpdModuleId));
+                    
+                    //
+                    // Prepare for all other common properties
+                    // PACKAGE, PACKAGE_GUID, PACKAGE_VERSION, PACKAGE_DIR, PACKAGE_RELATIVE_DIR
+                    // MODULE or BASE_NAME, GUID or FILE_GUID, VERSION, MODULE_TYPE
+                    // MODULE_DIR, MODULE_RELATIVE_DIR
+                    // SUBSYSTEM, ENTRYPOINT, EBC_TOOL_LIB_PATH
+                    // LIBS, OBJECTS, SDB_FILES
+                    //
+                    setModuleCommonProperties(archList[k]);
+                    
+                    //
+                    // OutputManage prepare for 
+                    // BIN_DIR, DEST_DIR_DEBUG, DEST_DIR_OUTPUT, BUILD_DIR, FV_DIR
+                    //
+                    OutputManager.getInstance().update(getProject());
+                    
+                    if (type.equalsIgnoreCase("all") || type.equalsIgnoreCase("build")) {
+                        applyBuild(targetList[i], toolchainList[j], fpdModuleId);
+                    }
+                    else if (type.equalsIgnoreCase("clean")) {
+                        applyClean(fpdModuleId);
+                    }
+                    else if (type.equalsIgnoreCase("cleanall")) {
+                        applyCleanall(fpdModuleId);
+                    }
+                }
+            }
+        }
+        popProperties();
+        }catch (Exception e){
+            e.printStackTrace();
+            throw new BuildException(e.getMessage());
+        }
+    }
+
+    /**
+      This method is used to prepare Platform-related information. 
+      
+      <p>In Single Module Build mode, platform-related information is not ready.
+      The method read the system environment variable <code>ACTIVE_PLATFORM</code> 
+      and search in the Framework Database. Note that platform name in the Framework
+      Database must be unique. </p>
+     
+    **/
+    private void prepareSingleModuleBuild(){
+        //
+        // Find out the package which the module belongs to
+        // TBD: Enhance it!!!!
+        //
+        PackageIdentification packageId = GlobalData.getPackageForModule(moduleId);
+        
+        moduleId.setPackage(packageId);
+        
+        //
+        // Read ACTIVE_PLATFORM's FPD file (Call FpdParserTask's method)
+        //
+        String activePlatformName = getProject().getProperty("ACTIVE_PLATFORM");
+        
+        if (activePlatformName == null){
+            throw new BuildException("Plese set ACTIVE_PLATFORM if you want to build a single module. ");
+        }
+        
+        PlatformIdentification platformId = GlobalData.getPlatform(activePlatformName);
+        
+        //
+        // Read FPD file
+        //
+        FpdParserTask fpdParser = new FpdParserTask();
+        fpdParser.setProject(getProject());
+        fpdParser.parseFpdFile(platformId.getFpdFile());
+        
+        //
+        // Prepare for Platform related common properties
+        // PLATFORM, PLATFORM_DIR, PLATFORM_RELATIVE_DIR
+        //
+        getProject().setProperty("PLATFORM", activePlatformName);
+        getProject().setProperty("PLATFORM_DIR", platformId.getFpdFile().getParent().replaceAll("(\\\\)", "/"));
+        getProject().setProperty("PLATFORM_RELATIVE_DIR", platformId.getPlatformRelativeDir().replaceAll("(\\\\)", "/"));
+    }
+
+
+    /**
+      Set Module-Related information to properties.
+    **/
+    private void setModuleCommonProperties(String arch) {
+        //
+        // Prepare for all other common properties
+        // PACKAGE, PACKAGE_GUID, PACKAGE_VERSION, PACKAGE_DIR, PACKAGE_RELATIVE_DIR
+        //
+        PackageIdentification packageId = moduleId.getPackage();
+        getProject().setProperty("PACKAGE", packageId.getName());
+        getProject().setProperty("PACKAGE_GUID", packageId.getGuid());
+        getProject().setProperty("PACKAGE_VERSION", packageId.getVersion());
+        getProject().setProperty("PACKAGE_DIR", packageId.getPackageDir().replaceAll("(\\\\)", "/"));
+        getProject().setProperty("PACKAGE_RELATIVE_DIR", packageId.getPackageRelativeDir().replaceAll("(\\\\)", "/"));
+        
+        //
+        // MODULE or BASE_NAME, GUID or FILE_GUID, VERSION, MODULE_TYPE
+        // MODULE_DIR, MODULE_RELATIVE_DIR
+        //
+        getProject().setProperty("MODULE", moduleId.getName());
+        String baseName = SurfaceAreaQuery.getModuleOutputFileBasename();
+        if (baseName == null) {
+            getProject().setProperty("BASE_NAME", moduleId.getName());
+        }
+        else {
+            getProject().setProperty("BASE_NAME", baseName);
+        }
+        getProject().setProperty("GUID", moduleId.getGuid());
+        getProject().setProperty("FILE_GUID", moduleId.getGuid());
+        getProject().setProperty("VERSION", moduleId.getVersion());
+        getProject().setProperty("MODULE_TYPE", moduleId.getModuleType());
+        getProject().setProperty("MODULE_DIR", moduleId.getMsaFile().getParent().replaceAll("(\\\\)", "/"));
+        getProject().setProperty("MODULE_RELATIVE_DIR", moduleId.getModuleRelativePath().replaceAll("(\\\\)", "/"));
+        
+        //
+        // SUBSYSTEM
+        //
+        String[][] subsystemMap = { { "BASE", "EFI_BOOT_SERVICE_DRIVER"},
+                                    { "SEC", "EFI_BOOT_SERVICE_DRIVER" }, 
+                                    { "PEI_CORE", "EFI_BOOT_SERVICE_DRIVER" }, 
+                                    { "PEIM", "EFI_BOOT_SERVICE_DRIVER" }, 
+                                    { "DXE_CORE", "EFI_BOOT_SERVICE_DRIVER" },
+                                    { "DXE_DRIVER", "EFI_BOOT_SERVICE_DRIVER" }, 
+                                    { "DXE_RUNTIME_DRIVER", "EFI_RUNTIME_DRIVER" }, 
+                                    { "DXE_SAL_DRIVER", "EFI_BOOT_SERVICE_DRIVER" }, 
+                                    { "DXE_SMM_DRIVER", "EFI_BOOT_SERVICE_DRIVER" }, 
+                                    { "TOOL", "EFI_BOOT_SERVICE_DRIVER" }, 
+                                    { "UEFI_DRIVER", "EFI_BOOT_SERVICE_DRIVER" },
+                                    { "UEFI_APPLICATION", "EFI_APPLICATION" }, 
+                                    { "USER_DEFINED", "EFI_BOOT_SERVICE_DRIVER"} }; 
+        
+        String subsystem = "EFI_BOOT_SERVICE_DRIVER";
+        for (int i = 0; i < subsystemMap.length; i++) {
+            if (moduleId.getModuleType().equalsIgnoreCase(subsystemMap[i][0])) {
+                subsystem = subsystemMap[i][1];
+                break ;
+            }
+        }
+        getProject().setProperty("SUBSYSTEM", subsystem);
+        
+        //
+        // ENTRYPOINT
+        //
+        if (arch.equalsIgnoreCase("EBC")) {
+            getProject().setProperty("ENTRYPOINT", "EfiStart");
+        }
+        else {
+            getProject().setProperty("ENTRYPOINT", "_ModuleEntryPoint");
+        }
+        
+        //
+        // LIBS, OBJECTS, SDB_FILES
+        //
+        getProject().setProperty("OBJECTS", "");
+        getProject().setProperty("SDB_FILES", "");
+        getProject().setProperty("LIBS", "");
+    }
+
+    private void getCompilerFlags(String target, String toolchain, FpdModuleIdentification fpdModuleId) throws EdkException {
+        String[] cmd = GlobalData.getToolChainInfo().getCommands();
+        for ( int m = 0; m < cmd.length; m++) {
+            //
+            // Set cmd, like CC, DLINK
+            //
+            String[] key = new String[]{target, toolchain, fpdModuleId.getArch(), cmd[m], null};
+            key[4] = "PATH";
+            String cmdPath = GlobalData.getCommandSetting(key, fpdModuleId);
+            key[4] = "NAME";
+            String cmdName = GlobalData.getCommandSetting(key, fpdModuleId);
+            File cmdFile = new File(cmdPath + File.separatorChar + cmdName);
+//            GlobalData.log.info("PATH: " + cmdFile.getPath());
+            getProject().setProperty(cmd[m], cmdFile.getPath().replaceAll("(\\\\)", "/"));
+            
+            //
+            // set CC_FLAGS
+            //
+            key[4] = "FLAGS";
+            String cmdFlags = GlobalData.getCommandSetting(key, fpdModuleId);
+//            GlobalData.log.info("Flags: " + cmdFlags);
+            Set<String> addset = new LinkedHashSet<String>();
+            Set<String> subset = new LinkedHashSet<String>();
+            putFlagsToSet(addset, cmdFlags);
+            getProject().setProperty(cmd[m] + "_FLAGS", getProject().replaceProperties(getFlags(addset, subset)));
+            
+            //
+            // Set CC_EXT
+            //
+            key[4] = "EXT";
+            String extName = GlobalData.getCommandSetting(key, fpdModuleId);
+//            GlobalData.log.info("Ext: " + extName);
+            if ( extName != null && ! extName.equalsIgnoreCase("")) {
+                getProject().setProperty(cmd[m] + "_EXT", extName);
+            }
+            else {
+                getProject().setProperty(cmd[m] + "_EXT", "");
+            }
+            
+            //
+            // set CC_FAMILY
+            //
+            key[4] = "FAMILY";
+            String toolChainFamily = GlobalData.getCommandSetting(key, fpdModuleId);
+//            GlobalData.log.info("FAMILY: " + toolChainFamily);
+            if (toolChainFamily != null) {
+                getProject().setProperty(cmd[m] + "_FAMILY", toolChainFamily);
+            }
+            
+            //
+            // set CC_SPATH
+            //
+            key[4] = "SPATH";
+            String spath = GlobalData.getCommandSetting(key, fpdModuleId);
+//            GlobalData.log.info("SPATH: " + spath);
+            if (spath != null) {
+                getProject().setProperty(cmd[m] + "_SPATH", spath.replaceAll("(\\\\)", "/"));
+            }
+            else {
+                getProject().setProperty(cmd[m] + "_SPATH", "");
+            }
+            
+            //
+            // set CC_DPATH
+            //
+            key[4] = "DPATH";
+            String dpath = GlobalData.getCommandSetting(key, fpdModuleId);
+//            GlobalData.log.info("DPATH: " + dpath);
+            if (dpath != null) {
+                getProject().setProperty(cmd[m] + "_DPATH", dpath.replaceAll("(\\\\)", "/"));
+            }
+            else {
+                getProject().setProperty(cmd[m] + "_DPATH", "");
+            }
+        }
+    }
+    
+    public void setMsaFile(File msaFile) {
+        this.msaFile = msaFile;
+    }
+
+    /**
+      Method is for ANT to initialize MSA file. 
+      
+      @param msaFilename MSA file name
+    **/
+    public void setMsaFile(String msaFilename) {
+        String moduleDir = getProject().getProperty("MODULE_DIR");
+        
+        //
+        // If is Single Module Build, then use the Base Dir defined in build.xml
+        //
+        if (moduleDir == null) {
+            moduleDir = getProject().getBaseDir().getPath();
+        }
+        msaFile = new File(moduleDir + File.separatorChar + msaFilename);
+    }
+    
+    public void addConfiguredModuleItem(ModuleItem moduleItem) {
+        PackageIdentification packageId = new PackageIdentification(moduleItem.getPackageGuid(), moduleItem.getPackageVersion());
+        ModuleIdentification moduleId = new ModuleIdentification(moduleItem.getModuleGuid(), moduleItem.getModuleVersion());
+        moduleId.setPackage(packageId);
+        this.moduleId = moduleId;
+    }
+    
+    /**
+      Add a property. 
+    
+      @param p property
+    **/
+    public void addProperty(Property p) {
+        properties.addElement(p);
+    }
+
+    public void setType(String type) {
+        this.type = type;
+    }
+    
+    private void applyBuild(String buildTarget, String buildTagname, FpdModuleIdentification fpdModuleId) throws EdkException{
+        //
+        // AutoGen
+        //
+//        AutoGen autogen = new AutoGen(getProject().getProperty("DEST_DIR_DEBUG"), fpdModuleId);
+//        autogen.genAutogen();
+        
+        
+        //
+        // Get compiler flags
+        //
+        getCompilerFlags(buildTarget, buildTagname, fpdModuleId);
+        
+        //
+        // Prepare LIBS
+        //
+        ModuleIdentification[] libinstances = SurfaceAreaQuery.getLibraryInstance(fpdModuleId.getArch());
+        String propertyLibs = "";
+        for (int i = 0; i < libinstances.length; i++) {
+            propertyLibs += " " + getProject().getProperty("BIN_DIR") + File.separatorChar + libinstances[i].getName() + ".lib";
+        }
+        getProject().setProperty("LIBS", propertyLibs.replaceAll("(\\\\)", "/"));
+        
+        //
+        // if it is CUSTOM_BUILD
         // then call the exist BaseName_build.xml directly.
         //
-        if (buildType.equalsIgnoreCase("CUSTOM_BUILD")) {
-            System.out.println("Call user-defined " + baseName + "_build.xml");
+        if (moduleId.getModuleType().equalsIgnoreCase("USER_DEFINED")) {
+            GlobalData.log.info("Call user-defined " + moduleId.getName() + "_build.xml");
             Ant ant = new Ant();
             ant.setProject(getProject());
-            ant.setAntfile(getProject().getProperty("MODULE_DIR") + File.separatorChar + baseName + "_build.xml");
+            ant.setAntfile(getProject().getProperty("MODULE_DIR") + File.separatorChar + moduleId.getName() + "_build.xml");
             ant.setInheritAll(true);
             ant.init();
             ant.execute();
-            return;
+            return ;
         }
+        
         //
-        // Generate ${BASE_NAME}_build.xml file
+        // Generate ${BASE_NAME}_build.xml
+        // TBD
+        //
+        String ffsKeyword = SurfaceAreaQuery.getModuleFfsKeyword();
+        ModuleBuildFileGenerator fileGenerator = new ModuleBuildFileGenerator(getProject(), ffsKeyword, fpdModuleId);
+        String buildFilename = getProject().getProperty("DEST_DIR_OUTPUT") + File.separatorChar + moduleId.getName() + "_build.xml";
+        fileGenerator.genBuildFile(buildFilename);
+        
+        //
+        // Ant call ${BASE_NAME}_build.xml
         //
-        System.out.println("Generate " + baseName + "_build.xml");
-        genBuildFile();
-        System.out.println("Call the " + baseName + "_build.xml");
         Ant ant = new Ant();
         ant.setProject(getProject());
-        ant.setAntfile(getProject().getProperty("DEST_DIR_OUTPUT") + File.separatorChar + baseName + "_build.xml");
+        ant.setAntfile(getProject().getProperty("DEST_DIR_OUTPUT") + File.separatorChar + moduleId.getName() + "_build.xml");
         ant.setInheritAll(true);
         ant.init();
         ant.execute();
     }
-
-    /**
-      Return the name of the directory that corresponds to the architecture.
-      This is a translation from the XML Schema tag to a directory that
-      corresponds to our directory name coding convention.
-     
-    **/
-    private String archDir(String arch) {
-        return arch.replaceFirst("X64", "x64")
-                   .replaceFirst("IPF", "Ipf")
-                   .replaceFirst("IA32", "Ia32")
-                   .replaceFirst("ARM", "Arm")
-                   .replaceFirst("EBC", "Ebc");
-    }
-
-    /**
-      Get the dependent library instances and include package name from 
-      surface area, and initialize module include pathes. 
-     
-    **/
-    private void updateIncludesAndLibraries() {
-        List<String> rawIncludes = SurfaceAreaQuery.getIncludePackageName(arch);
-        if (rawIncludes != null) {
-            Iterator iter = rawIncludes.iterator();
-            while (iter.hasNext()) {
-                String packageName = (String) iter.next();
-                includes.add("${WORKSPACE_DIR}" + File.separatorChar + GlobalData.getPackagePath(packageName)
-                             + File.separatorChar + "Include");
-                includes.add("${WORKSPACE_DIR}" + File.separatorChar + GlobalData.getPackagePath(packageName)
-                             + File.separatorChar + "Include" + File.separatorChar + archDir(arch));
-            }
-        }
-        includes.add("${DEST_DIR_DEBUG}");
-        List<String> rawLibraries = SurfaceAreaQuery.getLibraryInstance(this.arch, CommonDefinition.AlwaysConsumed);
-        if (rawLibraries != null) {
-            Iterator iter = rawLibraries.iterator();
-            while (iter.hasNext()) {
-                libraries.add((String) iter.next());
-            }
-        }
-        normalize();
-    }
-
-    /**
-      Normalize all dependent library instance and include pathes' format. 
-     
-    **/
-    private void normalize() {
-        String[] includesArray = includes.toArray(new String[includes.size()]);
-        includes.clear();
-        for (int i = 0; i < includesArray.length; i++) {
-            includes.add((new File(includesArray[i])).getPath());
-        }
-        String[] librariesArray = libraries.toArray(new String[libraries.size()]);
-        libraries.clear();
-        for (int i = 0; i < librariesArray.length; i++) {
-            libraries.add((new File(librariesArray[i])).getPath());
-        }
-    }
-
-    /**
-      Restore some important ANT property. If current build is single module 
-      build, here will set many default values.
-      
-      <p> If current build is single module build, then the default <code>ARCH</code>
-      is <code>IA32</code>. Also set up the properties <code>PACKAGE</code>, 
-      <code>PACKAGE_DIR</code>, <code>TARGET</code> and <code>MODULE_DIR</code></p>
-      
-      <p> Note that for package build, package name is stored in <code>PLATFORM</code>
-      and package directory is stored in <code>PLATFORM_DIR</code>. </p> 
-     
-      @see org.tianocore.build.global.OutputManager
-    **/
-    private void recallFixedProperties() {
+    
+    private void applyClean(FpdModuleIdentification fpdModuleId){
         //
-        // If build is for module build
+        // if it is CUSTOM_BUILD
+        // then call the exist BaseName_build.xml directly.
         //
-        if (getProject().getProperty("PACKAGE_DIR") == null) {
-            ToolChainFactory toolChainFactory = new ToolChainFactory(getProject());
-            toolChainFactory.setupToolChain();
-            //
-            // PACKAGE PACKAGE_DIR ARCH (Default) COMMON_FILE BUILD_MACRO
-            //
-            if (getProject().getProperty("ARCH") == null) {
-                getProject().setProperty("ARCH", "IA32");
-            }
-            String packageName = GlobalData.getPackageNameForModule(baseName);
-            getProject().setProperty("PACKAGE", packageName);
-            
-            String packageDir = GlobalData.getPackagePath(packageName);
-            getProject().setProperty("PACKAGE_DIR",
-                                     getProject().getProperty("WORKSPACE_DIR") + File.separatorChar + packageDir);
-            
-            getProject().setProperty("TARGET", toolChainFactory.getCurrentTarget());
-            
-            getProject().setProperty("MODULE_DIR",
-                                     getProject().replaceProperties(getProject().getProperty("MODULE_DIR")));
+        if (moduleId.getModuleType().equalsIgnoreCase("USER_DEFINED")) {
+            GlobalData.log.info("Call user-defined " + moduleId.getName() + "_build.xml");
+            Ant ant = new Ant();
+            ant.setProject(getProject());
+            ant.setAntfile(getProject().getProperty("MODULE_DIR") + File.separatorChar + moduleId.getName() + "_build.xml");
+            ant.setTarget("clean");
+            ant.setInheritAll(true);
+            ant.init();
+            ant.execute();
+            return ;
         }
-        if (OutputManager.PLATFORM != null) {
-            getProject().setProperty("PLATFORM", OutputManager.PLATFORM);
-        }
-        if (OutputManager.PLATFORM_DIR != null) {
-            getProject().setProperty("PLATFORM_DIR", OutputManager.PLATFORM_DIR);
-        }
-    }
-
-    /**
-      The whole BaseName_build.xml is composed of seven part. 
-      <ul>
-      <li> ANT properties; </li>
-      <li> Dependent module (dependent library instances in most case); </li>
-      <li> Source files; </li>
-      <li> Sections if module is not library; </li>
-      <li> Output (different for library module and driver module); </li>
-      <li> Clean; </li>
-      <li> Clean all. </li>
-      </ul>
-      
-      @throws BuildException
-              Error throws during BaseName_build.xml generating. 
-    **/
-    private void genBuildFile() throws BuildException {
-        FfsProcess fp = new FfsProcess();
-        DocumentBuilderFactory domfac = DocumentBuilderFactory.newInstance();
-        try {
-            DocumentBuilder dombuilder = domfac.newDocumentBuilder();
-            Document document = dombuilder.newDocument();
-            Comment rootComment = document.createComment(info);
-            //
-            // create root element and its attributes
-            //
-            Element root = document.createElement("project");
-            //
-            // root.setAttribute("name", base_name);
-            //
-            root.setAttribute("default", "main");
-            root.setAttribute("basedir", ".");
-            //
-            // element for External ANT tasks
-            //
-            root.appendChild(document.createComment("Apply external ANT tasks"));
-            Element ele = document.createElement("taskdef");
-            ele.setAttribute("resource", "frameworktasks.tasks");
-            root.appendChild(ele);
-            ele = document.createElement("taskdef");
-            ele.setAttribute("resource", "cpptasks.tasks");
-            root.appendChild(ele);
-            ele = document.createElement("typedef");
-            ele.setAttribute("resource", "cpptasks.types");
-            root.appendChild(ele);
-            ele = document.createElement("taskdef");
-            ele.setAttribute("resource", "net/sf/antcontrib/antlib.xml");
-            root.appendChild(ele);
-            //
-            // elements for Properties
-            //
-            root.appendChild(document.createComment("All Properties"));
-            ele = document.createElement("property");
-            ele.setAttribute("name", "BASE_NAME");
-            ele.setAttribute("value", baseName);
-            root.appendChild(ele);
-            //
-            // Generate the default target,
-            // which depends on init, sections and output target
-            //
-            root.appendChild(document.createComment("Default target"));
-            ele = document.createElement("target");
-            ele.setAttribute("name", "main");
-            ele.setAttribute("depends", "libraries, sourcefiles, sections, output");
-            root.appendChild(ele);
-            //
-            // compile all source files
-            //
-            root.appendChild(document.createComment("Compile all dependency Library instances."));
-            ele = document.createElement("target");
-            ele.setAttribute("name", "libraries");
-            //
-            // Parse all sourfiles but files specified in sections
-            //
-            applyLibraryInstance(document, ele);
-            root.appendChild(ele);
-            //
-            // compile all source files
-            //
-            root.appendChild(document.createComment("sourcefiles target"));
-            ele = document.createElement("target");
-            ele.setAttribute("name", "sourcefiles");
-            //
-            // Parse all sourfiles but files specified in sections
-            //
-            applyCompileElement(document, ele);
-            root.appendChild(ele);
-            //
-            // generate the init target
-            // main purpose is create all nessary pathes
-            // generate the sections target
-            //
-            root.appendChild(document.createComment("sections target"));
-            ele = document.createElement("target");
-            ele.setAttribute("name", "sections");
-            applySectionsElement(document, ele, fp);
-            root.appendChild(ele);
-            //
-            // generate the output target
-            //
-            root.appendChild(document.createComment("output target"));
-            ele = document.createElement("target");
-            ele.setAttribute("name", "output");
-            applyOutputElement(document, ele, fp);
-            root.appendChild(ele);
-            //
-            // generate the clean target
-            //
-            root.appendChild(document.createComment("clean target"));
-            ele = document.createElement("target");
-            ele.setAttribute("name", "clean");
-            applyCleanElement(document, ele);
-            root.appendChild(ele);
-            //
-            // generate the Clean All target
-            //
-            root.appendChild(document.createComment("Clean All target"));
-            ele = document.createElement("target");
-            ele.setAttribute("name", "cleanall");
-            applyDeepcleanElement(document, ele);
-            root.appendChild(ele);
-            //
-            // add the root element to the document
-            //
-            document.appendChild(rootComment);
-            document.appendChild(root);
-            //
-            // Prepare the DOM document for writing
-            //
-            Source source = new DOMSource(document);
-            //
-            // Prepare the output file
-            //
-            File file = new File(getProject().getProperty("DEST_DIR_OUTPUT") + File.separatorChar + baseName
-                                 + "_build.xml");
-            //
-            // generate all directory path
-            //
-            (new File(file.getParent())).mkdirs();
-            Result result = new StreamResult(file);
-            //
-            // Write the DOM document to the file
-            //
-            Transformer xformer = TransformerFactory.newInstance().newTransformer();
-            xformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
-            xformer.setOutputProperty(OutputKeys.INDENT, "yes");
-            xformer.transform(source, result);
-        } catch (Exception ex) {
-            throw new BuildException("Module [" + baseName + "] generating build file failed.\n" + ex.getMessage());
-        }
-    }
-
-    /**
-      Generate the clean elements for BaseName_build.xml. 
-      
-      @param document current BaseName_build.xml XML document
-      @param root Root element for current
-    **/
-    private void applyCleanElement(Document document, Node root) {
-        String[] libinstances = libraries.toArray(new String[libraries.size()]);
-        for (int i = 0; i < libinstances.length; i++) {
-            File file = new File(GlobalData.getModulePath(libinstances[i]) + File.separatorChar + "build.xml");
-
-            Element ifEle = document.createElement("if");
-            Element availableEle = document.createElement("available");
-            availableEle.setAttribute("file", file.getPath());
-            ifEle.appendChild(availableEle);
-            Element elseEle = document.createElement("then");
-
-            Element ele = document.createElement("ant");
-            ele.setAttribute("antfile", file.getPath());
-            ele.setAttribute("inheritAll", "false");
-            ele.setAttribute("target", libinstances[i] + "_clean");
-            //
-            // Workspace_DIR
-            //
-            Element property = document.createElement("property");
-            property.setAttribute("name", "WORKSPACE_DIR");
-            property.setAttribute("value", "${WORKSPACE_DIR}");
-            ele.appendChild(property);
-            //
-            // Package Dir
-            //
-            property = document.createElement("property");
-            property.setAttribute("name", "PACKAGE_DIR");
-            property.setAttribute("value", "${WORKSPACE_DIR}" + File.separatorChar
-                                           + GlobalData.getPackagePathForModule(libinstances[i]));
-            ele.appendChild(property);
-            //
-            // ARCH
-            //
-            property = document.createElement("property");
-            property.setAttribute("name", "ARCH");
-            property.setAttribute("value", "${ARCH}");
-            ele.appendChild(property);
-            //
-            // TARGET
-            //
-            property = document.createElement("property");
-            property.setAttribute("name", "TARGET");
-            property.setAttribute("value", "${TARGET}");
-            ele.appendChild(property);
-            //
-            // PACKAGE
-            //
-            property = document.createElement("property");
-            property.setAttribute("name", "PACKAGE");
-            property.setAttribute("value", GlobalData.getPackageNameForModule(libinstances[i]));
-            ele.appendChild(property);
-
-            elseEle.appendChild(ele);
-            ifEle.appendChild(elseEle);
-            root.appendChild(ifEle);
-        }
-    }
-
-    /**
-      Generate the cleanall elements for BaseName_build.xml. 
-      
-      @param document current BaseName_build.xml XML document
-      @param root Root element for current
-    **/
-    private void applyDeepcleanElement(Document document, Node root) {
-        String[] libinstances = libraries.toArray(new String[libraries.size()]);
-        for (int i = 0; i < libinstances.length; i++) {
-            File file = new File(GlobalData.getModulePath(libinstances[i]) + File.separatorChar + "build.xml");
-
-            Element ifEle = document.createElement("if");
-            Element availableEle = document.createElement("available");
-            availableEle.setAttribute("file", file.getPath());
-            ifEle.appendChild(availableEle);
-            Element elseEle = document.createElement("then");
-
-            Element ele = document.createElement("ant");
-            ele.setAttribute("antfile", file.getPath());
-            ele.setAttribute("inheritAll", "false");
-            ele.setAttribute("target", libinstances[i] + "_cleanall");
-            //
-            // Workspace_DIR
-            //
-            Element property = document.createElement("property");
-            property.setAttribute("name", "WORKSPACE_DIR");
-            property.setAttribute("value", "${WORKSPACE_DIR}");
-            ele.appendChild(property);
-            //
-            // Package Dir
-            //
-            property = document.createElement("property");
-            property.setAttribute("name", "PACKAGE_DIR");
-            property.setAttribute("value", "${WORKSPACE_DIR}" + File.separatorChar
-                                           + GlobalData.getPackagePathForModule(libinstances[i]));
-            ele.appendChild(property);
-            //
-            // ARCH
-            //
-            property = document.createElement("property");
-            property.setAttribute("name", "ARCH");
-            property.setAttribute("value", "${ARCH}");
-            ele.appendChild(property);
-            //
-            // TARGET
-            //
-            property = document.createElement("property");
-            property.setAttribute("name", "TARGET");
-            property.setAttribute("value", "${TARGET}");
-            ele.appendChild(property);
-            //
-            // PACKAGE
-            //
-            property = document.createElement("property");
-            property.setAttribute("name", "PACKAGE");
-            property.setAttribute("value", GlobalData.getPackageNameForModule(libinstances[i]));
-            ele.appendChild(property);
-
-            elseEle.appendChild(ele);
-            ifEle.appendChild(elseEle);
-            root.appendChild(ifEle);
-        }
-    }
-
-    /**
-      Generate the dependent library instances elements for BaseName_build.xml. 
-      
-      @param document current BaseName_build.xml XML document
-      @param root Root element for current
-    **/
-    private void applyLibraryInstance(Document document, Node root) {
-        String[] libinstances = libraries.toArray(new String[libraries.size()]);
-        for (int i = 0; i < libinstances.length; i++) {
-            Element ele = document.createElement("ant");
-            File file = new File(GlobalData.getModulePath(libinstances[i]) + File.separatorChar + "build.xml");
-            ele.setAttribute("antfile", file.getPath());
-            ele.setAttribute("inheritAll", "false");
-            ele.setAttribute("target", libinstances[i]);
-            //
-            // Workspace_DIR
-            //
-            Element property = document.createElement("property");
-            property.setAttribute("name", "WORKSPACE_DIR");
-            property.setAttribute("value", "${WORKSPACE_DIR}");
-            ele.appendChild(property);
-            //
-            // Package Dir
-            //
-            property = document.createElement("property");
-            property.setAttribute("name", "PACKAGE_DIR");
-            property.setAttribute("value", "${WORKSPACE_DIR}" + File.separatorChar
-                                           + GlobalData.getPackagePathForModule(libinstances[i]));
-            ele.appendChild(property);
-            //
-            // ARCH
-            //
-            property = document.createElement("property");
-            property.setAttribute("name", "ARCH");
-            property.setAttribute("value", "${ARCH}");
-            ele.appendChild(property);
-            //
-            // TARGET
-            //
-            property = document.createElement("property");
-            property.setAttribute("name", "TARGET");
-            property.setAttribute("value", "${TARGET}");
-            ele.appendChild(property);
-            //
-            // PACKAGE
-            //
-            property = document.createElement("property");
-            property.setAttribute("name", "PACKAGE");
-            property.setAttribute("value", GlobalData.getPackageNameForModule(libinstances[i]));
-            ele.appendChild(property);
-            root.appendChild(ele);
-        }
-        Element expand = document.createElement("Expand");
-        root.appendChild(expand);
+        
+        Ant ant = new Ant();
+        ant.setProject(getProject());
+        ant.setAntfile(getProject().getProperty("DEST_DIR_OUTPUT") + File.separatorChar + moduleId.getName() + "_build.xml");
+        ant.setTarget("clean");
+        ant.setInheritAll(true);
+        ant.init();
+        ant.execute();
+        
+        //
+        // Delete current module's DEST_DIR_OUTPUT
+        // TBD
     }
     
-    /**
-      Generate the build source files elements for BaseName_build.xml. 
-      
-      @param document current BaseName_build.xml XML document
-      @param root Root element for current
-    **/
-    private void applyCompileElement(Document document, Node root) {
-        FileProcess fileProcess = new FileProcess();
-        fileProcess.init(getProject(), includes, sourceFiles, document);
-        Node[] files = this.getSourceFiles();
+    private void applyCleanall(FpdModuleIdentification fpdModuleId){
         //
-        // Parse all unicode files
+        // if it is CUSTOM_BUILD
+        // then call the exist BaseName_build.xml directly.
         //
-        for (int i = 0; i < files.length; i++) {
-            String filetype = getFiletype(files[i]);
-            if (filetype != null) {
-                fileProcess.parseFile(getFilename(files[i]), filetype, root, true);
-            } else {
-                fileProcess.parseFile(getFilename(files[i]), root, true);
-            }
-        }
-        if (fileProcess.isUnicodeExist()) {
-            Element ele = document.createElement("Build_Unicode_Database");
-            ele.setAttribute("FILEPATH", ".");
-            ele.setAttribute("FILENAME", "${BASE_NAME}");
-            root.appendChild(ele);
-        }
-
-        //
-        // Parse AutoGen.c & AutoGen.h
-        //
-        if (!baseName.equalsIgnoreCase("Shell")) {
-            fileProcess.parseFile(getProject().getProperty("DEST_DIR_DEBUG") + File.separatorChar + "AutoGen.c", root,
-                                  false);
-        }
-        //
-        // Parse all source files
-        //
-        for (int i = 0; i < files.length; i++) {
-            String filetype = getFiletype(files[i]);
-            if (filetype != null) {
-                fileProcess.parseFile(getFilename(files[i]), filetype, root, false);
-            } else {
-                fileProcess.parseFile(getFilename(files[i]), root, false);
-            }
-        }
-        //
-        // root.appendChild(parallelEle);
-        //
-        Iterator iter = sourceFiles.iterator();
-        String str = "";
-        while (iter.hasNext()) {
-            str += " " + (String) iter.next();
-        }
-        getProject().setProperty("SOURCE_FILES", str);
-    }
-
-    /**
-      Generate the section elements for BaseName_build.xml. Library module will
-      skip this process.  
-      
-      @param document current BaseName_build.xml XML document
-      @param root Root element for current
-    **/
-    private void applySectionsElement(Document document, Node root, FfsProcess fp) {
-        if (fp.initSections(buildType, getProject())) {
-            String targetFilename = guid + "-" + baseName + FpdParserTask.getSuffix(componentType);
-            String[] list = fp.getGenSectionElements(document, baseName, guid, targetFilename);
-
-            for (int i = 0; i < list.length; i++) {
-                Element ele = document.createElement(list[i]);
-                ele.setAttribute("FILEPATH", ".");
-                ele.setAttribute("FILENAME", "${BASE_NAME}");
-                root.appendChild(ele);
-            }
-        }
-    }
-
-    /**
-      Generate the output elements for BaseName_build.xml. If module is library,
-      call the <em>LIB</em> command, else call the <em>GenFfs</em> command. 
-      
-      @param document current BaseName_build.xml XML document
-      @param root Root element for current
-    **/
-    private void applyOutputElement(Document document, Node root, FfsProcess fp) {
-        if (flag == GlobalData.ONLY_LIBMSA || flag == GlobalData.LIBMSA_AND_LIBMBD) {
-            //
-            // call Lib command
-            //
-            Element cc = document.createElement("Build_Library");
-            cc.setAttribute("FILENAME", baseName);
-            root.appendChild(cc);
-        }
-        //
-        // if it is a module but library
-        //
-        else {
-            if (fp.getFfsNode() != null) {
-                root.appendChild(fp.getFfsNode());
-            }
-        }
-    }
-
-    /**
-      Get file name from node. If some wrong, return string with zero length. 
-      
-       @param node Filename node of MSA/MBD or specified in each Section
-       @return File name
-    **/
-    private String getFilename(Node node) {
-        String path = null;
-        String filename = "${MODULE_DIR}" + File.separatorChar;
-        String str = "";
-        try {
-            FilenameDocument file = (FilenameDocument) XmlObject.Factory.parse(node);
-            str = file.getFilename().getStringValue().trim();
-            path = file.getFilename().getPath();
-        } catch (Exception e) {
-            str = "";
-        }
-        if (path != null) {
-            filename += path + File.separatorChar + str;
-        } else {
-            filename += str;
-        }
-        return getProject().replaceProperties(filename);
-    }
-
-    /**
-      Get file type from node. If some wrong or not specified, return 
-      <code>null</code>.  
-      
-      @param node Filename node of MSA/MBD or specified in each Section
-      @return File type
-    **/
-    private String getFiletype(Node node) {
-        String str = null;
-        try {
-            FilenameDocument file = (FilenameDocument) XmlObject.Factory.parse(node);
-            str = file.getFilename().getFileType();
-        } catch (Exception e) {
-            str = null;
-        }
-        return str;
-    }
-
-    /**
-      Return all source files but AutoGen.c.
-      
-      @return source files Node array
-    **/
-    public Node[] getSourceFiles() {
-        XmlObject[] files = SurfaceAreaQuery.getSourceFiles(arch);
-        if (files == null) {
-            return new Node[0];
-        }
-        Vector<Node> vector = new Vector<Node>();
-        for (int i = 0; i < files.length; i++) {
-            vector.addElement(files[i].getDomNode());
-        }
-        //
-        // To be consider sourcefiles from Sections
-        //
-        return vector.toArray(new Node[vector.size()]);
-    }
-
-    /**
-      Get current module's base name. 
-      
-      @return base name
-    **/
-    public String getBaseName() {
-        return baseName;
-    }
-
-    /**
-      Set MBD surface area file. For ANT use.
-      
-      @param mbdFilename Surface Area file
-    **/
-    public void setMbdFilename(File mbdFilename) {
-        this.mbdFilename = mbdFilename;
-    }
-
-    /**
-      Set MSA surface area file. For ANT use.
-      
-      @param msaFilename Surface Area file
-    **/
-    public void setMsaFilename(File msaFilename) {
-        this.msaFilename = msaFilename;
-    }
-
-    /**
-      Compile flags setup. 
-      
-      <p> Take command <code>CC</code> and arch <code>IA32</code> for example, 
-      Those flags are from <code>ToolChainFactory</code>: </p>
-      <ul>
-      <li> IA32_CC </li>
-      <li> IA32_CC_STD_FLAGS </li>
-      <li> IA32_CC_GLOBAL_FLAGS </li>
-      <li> IA32_CC_GLOBAL_ADD_FLAGS </li>
-      <li> IA32_CC_GLOBAL_SUB_FLAGS </li>
-      </ul>
-      Those flags can user-define: 
-      <ul>
-      <li> IA32_CC_PROJ_FLAGS </li>
-      <li> IA32_CC_PROJ_ADD_FLAGS </li>
-      <li> IA32_CC_PROJ_SUB_FLAGS </li>
-      <li> CC_PROJ_FLAGS </li>
-      <li> CC_PROJ_ADD_FLAGS </li>
-      <li> CC_PROJ_SUB_FLAGS </li>
-      <li> CC_FLAGS </li>
-      <li> IA32_CC_FLAGS </li>
-      </ul>
-      
-      <p> The final flags is composed of STD, GLOBAL and PROJ. If CC_FLAGS or
-      IA32_CC_FLAGS is specified, STD, GLOBAL and PROJ will not affect. </p>
-      
-      Note that the <code>ToolChainFactory</code> executes only once 
-      during whole build process. 
-    **/
-    private void flagsSetup() {
-        Project project = getProject();
-        //
-        // If ToolChain has been set up before, do nothing.
-        //
-        ToolChainFactory toolChainFactory = new ToolChainFactory(project);
-        toolChainFactory.setupToolChain();
-
-        String[] cmd = ToolChainFactory.commandType;
-        Set<String> addSet = new HashSet<String>(40);
-        Set<String> subSet = new HashSet<String>(40);
-        for (int i = 0; i < cmd.length; i++) {
-            String str = ToolChainFactory.getValue(arch + "_" + cmd[i]);
-            //
-            // Command line path+command name
-            //
-            if (str != null) {
-                project.setProperty(cmd[i], str);
-            }
-            //
-            // ARCH_CMD_STD_FLAGS
-            //
-            str = ToolChainFactory.getValue(arch + "_" + cmd[i] + "_STD_FLAGS");
-            if (str != null) {
-                putFlagsToSet(addSet, str);
-                project.setProperty(cmd[i] + "_STD_FLAGS", str);
-            }
-            //
-            // ARCH_CMD_GLOBAL_FLAGS
-            //
-            str = ToolChainFactory.getValue(arch + "_" + cmd[i] + "_GLOBAL_FLAGS");
-            if (str != null) {
-                putFlagsToSet(addSet, str);
-            }
-            //
-            // ARCH_CMD_GLOBAL_ADD_FLAGS
-            //
-            str = ToolChainFactory.getValue(arch + "_" + cmd[i] + "_GLOBAL_ADD_FLAGS");
-            if (str != null) {
-                putFlagsToSet(addSet, str);
-            }
-            //
-            // ARCH_CMD_GLOBAL_SUB_FLAGS
-            //
-            str = ToolChainFactory.getValue(arch + "_" + cmd[i] + "_GLOBAL_SUB_FLAGS");
-            if (str != null) {
-                putFlagsToSet(subSet, str);
-            }
-            //
-            // ARCH_CMD_PROJ_FLAGS
-            //
-            str = project.getProperty(arch + "_" + cmd[i] + "_PROJ_FLAGS");
-            if (str != null) {
-                putFlagsToSet(addSet, str);
-            }
-            //
-            // ARCH_CMD_PROG_FLAGS
-            //
-            str = project.getProperty(arch + "_" + cmd[i] + "_PROJ_ADD_FLAGS");
-            if (str != null) {
-                putFlagsToSet(addSet, str);
-            }
-            //
-            // ARCH_CMD_PROG_FLAGS
-            //
-            str = project.getProperty(arch + "_" + cmd[i] + "_PROJ_SUB_FLAGS");
-            if (str != null) {
-                putFlagsToSet(subSet, str);
-            }
-            //
-            // CMD_PROJ_FLAGS
-            //
-            str = project.getProperty(cmd[i] + "_PROJ_FLAGS");
-            if (str != null) {
-                putFlagsToSet(addSet, str);
-            }
-            //
-            // CMD_PROG_FLAGS
-            //
-            str = project.getProperty(cmd[i] + "_PROJ_ADD_FLAGS");
-            if (str != null) {
-                putFlagsToSet(addSet, str);
-            }
-            //
-            // CMD_PROG_FLAGS
-            //
-            str = project.getProperty(cmd[i] + "_PROJ_SUB_FLAGS");
-            if (str != null) {
-                putFlagsToSet(subSet, str);
-            }
-            //
-            // If IA32_CC_FLAGS or IA32_LIB_FLAGS .. has defined in BuildOptions
-            //
-            if ((str = project.getProperty(arch + "_" + cmd[i] + "_FLAGS")) != null) {
-                project.setProperty(cmd[i] + "_FLAGS", getRawFlags(addSet, subSet));
-                addSet.clear();
-                subSet.clear();
-                putFlagsToSet(addSet, project.replaceProperties(str));
-                project.setProperty(cmd[i] + "_FLAGS", project.replaceProperties(getFlags(addSet, subSet)));
-                addSet.clear();
-                subSet.clear();
-            }
-            //
-            // If CC_FLAGS or LIB_FLAGS .. has defined in BuildOptions
-            //
-            else if ((str = project.getProperty(cmd[i] + "_FLAGS")) != null) {
-                project.setProperty(cmd[i] + "_FLAGS", getRawFlags(addSet, subSet));
-                addSet.clear();
-                subSet.clear();
-                putFlagsToSet(addSet, project.replaceProperties(str));
-                project.setProperty(cmd[i] + "_FLAGS", project.replaceProperties(getFlags(addSet, subSet)));
-                addSet.clear();
-                subSet.clear();
-            } else {
-                project.setProperty(cmd[i] + "_FLAGS", getFlags(addSet, subSet));
-                addSet.clear();
-                subSet.clear();
-            }
-        }
-        project.setProperty("C_FLAGS", project.getProperty("CC_FLAGS"));
-    }
-
-    /**
-      Initialize some properties will be used in current module build, including
-      user-defined option from <em>Option</em> of <em>BuildOptions</em> in 
-      surface area. 
-    **/
-    private void updateParameters() {
-        getProject().setProperty("OBJECTS", "");
-        getProject().setProperty("SDB_FILES", "");
-        getProject().setProperty("BASE_NAME", baseName);
-        if (map.get("MsaHeader") != null) {
-            guid = SurfaceAreaQuery.getModuleGuid();//header.getGuid().getStringValue();
-            componentType = SurfaceAreaQuery.getComponentType();//header.getComponentType().toString();
-            if (!componentType.equalsIgnoreCase("LIBRARY")) {
-                flag = GlobalData.MSA_AND_MBD;
-            } else {
-                flag = GlobalData.LIBMSA_AND_LIBMBD;
-            }
-        } 
-        
-        else if (map.get("MsaLibHeader") != null) {
-            flag = GlobalData.LIBMSA_AND_LIBMBD;
-            MsaLibHeaderDocument.MsaLibHeader header = ((MsaLibHeaderDocument) map.get("MsaLibHeader"))
-                                                                                                       .getMsaLibHeader();
-            guid = header.getGuid().getStringValue();
-            componentType = header.getComponentType().toString();
+        if (moduleId.getModuleType().equalsIgnoreCase("USER_DEFINED")) {
+            GlobalData.log.info("Call user-defined " + moduleId.getName() + "_build.xml");
+            Ant ant = new Ant();
+            ant.setProject(getProject());
+            ant.setAntfile(getProject().getProperty("MODULE_DIR") + File.separatorChar + moduleId.getName() + "_build.xml");
+            ant.setTarget("cleanall");
+            ant.setInheritAll(true);
+            ant.init();
+            ant.execute();
+            return ;
         }
         
-        if (componentType != null) {
-            getProject().setProperty("COMPONENT_TYPE", componentType);
-        }
-
-        if (guid != null) {
-            getProject().setProperty("FILE_GUID", guid);
-        }
+        Ant ant = new Ant();
+        ant.setProject(getProject());
+        ant.setAntfile(getProject().getProperty("DEST_DIR_OUTPUT") + File.separatorChar + moduleId.getName() + "_build.xml");
+        ant.setTarget("cleanall");
+        ant.setInheritAll(true);
+        ant.init();
+        ant.execute();
+        
         //
-        // Get all options and set to properties
-        //
-        String[][] options = SurfaceAreaQuery.getOptions(arch);
-        for (int i = 0; i < options.length; i++) {
-            if (options[i][0] != null && options[i][1] != null) {
-                getProject().setProperty(options[i][0], getProject().replaceProperties(options[i][1]));
-            }
-        }
-
-        buildType = getProject().getProperty("BUILD_TYPE");
-        if (buildType == null) {
-            buildType = componentType;
-        }
-
+        // Delete current module's DEST_DIR_OUTPUT
+        // TBD
     }
 
+
+
+
     /**
       Separate the string and instore in set.
        
@@ -1130,13 +658,15 @@ public class GenBuildTask extends Task {
       @param str string to separate
     **/
     private void putFlagsToSet(Set<String> set, String str) {
+        if (str == null || str.length() == 0) {
+            return;
+        }
+
         Pattern myPattern = Pattern.compile("[^\\\\]?(\".*?[^\\\\]\")[ \t,]+");
         Matcher matcher = myPattern.matcher(str + " ");
         while (matcher.find()) {
             String item = str.substring(matcher.start(1), matcher.end(1));
-            if (!set.contains(item)) {
-                set.add(item);
-            }
+            set.add(item);
         }
     }
     
@@ -1152,7 +682,7 @@ public class GenBuildTask extends Task {
         add.removeAll(sub);
         Iterator iter = add.iterator();
         while (iter.hasNext()) {
-            String str = getProject().replaceProperties((String) iter.next());
+            String str = (String) iter.next();
             result += str.substring(1, str.length() - 1) + " ";
         }
         return result;
@@ -1174,23 +704,55 @@ public class GenBuildTask extends Task {
       @return flags with original format
     **/
     private String getRawFlags(Set<String> add, Set<String> sub) {
-        String result = "";
+        String result = null;
         add.removeAll(sub);
         Iterator iter = add.iterator();
         while (iter.hasNext()) {
-            String str = getProject().replaceProperties((String) iter.next());
+            String str = (String) iter.next();
             result += "\"" + str.substring(1, str.length() - 1) + "\", ";
         }
         return result;
     }
 
-    /**
-      Set base name. For ANT use.
-      
-      @param baseName Base name
-    **/
-    public void setBaseName(String baseName) {
-        this.baseName = baseName;
-    }
+    private String parseOptionString(String optionString, Set<String> addSet, Set<String> subSet) {
+        boolean overrideOption = false;
+        Pattern pattern = Pattern.compile("ADD\\.\\[(.+)\\]");
+        Matcher matcher = pattern.matcher(optionString);
 
+        while (matcher.find()) {
+            overrideOption = true;
+            String addOption = optionString.substring(matcher.start(1), matcher.end(1)).trim();
+            putFlagsToSet(addSet, addOption);
+            
+        }
+
+        pattern = Pattern.compile("SUB\\.\\[(.+)\\]");
+        matcher = pattern.matcher(optionString);
+
+        while (matcher.find()) {
+            overrideOption = true;
+            String subOption = optionString.substring(matcher.start(1), matcher.end(1)).trim();
+            putFlagsToSet(subSet, subOption);
+        }
+
+        if (overrideOption == true) {
+            return null;
+        }
+
+        return optionString;
+    }
+    
+    private void pushProperties() {
+        backupPropertiesStack.push(getProject().getProperties());
+    }
+    
+    private void popProperties() {
+        Hashtable backupProperties = backupPropertiesStack.pop();
+        Set keys = backupProperties.keySet();
+        Iterator iter = keys.iterator();
+        while (iter.hasNext()) {
+            String item = (String)iter.next();
+            getProject().setProperty(item, (String)backupProperties.get(item));
+        }
+    }
 }
diff --git a/Tools/Source/GenBuild/org/tianocore/build/ModuleBuildFileGenerator.java b/Tools/Source/GenBuild/org/tianocore/build/ModuleBuildFileGenerator.java
new file mode 100644
index 0000000000..4c6843e6b2
--- /dev/null
+++ b/Tools/Source/GenBuild/org/tianocore/build/ModuleBuildFileGenerator.java
@@ -0,0 +1,591 @@
+/** @file
+ 
+ Copyright (c) 2006, Intel Corporation
+ All rights reserved. This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution.  The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+ **/
+package org.tianocore.build;
+
+import java.io.File;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.Map;
+import java.util.Set;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Result;
+import javax.xml.transform.Source;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.tianocore.build.fpd.FpdParserTask;
+import org.tianocore.build.global.GlobalData;
+import org.tianocore.build.global.SurfaceAreaQuery;
+import org.tianocore.build.id.FpdModuleIdentification;
+import org.tianocore.build.id.ModuleIdentification;
+import org.tianocore.build.id.PackageIdentification;
+import org.w3c.dom.Comment;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+public class ModuleBuildFileGenerator {
+
+    ///
+    /// Pass: TARGET, TOOLCHAIN, ARCH
+    /// PACKAGE, PACKAGE_GUID, PACKAGE_VERSION
+    ///
+    String[] inheritProperties = {"ARCH", "MODULE_GUID", "MODULE_VERSION", "PLATFORM", "PACKAGE_GUID", "PACKAGE_VERSION"};
+
+    ///
+    /// The information at the header of <em>build.xml</em>.
+    ///
+    private String info = "DO NOT EDIT \n"
+                        + "File auto-generated by build utility\n"
+                        + "\n"
+                        + "Abstract:\n"
+                        + "Auto-generated ANT build file for building of EFI Modules/Platforms\n";
+
+    private FpdModuleIdentification fpdModuleId;
+    
+    private Project project;
+    
+    private String ffsKeyword;
+    
+    public ModuleBuildFileGenerator(Project project, String ffsKeyword, FpdModuleIdentification fpdModuleId) {
+        this.project = project;
+        this.fpdModuleId = fpdModuleId;
+        this.ffsKeyword = ffsKeyword;
+    }
+    
+    /**
+      The whole BaseName_build.xml is composed of seven part. 
+      <ul>
+      <li> ANT properties; </li>
+      <li> Dependent module (dependent library instances in most case); </li>
+      <li> Source files; </li>
+      <li> Sections if module is not library; </li>
+      <li> Output (different for library module and driver module); </li>
+      <li> Clean; </li>
+      <li> Clean all. </li>
+      </ul>
+      
+      @throws BuildException
+              Error throws during BaseName_build.xml generating. 
+    **/
+    public void genBuildFile(String buildFilename) throws BuildException {
+        FfsProcess fp = new FfsProcess();
+        DocumentBuilderFactory domfac = DocumentBuilderFactory.newInstance();
+        try {
+            DocumentBuilder dombuilder = domfac.newDocumentBuilder();
+            Document document = dombuilder.newDocument();
+            Comment rootComment = document.createComment(info);
+            
+            //
+            // create root element and its attributes
+            //
+            Element root = document.createElement("project");
+            root.setAttribute("name", fpdModuleId.getModule().getName());
+            root.setAttribute("default", "all");
+            root.setAttribute("basedir", ".");
+            
+            //
+            // element for External ANT tasks
+            //
+            root.appendChild(document.createComment("Apply external ANT tasks"));
+            Element ele = document.createElement("taskdef");
+            ele.setAttribute("resource", "frameworktasks.tasks");
+            root.appendChild(ele);
+            ele = document.createElement("taskdef");
+            ele.setAttribute("resource", "cpptasks.tasks");
+            root.appendChild(ele);
+            ele = document.createElement("typedef");
+            ele.setAttribute("resource", "cpptasks.types");
+            root.appendChild(ele);
+            ele = document.createElement("taskdef");
+            ele.setAttribute("resource", "net/sf/antcontrib/antlib.xml");
+            root.appendChild(ele);
+
+            //
+            // Generate the default target,
+            // which depends on init, sections and output target
+            //
+            root.appendChild(document.createComment("Default target"));
+            ele = document.createElement("target");
+            ele.setAttribute("name", "all");
+            ele.setAttribute("depends", "libraries, sourcefiles, sections, output");
+            root.appendChild(ele);
+            
+            //
+            // compile all source files
+            //
+            root.appendChild(document.createComment("Compile all dependency Library instances."));
+            ele = document.createElement("target");
+            ele.setAttribute("name", "libraries");
+
+            //
+            // Parse all sourfiles but files specified in sections
+            //
+            applyLibraryInstance(document, ele);
+            root.appendChild(ele);
+
+            //
+            // compile all source files
+            //
+            root.appendChild(document.createComment("sourcefiles target"));
+            ele = document.createElement("target");
+            ele.setAttribute("name", "sourcefiles");
+            
+            //
+            // Parse all sourfiles but files specified in sections
+            //
+            applyCompileElement(document, ele);
+            root.appendChild(ele);
+
+            //
+            // generate the init target
+            // main purpose is create all nessary pathes
+            // generate the sections target
+            //
+            root.appendChild(document.createComment("sections target"));
+            ele = document.createElement("target");
+            ele.setAttribute("name", "sections");
+            applySectionsElement(document, ele, fp);
+            root.appendChild(ele);
+
+            //
+            // generate the output target
+            //
+            root.appendChild(document.createComment("output target"));
+            ele = document.createElement("target");
+            ele.setAttribute("name", "output");
+            applyOutputElement(document, ele, fp);
+            root.appendChild(ele);
+
+            
+            //
+            // generate the clean target
+            //
+            root.appendChild(document.createComment("clean target"));
+            ele = document.createElement("target");
+            ele.setAttribute("name", "clean");
+            applyCleanElement(document, ele);
+            root.appendChild(ele);
+            
+            //
+            // generate the Clean All target
+            //
+            root.appendChild(document.createComment("Clean All target"));
+            ele = document.createElement("target");
+            ele.setAttribute("name", "cleanall");
+            applyDeepcleanElement(document, ele);
+            root.appendChild(ele);
+            
+            //
+            // add the root element to the document
+            //
+            document.appendChild(rootComment);
+            document.appendChild(root);
+            //
+            // Prepare the DOM document for writing
+            //
+            Source source = new DOMSource(document);
+
+            //
+            // Prepare the output file
+            //
+            File file = new File(buildFilename);
+
+            //
+            // generate all directory path
+            //
+            (new File(file.getParent())).mkdirs();
+            Result result = new StreamResult(file);
+            
+            //
+            // Write the DOM document to the file
+            //
+            Transformer xformer = TransformerFactory.newInstance().newTransformer();
+            xformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
+            xformer.setOutputProperty(OutputKeys.INDENT, "yes");
+            xformer.transform(source, result);
+        } catch (Exception ex) {
+            ex.printStackTrace();
+            throw new BuildException("Module [" + fpdModuleId.getModule().getName() + "] generating build file failed.\n" + ex.getMessage());
+        }
+    }
+
+    /**
+      Generate the clean elements for BaseName_build.xml. 
+      
+      @param document current BaseName_build.xml XML document
+      @param root Root element for current
+    **/
+    private void applyCleanElement(Document document, Node root) {
+        ModuleIdentification[] libinstances = SurfaceAreaQuery.getLibraryInstance(fpdModuleId.getArch());
+        for (int i = 0; i < libinstances.length; i++) {
+            //
+            // Put package file path to module identification
+            //
+            PackageIdentification packageId = libinstances[i].getPackage();
+            
+            //
+            // Generate ANT script to clean
+            //
+            Element ele = document.createElement("GenBuild");
+            ele.setAttribute("type", "clean");
+            
+            //
+            // Prepare pass down information
+            //
+            Map<String, String> passDownMap = new LinkedHashMap<String, String>();
+            for (int j = 0; j < inheritProperties.length; j ++){
+                passDownMap.put(inheritProperties[j], "${" + inheritProperties[j] + "}");
+            }
+            passDownMap.put("MODULE_GUID", libinstances[i].getGuid());
+            passDownMap.put("MODULE_VERSION", libinstances[i].getVersion());
+            
+            passDownMap.put("PACKAGE_GUID", packageId.getGuid());
+            passDownMap.put("PACKAGE_VERSION", packageId.getVersion());
+            
+            for (int j = 0; j < inheritProperties.length; j ++){
+                Element property = document.createElement("property");
+                property.setAttribute("name", inheritProperties[j]);
+                property.setAttribute("value", passDownMap.get(inheritProperties[j]));
+                ele.appendChild(property);
+            }
+
+            root.appendChild(ele);
+        }
+        //
+        // <delete includeemptydirs="true">
+        //   <fileset dir="${DEST_DIR_OUTPUT}" includes="" excludes="" />
+        // </delete>
+        //
+        Element deleteEle = document.createElement("delete");
+        deleteEle.setAttribute("includeemptydirs", "true");
+        Element filesetEle = document.createElement("fileset");
+        filesetEle.setAttribute("dir", "${DEST_DIR_OUTPUT}");
+        filesetEle.setAttribute("includes", "**/*");
+        filesetEle.setAttribute("excludes", "*.xml");
+        deleteEle.appendChild(filesetEle);
+        root.appendChild(deleteEle);
+    }
+
+    /**
+      Generate the cleanall elements for BaseName_build.xml. 
+      
+      @param document current BaseName_build.xml XML document
+      @param root Root element for current
+    **/
+    private void applyDeepcleanElement(Document document, Node root) {
+        ModuleIdentification[] libinstances = SurfaceAreaQuery.getLibraryInstance(fpdModuleId.getArch());
+        for (int i = 0; i < libinstances.length; i++) {
+            //
+            // Put package file path to module identification
+            //
+            PackageIdentification packageId = libinstances[i].getPackage();
+            
+            //
+            // Generate ANT script to clean
+            //
+            Element ele = document.createElement("GenBuild");
+            ele.setAttribute("type", "cleanall");
+            
+            //
+            // Prepare pass down information
+            //
+            Map<String, String> passDownMap = new LinkedHashMap<String, String>();
+            for (int j = 0; j < inheritProperties.length; j ++){
+                passDownMap.put(inheritProperties[j], "${" + inheritProperties[j] + "}");
+            }
+            
+            passDownMap.put("MODULE_GUID", libinstances[i].getGuid());
+            passDownMap.put("MODULE_VERSION", libinstances[i].getVersion());
+            
+            passDownMap.put("PACKAGE_GUID", packageId.getGuid());
+            passDownMap.put("PACKAGE_VERSION", packageId.getVersion());
+            
+            for (int j = 0; j < inheritProperties.length; j ++){
+                Element property = document.createElement("property");
+                property.setAttribute("name", inheritProperties[j]);
+                property.setAttribute("value", passDownMap.get(inheritProperties[j]));
+                ele.appendChild(property);
+            }
+
+            root.appendChild(ele);
+        }
+        //
+        // <delete includeemptydirs="true">
+        //   <fileset dir="${DEST_DIR_OUTPUT}" includes="" excludes="" />
+        // </delete>
+        //
+        Element deleteEle = document.createElement("delete");
+        deleteEle.setAttribute("includeemptydirs", "true");
+        Element filesetEle = document.createElement("fileset");
+        filesetEle.setAttribute("dir", "${DEST_DIR_OUTPUT}");
+        filesetEle.setAttribute("includes", "**/*");
+        filesetEle.setAttribute("excludes", "*.xml");
+        deleteEle.appendChild(filesetEle);
+        root.appendChild(deleteEle);
+        
+        //
+        // <delete includeemptydirs="true">
+        //   <fileset dir="${DEST_DIR_DEBUG}" includes="" />
+        // </delete>
+        //
+        deleteEle = document.createElement("delete");
+        deleteEle.setAttribute("includeemptydirs", "true");
+        filesetEle = document.createElement("fileset");
+        filesetEle.setAttribute("dir", "${DEST_DIR_DEBUG}");
+        filesetEle.setAttribute("includes", "**/*");
+        deleteEle.appendChild(filesetEle);
+        root.appendChild(deleteEle);
+    }
+
+    /**
+      Generate the dependent library instances elements for BaseName_build.xml. 
+      
+      @param document current BaseName_build.xml XML document
+      @param root Root element for current
+    **/
+    private void applyLibraryInstance(Document document, Node root) {
+        ModuleIdentification[] libinstances = SurfaceAreaQuery.getLibraryInstance(fpdModuleId.getArch());
+//        String propertyLibs = "";
+        for (int i = 0; i < libinstances.length; i++) {
+            //
+            // Put package file path to module identification
+            //
+            PackageIdentification packageId = libinstances[i].getPackage();
+            
+            //
+            // Generate ANT script to build library instances
+            //
+            Element ele = document.createElement("GenBuild");
+            ele.setAttribute("type", "build");
+//            ele.setAttribute("inheritAll", "false");
+            
+            //
+            // Prepare pass down information
+            //
+            Map<String, String> passDownMap = new LinkedHashMap<String, String>();
+            for (int j = 0; j < inheritProperties.length; j ++){
+                passDownMap.put(inheritProperties[j], "${" + inheritProperties[j] + "}");
+            }
+            
+            passDownMap.put("MODULE_GUID", libinstances[i].getGuid());
+            passDownMap.put("MODULE_VERSION", libinstances[i].getVersion());
+            
+            passDownMap.put("PACKAGE_GUID", packageId.getGuid());
+            passDownMap.put("PACKAGE_VERSION", packageId.getVersion());
+            
+            for (int j = 0; j < inheritProperties.length; j ++){
+                Element property = document.createElement("property");
+                property.setAttribute("name", inheritProperties[j]);
+                property.setAttribute("value", passDownMap.get(inheritProperties[j]));
+                ele.appendChild(property);
+            }
+            
+            root.appendChild(ele);
+//            propertyLibs += " " + project.getProperty("BIN_DIR") + File.separatorChar + libinstances[i].getName() + ".lib";
+        }
+//        project.setProperty("LIBS", propertyLibs.replaceAll("(\\\\)", "/"));
+    }
+    
+    /**
+      Generate the build source files elements for BaseName_build.xml. 
+      
+      @param document current BaseName_build.xml XML document
+      @param root Root element for current
+    **/
+    private void applyCompileElement(Document document, Node root) {
+        //
+        // Prepare the includes: PackageDependencies and Output debug direactory
+        //
+        Set<String> includes = new LinkedHashSet<String>();
+        
+        //
+        // WORKSPACE
+        //
+        includes.add("${WORKSPACE_DIR}");
+        
+        //
+        // Module iteself
+        //
+        includes.add("${MODULE_DIR}");
+        includes.add("${MODULE_DIR}" + File.separatorChar + "${ARCH}");
+        
+        //
+        // Packages in PackageDenpendencies
+        //
+        PackageIdentification[] packageDependencies = SurfaceAreaQuery.getDependencePkg(fpdModuleId.getArch());
+        for (int i = 0; i < packageDependencies.length; i++) {
+            GlobalData.refreshPackageIdentification(packageDependencies[i]);
+            File packageFile = packageDependencies[i].getSpdFile();
+            includes.add(packageFile.getParent() + File.separatorChar + "Include");
+            includes.add(packageFile.getParent() + File.separatorChar + "Include" + File.separatorChar + "${ARCH}");
+        }
+
+        //
+        // All Dependency Library Instance's PackageDependencies
+        //
+        ModuleIdentification[] libinstances = SurfaceAreaQuery.getLibraryInstance(fpdModuleId.getArch());
+        for (int i = 0; i < libinstances.length; i++) {
+            SurfaceAreaQuery.push(GlobalData.getDoc(libinstances[i], fpdModuleId.getArch()));
+            PackageIdentification[] libraryPackageDependencies = SurfaceAreaQuery.getDependencePkg(fpdModuleId.getArch());
+            for (int j = 0; j < libraryPackageDependencies.length; j++) {
+                GlobalData.refreshPackageIdentification(libraryPackageDependencies[j]);
+                File packageFile = libraryPackageDependencies[j].getSpdFile();
+                includes.add(packageFile.getParent() + File.separatorChar + "Include");
+                includes.add(packageFile.getParent() + File.separatorChar + "Include" + File.separatorChar + "${ARCH}");
+            }
+            SurfaceAreaQuery.pop();
+        }
+        
+        
+        //
+        // The package which the module belongs to
+        // TBD
+        includes.add(fpdModuleId.getModule().getPackage().getPackageDir() + File.separatorChar + "Include");
+        includes.add(fpdModuleId.getModule().getPackage().getPackageDir() + File.separatorChar + "Include" + File.separatorChar + "${ARCH}");
+
+        //
+        // Debug files output directory
+        //
+        includes.add("${DEST_DIR_DEBUG}");
+        
+        //
+        // sourceFiles[][0] is FileType, [][1] is File name relative to Module_Dir
+        //
+        String[][] sourceFiles = SurfaceAreaQuery.getSourceFiles(fpdModuleId.getArch());
+
+        FileProcess fileProcess = new FileProcess();
+        fileProcess.init(project, includes, document);
+
+        String moduleDir = project.getProperty("MODULE_DIR");
+        //
+        // Parse all Unicode files
+        //
+        for (int i = 0; i < sourceFiles.length; i++) {
+            //
+            // Go through all source files. Add MODULE_DIR to preffix
+            //
+            File sourceFile =  new File(moduleDir + File.separatorChar + sourceFiles[i][1]);
+            sourceFiles[i][1] = sourceFile.getPath();
+            String filetype = sourceFiles[i][0];
+            if (filetype != null) {
+                fileProcess.parseFile(sourceFiles[i][1], filetype, root, true);
+            } else {
+                fileProcess.parseFile(sourceFiles[i][1], root, true);
+            }
+        }
+        
+        //
+        // If exist Unicode file
+        //
+        if (fileProcess.isUnicodeExist()) {
+            Element ele = document.createElement("Build_Unicode_Database");
+            ele.setAttribute("FILEPATH", ".");
+            ele.setAttribute("FILENAME", "${BASE_NAME}");
+            String[] includePaths = includes.toArray(new String[includes.size()]);
+            Element includesEle = document.createElement("EXTRA.INC");
+            for (int i = 0; i < includePaths.length; i++) {
+                Element includeEle = document.createElement("includepath");
+                includeEle.setAttribute("path", includePaths[i]);
+                includesEle.appendChild(includeEle);
+            }
+            ele.appendChild(includesEle);
+            root.appendChild(ele);
+        }
+
+        //
+        // Parse AutoGen.c & AutoGen.h
+        //
+        if ( ! fpdModuleId.getModule().getName().equalsIgnoreCase("Shell")) {
+            fileProcess.parseFile(project.getProperty("DEST_DIR_DEBUG") + File.separatorChar + "AutoGen.c", root, false);
+        }
+        
+        //
+        // Parse all source files but Unicode files
+        //
+        for (int i = 0; i < sourceFiles.length; i++) {
+            String filetype = sourceFiles[i][0];
+            if (filetype != null) {
+                fileProcess.parseFile(sourceFiles[i][1], filetype, root, false);
+            } else {
+                fileProcess.parseFile(sourceFiles[i][1], root, false);
+            }
+        }
+        
+        //
+        // Initialize SOURCE_FILES for dependcy check use
+        //
+        String str = "";
+        for (int i = 0; i < sourceFiles.length; i++) {
+            str += " " + sourceFiles[i][1];
+        }
+        project.setProperty("SOURCE_FILES", str.replaceAll("(\\\\)", "/"));
+    }
+
+    /**
+      Generate the section elements for BaseName_build.xml. Library module will
+      skip this process.  
+      
+      @param document current BaseName_build.xml XML document
+      @param root Root element for current
+    **/
+    private void applySectionsElement(Document document, Node root, FfsProcess fp) {
+        if (fpdModuleId.getModule().isLibrary()) {
+            return ;
+        }
+        if (fp.initSections(ffsKeyword, project, fpdModuleId)) {
+            String targetFilename = fpdModuleId.getModule().getGuid() + "-" + fpdModuleId.getModule().getName() + FpdParserTask.getSuffix(fpdModuleId.getModule().getModuleType());
+            String[] list = fp.getGenSectionElements(document, "${BASE_NAME}", fpdModuleId.getModule().getGuid(), targetFilename);
+
+            for (int i = 0; i < list.length; i++) {
+                Element ele = document.createElement(list[i]);
+                ele.setAttribute("FILEPATH", ".");
+                ele.setAttribute("FILENAME", "${BASE_NAME}");
+                root.appendChild(ele);
+            }
+        }
+    }
+
+    /**
+      Generate the output elements for BaseName_build.xml. If module is library,
+      call the <em>LIB</em> command, else call the <em>GenFfs</em> command. 
+      
+      @param document current BaseName_build.xml XML document
+      @param root Root element for current
+    **/
+    private void applyOutputElement(Document document, Node root, FfsProcess fp) {
+        if (fpdModuleId.getModule().isLibrary()) {
+            //
+            // call Lib command
+            //
+            Element cc = document.createElement("Build_Library");
+            cc.setAttribute("FILENAME", fpdModuleId.getModule().getName());
+            root.appendChild(cc);
+        }
+        //
+        // if it is a module but library
+        //
+        else {
+            if (fp.getFfsNode() != null) {
+                root.appendChild(fp.getFfsNode());
+            }
+        }
+    }
+
+}
diff --git a/Tools/Source/GenBuild/org/tianocore/build/OutputDirSetup.java b/Tools/Source/GenBuild/org/tianocore/build/OutputDirSetup.java
new file mode 100644
index 0000000000..6a53fa6dbb
--- /dev/null
+++ b/Tools/Source/GenBuild/org/tianocore/build/OutputDirSetup.java
@@ -0,0 +1,271 @@
+package org.tianocore.build;
+
+import java.io.File;
+import java.util.Map;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Task;
+import org.apache.xmlbeans.XmlObject;
+import org.tianocore.build.fpd.FpdParserTask;
+import org.tianocore.build.global.GlobalData;
+import org.tianocore.build.global.OutputManager;
+import org.tianocore.build.global.SurfaceAreaQuery;
+import org.tianocore.build.id.FpdModuleIdentification;
+import org.tianocore.build.id.ModuleIdentification;
+import org.tianocore.build.id.PackageIdentification;
+import org.tianocore.build.id.PlatformIdentification;
+
+public class OutputDirSetup extends Task {
+    ///
+    /// Module surface area file.
+    ///
+    File msaFile;
+
+    ///
+    /// Module's Identification.
+    ///
+    private ModuleIdentification moduleId;
+    
+    ///
+    /// Module's component type, such as SEC, LIBRARY, BS_DRIVER and so on.
+    ///
+    private String componentType;
+    
+//    private ToolChainFactory toolChainFactory;
+    
+    /**
+      Public construct method. It is necessary for ANT task.
+    **/
+    public OutputDirSetup() {
+    }
+  
+    public void execute() throws BuildException {
+        //
+        // Global Data initialization
+        //
+//        GlobalData.initInfo("Tools" + File.separatorChar + "Conf" + File.separatorChar + "FrameworkDatabase.db",
+//                            getProject().getProperty("WORKSPACE_DIR"));
+      
+        //
+        // Parse MSA and get the basic information
+        // Including BaseName, GUID, Version, ComponentType and SupportedArchs
+        //
+        Map<String, XmlObject> doc = GlobalData.getNativeMsa(msaFile);
+        
+        SurfaceAreaQuery.setDoc(doc);
+      
+        //
+        // String[]: {BaseName, ModuleType, ComponentType, Guid, Version}
+        //
+        moduleId = SurfaceAreaQuery.getMsaHeader();
+        // REMOVE!!! TBD
+        componentType = "APPLICATION";
+      
+        //
+        // Judge whether it is single module build or not
+        //
+        if (getProject().getProperty("PLATFORM") == null) {
+            //
+            // Single Module build
+            //
+            prepareSingleModuleBuild();
+        }
+        else {
+            //
+            // Platform build
+            //
+            String platformName = getProject().getProperty("PLATFORM");
+            PlatformIdentification platformId = GlobalData.getPlatform(platformName);
+            getProject().setProperty("PLATFORM_DIR", platformId.getFpdFile().getParent().replaceAll("(\\\\)", "/"));
+            getProject().setProperty("PLATFORM_RELATIVE_DIR", platformId.getPlatformRelativeDir().replaceAll("(\\\\)", "/"));
+          
+            String packageName = getProject().getProperty("PACKAGE");
+            String packageGuid = getProject().getProperty("PACKAGE_GUID");
+            String packageVersion = getProject().getProperty("PACKAGE_VERSION");
+            PackageIdentification packageId = new PackageIdentification(packageName, packageGuid, packageVersion);
+            moduleId.setPackage(packageId);
+        }
+        
+        //
+        // Tools Definition file parse
+        //
+        parseToolsDefinitionFile();
+        
+        //
+        // For Every TOOLCHAIN, TARGET, ARCH
+        //
+//        String[] targetList = GlobalData.getTargets();
+//        for (int i = 0; i < targetList.length; i ++){
+//            //
+//            // Prepare for target related common properties
+//            // TARGET
+//            //
+//            getProject().setProperty("TARGET", targetList[i]);
+//            String[] toolchainList = GlobalData.getToolChains();
+//            for(int j = 0; j < toolchainList.length; j ++){
+//                //
+//                // Prepare for toolchain related common properties
+//                // TOOLCHAIN
+//                //
+//                getProject().setProperty("TOOLCHAIN", toolchainList[j]);
+//                //
+//                // If single module : intersection MSA supported ARCHs and tools def!!
+//                // else, get arch from pass down
+//                //
+//                String[] archList = GlobalData.getArchs();
+//                for (int k = 0; k < archList.length; k++) {
+//                    
+//                    FpdModuleIdentification fpdModuleId = new FpdModuleIdentification(moduleId, archList[k]);
+//                    
+//                    SurfaceAreaQuery.setDoc(GlobalData.getDoc(fpdModuleId));
+//                    
+//                    //
+//                    // Prepare for all other common properties
+//                    // PACKAGE, PACKAGE_GUID, PACKAGE_VERSION, PACKAGE_DIR, PACKAGE_RELATIVE_DIR
+//                    // MODULE or BASE_NAME, GUID or FILE_GUID, VERSION, COMPONENT_TYPE
+//                    // MODULE_DIR, MODULE_RELATIVE_DIR
+//                    // SUBSYSTEM, ENTRYPOINT, EBC_TOOL_LIB_PATH
+//                    // LIBS, OBJECTS, SDB_FILES
+//                    //
+//                    getProject().setProperty("ARCH", archList[k]);
+//                    setModuleCommonProperties();
+//        
+//                    //
+//                    // String[0] is build mode. String[1] is user-defined output dir. 
+//                    //
+//                    String buildMode = SurfaceAreaQuery.getFpdIntermediateDirectories();
+//                    String userDefinedOutputDir = SurfaceAreaQuery.getFpdOutputDirectory();
+//                    
+//                    //
+//                    // OutputManage prepare for 
+//                    // BIN_DIR, DEST_DIR_DEBUG, DEST_DIR_OUTPUT, BUILD_DIR, FV_DIR
+//                    //
+//                    OutputManager.getInstance().update(getProject(), userDefinedOutputDir, buildMode);
+//                    
+//                }
+//            }
+//        }
+        
+    }
+    
+    private void prepareSingleModuleBuild(){
+        //
+        // Find out the package which the module belongs to
+        // TBD: Enhance it!!!!
+        //
+        PackageIdentification packageId = GlobalData.getPackageForModule(moduleId);
+        
+        moduleId.setPackage(packageId);
+        
+        //
+        // Read ACTIVE_PLATFORM's FPD file (Call FpdParserTask's method)
+        //
+        String activePlatformName = getProject().getProperty("env.ACTIVE_PLATFORM");
+        
+        PlatformIdentification platformId = GlobalData.getPlatform(activePlatformName);
+        
+        //
+        // Read FPD file
+        //
+        FpdParserTask fpdParser = new FpdParserTask();
+        fpdParser.parseFpdFile(platformId.getFpdFile());
+        
+        //
+        // Prepare for Platform related common properties
+        // PLATFORM, PLATFORM_DIR, PLATFORM_RELATIVE_DIR
+        //
+        getProject().setProperty("PLATFORM", activePlatformName);
+        getProject().setProperty("PLATFORM_DIR", platformId.getFpdFile().getParent().replaceAll("(\\\\)", "/"));
+        getProject().setProperty("PLATFORM_RELATIVE_DIR", platformId.getPlatformRelativeDir().replaceAll("(\\\\)", "/"));
+    }
+    
+
+
+    /**
+
+    **/
+    private void setModuleCommonProperties() {
+        //
+        // Prepare for all other common properties
+        // PACKAGE, PACKAGE_GUID, PACKAGE_VERSION, PACKAGE_DIR, PACKAGE_RELATIVE_DIR
+        //
+        PackageIdentification packageId = moduleId.getPackage();
+        getProject().setProperty("PACKAGE", packageId.getName());
+        getProject().setProperty("PACKAGE_GUID", packageId.getGuid());
+        getProject().setProperty("PACKAGE_VERSION", packageId.getVersion());
+        GlobalData.log.info("" + packageId);
+        getProject().setProperty("PACKAGE_DIR", packageId.getPackageDir().replaceAll("(\\\\)", "/"));
+        getProject().setProperty("PACKAGE_RELATIVE_DIR", packageId.getPackageRelativeDir().replaceAll("(\\\\)", "/"));
+        
+        //
+        // MODULE or BASE_NAME, GUID or FILE_GUID, VERSION, COMPONENT_TYPE
+        // MODULE_DIR, MODULE_RELATIVE_DIR
+        //
+        getProject().setProperty("MODULE", moduleId.getName());
+        getProject().setProperty("BASE_NAME", moduleId.getName());
+        getProject().setProperty("GUID", moduleId.getGuid());
+        getProject().setProperty("FILE_GUID", moduleId.getGuid());
+        getProject().setProperty("VERSION", moduleId.getVersion());
+        getProject().setProperty("COMPONENT_TYPE", componentType);
+        getProject().setProperty("MODULE_DIR", moduleId.getMsaFile().getParent().replaceAll("(\\\\)", "/"));
+        getProject().setProperty("MODULE_RELATIVE_DIR", moduleId.getModuleRelativePath().replaceAll("(\\\\)", "/"));
+    }
+    
+
+    /**
+      Method is for ANT use to initialize MSA file.
+      
+      @param msaFilename MSA file name
+    **/
+    public void setMsaFile(String msaFilename) {
+        String moduleDir = getProject().getProperty("MODULE_DIR");
+        if (moduleDir == null) {
+            moduleDir = getProject().getBaseDir().getPath();
+        }
+        msaFile = new File(moduleDir + File.separatorChar + msaFilename);
+    }
+
+    /**
+      Compile flags setup. 
+      
+      <p> Take command <code>CC</code> and arch <code>IA32</code> for example, 
+      Those flags are from <code>ToolChainFactory</code>: </p>
+      <ul>
+      <li> IA32_CC </li>
+      <li> IA32_CC_STD_FLAGS </li>
+      <li> IA32_CC_GLOBAL_FLAGS </li>
+      <li> IA32_CC_GLOBAL_ADD_FLAGS </li>
+      <li> IA32_CC_GLOBAL_SUB_FLAGS </li>
+      </ul>
+      Those flags can user-define: 
+      <ul>
+      <li> IA32_CC_PROJ_FLAGS </li>
+      <li> IA32_CC_PROJ_ADD_FLAGS </li>
+      <li> IA32_CC_PROJ_SUB_FLAGS </li>
+      <li> CC_PROJ_FLAGS </li>
+      <li> CC_PROJ_ADD_FLAGS </li>
+      <li> CC_PROJ_SUB_FLAGS </li>
+      <li> CC_FLAGS </li>
+      <li> IA32_CC_FLAGS </li>
+      </ul>
+      
+      <p> The final flags is composed of STD, GLOBAL and PROJ. If CC_FLAGS or
+      IA32_CC_FLAGS is specified, STD, GLOBAL and PROJ will not affect. </p>
+      
+      Note that the <code>ToolChainFactory</code> executes only once 
+      during whole build process. 
+    **/
+    private void parseToolsDefinitionFile() {
+        //
+        // If ToolChain has been set up before, do nothing.
+        // CONF dir + tools definition file name
+        //
+        String confDir = GlobalData.getWorkspacePath() + File.separatorChar + "Tools" + File.separatorChar + "Conf";
+        String toolsDefFilename = "tools_def.txt";
+        if (getProject().getProperty("env.TOOLS_DEF") != null) {
+            toolsDefFilename = getProject().getProperty("env.TOOLS_DEF");
+        }
+//        toolChainFactory = new ToolChainFactory(confDir, toolsDefFilename);
+//        toolChainFactory.setupToolChain();
+    }
+}
diff --git a/Tools/Source/GenBuild/org/tianocore/build/OutputDirSetupTask.java b/Tools/Source/GenBuild/org/tianocore/build/OutputDirSetupTask.java
deleted file mode 100644
index c2b7cc997b..0000000000
--- a/Tools/Source/GenBuild/org/tianocore/build/OutputDirSetupTask.java
+++ /dev/null
@@ -1,190 +0,0 @@
-/** @file
-  
-  This file is an ANT task OutputDirSetupTask. 
-  
-  This task main purpose is to setup some necessary properties for Package,
-  Platform or Module clean. 
- 
-Copyright (c) 2006, Intel Corporation
-All rights reserved. This program and the accompanying materials
-are licensed and made available under the terms and conditions of the BSD License
-which accompanies this distribution.  The full text of the license may be found at
-http://opensource.org/licenses/bsd-license.php
-
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
-**/
-package org.tianocore.build;
-
-import java.io.File;
-import java.util.HashMap;
-import java.util.Map;
-
-import org.apache.tools.ant.BuildException;
-import org.apache.tools.ant.Task;
-import org.apache.xmlbeans.XmlObject;
-
-import org.tianocore.build.global.GlobalData;
-import org.tianocore.build.global.OutputManager;
-import org.tianocore.build.global.SurfaceAreaQuery;
-import org.tianocore.build.toolchain.ToolChainFactory;
-
-/**
-  <code>OutputDirSetupTask</code> is an ANT task that can be used in ANT build
-  system. The main function of this task is to initialize some basic information
-  for Package|Platform|Module clean or cleanall usage. 
-  
-  <p>Here is an example: </p> 
-  <pre>
-     &lt;OutputDirSetup baseName="HelloWorld" 
-                     mbdFilename="${MODULE_DIR}\HelloWorld.mbd" 
-                     msaFilename="${MODULE_DIR}\HelloWorld.msa" /&gt;
-  </pre>
-  
-  <p>Note that all this task doing is part of GenBuildTask. </p>
-  
-  @since GenBuild 1.0
-  @see org.tianocore.build.GenBuildTask
-**/
-public class OutputDirSetupTask extends Task {
-    
-    ///
-    /// Module surface area file.
-    ///
-    File msaFilename;
-
-    ///
-    /// Module build description file.
-    ///
-    File mbdFilename;
-    
-    ///
-    /// Module surface area information after overrided.
-    ///
-    public Map<String, XmlObject> map = new HashMap<String, XmlObject>();
-    
-    ///
-    /// Module's base name.
-    ///
-    private String baseName;
-    
-    /**
-      Public construct method. It is necessary for ANT task.
-    **/
-    public OutputDirSetupTask () {
-    }
-    
-    /**
-      ANT task's entry point, will be called after init(). The main steps is described
-      as following: 
-      <ul>
-      <li> Judge current build mode (MODULE | PACKAGE | PLATFORM). This step will execute
-      only once in whole build process; </li>
-      <li> Initialize global information (Framework DB, SPD files and all MSA files 
-      listed in SPD). This step will execute only once in whole build process; </li>
-      <li> Restore some important ANT property. If current build is single module 
-      build, here will set many default values; </li>
-      <li> Get the current module's overridded surface area information from 
-      global data; </li> 
-      <li> Set up the output directories, including BIN_DIR, DEST_DIR_OUTPUT and
-      DEST_DIR_DEBUG; </li>
-      </ul>
-      
-      @throws BuildException
-              From module build, exception from module surface area invalid.
-    **/
-    public void execute() throws BuildException {
-        System.out.println("Deleting module [" + baseName + "] start.");
-        OutputManager.update(getProject());
-        GlobalData.initInfo("Tools" + File.separatorChar + "Conf" + File.separatorChar + "FrameworkDatabase.db", getProject()
-                        .getProperty("WORKSPACE_DIR"));
-        recallFixedProperties();
-        map = GlobalData.getDoc(baseName);
-        //
-        // Initialize SurfaceAreaQuery
-        //
-        SurfaceAreaQuery.setDoc(map);
-        //
-        // Setup Output Management
-        //
-        String[] outdir = SurfaceAreaQuery.getOutputDirectory();
-        OutputManager.update(getProject(), outdir[1], outdir[0]);
-    }
-    
-    /**
-      Get current module's base name. 
-      
-      @return base name
-    **/
-    public String getBaseName() {
-        return baseName;
-    }
-
-    /**
-      Set base name. For ANT use.
-      
-      @param baseName Base name
-    **/
-    public void setBaseName(String baseName) {
-        this.baseName = baseName;
-    }
-
-    /**
-      Set MBD surface area file. For ANT use.
-      
-      @param mbdFilename Surface Area file
-    **/
-    public void setMbdFilename(File mbdFilename) {
-        this.mbdFilename = mbdFilename;
-    }
-
-    /**
-      Set MSA surface area file. For ANT use.
-      
-      @param msaFilename Surface Area file
-    **/
-    public void setMsaFilename(File msaFilename) {
-        this.msaFilename = msaFilename;
-    }
-    
-    /**
-      Restore some important ANT property. If current build is single module 
-      build, here will set many default values.
-      
-      <p> If current build is single module build, then the default <code>ARCH</code>
-      is <code>IA32</code>. Also set up the properties <code>PACKAGE</code>, 
-      <code>PACKAGE_DIR</code>, <code>TARGET</code> and <code>MODULE_DIR</code></p>
-      
-      <p> Note that for package build, package name is stored in <code>PLATFORM</code>
-      and package directory is stored in <code>PLATFORM_DIR</code>. </p> 
-     
-      @see org.tianocore.build.global.OutputManager
-    **/
-    private void recallFixedProperties(){
-        //
-        // If build is for module build
-        //
-        if (getProject().getProperty("PACKAGE_DIR") == null) {
-            ToolChainFactory toolChainFactory = new ToolChainFactory(getProject());
-            toolChainFactory.setupToolChain();
-            //
-            // PACKAGE PACKAGE_DIR ARCH (Default) COMMON_FILE BUILD_MACRO
-            //
-            if (getProject().getProperty("ARCH") == null){
-                getProject().setProperty("ARCH", "IA32");
-            }
-            String packageName = GlobalData.getPackageNameForModule(baseName);
-            getProject().setProperty("PACKAGE", packageName);
-            String packageDir = GlobalData.getPackagePath(packageName);
-            getProject().setProperty("PACKAGE_DIR", getProject().getProperty("WORKSPACE_DIR") + File.separatorChar + packageDir);
-            getProject().setProperty("TARGET", toolChainFactory.getCurrentTarget());
-            getProject().setProperty("MODULE_DIR", getProject().replaceProperties(getProject().getProperty("MODULE_DIR")));
-        }
-        if (OutputManager.PLATFORM != null) {
-            getProject().setProperty("PLATFORM", OutputManager.PLATFORM);
-        }
-        if (OutputManager.PLATFORM_DIR != null) {
-            getProject().setProperty("PLATFORM_DIR", OutputManager.PLATFORM_DIR);
-        }
-    }
-}
diff --git a/Tools/Source/GenBuild/org/tianocore/build/autogen/AutoGen.java b/Tools/Source/GenBuild/org/tianocore/build/autogen/AutoGen.java
index 1b9c5a0e4a..95875544b3 100644
--- a/Tools/Source/GenBuild/org/tianocore/build/autogen/AutoGen.java
+++ b/Tools/Source/GenBuild/org/tianocore/build/autogen/AutoGen.java
@@ -20,12 +20,14 @@ package org.tianocore.build.autogen;
 import org.tianocore.build.global.GlobalData;
 import org.tianocore.build.global.Spd;
 import org.tianocore.build.global.SurfaceAreaQuery;
+import org.tianocore.build.id.ModuleIdentification;
+import org.tianocore.build.id.PackageIdentification;
 import org.tianocore.GuidsDocument;
 import org.tianocore.LibraryClassDocument.LibraryClass;
 import org.tianocore.PPIsDocument;
 import org.tianocore.ProtocolsDocument;
-import org.tianocore.build.pcd.action.PCDAutoGenAction;
-
+//import org.tianocore.build.pcd.action.PCDAutoGenAction;
+import org.tianocore.build.exception.*;
 import org.apache.tools.ant.BuildException;
 import org.apache.xmlbeans.XmlObject;
 
@@ -33,78 +35,86 @@ import java.io.File;
 import java.io.FileReader;
 import java.io.FileWriter;
 import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 
 /**
-  This class is to generate Autogen.h and Autogen.c according to module surface
-  area or library surface area.
-**/
+ * This class is to generate Autogen.h and Autogen.c according to module surface
+ * area or library surface area.
+ */
 public class AutoGen {
-    ///
-    /// The output path of Autogen.h and Autogen.c
-    ///
+    // /
+    // / The output path of Autogen.h and Autogen.c
+    // /
     private String outputPath;
 
-    ///
-    /// The base name of module or library.
-    ///
-    private String baseName;
+    // /
+    // / The base name of module or library.
+    // /
+    private ModuleIdentification moduleId;
 
-    ///
-    /// The build architecture
-    ///
+    // /
+    // / The build architecture
+    // /
     private String arch;
 
-    ///
-    /// PcdAutogen instance which is used to manage how to generate the PCD
-    /// information.
-    ///
-    private PCDAutoGenAction myPcdAutogen;
+    // /
+    // / PcdAutogen instance which is used to manage how to generate the PCD
+    // / information.
+    // /
+//    private PCDAutoGenAction myPcdAutogen;
 
-    ///
-    /// The protocl list which records in module or library surface area and
-    /// it's dependence on library instance surface area.
-    ///
-    private List<String> mProtocolList = new ArrayList<String>();
+    // /
+    // / The protocl list which records in module or library surface area and
+    // / it's dependence on library instance surface area.
+    // /
+    private Set<String> mProtocolList = new HashSet<String>();
 
-    ///
-    /// The Ppi list which recorded in module or library surface area and its
-    /// dependency on library instance surface area.
-    ///
-    private List<String> mPpiList = new ArrayList<String>();
+    // /
+    // / The Ppi list which recorded in module or library surface area and its
+    // / dependency on library instance surface area.
+    // /
+    private Set<String> mPpiList = new HashSet<String>();
 
-    ///
-    /// The Guid list which recoreded in module or library surface are and it's
-    /// dependence on library instance surface area.
-    ///
-    private List<GuidsDocument.Guids.GuidEntry> mGuidList = new ArrayList<GuidsDocument.Guids.GuidEntry>();
+    // /
+    // / The Guid list which recoreded in module or library surface are and it's
+    // / dependence on library instance surface area.
+    // /
+    private Set<String> mGuidList = new HashSet<String>();
 
     /**
-      Construct function
-      
-      This function mainly initialize some member variable.
-      
-      @param outputPath    Output path of AutoGen file.
-      @param baseName      Module base name.
-      @param arch          Target architecture.
-    **/
-    public AutoGen(String outputPath, String baseName, String arch) {
+     * Construct function
+     * 
+     * This function mainly initialize some member variable.
+     * 
+     * @param outputPath
+     *            Output path of AutoGen file.
+     * @param baseName
+     *            Module base name.
+     * @param arch
+     *            Target architecture.
+     */
+    public AutoGen(String outputPath, ModuleIdentification moduleId, String arch) {
         this.outputPath = outputPath;
-        this.baseName = baseName;
+        this.moduleId = moduleId;
         this.arch = arch;
 
     }
 
     /**
-      saveFile function
-      
-      This function save the content in stringBuffer to file.
-      
-      @param fileName      The name of file.
-      @param fileBuffer    The content of AutoGen file in buffer.
-      @return              "true" successful, "false" failed.
-    **/
+     * saveFile function
+     * 
+     * This function save the content in stringBuffer to file.
+     * 
+     * @param fileName
+     *            The name of file.
+     * @param fileBuffer
+     *            The content of AutoGen file in buffer.
+     * @return "true" successful, "false" failed.
+     */
     private boolean saveFile(String fileName, StringBuffer fileBuffer) {
         try {
             File autoGenH = new File(fileName);
@@ -136,13 +146,14 @@ public class AutoGen {
     }
 
     /**
-      genAutogen function
-      
-      This function call libGenAutoGen or moduleGenAutogen function, which
-      dependence on generate library autogen or module autogen.
-      
-      @throws BuildException    Failed to creat AutoGen.c & AutoGen.h.
-    **/
+     * genAutogen function
+     * 
+     * This function call libGenAutoGen or moduleGenAutogen function, which
+     * dependence on generate library autogen or module autogen.
+     * 
+     * @throws BuildException
+     *             Failed to creat AutoGen.c & AutoGen.h.
+     */
     public void genAutogen() throws BuildException {
         try {
             //
@@ -155,8 +166,7 @@ public class AutoGen {
             // Check current is library or not, then call the corresponding
             // function.
             //
-            if (SurfaceAreaQuery.getComponentType().equalsIgnoreCase(
-                    CommonDefinition.LibraryStr)) {
+            if (this.moduleId.isLibrary()) {
                 libGenAutogen();
             } else {
                 moduleGenAutogen();
@@ -169,13 +179,14 @@ public class AutoGen {
         }
     }
 
-    /** 
-      moduleGenAutogen function
-    
-      This function generates AutoGen.c & AutoGen.h for module.
-     
-      @throws BuildException  Faile to create module AutoGen.c & AutoGen.h.
-    **/
+    /**
+     * moduleGenAutogen function
+     * 
+     * This function generates AutoGen.c & AutoGen.h for module.
+     * 
+     * @throws BuildException
+     *             Faile to create module AutoGen.c & AutoGen.h.
+     */
     void moduleGenAutogen() throws BuildException {
 
         try {
@@ -189,13 +200,13 @@ public class AutoGen {
     }
 
     /**
-      libGenAutogen function
-      
-      This function generates AutoGen.c & AutoGen.h for library.
-      
-      @throws BuildException
-                  Faile to create library AutoGen.c & AutoGen.h
-    **/
+     * libGenAutogen function
+     * 
+     * This function generates AutoGen.c & AutoGen.h for library.
+     * 
+     * @throws BuildException
+     *             Faile to create library AutoGen.c & AutoGen.h
+     */
     void libGenAutogen() throws BuildException {
         try {
             libGenAutogenC();
@@ -208,38 +219,42 @@ public class AutoGen {
     }
 
     /**
-      moduleGenAutogenH
-     
-      This function generates AutoGen.h for module.
-      
-      @throws BuildException
-                  Failed to generate AutoGen.h.
-    **/
-    void moduleGenAutogenH() throws BuildException {
+     * moduleGenAutogenH
+     * 
+     * This function generates AutoGen.h for module.
+     * 
+     * @throws BuildException
+     *             Failed to generate AutoGen.h.
+     */
+    void moduleGenAutogenH() throws AutoGenException {
 
-        List<String> libClassIncludeH;
+        Set<String> libClassIncludeH;
         String moduleType;
-        List<String> headerFileList;
-
+        // List<String> headerFileList;
+        Set<String> headerFileList;
+        Iterator item;
         StringBuffer fileBuffer = new StringBuffer(8192);
-        
+
         //
-        // Write Autogen.h header notation 
+        // Write Autogen.h header notation
         //
         fileBuffer.append(CommonDefinition.autogenHNotation);
-        
+
         //
-        // Add #ifndef  ${BaseName}_AUTOGENH
-        //     #def     ${BseeName}_AUTOGENH
+        // Add #ifndef ${BaseName}_AUTOGENH
+        // #def ${BseeName}_AUTOGENH
         //
-        fileBuffer.append("#ifndef    " + this.baseName.toUpperCase() + "_AUTOGENH\r\n");
-        fileBuffer.append("#define    " + this.baseName.toUpperCase() + "_AUTOGENH\r\n\r\n");
-        
+        fileBuffer.append("#ifndef    " + this.moduleId.getName().toUpperCase()
+                + "_AUTOGENH\r\n");
+        fileBuffer.append("#define    " + this.moduleId.getName().toUpperCase()
+                + "_AUTOGENH\r\n\r\n");
+
         //
         // Write the specification version and release version at the begine
         // of autogen.h file.
         // Note: the specification version and release version should
-        // be got from module surface area instead of hard code by it's moduleType.
+        // be got from module surface area instead of hard code by it's
+        // moduleType.
         //
         moduleType = SurfaceAreaQuery.getModuleType();
         switch (CommonDefinition.getModuleType(moduleType)) {
@@ -267,7 +282,7 @@ public class AutoGen {
         }
 
         //
-        // Add "extern int __make_me_compile_correctly;" at begin of 
+        // Add "extern int __make_me_compile_correctly;" at begin of
         // AutoGen.h.
         //
         fileBuffer.append(CommonDefinition.autoGenHbegin);
@@ -275,49 +290,53 @@ public class AutoGen {
         //
         // Write consumed package's mdouleInfo related .h file to autogen.h
         //
-        List<String> consumedPkgList = SurfaceAreaQuery
-                .getIncludePackageName(this.arch);
-        if (consumedPkgList != null) {
-            headerFileList = IncludesToAutogenH(consumedPkgList, moduleType);
-            for (int i = 0; i < headerFileList.size(); i++) {
-                fileBuffer.append(headerFileList.get(i));
+//        PackageIdentification[] consumedPkgIdList = SurfaceAreaQuery
+//                .getDependencePkg(this.arch);
+        PackageIdentification[] consumedPkgIdList = SurfaceAreaQuery.getDependencePkg(null);
+        if (consumedPkgIdList != null) {
+            headerFileList = depPkgToAutogenH(consumedPkgIdList, moduleType);
+            item = headerFileList.iterator();
+            while (item.hasNext()){
+            	fileBuffer.append(item.next().toString());
             }
         }
 
         //
         // Write library class's related *.h file to autogen.h.
         //
-        LibraryClass[] libClassList = SurfaceAreaQuery
-                .getLibraryClassArray(CommonDefinition.AlwaysConsumed);
+        String[] libClassList = SurfaceAreaQuery
+                .getLibraryClasses(CommonDefinition.AlwaysConsumed);
         if (libClassList != null) {
             libClassIncludeH = LibraryClassToAutogenH(libClassList);
-            for (int i = 0; i < libClassIncludeH.size(); i++) {
-                fileBuffer.append(libClassIncludeH.get(i));
+            item = libClassIncludeH.iterator();
+            while (item.hasNext()){
+            	fileBuffer.append(item.next().toString());
             }
         }
 
         libClassList = SurfaceAreaQuery
-                .getLibraryClassArray(CommonDefinition.AlwaysProduced);
+                .getLibraryClasses(CommonDefinition.AlwaysProduced);
         if (libClassList != null) {
             libClassIncludeH = LibraryClassToAutogenH(libClassList);
-            for (int i = 0; i < libClassIncludeH.size(); i++) {
-                fileBuffer.append(libClassIncludeH.get(i));
+            item = libClassIncludeH.iterator();
+            while (item.hasNext()){
+            	fileBuffer.append(item.next().toString());
             }
         }
         fileBuffer.append("\r\n");
-        
+
         //
         // Write PCD autogen information to AutoGen.h.
         //
-        if (this.myPcdAutogen != null) {
-            fileBuffer.append(this.myPcdAutogen.OutputH());
-        }
+//        if (this.myPcdAutogen != null) {
+//            fileBuffer.append(this.myPcdAutogen.OutputH());
+//        }
 
         //
         // Append the #endif at AutoGen.h
         //
         fileBuffer.append("#endif\r\n");
-        
+
         //
         // Save string buffer content in AutoGen.h.
         //
@@ -325,32 +344,40 @@ public class AutoGen {
             throw new BuildException("Failed to generate AutoGen.h !!!");
         }
     }
-    
+
     /**
-      moduleGenAutogenC
-   
-      This function generates AutoGen.c for module.
-    
-      @throws BuildException
-                Failed to generate AutoGen.c.
-    **/
-    void moduleGenAutogenC() throws BuildException {
+     * moduleGenAutogenC
+     * 
+     * This function generates AutoGen.c for module.
+     * 
+     * @throws BuildException
+     *             Failed to generate AutoGen.c.
+     */
+    void moduleGenAutogenC() throws AutoGenException {
 
         StringBuffer fileBuffer = new StringBuffer(8192);
         //
-        // Write Autogen.c header notation 
+        // Write Autogen.c header notation
         //
         fileBuffer.append(CommonDefinition.autogenCNotation);
-        
+
         //
         // Write #include <AutoGen.h> at beginning of AutoGen.c
         //
         fileBuffer.append(CommonDefinition.includeAutogenH);
-        
+
         //
-        // Write DriverBinding/ComponentName/DriverConfiguration/DriverDialog
+        // Get the native MSA file infomation. Since before call autogen, 
+        // the MSA native <Externs> information were overrided. So before 
+        // process <Externs> it should be set the DOC as the Native MSA info.
+        //
+        Map<String, XmlObject> doc  = GlobalData.getNativeMsa(this.moduleId);
+        SurfaceAreaQuery.push(doc);
+        //
+        // Write <Extern> DriverBinding/ComponentName/DriverConfiguration/DriverDialog
         // to AutoGen.c
         //
+        
         ExternsDriverBindingToAutoGenC(fileBuffer);
 
         //
@@ -367,21 +394,29 @@ public class AutoGen {
             EntryPointToAutoGen(entryPointList, fileBuffer);
         }
 
+        //
+        // Restore the DOC which include the FPD module info. 
+        //
+        SurfaceAreaQuery.pop();
+        
         //
         // Write Guid to autogen.c
         //
-        String guid = SurfaceAreaQuery.getModuleGuid();
+        String guid = CommonDefinition.formatGuidName(SurfaceAreaQuery.getModuleGuid());
+        
         fileBuffer
                 .append("GLOBAL_REMOVE_IF_UNREFERENCED EFI_GUID gEfiCallerIdGuid = {");
         if (guid == null) {
-            throw new BuildException("Guid value must set!\n");
+            throw new AutoGenException("Guid value must set!\n");
         }
 
         //
         // Formate Guid as ANSI c form.Example:
-        // {0xd2b2b828, 0x826, 0x48a7,{0xb3, 0xdf, 0x98, 0x3c, 0x0, 0x60, 0x24, 0xf0}}
+        // {0xd2b2b828, 0x826, 0x48a7,{0xb3, 0xdf, 0x98, 0x3c, 0x0, 0x60, 0x24,
+        // 0xf0}}
         //
-        fileBuffer.append(Spd.formatGuidName(guid));
+
+        fileBuffer.append(guid);
         fileBuffer.append("};\r\n");
 
         //
@@ -403,116 +438,119 @@ public class AutoGen {
         // Call pcd autogen. PCDAutoGenAction tool only need module name and
         // isPcdEmulatedDriver as parameter. Library inherits PCD and module's
         // PCD information has been collected in FPDParser task by
-        // CollectPCDAction. 
+        // CollectPCDAction.
         // Note : when PCD image tool ready,
         // isPCDEmulatedDriver parameter will be removed.
         //
-        try {
-            this.myPcdAutogen = new PCDAutoGenAction(baseName,
-                                                     null,
-                                                     null,
-                                                     null,
-                                                     this.arch,
-                                                     null,
-                                                     false,
-                                                     SurfaceAreaQuery.getModulePcdEntryNameArray());
-            this.myPcdAutogen.execute();
-        } catch (Exception e) {
-            throw new BuildException("PCD Autogen for module failed:" + e.getMessage());
-        }
-
-        if (this.myPcdAutogen != null) {
-            fileBuffer.append(this.myPcdAutogen.OutputC());
-        }
+//        try {
+//            this.myPcdAutogen = new PCDAutoGenAction(moduleId.getName(),
+//                    moduleId.getName().equalsIgnoreCase("PcdEmulatorPeim"));
+//            this.myPcdAutogen.execute();
+//        } catch (Exception e) {
+//            throw new BuildException("PCD Autogen failed:" + e.getMessage());
+//        }
+//
+//        if (this.myPcdAutogen != null) {
+//            fileBuffer.append(this.myPcdAutogen.OutputC());
+//        }
 
         if (!saveFile(outputPath + File.separatorChar + "AutoGen.c", fileBuffer)) {
             throw new BuildException("Failed to generate AutoGen.c !!!");
         }
 
     }
-    
-    /**
-      libGenAutogenH
-   
-      This function generates AutoGen.h for library.
-    
-      @throws BuildException
-                Failed to generate AutoGen.c.
-    **/
-    void libGenAutogenH() throws BuildException {
 
-        List<String> libClassIncludeH;
+    /**
+     * libGenAutogenH
+     * 
+     * This function generates AutoGen.h for library.
+     * 
+     * @throws BuildException
+     *             Failed to generate AutoGen.c.
+     */
+    void libGenAutogenH() throws AutoGenException {
+
+        Set<String> libClassIncludeH;
         String moduleType;
-        List<String> headerFileList;
+        Set<String> headerFileList;
+        Iterator item;
         StringBuffer fileBuffer = new StringBuffer(10240);
 
         //
-        // Write Autogen.h header notation 
+        // Write Autogen.h header notation
         //
         fileBuffer.append(CommonDefinition.autogenHNotation);
-        
+
         //
-        // Add #ifndef  ${BaseName}_AUTOGENH
-        //     #def     ${BseeName}_AUTOGENH
+        // Add #ifndef ${BaseName}_AUTOGENH
+        // #def ${BseeName}_AUTOGENH
         //
-        fileBuffer.append("#ifndef    " + this.baseName.toUpperCase() + "_AUTOGENH\r\n");
-        fileBuffer.append("#define    " + this.baseName.toUpperCase() + "_AUTOGENH\r\n\r\n");
-        
+        fileBuffer.append("#ifndef    " + this.moduleId.getName().toUpperCase()
+                + "_AUTOGENH\r\n");
+        fileBuffer.append("#define    " + this.moduleId.getName().toUpperCase()
+                + "_AUTOGENH\r\n\r\n");
+
         //
-        // Write EFI_SPECIFICATION_VERSION and EDK_RELEASE_VERSION 
+        // Write EFI_SPECIFICATION_VERSION and EDK_RELEASE_VERSION
         // to autogen.h file.
         // Note: the specification version and release version should
         // be get from module surface area instead of hard code.
         //
         fileBuffer.append(CommonDefinition.autoGenHbegin);
-        fileBuffer.append(CommonDefinition.autoGenHLine1);
-        fileBuffer.append(CommonDefinition.autoGenHLine2);
+        String[] specList = SurfaceAreaQuery.getExternSpecificaiton();
+        for (int i = 0; i < specList.length; i++){
+            fileBuffer.append(CommonDefinition.marcDefineStr + specList[i] + "\r\n");
+        }
+//        fileBuffer.append(CommonDefinition.autoGenHLine1);
+//        fileBuffer.append(CommonDefinition.autoGenHLine2);
 
         //
         // Write consumed package's mdouleInfo related *.h file to autogen.h.
         // 
         moduleType = SurfaceAreaQuery.getModuleType();
-        List<String> cosumedPkglist = SurfaceAreaQuery
-                .getIncludePackageName(this.arch);
-        headerFileList = IncludesToAutogenH(cosumedPkglist, moduleType);
-        for (int i = 0; i < headerFileList.size(); i++) {
-            fileBuffer.append(headerFileList.get(i));
+        PackageIdentification[] cosumedPkglist = SurfaceAreaQuery
+                .getDependencePkg(this.arch);
+        headerFileList = depPkgToAutogenH(cosumedPkglist, moduleType);
+        item = headerFileList.iterator();
+        while (item.hasNext()){
+        	fileBuffer.append(item.next().toString());
         }
-
         //
         // Write library class's related *.h file to autogen.h
         //
-        LibraryClass[] libClassList = SurfaceAreaQuery
-                .getLibraryClassArray(CommonDefinition.AlwaysConsumed);
+        String[] libClassList = SurfaceAreaQuery
+                .getLibraryClasses(CommonDefinition.AlwaysConsumed);
         if (libClassList != null) {
             libClassIncludeH = LibraryClassToAutogenH(libClassList);
-            for (int i = 0; i < libClassIncludeH.size(); i++) {
-                fileBuffer.append(libClassIncludeH.get(i));
+            item = libClassIncludeH.iterator();
+            while (item.hasNext()){
+            	fileBuffer.append(item.next().toString());
             }
         }
 
         libClassList = SurfaceAreaQuery
-                .getLibraryClassArray(CommonDefinition.AlwaysProduced);
+                .getLibraryClasses(CommonDefinition.AlwaysProduced);
         if (libClassList != null) {
             libClassIncludeH = LibraryClassToAutogenH(libClassList);
-            for (int i = 0; i < libClassIncludeH.size(); i++) {
-                fileBuffer.append(libClassIncludeH.get(i));
+            item = libClassIncludeH.iterator();
+            while (item.hasNext()){
+            	fileBuffer.append(item.next().toString());
             }
         }
         fileBuffer.append("\r\n");
-        
+
         //
         // Write PCD information to library AutoGen.h.
         //
-        if (this.myPcdAutogen != null) {
-            fileBuffer.append(this.myPcdAutogen.OutputH());
-        }
+//        if (this.myPcdAutogen != null) {
+//            fileBuffer.append(this.myPcdAutogen.OutputH());
+//        }
 
         //
         // Append the #endif at AutoGen.h
         //
         fileBuffer.append("#endif\r\n");
-        
+
         //
         // Save content of string buffer to AutoGen.h file.
         //
@@ -522,21 +560,21 @@ public class AutoGen {
     }
 
     /**
-      libGenAutogenC
-   
-      This function generates AutoGen.h for library.
-    
-      @throws BuildException
-                Failed to generate AutoGen.c.
-    **/
+     * libGenAutogenC
+     * 
+     * This function generates AutoGen.h for library.
+     * 
+     * @throws BuildException
+     *             Failed to generate AutoGen.c.
+     */
     void libGenAutogenC() throws BuildException {
         StringBuffer fileBuffer = new StringBuffer(10240);
 
         //
-        // Write Autogen.c header notation 
+        // Write Autogen.c header notation
         //
         fileBuffer.append(CommonDefinition.autogenCNotation);
-        
+
         fileBuffer.append(CommonDefinition.autoGenCLine1);
         fileBuffer.append("\r\n");
 
@@ -544,27 +582,22 @@ public class AutoGen {
         // Call pcd autogen. PCDAutoGenAction tool only need module name and
         // isPcdEmulatedDriver as parameter. Library inherit PCD and module's
         // PCD information has been collected in FPDParser task by
-        // CollectPCDAction. 
+        // CollectPCDAction.
         // Note : when PCD image tool ready,
         // isPCDEmulatedDriver parameter will be removed.
         //
         try {
-            this.myPcdAutogen = new PCDAutoGenAction(baseName, 
-                                                     null,
-                                                     null,
-                                                     null,
-                                                     this.arch,
-                                                     null,
-                                                     true,
-                                                     SurfaceAreaQuery.getModulePcdEntryNameArray());
-            this.myPcdAutogen.execute();
+//            this.myPcdAutogen = new PCDAutoGenAction(this.moduleId.getName(),
+//                    this.moduleId.getName().equalsIgnoreCase("PcdEmulatorPeim"));
+//            this.myPcdAutogen.execute();
+//        	this.myPcdAutogen = new PCDAutoGenAction(this.moduleId,);
         } catch (Exception e) {
-            throw new BuildException("Pcd Autogen for library failed! " + e.getMessage());
+            throw new BuildException(e.getMessage());
         }
 
-        if (this.myPcdAutogen != null) {
-            fileBuffer.append(this.myPcdAutogen.OutputC());
-        }
+//        if (this.myPcdAutogen != null) {
+//            fileBuffer.append(this.myPcdAutogen.OutputC());
+//        }
 
         if (!saveFile(outputPath + File.separatorChar + "AutoGen.c", fileBuffer)) {
             throw new BuildException("Failed to generate AutoGen.c !!!");
@@ -572,78 +605,97 @@ public class AutoGen {
     }
 
     /**
-      LibraryClassToAutogenH
-      
-      This function returns *.h files declared by library classes which are 
-      consumed or produced by current build module or library.
-      
-      @param   libClassList     List of library class which consumed or produce
-                                by current build module or library.
-      @return  includeStrList   List of *.h file.             
-    **/
-    List<String> LibraryClassToAutogenH(LibraryClass[] libClassList) {
-        List<String> includStrList = new ArrayList<String>();
-        String includerName;
+     * LibraryClassToAutogenH
+     * 
+     * This function returns *.h files declared by library classes which are
+     * consumed or produced by current build module or library.
+     * 
+     * @param libClassList
+     *            List of library class which consumed or produce by current
+     *            build module or library.
+     * @return includeStrList List of *.h file.
+     */
+    Set<String> LibraryClassToAutogenH(String[] libClassList) throws AutoGenException{
+        Set<String> includStrList = new HashSet<String>();
+        String includerName[];
         String str = "";
-       
+
         //
-        // Get include file from GlobalData's SPDTable according to 
+        // Get include file from GlobalData's SPDTable according to
         // library class name.
         //
+
         for (int i = 0; i < libClassList.length; i++) {
-            includerName = GlobalData.getLibClassIncluder(getStringValue((XmlObject)libClassList[i]));
-            if (includerName != null) {
-                str = CommonDefinition.include + " " + "<";
-                str = str + includerName + ">\r\n";
-                includStrList.add(str);
-                includerName = null;
+            includerName = GlobalData.getLibraryClassHeaderFiles(
+                    SurfaceAreaQuery.getDependencePkg(this.arch),
+                    libClassList[i]);
+            if (includerName == null){
+                throw new AutoGenException("Can not find library class [" + libClassList[i] + "] declaration in every packages. ");
+            }
+            for (int j = 0; j < includerName.length; j++) {
+                String includeNameStr = includerName[j];
+                if (includeNameStr != null) {
+                    str = CommonDefinition.include + " " + "<";
+                    str = str + includeNameStr + ">\r\n";
+                    includStrList.add(str);
+                    includeNameStr = null;
+                }
             }
         }
         return includStrList;
     }
 
     /**
-      IncludesToAutogenH
-      
-      This function add include file in AutoGen.h file.
-      @param   packageNameList   List of module depended package.
-      @param   moduleType        Module type.
-      @return 
-    **/
-    List<String> IncludesToAutogenH(List<String> packageNameList,
-            String moduleType) {
+     * IncludesToAutogenH
+     * 
+     * This function add include file in AutoGen.h file.
+     * 
+     * @param packageNameList
+     *            List of module depended package.
+     * @param moduleType
+     *            Module type.
+     * @return
+     */
+    Set<String> depPkgToAutogenH(PackageIdentification[] packageNameList,
+            String moduleType) throws AutoGenException{
 
-        List<String> includeStrList = new ArrayList<String>();
-        String packageName = "";
+        Set<String> includeStrList = new HashSet<String>();
+        String pkgHeader;
         String includeStr = "";
 
         //
         // Get include file from moduleInfo file
         //
-        for (int i = 0; i < packageNameList.size(); i++) {
-            packageName = packageNameList.get(i);
-            includeStr = GlobalData.getModuleInfoByPackageName(packageName,
-                    moduleType);
-            includeStrList.add(includeStr);
+        for (int i = 0; i < packageNameList.length; i++){
+//        	pkgHeader = GlobalData.getPackageHeaderFiles(packageNameList[i], moduleType);
+//            if (pkgHeader == null){
+//            	throw new AutoGenException("Can not find package [" + packageNameList[i] + "] declaration in every packages. ");
+//            }else if (!pkgHeader.equalsIgnoreCase("")){
+//            	includeStr = CommonDefinition.include + "<" + pkgHeader + ">\r\n";
+//                includeStrList.add(includeStr);
+//            }
         }
+        
         return includeStrList;
     }
 
     /**
-      EntryPointToAutoGen 
-      
-      This function convert <ModuleEntryPoint> & <ModuleUnloadImage> information
-      in mas to AutoGen.c
-      
-      @param  entryPointList    List of entry point.                            
-      @param  fileBuffer        String buffer fo AutoGen.c.
-      @throws Exception
-    **/
+     * EntryPointToAutoGen
+     * 
+     * This function convert <ModuleEntryPoint> & <ModuleUnloadImage>
+     * information in mas to AutoGen.c
+     * 
+     * @param entryPointList
+     *            List of entry point.
+     * @param fileBuffer
+     *            String buffer fo AutoGen.c.
+     * @throws Exception
+     */
     void EntryPointToAutoGen(String[] entryPointList, StringBuffer fileBuffer)
             throws BuildException {
 
         String typeStr = SurfaceAreaQuery.getModuleType();
-        
+
         //
         // The parameters and return value of entryPoint is difference
         // for difference module type.
@@ -833,23 +885,7 @@ public class AutoGen {
             //
             entryPointList = SurfaceAreaQuery.getModuleUnloadImageArray();
             entryPointCount = 0;
-            if (entryPointList != null) {
-                for (int i = 0; i < entryPointList.length; i++) {
-                    if (!entryPointList[i].equals("")) {
-                        fileBuffer.append("EFI_STATUS\r\n");
-                        fileBuffer.append("EFIAPI\r\n");
-                        fileBuffer.append(entryPointList[i]);
-                        fileBuffer.append(" (\r\n");
-                        fileBuffer
-                                .append("  EFI_HANDLE        ImageHandle\r\n");
-                        fileBuffer.append("  );\r\n");
-                        entryPointCount++;
-                    } else {
-                        break;
-                    }
-                }
-            }
-
+            
             fileBuffer
                     .append("GLOBAL_REMOVE_IF_UNREFERENCED const UINT8  _gDriverUnloadImageCount = ");
             fileBuffer.append(Integer.toString(entryPointCount));
@@ -1078,198 +1114,170 @@ public class AutoGen {
     }
 
     /**
-      PpiGuidToAutogenc 
-    
-      This function gets GUIDs from SPD file accrodeing to <PPIs> information and 
-      write those GUIDs to AutoGen.c.
-    
-      @param   fileBuffer         String Buffer for Autogen.c file.
-      @throws  BuildException     Guid must set value!
-    **/
-    void PpiGuidToAutogenC(StringBuffer fileBuffer) throws BuildException {
+     * PpiGuidToAutogenc
+     * 
+     * This function gets GUIDs from SPD file accrodeing to <PPIs> information
+     * and write those GUIDs to AutoGen.c.
+     * 
+     * @param fileBuffer
+     *            String Buffer for Autogen.c file.
+     * @throws BuildException
+     *             Guid must set value!
+     */
+    void PpiGuidToAutogenC(StringBuffer fileBuffer) throws AutoGenException {
         String[] cNameGuid = null;
-        boolean isEqual = false;
 
-        PPIsDocument.PPIs.Ppi[] ppiList = SurfaceAreaQuery.getPpiArray(null);
-        if (ppiList != null) {
-            for (int i = 0; i < ppiList.length; i++) {
-                isEqual = false;
-                String ppiName = getStringValue((XmlObject)ppiList[i]);
-                for (int j = 0; j < this.mPpiList.size(); j++) {
-                    if (this.mPpiList.get(j).equalsIgnoreCase(ppiName)) {
-                        isEqual = true;
-                    }
-                }
-                if (!isEqual) {
-                    this.mPpiList.add(ppiName);
-                }
-            }
+        //
+        // Get the all PPI adn PPI Notify from MSA file,
+        // then add those PPI ,and PPI Notify name to list.
+        //
+        String[] ppiList = SurfaceAreaQuery.getPpiArray(null);
+        for (int i = 0; i < ppiList.length; i++) {
+            this.mPpiList.add(ppiList[i]);
         }
 
-        PPIsDocument.PPIs.PpiNotify[] ppiNotifyList = SurfaceAreaQuery
-                .getPpiNotifyArray(null);
-        if (ppiNotifyList != null) {
-            for (int i = 0; i < ppiNotifyList.length; i++) {
-                isEqual = false;
-                String ppiNotifyName = getStringValue((XmlObject)ppiNotifyList[i]);
-                for (int j = 0; j < this.mPpiList.size(); j++) {
-                    if (this.mPpiList.get(j).equalsIgnoreCase(ppiNotifyName)) {
-                        isEqual = true;
-                    }
-                }
-                if (!isEqual) {
-                    this.mPpiList.add(ppiNotifyName);
-                }
-            }
+        String[] ppiNotifyList = SurfaceAreaQuery.getPpiNotifyArray(null);
+        for (int i = 0; i < ppiNotifyList.length; i++) {
+            this.mPpiList.add(ppiNotifyList[i]);
         }
 
-        for (int i = 0; i < this.mPpiList.size(); i++) {
-            if (this.mPpiList.get(i) != null) {
-                cNameGuid = GlobalData.getPpiInfoGuid(this.mPpiList.get(i));
-                if (cNameGuid != null) {
-                    fileBuffer
-                            .append("\r\nGLOBAL_REMOVE_IF_UNREFERENCED EFI_GUID ");
-                    fileBuffer.append(cNameGuid[0]);
-                    fileBuffer.append(" =     { ");
-                    fileBuffer.append(cNameGuid[1]);
-                    fileBuffer.append(" } ;");
-                }
+        //
+        // Find CNAME and GUID from dependence SPD file and write to Autogen.c
+        //
+        Iterator ppiIterator = this.mPpiList.iterator();
+        String ppiKeyWord = null;
+        while (ppiIterator.hasNext()) {
+        	ppiKeyWord = ppiIterator.next().toString();
+            cNameGuid = GlobalData
+                    .getPpiGuid(SurfaceAreaQuery.getDependencePkg(this.arch),
+                            ppiKeyWord);
+            if (cNameGuid != null) {
+                fileBuffer
+                        .append("\r\nGLOBAL_REMOVE_IF_UNREFERENCED EFI_GUID ");
+                fileBuffer.append(cNameGuid[0]);
+                fileBuffer.append(" =     { ");
+                fileBuffer.append(cNameGuid[1]);
+                fileBuffer.append(" } ;");
             } else {
-                throw new BuildException("Guid must set value!");
+            	//
+                // If can't find Ppi GUID declaration in every package
+                //
+                throw new AutoGenException("Can not find Ppi GUID [" + ppiKeyWord + "] declaration in every packages. ");
             }
         }
     }
 
     /**
-      ProtocolGuidToAutogenc 
-    
-      This function gets GUIDs from SPD file accrodeing to <Protocol> 
-      information and write those GUIDs to AutoGen.c.
-    
-      @param   fileBuffer         String Buffer for Autogen.c file.
-      @throws  BuildException     Protocol name must set.
-    **/
+     * ProtocolGuidToAutogenc
+     * 
+     * This function gets GUIDs from SPD file accrodeing to <Protocol>
+     * information and write those GUIDs to AutoGen.c.
+     * 
+     * @param fileBuffer
+     *            String Buffer for Autogen.c file.
+     * @throws BuildException
+     *             Protocol name must set.
+     */
     void ProtocolGuidToAutogenC(StringBuffer fileBuffer) throws BuildException {
         String[] cNameGuid = null;
-        boolean isEqual = false;
 
-        ProtocolsDocument.Protocols.Protocol[] protocolList = SurfaceAreaQuery
-                .getProtocolArray(null);
-        if (protocolList != null) {
-            for (int i = 0; i < protocolList.length; i++) {
-                isEqual = false;
-                String protocolName = getStringValue((XmlObject)protocolList[i]);
-                for (int j = 0; j < this.mProtocolList.size(); j++) {
-                    if (this.mProtocolList.get(j).equalsIgnoreCase(protocolName)) {
-                        isEqual = true;
-                    }
-                }
-                if (!isEqual) {
-                    this.mProtocolList.add(protocolName);
+        String[] protocolList = SurfaceAreaQuery.getProtocolArray(this.arch);
 
-                }
-            }
+        //
+        // Add result to Autogen global list.
+        //
+        for (int i = 0; i < protocolList.length; i++) {
+            this.mProtocolList.add(protocolList[i]);
         }
 
-        ProtocolsDocument.Protocols.ProtocolNotify[] protocolNotifyList = SurfaceAreaQuery
-                .getProtocolNotifyArray(null);
-        if (protocolNotifyList != null) {
-            for (int i = 0; i < protocolNotifyList.length; i++) {
-                isEqual = false;
-                String protocolNotifyName = getStringValue((XmlObject)protocolNotifyList[i]);
-                for (int j = 0; j < this.mProtocolList.size(); j++) {
-                    if (this.mProtocolList.get(j).equalsIgnoreCase(protocolNotifyName)) {
-                        isEqual = true;
-                    }
-                }
-                if (!isEqual) {
-                    this.mProtocolList.add(protocolNotifyName);
+        String[] protocolNotifyList = SurfaceAreaQuery
+                .getProtocolNotifyArray(this.arch);
 
-                }
-            }
+        for (int i = 0; i < protocolNotifyList.length; i++) {
+            this.mProtocolList.add(protocolNotifyList[i]);
         }
-        if (this.mProtocolList.size() > 0) {
-            for (int i = 0; i < this.mProtocolList.size(); i++) {
-                if (this.mProtocolList.get(i) != null) {
-                    cNameGuid = GlobalData
-                            .getProtocolInfoGuid(this.mProtocolList.get(i));
-                    if (cNameGuid != null) {
-                        fileBuffer
-                                .append("\r\nGLOBAL_REMOVE_IF_UNREFERENCED EFI_GUID ");
-                        fileBuffer.append(cNameGuid[0]);
-                        fileBuffer.append(" =     { ");
-                        fileBuffer.append(cNameGuid[1]);
-                        fileBuffer.append(" } ;");
-                    }
-                } else {
-                    throw new BuildException("Protocol name must set!");
-                }
+
+        //
+        // Get the NAME and GUID from dependence SPD and write to Autogen.c
+        //
+        Iterator protocolIterator = this.mPpiList.iterator();
+        String protocolKeyWord = null;
+        while (protocolIterator.hasNext()) {
+        	protocolKeyWord = protocolIterator.next().toString();
+            cNameGuid = GlobalData.getProtocolGuid(SurfaceAreaQuery
+                    .getDependencePkg(this.arch), protocolKeyWord);
+            if (cNameGuid != null) {
+                fileBuffer
+                        .append("\r\nGLOBAL_REMOVE_IF_UNREFERENCED EFI_GUID ");
+                fileBuffer.append(cNameGuid[0]);
+                fileBuffer.append(" =     { ");
+                fileBuffer.append(cNameGuid[1]);
+                fileBuffer.append(" } ;");
+            } else {
+            	//
+                // If can't find protocol GUID declaration in every package
+                //
+                throw new BuildException("Can not find protocol Guid [" + cNameGuid + "] declaration in every packages. ");
             }
         }
     }
 
     /**
-      GuidGuidToAutogenc
-    
-      This function gets GUIDs from SPD file accrodeing to <Guids> information
-      and write those GUIDs to AutoGen.c.
-    
-      @param  fileBuffer       String Buffer for Autogen.c file.
-    
-    **/
-    void GuidGuidToAutogenC(StringBuffer fileBuffer) {
+     * GuidGuidToAutogenc
+     * 
+     * This function gets GUIDs from SPD file accrodeing to <Guids> information
+     * and write those GUIDs to AutoGen.c.
+     * 
+     * @param fileBuffer
+     *            String Buffer for Autogen.c file.
+     * 
+     */
+    void GuidGuidToAutogenC(StringBuffer fileBuffer) throws AutoGenException {
         String[] cNameGuid = null;
-        boolean isEqual = false;
-        GuidsDocument.Guids.GuidEntry[] guidList = SurfaceAreaQuery
-                .getGuidEntryArray(null);
+        String   guidKeyWord = null;
 
-        if (guidList != null) {
-            for (int i = 0; i < guidList.length; i++) {
-                for (int j = 0; j < this.mGuidList.size(); j++) {
-                    isEqual = false;
-                    if (this.mGuidList.get(j).getCName().equalsIgnoreCase(
-                            guidList[i].getCName().toString())) {
-                        isEqual = true;
-                        break;
-                    }
-                }
-                if (!isEqual) {
-                    this.mGuidList.add(guidList[i]);
+        String[] guidList = SurfaceAreaQuery.getGuidEntryArray(this.arch);
 
-                }
-
-            }
+        for (int i = 0; i < guidList.length; i++) {
+            this.mGuidList.add(guidList[i]);
         }
 
-        for (int i = 0; i < this.mGuidList.size(); i++) {
-            if (this.mGuidList.get(i).getCName() != null) {
-                cNameGuid = GlobalData.getGuidInfoGuid(this.mGuidList.get(i)
-                        .getCName());
-                if (cNameGuid != null) {
-                    fileBuffer
-                            .append("\r\nGLOBAL_REMOVE_IF_UNREFERENCED EFI_GUID ");
-                    fileBuffer.append(cNameGuid[0]);
-                    fileBuffer.append(" =     { ");
-                    fileBuffer.append(cNameGuid[1]);
-                    fileBuffer.append("} ;");
-                }
+        Iterator guidIterator = this.mGuidList.iterator();
+        while (guidIterator.hasNext()) {
+        	guidKeyWord = guidIterator.next().toString();
+            cNameGuid = GlobalData.getGuid(SurfaceAreaQuery
+                    .getDependencePkg(this.arch), guidKeyWord);
+            
+            if (cNameGuid != null) {
+                fileBuffer
+                        .append("\r\nGLOBAL_REMOVE_IF_UNREFERENCED EFI_GUID ");
+                fileBuffer.append(cNameGuid[0]);
+                fileBuffer.append(" =     { ");
+                fileBuffer.append(cNameGuid[1]);
+                fileBuffer.append("} ;");
+            }else {
+            	//
+                // If can't find GUID declaration in every package
+                //
+                throw new AutoGenException("Can not find Guid [" + guidKeyWord + "] declaration in every packages. ");
             }
+
         }
     }
 
     /**
-      LibInstanceToAutogenC
-      
-      This function adds dependent library instance to autogen.c,which includeing 
-      library's constructor, destructor, and library dependent ppi, protocol, guid,
-      pcd information.
-         
-      @param  fileBuffer              String buffer for AutoGen.c
-      @throws BuildException          
-    **/
+     * LibInstanceToAutogenC
+     * 
+     * This function adds dependent library instance to autogen.c,which
+     * includeing library's constructor, destructor, and library dependent ppi,
+     * protocol, guid, pcd information.
+     * 
+     * @param fileBuffer
+     *            String buffer for AutoGen.c
+     * @throws BuildException
+     */
     void LibInstanceToAutogenC(StringBuffer fileBuffer) throws BuildException {
         int index;
-        boolean isEqual = false;
 
         String moduleType = SurfaceAreaQuery.getModuleType();
         List<String> libConstructList = new ArrayList<String>();
@@ -1277,144 +1285,83 @@ public class AutoGen {
 
         String libConstructName = null;
         String libDestructName = null;
-        List<String> libraryList = SurfaceAreaQuery.getLibraryInstance(
-                this.arch, CommonDefinition.AlwaysConsumed);
+        ModuleIdentification[] libraryIdList = SurfaceAreaQuery.getLibraryInstance(this.arch);
 
         try {
-            if (libraryList != null) {
+            if (libraryIdList != null) {
                 //
                 // Reorder library instance sequence.
                 //
-                AutogenLibOrder libOrder = new AutogenLibOrder(libraryList);
-                List orderList = libOrder.orderLibInstance();
-                
+                AutogenLibOrder libOrder = new AutogenLibOrder(libraryIdList, this.arch);
+                List<ModuleIdentification> orderList = libOrder.orderLibInstance();
+
                 if (orderList != null) {
                     //
                     // Process library instance one by one.
                     //
                     for (int i = 0; i < orderList.size(); i++) {
-                        
+
                         //
                         // Get library instance basename.
                         //
-                        String libInstanceName = orderList.get(i).toString();
-                        
+                        ModuleIdentification libInstanceId = orderList.get(i);
+
                         //
                         // Get override map
                         //
                         Map<String, XmlObject> libDoc = GlobalData
-                                .getDoc(libInstanceName);
+                                .getDoc(libInstanceId, this.arch);
                         SurfaceAreaQuery.push(libDoc);
-                        
+
                         //
                         // Get <PPis>, <Protocols>, <Guids> list of this library
                         // instance.
                         //
-                        PPIsDocument.PPIs.Ppi[] ppiList = SurfaceAreaQuery
+                        String[] ppiList = SurfaceAreaQuery
                                 .getPpiArray(null);
-                        PPIsDocument.PPIs.PpiNotify[] ppiNotifyList = SurfaceAreaQuery
+                        String[] ppiNotifyList = SurfaceAreaQuery
                                 .getPpiNotifyArray(null);
-                        ProtocolsDocument.Protocols.Protocol[] protocolList = SurfaceAreaQuery
+                        String[] protocolList = SurfaceAreaQuery
                                 .getProtocolArray(null);
-                        ProtocolsDocument.Protocols.ProtocolNotify[] protocolNotifyList = SurfaceAreaQuery
+                        String[] protocolNotifyList = SurfaceAreaQuery
                                 .getProtocolNotifyArray(null);
-                        GuidsDocument.Guids.GuidEntry[] guidList = SurfaceAreaQuery
+                        String[] guidList = SurfaceAreaQuery
                                 .getGuidEntryArray(null);
 
                         //
-                        // Add those ppi, protocol, guid in global ppi, protocol, guid
+                        // Add those ppi, protocol, guid in global ppi,
+                        // protocol, guid
                         // list.
                         //
-                        if (ppiList != null) {
-                            for (index = 0; index < ppiList.length; index++) {
-                                isEqual = false;
-                                String name = getStringValue((XmlObject)ppiList[index]);
-                                for (int j = 0; j < this.mPpiList.size(); j++) {
-                                    if (this.mPpiList.get(j).equalsIgnoreCase(name)) {
-                                        isEqual = true;
-                                    }
-                                }
-                                if (!isEqual) {
-                                    this.mPpiList.add(name);
-                                }
-                            }
+                        for (index = 0; index < ppiList.length; index++) {
+                            this.mPpiList.add(ppiList[index]);
                         }
-                        if (ppiNotifyList != null) {
-                            for (index = 0; index < ppiNotifyList.length; index++) {
-                                isEqual = false;
-                                String name = getStringValue((XmlObject)ppiNotifyList[index]);
-                                for (int j = 0; j < this.mPpiList.size(); j++) {
-                                    if (this.mPpiList.get(j).equalsIgnoreCase(name)) {
-                                        isEqual = true;
-                                    }
-                                }
-                                if (!isEqual) {
-                                    this.mPpiList.add(name);
-                                }
-                            }
+                        
+                        for (index = 0; index < ppiNotifyList.length; index++) {
+                            this.mPpiList.add(ppiNotifyList[index]);
                         }
-                        if (protocolList != null) {
-                            for (index = 0; index < protocolList.length; index++) {
-                                isEqual = false;
-                                String name = getStringValue((XmlObject)protocolList[index]);
-                                for (int j = 0; j < this.mProtocolList.size(); j++) {
-                                    if (this.mProtocolList.get(j).equalsIgnoreCase(name)) {
-                                        isEqual = true;
-                                    }
-                                }
-                                if (!isEqual) {
-                                    this.mProtocolList.add(name);
-                                }
-                            }
+                        
+                        for (index = 0; index < protocolList.length; index++) {
+                            this.mProtocolList.add(protocolList[index]);
                         }
-                        if (protocolNotifyList != null) {
-                            for (index = 0; index < protocolNotifyList.length; index++) {
-                                isEqual = false;
-                                String name = getStringValue((XmlObject)protocolNotifyList[index]);
-                                for (int j = 0; j < this.mProtocolList.size(); j++) {
-                                    if (this.mProtocolList.get(j).equalsIgnoreCase(name)) {
-                                        isEqual = true;
-                                    }
-                                }
-                                if (!isEqual) {
-                                    this.mProtocolList.add(name);
-                                }
-                            }
+                        
+                        for (index = 0; index < protocolNotifyList.length; index++) {
+                            this.mProtocolList.add(protocolNotifyList[index]);
                         }
-                        if (guidList != null) {
-                            for (index = 0; index < guidList.length; index++) {
-                                isEqual = false;
-                                for (int j = 0; j < this.mGuidList.size(); j++) {
-                                    if (this.mGuidList.get(j).getCName()
-                                            .equalsIgnoreCase(
-                                                    guidList[index].getCName())) {
-                                        isEqual = true;
-                                    }
-                                }
-                                if (!isEqual) {
-                                    this.mGuidList.add(guidList[index]);
-                                }
-                            }
+                        
+                        for (index = 0; index < guidList.length; index++) {
+                            this.mGuidList.add(guidList[index]);   
                         }
 
                         //
                         // If not yet parse this library instance's constructor
                         // element,parse it.
                         //
-                        if (!GlobalData.isHaveLibInstance(libInstanceName)) {
-                            libConstructName = SurfaceAreaQuery
+                        libConstructName = SurfaceAreaQuery
                                     .getLibConstructorName();
-                            libDestructName = SurfaceAreaQuery
+                        libDestructName = SurfaceAreaQuery
                                     .getLibDestructorName();
 
-                            GlobalData.setLibInstanceInfo(libInstanceName,
-                                    libConstructName, libDestructName);
-                        } else {
-                            libConstructName = GlobalData
-                                    .getLibInstanceConstructor(libInstanceName);
-                            libDestructName = GlobalData
-                                    .getLibInstanceDestructor(libInstanceName);
-                        }
                         SurfaceAreaQuery.pop();
                         //
                         // Add dependent library instance constructor function.
@@ -1440,8 +1387,7 @@ public class AutoGen {
                 //
                 // Add library destructor to AutoGen.c
                 //
-                LibDestructorToAutogenC(libDestructList, moduleType,
-                        fileBuffer/* autogenC */);
+                LibDestructorToAutogenC(libDestructList, moduleType, fileBuffer/* autogenC */);
             }
 
         } catch (Exception e) {
@@ -1449,24 +1395,26 @@ public class AutoGen {
         }
     }
 
- 
     /**
-      LibConstructorToAutogenc
-    
-      This function writes library constructor list to AutoGen.c. The library 
-      constructor's parameter and return value depend on module type.
-    
-      @param  libInstanceList        List of library construct name.
-      @param  moduleType             Module type.
-      @param  fileBuffer             String buffer for AutoGen.c
-      @throws Exception              
-    **/
+     * LibConstructorToAutogenc
+     * 
+     * This function writes library constructor list to AutoGen.c. The library
+     * constructor's parameter and return value depend on module type.
+     * 
+     * @param libInstanceList
+     *            List of library construct name.
+     * @param moduleType
+     *            Module type.
+     * @param fileBuffer
+     *            String buffer for AutoGen.c
+     * @throws Exception
+     */
     void LibConstructorToAutogenC(List<String> libInstanceList,
             String moduleType, StringBuffer fileBuffer) throws Exception {
         boolean isFirst = true;
 
         //
-        // The library constructor's parameter and return value depend on 
+        // The library constructor's parameter and return value depend on
         // module type.
         //
         for (int i = 0; i < libInstanceList.size(); i++) {
@@ -1577,16 +1525,19 @@ public class AutoGen {
     }
 
     /**
-      LibDestructorToAutogenc
-    
-      This function writes library destructor list to AutoGen.c. The library 
-      destructor's parameter and return value depend on module type.
-    
-      @param  libInstanceList        List of library destructor name.
-      @param  moduleType             Module type.
-      @param  fileBuffer             String buffer for AutoGen.c
-      @throws Exception              
-    **/
+     * LibDestructorToAutogenc
+     * 
+     * This function writes library destructor list to AutoGen.c. The library
+     * destructor's parameter and return value depend on module type.
+     * 
+     * @param libInstanceList
+     *            List of library destructor name.
+     * @param moduleType
+     *            Module type.
+     * @param fileBuffer
+     *            String buffer for AutoGen.c
+     * @throws Exception
+     */
     void LibDestructorToAutogenC(List<String> libInstanceList,
             String moduleType, StringBuffer fileBuffer) throws Exception {
         boolean isFirst = true;
@@ -1666,12 +1617,13 @@ public class AutoGen {
     }
 
     /**
-      ExternsDriverBindingToAutoGenC
-      
-      This function is to write DRIVER_BINDING, COMPONENT_NAME, 
-      DRIVER_CONFIGURATION, DRIVER_DIAGNOSTIC in AutoGen.c.
-      
-      @param  fileBuffer             String buffer for AutoGen.c
+     * ExternsDriverBindingToAutoGenC
+     * 
+     * This function is to write DRIVER_BINDING, COMPONENT_NAME,
+     * DRIVER_CONFIGURATION, DRIVER_DIAGNOSTIC in AutoGen.c.
+     * 
+     * @param fileBuffer
+     *            String buffer for AutoGen.c
      */
     void ExternsDriverBindingToAutoGenC(StringBuffer fileBuffer)
             throws BuildException {
@@ -1681,12 +1633,12 @@ public class AutoGen {
         // under <extern> should be same. 1. DRIVER_BINDING 2. COMPONENT_NAME
         // 3.DRIVER_CONFIGURATION 4. DRIVER_DIAGNOSTIC
         //
-        
+
         String[] drvBindList = SurfaceAreaQuery.getDriverBindingArray();
-        
+
         //
         // If component name protocol,component configuration protocol,
-        // component diagnostic protocol is not null or empty, check 
+        // component diagnostic protocol is not null or empty, check
         // if every one have the same number of the driver binding protocol.
         //
         if (drvBindList == null || drvBindList.length == 0) {
@@ -1819,14 +1771,15 @@ public class AutoGen {
     }
 
     /**
-      ExternCallBackToAutoGenC
-    
-      This function adds <SetVirtualAddressMapCallBack> and <ExitBootServicesCallBack>
-      infomation to AutoGen.c
-    
-      @param  fileBuffer           String buffer for AutoGen.c
-      @throws BuildException
-    **/
+     * ExternCallBackToAutoGenC
+     * 
+     * This function adds <SetVirtualAddressMapCallBack> and
+     * <ExitBootServicesCallBack> infomation to AutoGen.c
+     * 
+     * @param fileBuffer
+     *            String buffer for AutoGen.c
+     * @throws BuildException
+     */
     void ExternCallBackToAutoGenC(StringBuffer fileBuffer)
             throws BuildException {
         String[] setVirtualList = SurfaceAreaQuery
@@ -2003,7 +1956,4 @@ public class AutoGen {
 
     }
 
-    private String getStringValue(XmlObject xmlDoc) {
-        return xmlDoc.getDomNode().getFirstChild().getNodeValue();
-    }
-}
+}
\ No newline at end of file
diff --git a/Tools/Source/GenBuild/org/tianocore/build/autogen/AutogenLibOrder.java b/Tools/Source/GenBuild/org/tianocore/build/autogen/AutogenLibOrder.java
index 50668b096b..f08fec70e7 100644
--- a/Tools/Source/GenBuild/org/tianocore/build/autogen/AutogenLibOrder.java
+++ b/Tools/Source/GenBuild/org/tianocore/build/autogen/AutogenLibOrder.java
@@ -20,11 +20,13 @@ import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+
 import org.apache.xmlbeans.XmlObject;
 import org.tianocore.LibraryClassDocument.LibraryClass;
 
 import org.tianocore.build.global.GlobalData;
 import org.tianocore.build.global.SurfaceAreaQuery;
+import org.tianocore.build.id.ModuleIdentification;
 
 /**
   This class This class is to reorder library instance sequence according to
@@ -34,18 +36,18 @@ public class AutogenLibOrder {
     ///
     /// The map of library class and its library instance.
     ///
-    private Map<String, String> libClassMap = new HashMap<String, String>();
+    private Map<String, ModuleIdentification> libClassMap = new HashMap<String, ModuleIdentification>();
 
     ///
-    /// The map of library instance and its implemet instance.
+    /// The map of library instance and its implemet libraryClass.
     ///
-    private Map<String, String[]> libInstanceMap = new HashMap<String, String[]>();
+    private Map<ModuleIdentification, String[]> libInstanceMap = new HashMap<ModuleIdentification, String[]>();
 
     ///
     /// List of library instance. It is String[3] list, String[0] is libraryName,
     /// String[1] is libraryConstructor name, String[2] is libDestructor name.
     ///
-    private List<String[]> libInstanceList = new ArrayList<String[]>();
+    private List<LibraryInstanceNode> libInstanceList = new ArrayList<LibraryInstanceNode>();
     
     /**
       Constructor function
@@ -55,40 +57,37 @@ public class AutogenLibOrder {
       @param  libraryList   List of the library instance.
       @throws Exception
     **/
-    AutogenLibOrder(List<String> libraryList) throws Exception {
-        String[]       libInstance = new String[3];
-        LibraryClass[] libClassDeclList = null;
-        LibraryClass[] libClassConsmList = null;
+    AutogenLibOrder(ModuleIdentification[] libraryList, String arch) throws Exception {
+        LibraryInstanceNode libInstanceNode;
+        String[]       libClassDeclList = null;
+        String[]       libClassConsmList = null;
         
-        for (int i = 0; i < libraryList.size(); i++) {
+        for (int i = 0; i < libraryList.length; i++) {
             //
             // Add libraryInstance in to libInstanceList.
-            //
-            libInstance[0] = libraryList.get(i);
-            Map<String, XmlObject> libDoc = GlobalData.getDoc(libInstance[0]);
+            // 
+            Map<String, XmlObject> libDoc = GlobalData.getDoc(libraryList[i], arch);
             SurfaceAreaQuery.push(libDoc);
-            libInstance[1] = SurfaceAreaQuery.getLibConstructorName();
-            libInstance[2] = SurfaceAreaQuery.getLibDestructorName();
-            libInstanceList.add(libInstance.clone());
+            libInstanceNode = new LibraryInstanceNode (libraryList[i],SurfaceAreaQuery.getLibConstructorName(), SurfaceAreaQuery.getLibDestructorName());
+            libInstanceList.add(libInstanceNode);
             
             //
             // Add library instance and consumed library class list to
             // libInstanceMap.
             //
             libClassConsmList = SurfaceAreaQuery
-                    .getLibraryClassArray(CommonDefinition.AlwaysConsumed);
+                    .getLibraryClasses(CommonDefinition.AlwaysConsumed);
             if (libClassConsmList != null) {
                 String[] classStr = new String[libClassConsmList.length];
                 for (int k = 0; k < libClassConsmList.length; k++) {
-                    //classStr[k] = libClassConsmList[k].getStringValue();
-                    classStr[k] = getStringValue((XmlObject)libClassConsmList[k]);
+                    classStr[k] = libClassConsmList[k];
                 }
-                if (this.libInstanceMap.containsKey(libInstance[0])) {
+                if (this.libInstanceMap.containsKey(libraryList[i])) {
                     throw new Exception(
-                            libInstance[0]
+                            libraryList[i].getName()
                                     + "this library instance is already exist, please check you library instance list!");
                 } else {
-                    this.libInstanceMap.put(libInstance[0], classStr);
+                    this.libInstanceMap.put(libraryList[i], classStr);
                 }
             }
 
@@ -96,20 +95,17 @@ public class AutogenLibOrder {
             // Add library class and library instance map.
             //
             libClassDeclList = SurfaceAreaQuery
-                    .getLibraryClassArray(CommonDefinition.AlwaysProduced);
+                    .getLibraryClasses(CommonDefinition.AlwaysProduced);
             if (libClassDeclList != null) {
                 for (int j = 0; j < libClassDeclList.length; j++) {
-                    //if (this.libClassMap.containsKey(libClassDeclList[j]
-                    //        .getStringValue())) {
-                    String libClassName = getStringValue((XmlObject)libClassDeclList[j]);
-                    if (this.libClassMap.containsKey(libClassName)) {
-                        System.out.println(libClassName
+                    if (this.libClassMap.containsKey(libClassDeclList[j])) {
+                        System.out.println(libClassDeclList[j]
                                 + " class is already implement by "
-                                + this.libClassMap.get(libClassName));
+                                + this.libClassMap.get(libClassDeclList[j]));
                         throw new Exception(libClassDeclList
                                 + " is already have library instance!");
                     } else {
-                        this.libClassMap.put(libClassName, libInstance[0]);
+                        this.libClassMap.put(libClassDeclList[j], libraryList[i]);
                     }
                 }
             }
@@ -149,15 +145,15 @@ public class AutogenLibOrder {
       
       @return     List which content the ordered library instance.
     **/
-    List orderLibInstance() {
-        List<String> orderList = new ArrayList<String>();
+    List<ModuleIdentification> orderLibInstance() {
+        List<ModuleIdentification> orderList = new ArrayList<ModuleIdentification>();
         //
         // Stack of node which track the library instance name ant its visiting
         // flag.
         //
         List<Node> stackList = new ArrayList<Node>();
         int stackSize = 0;
-        String libInstance = null;
+        ModuleIdentification libInstanceId = null;
         if (libInstanceList.size() < 0) {
             return null;
         }
@@ -169,11 +165,11 @@ public class AutogenLibOrder {
             //
             // If library instance is already in the order list skip it.
             //
-            if (isInLibInstance(orderList, libInstanceList.get(i)[0])) {
+            if (isInLibInstance(orderList, libInstanceList.get(i).libId)) {
                 continue;
             }
             
-            Node node = new Node(libInstanceList.get(i)[0], false);
+            Node node = new Node(libInstanceList.get(i).libId, false);
             //
             // Use stack to reorder library instance.
             // Push node to stack.
@@ -187,8 +183,8 @@ public class AutogenLibOrder {
                 //
                 if (stackList.get(stackSize).isVisit) {
                     if (!isInLibInstance(orderList,
-                            stackList.get(stackSize).nodeName)) {
-                        orderList.add(stackList.get(stackSize).nodeName);
+                            stackList.get(stackSize).nodeId)) {
+                        orderList.add(stackList.get(stackSize).nodeId);
                         stackList.remove(stackSize);
                     }
                     
@@ -198,15 +194,15 @@ public class AutogenLibOrder {
                     //
                     stackList.get(stackList.size() - 1).isVisit = true;
                     String[] libClassList = this.libInstanceMap.get(stackList
-                            .get(stackSize).nodeName);
+                            .get(stackSize).nodeId);
                     //
                     // Push the node dependence library instance to the stack.
                     //
                     if (libClassList != null) {
                         for (int j = 0; j < libClassList.length; j++) {
-                            libInstance = this.libClassMap.get(libClassList[j]);
-                            if (libInstance != null
-                                    && !isInLibInstance(orderList, libInstance)) {
+                            libInstanceId = this.libClassMap.get(libClassList[j]);
+                            if (libInstanceId != null
+                                    && !isInLibInstance(orderList, libInstanceId)) {
                                 //
                                 // If and only if the currently library instance
                                 // is not in stack and it have constructor or 
@@ -214,7 +210,7 @@ public class AutogenLibOrder {
                                 // instacne in stack.
                                 //
                                 if (!isInStackList(stackList, this.libClassMap
-                                        .get(libClassList[j])) && isHaveConsDestructor(libInstance)) {
+                                        .get(libClassList[j])) && isHaveConsDestructor(libInstanceId)) {
                                     stackList.add(new Node(this.libClassMap
                                             .get(libClassList[j]), false));
                                 }
@@ -237,9 +233,10 @@ public class AutogenLibOrder {
       @return                 "true" the library instance in list |
                               "false" the library instance is not in list.
     **/
-    private boolean isInLibInstance(List list, String instanceName) {
+    private boolean isInLibInstance(List<ModuleIdentification> list, ModuleIdentification instanceId) {
         for (int i = 0; i < list.size(); i++) {
-            if (instanceName.equalsIgnoreCase(list.get(i).toString())) {
+            
+            if (instanceId.equals(list.get(i))) {
                 return true;
             }
         }
@@ -256,9 +253,9 @@ public class AutogenLibOrder {
       @return            "true" if node have in stack |
                          "false" if node don't in stack.
     **/ 
-    private boolean isInStackList(List<Node> list, String nodeName) {
+    private boolean isInStackList(List<Node> list, ModuleIdentification instanceId) {
         for (int i = 0; i < list.size(); i++) {
-            if (nodeName.equalsIgnoreCase(list.get(i).nodeName)) {
+            if (instanceId.equals(list.get(i).nodeId)) {
                 return true;
             }
         }
@@ -276,20 +273,16 @@ public class AutogenLibOrder {
                          "false" if library don't have constructor 
                          and desconstructor.
     **/
-    private boolean isHaveConsDestructor (String libName){
+    private boolean isHaveConsDestructor (ModuleIdentification libNode){
         for (int i = 0; i < libInstanceList.size(); i++){
-            if (libInstanceList.get(i)[0].equalsIgnoreCase(libName)){
-                if (libInstanceList.get(i)[1] != null || libInstanceList.get(i)[2] != null){
+            if (libInstanceList.get(i).libId.equals(libNode)){
+                if (libInstanceList.get(i).constructorName != null || libInstanceList.get(i).deconstructorName != null){
                     return true;
                 }
             }
         }
         return false;
     }
-
-    private String getStringValue(XmlObject xmlDoc) {
-        return xmlDoc.getDomNode().getFirstChild().getNodeValue();
-    }
 }
 
 /**
@@ -299,12 +292,29 @@ public class AutogenLibOrder {
  
  **/
 class Node {
-    String nodeName;
+    ModuleIdentification nodeId;
 
     boolean isVisit;
 
-    Node(String name, boolean isVisit) {
-        this.nodeName = name;
+    Node(ModuleIdentification nodeId, boolean isVisit) {
+        this.nodeId = nodeId;
         this.isVisit = false;
     }
-}
\ No newline at end of file
+}  
+/**
+  LibraryInstance Node   
+  
+  This class is used to store LibrayInstance and it's deconstructor and constructor
+**/
+    
+class LibraryInstanceNode {
+    ModuleIdentification libId;
+    String deconstructorName;
+    String constructorName;
+    
+    LibraryInstanceNode (ModuleIdentification libId, String deconstructor, String constructor){
+        this.libId = libId;
+        this.deconstructorName = deconstructor;
+        this.constructorName   = constructor;
+    }
+}
diff --git a/Tools/Source/GenBuild/org/tianocore/build/autogen/CommonDefinition.java b/Tools/Source/GenBuild/org/tianocore/build/autogen/CommonDefinition.java
index 2da1c6b6f5..f449cb3a7c 100644
--- a/Tools/Source/GenBuild/org/tianocore/build/autogen/CommonDefinition.java
+++ b/Tools/Source/GenBuild/org/tianocore/build/autogen/CommonDefinition.java
@@ -44,6 +44,7 @@ public class CommonDefinition {
     public final static String autoGenHReleaseDefault = "#define EDK_RELEASE_VERSION        0x00000000\r\n";
 
     public final static String includeAutogenH        = "#include    <AutoGen.h>\r\n" ;
+    public final static String marcDefineStr          = "#define ";
 
     public final static String gEfi = "gEfi";
     public final static String protocolGuid = "ProtocolGuid";
@@ -148,10 +149,10 @@ public class CommonDefinition {
                     new MyEnum("PEI_CORE", ModuleTypePeiCore),
                     new MyEnum("PEIM", ModuleTypePeim),
                     new MyEnum("DXE_CORE", ModuleTypeDxeCore),
-                    new MyEnum("DXE_DRIVER", ModuleTypeDxeDriver),
+                    new MyEnum("DXE_DRIVER", ModuleTypeDxeRuntimeDriver),
                     new MyEnum("DXE_RUNTIME_DRIVER", ModuleTypeDxeRuntimeDriver),
-                    new MyEnum("DXE_SMM_DRIVER", ModuleTypeDxeSmmDriver),
                     new MyEnum("DXE_SAL_DRIVER", ModuleTypeDxeSalDriver),
+                    new MyEnum("DXE_SMM_DRIVER", ModuleTypeDxeSmmDriver),
                     new MyEnum("UEFI_DRIVER", ModuleTypeUefiDriver),
                     new MyEnum("UEFI_APPLICATION", ModuleTypeUefiApplication) };
     
@@ -254,29 +255,64 @@ public class CommonDefinition {
       }
       return false;
     }
+    
+    /**
+     * formateGuidName
+     * 
+     * This function is to formate GUID to ANSI c form.
+     * 
+     * @param guidNameCon
+     *            String of GUID.
+     * @return Formated GUID.
+     */
+    public static String formatGuidName(String guidNameConv) {
+        String[] strList;
+        String guid = "";
+        int index = 0;
+        if (guidNameConv
+                .matches("[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}")) {
+            strList = guidNameConv.split("-");
+            guid = "0x" + strList[0] + ", ";
+            guid = guid + "0x" + strList[1] + ", ";
+            guid = guid + "0x" + strList[2] + ", ";
+            guid = guid + "{";
+            guid = guid + "0x" + strList[3].substring(0, 2) + ", ";
+            guid = guid + "0x" + strList[3].substring(2, 4);
 
-		static public boolean isPeiPhaseComponent (int componentType) {
-			if (ComponentTypePe32Peim == componentType
-					|| ComponentTypePicPeim == componentType
-					|| ComponentTypeCombinedPeimDriver == componentType
-					|| ComponentTypePeiCore == componentType) {
-				return true;
-			}
-			return false;
-		}
+            while (index < strList[4].length()) {
+                guid = guid + ", ";
+                guid = guid + "0x" + strList[4].substring(index, index + 2);
+                index = index + 2;
+            }
+            guid = guid + "}";
+            return guid;
+        } else if (guidNameConv
+                .matches("0x[a-fA-F0-9]{1,8},( )*0x[a-fA-F0-9]{1,4},( )*0x[a-fA-F0-9]{1,4}(,( )*\\{)?(,?( )*0x[a-fA-F0-9]{1,2}){8}( )*(\\})?")) {
+            strList = guidNameConv.split(",");
 
-		static public boolean isPe32PeimComponent (int componentType) {
-			if (ComponentTypePe32Peim == componentType) {
-				return true;
-			}
-			return false;
-		}
+            //
+            // chang Microsoft specific form to ANSI c form
+            //
+            for (int i = 0; i < 3; i++) {
+                guid = guid + strList[i] + ",";
+            }
+            guid = guid + "{";
 
-		static public boolean isBsDriverComponent (int componentType) {
-			if (ComponentTypeBsDriver == componentType) {
-				return true;
-			}
-			return false;
-		}
-		
-}
+            for (int i = 3; i < strList.length; i++) {
+                if (i == strList.length - 1) {
+                    guid = guid + strList[i];
+                } else {
+                    guid = guid + strList[i] + ",";
+                }
+            }
+            guid = guid + "}";
+            return guid;
+        } else {
+            System.out
+                    .println("Check GUID Value, it don't conform to the schema!!!");
+            return "0";
+
+        }
+    }
+    
+}
\ No newline at end of file
diff --git a/Tools/Source/GenBuild/org/tianocore/build/exception/AutoGenException.java b/Tools/Source/GenBuild/org/tianocore/build/exception/AutoGenException.java
new file mode 100644
index 0000000000..0faf6c7113
--- /dev/null
+++ b/Tools/Source/GenBuild/org/tianocore/build/exception/AutoGenException.java
@@ -0,0 +1,39 @@
+/** @file
+  AutoGenException class.
+
+  The class handle the exception throwed by entity class.
+ 
+Copyright (c) 2006, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution.  The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+ 
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/   
+package org.tianocore.build.exception;
+
+
+/**
+  The class handle the exception throwed by entity class.
+**/
+public class AutoGenException extends GenBuildException {
+    //static final long serialVersionUID = -8034897190740066939L;
+    /**
+      Constructure function
+        
+      @param expStr exception message string.
+    **/
+    public AutoGenException(String expStr) {
+        super("[AutoGenException]:" + expStr);
+    }
+    
+    public AutoGenException() {
+        super();
+    }
+    public AutoGenException(Exception e, String messsge){
+        super(e, messsge);
+    }
+}
\ No newline at end of file
diff --git a/Tools/Source/GenBuild/org/tianocore/build/exception/EdkException.java b/Tools/Source/GenBuild/org/tianocore/build/exception/EdkException.java
new file mode 100644
index 0000000000..8be839bb48
--- /dev/null
+++ b/Tools/Source/GenBuild/org/tianocore/build/exception/EdkException.java
@@ -0,0 +1,36 @@
+/** @file
+  EntityException class.
+
+  The class handle the exception throwed by entity class.
+ 
+Copyright (c) 2006, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution.  The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+ 
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/   
+package org.tianocore.build.exception;
+
+/**
+  The class handle the exception throwed by entity class.
+**/
+public class EdkException extends Exception {
+    //static final long serialVersionUID = -8034897190740066939L;
+    /**
+      Constructure function
+        
+      @param expStr exception message string.
+    **/
+    public EdkException(String expStr) {
+        super("[EdkException]:" + expStr);
+    }
+    
+    public EdkException() {
+        super();
+    }
+}
+
diff --git a/Tools/Source/GenBuild/org/tianocore/build/exception/GenBuildException.java b/Tools/Source/GenBuild/org/tianocore/build/exception/GenBuildException.java
new file mode 100644
index 0000000000..ac75ca8f9d
--- /dev/null
+++ b/Tools/Source/GenBuild/org/tianocore/build/exception/GenBuildException.java
@@ -0,0 +1,40 @@
+/** @file
+  GenBuildException class.
+
+  The class handle the exception throwed by entity class.
+ 
+Copyright (c) 2006, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution.  The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+ 
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/   
+package org.tianocore.build.exception;
+
+import org.tianocore.build.exception.EdkException;
+
+/**
+  The class handle the exception throwed by entity class.
+**/
+public class GenBuildException extends EdkException {
+    //static final long serialVersionUID = -8034897190740066939L;
+    /**
+      Constructure function
+        
+      @param expStr exception message string.
+    **/
+    public GenBuildException(String expStr) {
+        super("[GenBuildException]:" + expStr);
+    }
+    
+    public GenBuildException() {
+        super();
+    }
+    public GenBuildException(Exception e, String message){
+//        super(e, message);
+    }
+}
diff --git a/Tools/Source/GenBuild/org/tianocore/build/exception/PcdAutogenException.java b/Tools/Source/GenBuild/org/tianocore/build/exception/PcdAutogenException.java
new file mode 100644
index 0000000000..49d5543e11
--- /dev/null
+++ b/Tools/Source/GenBuild/org/tianocore/build/exception/PcdAutogenException.java
@@ -0,0 +1,35 @@
+/** @file
+  AutoGenException class.
+
+  The class handle the exception throwed by entity class.
+ 
+Copyright (c) 2006, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution.  The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+ 
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/   
+package org.tianocore.build.exception;
+
+/**
+  The class handle the exception throwed by entity class.
+**/
+public class PcdAutogenException extends AutoGenException {
+    //static final long serialVersionUID = -8034897190740066939L;
+    /**
+      Constructure function
+        
+      @param expStr exception message string.
+    **/
+    public PcdAutogenException(String expStr) {
+        super("[PcdAutogenException]:" + expStr);
+    }
+    
+    public PcdAutogenException() {
+        super();
+    }
+}
diff --git a/Tools/Source/GenBuild/org/tianocore/build/exception/TianoToolsException.java b/Tools/Source/GenBuild/org/tianocore/build/exception/TianoToolsException.java
new file mode 100644
index 0000000000..3ab2fcf448
--- /dev/null
+++ b/Tools/Source/GenBuild/org/tianocore/build/exception/TianoToolsException.java
@@ -0,0 +1,41 @@
+/** @file
+  TianoToolsException class.
+
+  The class handle the exception throwed by entity class.
+ 
+Copyright (c) 2006, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution.  The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+ 
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/   
+package org.tianocore.build.exception;
+
+import org.tianocore.build.exception.EdkException;
+
+/**
+  The class handle the exception throwed by entity class.
+**/
+public class TianoToolsException extends EdkException {
+    //static final long serialVersionUID = -8034897190740066939L;
+    /**
+      Constructure function
+        
+      @param expStr exception message string.
+    **/
+    public TianoToolsException(String expStr) {
+        super("[TianoToolsException]:" + expStr);
+    }
+    
+    public TianoToolsException() {
+        super();
+    }
+    
+    public TianoToolsException (Exception e, String message){
+//        super(e, message);
+    }
+}
diff --git a/Tools/Source/GenBuild/org/tianocore/build/exception/XmlParseException.java b/Tools/Source/GenBuild/org/tianocore/build/exception/XmlParseException.java
new file mode 100644
index 0000000000..afa92f4598
--- /dev/null
+++ b/Tools/Source/GenBuild/org/tianocore/build/exception/XmlParseException.java
@@ -0,0 +1,35 @@
+/** @file
+  XmlParseException class.
+
+  The class handle the exception throwed by entity class.
+ 
+Copyright (c) 2006, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution.  The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+ 
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/   
+package org.tianocore.build.exception;
+
+/**
+  The class handle the exception throwed by entity class.
+**/
+public class XmlParseException extends GenBuildException {
+    //static final long serialVersionUID = -8034897190740066939L;
+    /**
+      Constructure function
+        
+      @param expStr exception message string.
+    **/
+    public XmlParseException(String expStr) {
+        super("[XmlParseException]:" + expStr);
+    }
+    
+    public XmlParseException() {
+        super();
+    }
+}
\ No newline at end of file
diff --git a/Tools/Source/GenBuild/org/tianocore/build/fpd/FpdParserTask.java b/Tools/Source/GenBuild/org/tianocore/build/fpd/FpdParserTask.java
index 21197b5c62..59bb47faa4 100644
--- a/Tools/Source/GenBuild/org/tianocore/build/fpd/FpdParserTask.java
+++ b/Tools/Source/GenBuild/org/tianocore/build/fpd/FpdParserTask.java
@@ -1,18 +1,18 @@
 /** @file
-  This file is ANT task FpdParserTask. 
+ This file is ANT task FpdParserTask. 
  
-  FpdParserTask is used to parse FPD (Framework Platform Description) and generate
-  build.out.xml. It is for Package or Platform build use. 
+ FpdParserTask is used to parse FPD (Framework Platform Description) and generate
+ build.out.xml. It is for Package or Platform build use. 
  
-Copyright (c) 2006, Intel Corporation
-All rights reserved. This program and the accompanying materials
-are licensed and made available under the terms and conditions of the BSD License
-which accompanies this distribution.  The full text of the license may be found at
-http://opensource.org/licenses/bsd-license.php
+ Copyright (c) 2006, Intel Corporation
+ All rights reserved. This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution.  The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
 
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
-**/
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+ **/
 package org.tianocore.build.fpd;
 
 import java.io.BufferedWriter;
@@ -25,67 +25,67 @@ import java.util.LinkedHashSet;
 import java.util.Map;
 import java.util.Set;
 import java.util.Vector;
-
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.transform.OutputKeys;
-import javax.xml.transform.Result;
-import javax.xml.transform.Source;
-import javax.xml.transform.Transformer;
-import javax.xml.transform.TransformerFactory;
-import javax.xml.transform.dom.DOMSource;
-import javax.xml.transform.stream.StreamResult;
+import java.util.TreeMap;
 
 import org.apache.tools.ant.BuildException;
 import org.apache.tools.ant.Task;
+import org.apache.tools.ant.taskdefs.Ant;
 import org.apache.tools.ant.taskdefs.Property;
 import org.apache.xmlbeans.XmlObject;
-import org.w3c.dom.Comment;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
 
+import org.tianocore.build.exception.EdkException;
 import org.tianocore.build.global.GlobalData;
 import org.tianocore.build.global.OutputManager;
-import org.tianocore.build.global.OverrideProcess;
 import org.tianocore.build.global.SurfaceAreaQuery;
-import org.tianocore.build.pcd.action.CollectPCDAction;
-import org.tianocore.build.pcd.action.ActionMessage;
-import org.tianocore.BuildOptionsDocument;
-import org.tianocore.FrameworkPlatformDescriptionDocument;
-import org.tianocore.ModuleSADocument;
-
+import org.tianocore.build.id.FpdModuleIdentification;
+import org.tianocore.build.id.ModuleIdentification;
+import org.tianocore.build.id.PlatformIdentification;
+import org.tianocore.build.toolchain.ToolChainAttribute;
+import org.tianocore.build.toolchain.ToolChainElement;
+import org.tianocore.build.toolchain.ToolChainMap;
 
 /**
-  <code>FpdParserTask</code> is an ANT task. The main function is parsing FPD
-  XML file and generating its ANT build script for Platform or Package. 
+  <code>FpdParserTask</code> is an ANT task. The main function is parsing Framework
+  Platform Descritpion (FPD) XML file and generating its ANT build script for 
+  corresponding platform.  
+
+  <p>The task sets global properties PLATFORM, PLATFORM_DIR, PLATFORM_RELATIVE_DIR
+  and BUILD_DIR. </p>
+  
+  <p>The task generates ${PLATFORM}_build.xml file which will be called by top level
+  build.xml. The task also generate Fv.inf files (File is for Tool GenFvImage) 
+  and flash definition file (File is for Tool FlashMap) if necessary. </p>
+  
+  <p>FpdParserTask task stores all FPD information to GlobalData. And parse
+  tools definition file to set up compiler options for different Target and
+  different ToolChainTag. </p>
+  
+  <p>The method parseFpdFile is also prepared for single module build. </p>
   
   <p>The usage is (take NT32 Platform for example):</p>
-  
+
   <pre>
-    &lt;FPDParser fpdfilename="Build\Nt32.fpd" /&gt;
+  &lt;FPDParser platformName="Nt32" /&gt;
   </pre>
-  
+
   <p>The task will initialize all information through parsing Framework Database, 
   SPD, Tool chain configuration files. </p>
-  
+
   @since GenBuild 1.0
 **/
 public class FpdParserTask extends Task {
+    
+    private String platformName;
 
+    private File fpdFile = null;
+    
+    private PlatformIdentification platformId;
+    
     ///
-    /// FV dir: ${PLATFORM_DIR}/Build/FV
+    /// 
     ///
-    public static final String FV_OUTPUT_DIR = "${PLATFORM_DIR}" + File.separatorChar + "Build" + File.separatorChar + "FV";
-
-    private File fpdFilename;
-
-    private File guiddatabase;
-
-    ///
-    /// Keep platform buildoption information
-    ///
-    public static XmlObject platformBuildOptions = null;
-
+    private String type;
+    
     ///
     /// Mapping from modules identification to out put file name
     ///
@@ -94,102 +94,138 @@ public class FpdParserTask extends Task {
     ///
     /// Mapping from FV name to its modules
     ///
-    private Map<String, Set<FpdModuleIdentification> > fvs = new HashMap<String, Set<FpdModuleIdentification> >();
+    private Map<String, Set<FpdModuleIdentification>> fvs = new HashMap<String, Set<FpdModuleIdentification>>();
 
     ///
-    /// Mapping from sequence number to its modules
+    /// Mapping from sequence number to FV names
     ///
-    private Map<String, Set<FpdModuleIdentification> > sequences = new HashMap<String, Set<FpdModuleIdentification> >();
+    private Map<String, Set<String>> sequences = new TreeMap<String, Set<String>>();
 
     ///
     /// FpdParserTask can specify some ANT properties. 
     ///
     private Vector<Property> properties = new Vector<Property>();
+    
+    private boolean isUnified = true;
 
-    private String info = "====================================================================\n"
-                    + "DO NOT EDIT \n"
-                    + "File auto-generated by build utility\n"
-                    + "\n"
-                    + "Abstract:\n"
-                    + "Auto-generated ANT build file for building of EFI Modules/Platforms\n"
-                    + "=====================================================================";
 
     /**
       Public construct method. It is necessary for ANT task.
     **/
-    public FpdParserTask () {
+    public FpdParserTask() {
     }
 
     /**
-      ANT task's entry method. The main steps is described as following: 
-      
-      <ul>
-        <li>Initialize global information (Framework DB, SPD files and all MSA files 
-        listed in SPD). This step will execute only once in whole build process;</li>
-        <li>Parse specified FPD file; </li>
-        <li>Generate FV.inf files; </li>
-        <li>Generate build.out.xml file for Flatform or Package build; </li>
-        <li>Collect PCD information. </li>
-      </ul>
-      
-      @throws BuildException
-                  Surface area is not valid. 
+     ANT task's entry method. The main steps is described as following: 
+     
+     <ul>
+     <li>Initialize global information (Framework DB, SPD files and all MSA files 
+     listed in SPD). This step will execute only once in whole build process;</li>
+     <li>Parse specified FPD file; </li>
+     <li>Generate FV.inf files; </li>
+     <li>Generate PlatformName_build.xml file for Flatform build; </li>
+     <li>Collect PCD information. </li>
+     </ul>
+     
+     @throws BuildException
+     Surface area is not valid. 
     **/
     public void execute() throws BuildException {
-        OutputManager.update(getProject());
-        //
-        // Parse DB and SPDs files. Initialize Global Data
-        //
-        GlobalData.initInfo("Tools" + File.separatorChar + "Conf" + File.separatorChar + "FrameworkDatabase.db", getProject()
-                        .getProperty("WORKSPACE_DIR"));
+        // Remove !!
+        if ( fpdFile == null) {
+            if (platformName == null) {
+                throw new BuildException("FpdParserTask parameter error. Please specify platform name or FPD file. ");
+            }
+            platformId = GlobalData.getPlatform(platformName);
+            fpdFile = platformId.getFpdFile();
+        }
+        
         //
         // Parse FPD file
         //
         parseFpdFile();
+        
         //
-        // Gen Fv.inf files
+        // Prepare BUILD_DIR
         //
-        genFvInfFiles();
+        isUnified = OutputManager.getInstance().prepareBuildDir(getProject());
+        
+        //
+        // Generate FDF (Flash Definition File) file
+        //
+
+        //
+        // For every Target and ToolChain
+        //
+        String[] targetList = GlobalData.getToolChainInfo().getTargets();
+        for (int i = 0; i < targetList.length; i++){
+            String[] toolchainList = GlobalData.getToolChainInfo().getTagnames();
+            for(int j = 0; j < toolchainList.length; j++){
+                //
+                // Prepare FV_DIR
+                //
+                String ffsCommonDir = getProject().getProperty("BUILD_DIR") + File.separatorChar 
+                                + targetList[i] + File.separatorChar 
+                                + toolchainList[j];
+                File fvDir = new File(ffsCommonDir + File.separatorChar + "FV");
+                fvDir.mkdirs();
+                getProject().setProperty("FV_DIR", fvDir.getPath().replaceAll("(\\\\)", "/"));
+                
+                //
+                // Gen Fv.inf files
+                //
+                genFvInfFiles(ffsCommonDir);
+            }
+        }
+
         //
         // Gen build.xml
         //
-        genBuildFile();
+        PlatformBuildFileGenerator fileGenerator = new PlatformBuildFileGenerator(getProject(), outfiles, fvs, sequences, isUnified);
+        fileGenerator.genBuildFile();
+        
         //
-        // Collect PCD information 
-        // 
-        collectPCDInformation (); 
+        // Ant call ${PLATFORM}_build.xml
+        //
+        Ant ant = new Ant();
+        ant.setProject(getProject());
+        ant.setAntfile(platformId.getFpdFile().getParent() + File.separatorChar + platformId.getName() + "_build.xml");
+        ant.setTarget(type);
+        ant.setInheritAll(true);
+        ant.init();
+        ant.execute();
+        
+//        GlobalData.log.info("Fpd build end. ");
     }
-    
+
     /**
       Generate Fv.inf files. The Fv.inf file is composed with four 
       parts: Options, Attributes, Components and Files. The Fv.inf files 
-      will be under ${PLATFOMR_DIR}\Build\Fv.
-      
+      will be under FV_DIR.
+     
       @throws BuildException
-              File write FV.inf files error. 
+                  File write FV.inf files error. 
     **/
-    private void genFvInfFiles() throws BuildException{
+    private void genFvInfFiles(String ffsCommonDir) throws BuildException {
         String[] validFv = SurfaceAreaQuery.getFpdValidImageNames();
         for (int i = 0; i < validFv.length; i++) {
-            getProject().setProperty("FV_FILENAME", validFv[i].toUpperCase());
             //
             // Get all global variables from FPD and set them to properties
             //
-            String[][] globalVariables = SurfaceAreaQuery
-                            .getFpdGlobalVariable();
+            String[][] globalVariables = SurfaceAreaQuery.getFpdGlobalVariable();
             for (int j = 0; j < globalVariables.length; j++) {
-                getProject().setProperty(globalVariables[j][0],
-                                globalVariables[j][1]);
+                getProject().setProperty(globalVariables[j][0], globalVariables[j][1]);
             }
 
-            File fvFile = new File(getProject().replaceProperties(
-                            FV_OUTPUT_DIR + File.separatorChar + validFv[i].toUpperCase()
-                                            + ".inf"));
+            getProject().setProperty("FV_FILENAME", validFv[i].toUpperCase());
+            
+            File fvFile = new File(getProject().replaceProperties( getProject().getProperty("FV_DIR") + File.separatorChar + validFv[i].toUpperCase() + ".inf"));
             fvFile.getParentFile().mkdirs();
 
             try {
                 FileWriter fw = new FileWriter(fvFile);
                 BufferedWriter bw = new BufferedWriter(fw);
+                
                 //
                 // Options
                 //
@@ -210,11 +246,11 @@ public class FpdParserTask extends Task {
                     }
                     bw.newLine();
                 }
+                
                 //
                 // Attributes;
                 //
-                String[][] attributes = SurfaceAreaQuery
-                                .getFpdAttributes(validFv[i]);
+                String[][] attributes = SurfaceAreaQuery.getFpdAttributes(validFv[i]);
                 if (attributes.length > 0) {
                     bw.write("[attributes]");
                     bw.newLine();
@@ -226,18 +262,16 @@ public class FpdParserTask extends Task {
                         }
                         str.append("=  ");
                         str.append(attributes[j][1]);
-                        bw
-                                        .write(getProject().replaceProperties(
-                                                        str.toString()));
+                        bw.write(getProject().replaceProperties(str.toString()));
                         bw.newLine();
                     }
                     bw.newLine();
                 }
+                
                 //
                 // Components
                 //
-                String[][] components = SurfaceAreaQuery
-                                .getFpdComponents(validFv[i]);
+                String[][] components = SurfaceAreaQuery.getFpdComponents(validFv[i]);
                 if (components.length > 0) {
                     bw.write("[components]");
                     bw.newLine();
@@ -249,26 +283,23 @@ public class FpdParserTask extends Task {
                         }
                         str.append("=  ");
                         str.append(components[j][1]);
-                        bw
-                                        .write(getProject().replaceProperties(
-                                                        str.toString()));
+                        bw.write(getProject().replaceProperties(str.toString()));
                         bw.newLine();
                     }
                     bw.newLine();
                 }
+                
                 //
                 // Files
                 //
                 Set<FpdModuleIdentification> filesSet = fvs.get(validFv[i].toUpperCase());
                 if (filesSet != null) {
-                    FpdModuleIdentification[] files = filesSet.toArray(new FpdModuleIdentification[filesSet
-                                    .size()]);
+                    FpdModuleIdentification[] files = filesSet.toArray(new FpdModuleIdentification[filesSet.size()]);
                     bw.write("[files]");
                     bw.newLine();
                     for (int j = 0; j < files.length; j++) {
-                        String str = outfiles.get(files[j]);
-                        bw.write(getProject().replaceProperties(
-                                        "EFI_FILE_NAME = " + str));
+                        String str = ffsCommonDir + File.separatorChar + outfiles.get(files[j]);
+                        bw.write(getProject().replaceProperties("EFI_FILE_NAME = " + str));
                         bw.newLine();
                     }
                 }
@@ -276,537 +307,286 @@ public class FpdParserTask extends Task {
                 bw.close();
                 fw.close();
             } catch (Exception e) {
-                throw new BuildException("Generate Fv.inf file failed. \n" + e.getMessage());
+                e.printStackTrace();
+                throw new BuildException("Generate FV file [" + fvFile.getPath() + "] failed. \n" + e.getMessage());
             }
         }
     }
+    /**
+      This method is used for Single Module Build.
+      
+      
+      @throws BuildException
+                  FPD file is not valid. 
+    **/
+    public void parseFpdFile(File fpdFile) throws BuildException {
+        this.fpdFile = fpdFile;
+        parseFpdFile();
+    }
 
     /**
       Parse FPD file. 
-    
+     
       @throws BuildException
-              FPD file is not valid. 
-    **/
+                  FPD file is not valid. 
+     **/
     private void parseFpdFile() throws BuildException {
         try {
-            FrameworkPlatformDescriptionDocument doc = (FrameworkPlatformDescriptionDocument) XmlObject.Factory
-                            .parse(fpdFilename);
-            if ( ! doc.validate() ){
-                throw new BuildException("FPD file is invalid.");
+            XmlObject doc = XmlObject.Factory.parse(fpdFile);
+            
+            if (!doc.validate()) {
+                throw new BuildException("Platform Surface Area file [" + fpdFile.getPath() + "] is invalid.");
             }
-            platformBuildOptions = doc.getFrameworkPlatformDescription()
-                            .getBuildOptions();
-            HashMap<String, XmlObject> map = new HashMap<String, XmlObject>();
-            map.put("FrameworkPlatformDescription", doc);
+            
+            Map<String, XmlObject> map = new HashMap<String, XmlObject>();
+            map.put("PlatformSurfaceArea", doc);
             SurfaceAreaQuery.setDoc(map);
+            
+            //
+            // Initialize
+            //
+            platformId = SurfaceAreaQuery.getFpdHeader();
+            platformId.setFpdFile(fpdFile);
+            getProject().setProperty("PLATFORM", platformId.getName());
+            getProject().setProperty("PLATFORM_DIR", platformId.getFpdFile().getParent().replaceAll("(\\\\)", "/"));
+            getProject().setProperty("PLATFORM_RELATIVE_DIR", platformId.getPlatformRelativeDir().replaceAll("(\\\\)", "/"));
+
+            //
+            // Build mode. User-defined output dir. 
+            //
+            String buildMode = SurfaceAreaQuery.getFpdIntermediateDirectories();
+            String userDefinedOutputDir = SurfaceAreaQuery.getFpdOutputDirectory();
+
+            OutputManager.getInstance().setup(userDefinedOutputDir, buildMode);
+
+            //
+            // TBD. Deal PCD and BuildOption related Info
+            //
+            GlobalData.setFpdBuildOptions(SurfaceAreaQuery.getFpdBuildOptions());
+            
+            GlobalData.setToolChainPlatformInfo(SurfaceAreaQuery.getFpdToolChainInfo());
+            
             //
             // Parse all list modules SA
             //
             parseModuleSAFiles();
+
+            //
+            // TBD. Deal PCD and BuildOption related Info
+            //
+            parseToolChainFamilyOptions();
+            parseToolChainOptions();
+
             SurfaceAreaQuery.setDoc(map);
         } catch (Exception e) {
-            throw new BuildException("Load FPD file [" + fpdFilename.getPath()
-                            + "] error. \n" + e.getMessage());
+            e.printStackTrace();
+            throw new BuildException("Load FPD file [" + fpdFile.getPath() + "] error. \n" + e.getMessage());
         }
     }
 
+
+    
     /**
       Parse all modules listed in FPD file. 
     **/
-    private void parseModuleSAFiles() {
-        ModuleSADocument.ModuleSA[] moduleSAs = SurfaceAreaQuery
-                        .getFpdModules();
+    private void parseModuleSAFiles() throws EdkException{
+        Map<FpdModuleIdentification, Map<String, XmlObject>> moduleSAs = SurfaceAreaQuery.getFpdModules();
+        System.out.println("Nubmer: ##" + moduleSAs.size());
         //
         // For every Module lists in FPD file.
         //
-        for (int i = 0; i < moduleSAs.length; i++) {
-            String defaultFv = "NULL";
-            String defaultArch = "IA32";
-            String baseName = moduleSAs[i].getModuleName();
+        Set<FpdModuleIdentification> keys = moduleSAs.keySet();
+        Iterator iter = keys.iterator();
+        while (iter.hasNext()) {
+            FpdModuleIdentification fpdModuleId = (FpdModuleIdentification) iter.next();
+            
+            //
+            // Judge if Module is existed? 
+            // TBD
+            
+            GlobalData.registerFpdModuleSA(fpdModuleId, moduleSAs.get(fpdModuleId));
+
+            //
+            // Put fpdModuleId to the corresponding FV
+            //
+            SurfaceAreaQuery.push(GlobalData.getDoc(fpdModuleId));
+            String fvBinding = SurfaceAreaQuery.getModuleFvBindingKeyword();
+            SurfaceAreaQuery.pop();
+
+            fpdModuleId.setFvBinding(fvBinding);
+            String fvSequence = fpdModuleId.getSequence();
+            updateFvs(fvSequence, fvBinding, fpdModuleId);
+            
+            //
+            // Prepare for out put file name
+            //
+            ModuleIdentification moduleId = fpdModuleId.getModule();
+            SurfaceAreaQuery.push(GlobalData.getDoc(fpdModuleId));
+            String baseName = SurfaceAreaQuery.getModuleOutputFileBasename();
+            SurfaceAreaQuery.pop();
             if (baseName == null) {
-                System.out.println("Warning: Module Name is not specified.");
-                continue;
+                baseName = moduleId.getName();
             }
-            String fvBinding = moduleSAs[i].getFvBinding();
+            outfiles.put(fpdModuleId, fpdModuleId.getArch() + File.separatorChar 
+                         + moduleId.getGuid() + "-" + baseName 
+                         + getSuffix(moduleId.getModuleType()));
+
             //
-            // If the module do not specify any FvBinding, use the default value.
-            // Else update the default FvBinding value to this value.
-            //
-            if (fvBinding == null) {
-                fvBinding = defaultFv;
-            }
-            else {
-                defaultFv = fvBinding;
-            }
-            String arch;
-            //
-            // If the module do not specify any Arch, use the default value.
-            // Else update the default Arch value to this value.
-            //
-            if (moduleSAs[i].getArch() == null ){
-                arch = defaultArch;
-            }
-            else {
-                arch = moduleSAs[i].getArch().toString();
-                defaultArch = arch;
-            }
-            Map<String, XmlObject> msaMap = GlobalData.getNativeMsa(baseName);
-            Map<String, XmlObject> mbdMap = GlobalData.getNativeMbd(baseName);
-            Map<String, XmlObject> fpdMap = new HashMap<String, XmlObject>();
-            Map<String, XmlObject> map = new HashMap<String, XmlObject>();
-            //
-            // Whether the Module SA has parsed before or not
-            //
-            if (!GlobalData.isModuleParsed(baseName)) {
-                OverrideProcess op = new OverrideProcess();
-                //
-                // using overriding rules
-                // Here we can also put platform Build override
-                //
-                map = op.override(mbdMap, msaMap);
-                fpdMap = getPlatformOverrideInfo(moduleSAs[i]);
-                XmlObject buildOption = (XmlObject)fpdMap.get("BuildOptions");
-                buildOption = (XmlObject)fpdMap.get("PackageDependencies");
-                buildOption = (XmlObject)fpdMap.get("BuildOptions");
-                buildOption = op.override(buildOption, platformBuildOptions);
-                fpdMap.put("BuildOptions", ((BuildOptionsDocument)buildOption).getBuildOptions());
-                Map<String, XmlObject> overrideMap = op.override(fpdMap, OverrideProcess.deal(map));
-                GlobalData.registerModule(baseName, overrideMap);
-            } else {
-                map = GlobalData.getDoc(baseName);
-            }
-            SurfaceAreaQuery.setDoc(map);
-            String guid = SurfaceAreaQuery.getModuleGuid();
-            String componentType = SurfaceAreaQuery.getComponentType();
-            FpdModuleIdentification moduleId = new FpdModuleIdentification(baseName, guid, arch);
-            updateFvs(fvBinding, moduleId);
-            outfiles.put(moduleId, "${PLATFORM_DIR}" + File.separatorChar + "Build" + File.separatorChar 
-                            + "${TARGET}" + File.separatorChar + arch
-                            + File.separatorChar + guid + "-" + baseName
-                            + getSuffix(componentType));
+            // parse module build options, if any
+            // 
+            SurfaceAreaQuery.push(GlobalData.getDoc(fpdModuleId));
+            GlobalData.addModuleToolChainOption(fpdModuleId, parseModuleBuildOptions(false));
+            GlobalData.addModuleToolChainFamilyOption(fpdModuleId, parseModuleBuildOptions(true));
+            SurfaceAreaQuery.pop();
         }
     }
 
+    private ToolChainMap parseModuleBuildOptions(boolean toolChainFamilyFlag) throws EdkException {
+        String[][] options = SurfaceAreaQuery.getModuleBuildOptions(toolChainFamilyFlag);
+        if (options == null || options.length == 0) {
+            return null;
+        }
+        return parseOptions(options);
+    }
+    
+    private ToolChainMap parsePlatformBuildOptions(boolean toolChainFamilyFlag) throws EdkException {
+        String[][] options = SurfaceAreaQuery.getPlatformBuildOptions(toolChainFamilyFlag);
+        if (options == null || options.length == 0) {
+            return null;
+        }
+        return parseOptions(options);
+    }
+
+    private ToolChainMap parseOptions(String[][] options) throws EdkException {
+        ToolChainMap map = new ToolChainMap();
+        int flagIndex = ToolChainElement.ATTRIBUTE.value;
+
+        for (int i = 0; i < options.length; ++i) {
+            String flagString = options[i][flagIndex];
+            if (flagString == null) {
+                flagString = "";
+            }
+            options[i][flagIndex] = ToolChainAttribute.FLAGS + "";
+            map.put(options[i], flagString.trim());
+        }
+
+        return map;
+    }
+    
+    private void parseToolChainFamilyOptions() throws EdkException {
+        GlobalData.setPlatformToolChainFamilyOption(parsePlatformBuildOptions(true));
+    }
+
+    private void parseToolChainOptions() throws EdkException {
+        GlobalData.setPlatformToolChainOption(parsePlatformBuildOptions(false));
+    }
+
     /**
       Add the current module to corresponding FV. 
-    
+     
       @param fvName current FV name
       @param moduleName current module identification
     **/
-    private void updateFvs(String fvName, FpdModuleIdentification moduleName) {
+    private void updateFvs(String fvSequence, String fvName, FpdModuleIdentification fpdModuleId) {
         String upcaseFvName = fvName.toUpperCase();
-        if (fvs.containsKey(upcaseFvName)) {
-            Set<FpdModuleIdentification> set = fvs.get(upcaseFvName);
-            set.add(moduleName);
-        } else {
-            Set<FpdModuleIdentification> set = new LinkedHashSet<FpdModuleIdentification>();
-            set.add(moduleName);
-            fvs.put(upcaseFvName, set);
+        String[] fvNameArray = upcaseFvName.split("[, \t]+");
+        for (int i = 0; i < fvNameArray.length; i++) {
+            //
+            // Put module to corresponding fvName
+            //
+            if (fvs.containsKey(fvNameArray[i])) {
+                Set<FpdModuleIdentification> set = fvs.get(fvNameArray[i]);
+                set.add(fpdModuleId);
+            }
+            else {
+                Set<FpdModuleIdentification> set = new LinkedHashSet<FpdModuleIdentification>();
+                set.add(fpdModuleId);
+                fvs.put(fvNameArray[i], set);
+            }
+            
+            //
+            // Put fvName to corresponding fvSequence
+            //
+            if (sequences.containsKey(fvSequence)) {
+                Set<String> set = sequences.get(fvSequence);
+                set.add(fvNameArray[i]);
+            }
+            else {
+                Set<String> set = new LinkedHashSet<String>();
+                set.add(fvNameArray[i]);
+                sequences.put(fvSequence, set);
+            }
         }
     }
 
     /**
-      Get the suffix based on component type. Current relationship are listed:  
+      Get the suffix based on module type. Current relationship are listed:  
       
       <pre>
-        <b>ComponentType</b>   <b>Suffix</b>
-           APPLICATION          .APP
-           SEC                  .SEC
-           PEI_CORE             .PEI
-           PE32_PEIM            .PEI
-           RELOCATABLE_PEIM     .PEI
-           PIC_PEIM             .PEI
-           COMBINED_PEIM_DRIVER .PEI
-           TE_PEIM              .PEI
-           LOGO                 .FFS
-           others               .DXE
+      <b>ModuleType</b>     <b>Suffix</b>
+      BASE                 .FFS
+      SEC                  .SEC
+      PEI_CORE             .PEI
+      PEIM                 .PEI
+      DXE_CORE             .DXE
+      DXE_DRIVER           .DXE
+      DXE_RUNTIME_DRIVER   .DXE
+      DXE_SAL_DRIVER       .DXE
+      DXE_SMM_DRIVER       .DXE
+      TOOL                 .FFS
+      UEFI_DRIVER          .DXE
+      UEFI_APPLICATION     .APP
+      USER_DEFINED         .FFS
       </pre>
-    
-      @param componentType component type
+     
+      @param moduleType module type
       @return
       @throws BuildException
-              If component type is null
+      If module type is null
     **/
-    public static String getSuffix(String componentType) throws BuildException{
-        if (componentType == null) {
-            throw new BuildException("Component type is not specified.");
+    public static String getSuffix(String moduleType) throws BuildException {
+        if (moduleType == null) {
+            throw new BuildException("Module type is not specified.");
         }
-        String str = ".DXE";
-        if (componentType.equalsIgnoreCase("APPLICATION")) {
-            str = ".APP";
-        } else if (componentType.equalsIgnoreCase("SEC")) {
-            str = ".SEC";
-        } else if (componentType.equalsIgnoreCase("PEI_CORE")) {
-            str = ".PEI";
-        } else if (componentType.equalsIgnoreCase("PE32_PEIM")) {
-            str = ".PEI";
-        } else if (componentType.equalsIgnoreCase("RELOCATABLE_PEIM")) {
-            str = ".PEI";
-        } else if (componentType.equalsIgnoreCase("PIC_PEIM")) {
-            str = ".PEI";
-        } else if (componentType.equalsIgnoreCase("COMBINED_PEIM_DRIVER")) {
-            str = ".PEI";
-        } else if (componentType.equalsIgnoreCase("TE_PEIM")) {
-            str = ".PEI";
-        } else if (componentType.equalsIgnoreCase("LOGO")) {
-            str = ".FFS";
+
+        String[][] suffix = { { "BASE", ".FFS"},
+                              { "SEC", ".SEC" }, { "PEI_CORE", ".PEI" }, 
+                              { "PEIM", ".PEI" }, { "DXE_CORE", ".DXE" },
+                              { "DXE_DRIVER", ".DXE" }, { "DXE_RUNTIME_DRIVER", ".DXE" }, 
+                              { "DXE_SAL_DRIVER", ".DXE" }, { "DXE_SMM_DRIVER", ".DXE" }, 
+                              { "TOOL", ".FFS" }, { "UEFI_DRIVER", ".DXE" },
+                              { "UEFI_APPLICATION", ".APP" }, { "USER_DEFINED", ".FFS" } };
+        
+        for (int i = 0; i < suffix.length; i++) {
+            if (suffix[i][0].equalsIgnoreCase(moduleType)) {
+                return suffix[i][1];
+            }
         }
-        return str;
+        //
+        // Default is '.FFS'
+        //
+        return ".FFS";
     }
-
     /**
-      Parse module surface are info described in FPD file and put them into map. 
-      
-      @param sa module surface area info descibed in FPD file
-      @return map list with top level elements
-    **/
-    private Map<String, XmlObject> getPlatformOverrideInfo(
-                    ModuleSADocument.ModuleSA sa) {
-        Map<String, XmlObject> map = new HashMap<String, XmlObject>();
-        map.put("SourceFiles", sa.getSourceFiles());
-        map.put("Includes", sa.getIncludes());
-        map.put("PackageDependencies", null);
-        map.put("Libraries", sa.getLibraries());
-        map.put("Protocols", sa.getProtocols());
-        map.put("Events", sa.getEvents());
-        map.put("Hobs", sa.getHobs());
-        map.put("PPIs", sa.getPPIs());
-        map.put("Variables", sa.getVariables());
-        map.put("BootModes", sa.getBootModes());
-        map.put("SystemTables", sa.getSystemTables());
-        map.put("DataHubs", sa.getDataHubs());
-        map.put("Formsets", sa.getFormsets());
-        map.put("Guids", sa.getGuids());
-        map.put("Externs", sa.getExterns());
-        map.put("BuildOptions", sa.getBuildOptions());//platformBuildOptions);
-        return map;
-    }
-
-    /**
-      Generate build.out.xml file.
-      
-      @throws BuildException
-              build.out.xml XML document create error
-    **/
-    private void genBuildFile() throws BuildException {
-        DocumentBuilderFactory domfac = DocumentBuilderFactory.newInstance();
-        try {
-            DocumentBuilder dombuilder = domfac.newDocumentBuilder();
-            Document document = dombuilder.newDocument();
-            Comment rootComment = document.createComment(info);
-            //
-            // create root element and its attributes
-            //
-            Element root = document.createElement("project");
-            root.setAttribute("name", getProject().getProperty("PLATFORM"));
-            root.setAttribute("default", "main");
-            root.setAttribute("basedir", ".");
-            //
-            // element for External ANT tasks
-            //
-            root.appendChild(document.createComment("Apply external ANT tasks"));
-            Element ele = document.createElement("taskdef");
-            ele.setAttribute("resource", "GenBuild.tasks");
-            root.appendChild(ele);
-
-            ele = document.createElement("taskdef");
-            ele.setAttribute("resource", "frameworktasks.tasks");
-            root.appendChild(ele);
-
-            ele = document.createElement("property");
-            ele.setAttribute("environment", "env");
-            root.appendChild(ele);
-            //
-            // Default Target
-            //
-            root.appendChild(document.createComment("Default target"));
-            ele = document.createElement("target");
-            ele.setAttribute("name", "main");
-            ele.setAttribute("depends", "modules, fvs");
-            root.appendChild(ele);
-            //
-            // Modules Target
-            //
-            root.appendChild(document.createComment("Modules target"));
-            ele = document.createElement("target");
-            ele.setAttribute("name", "modules");
-
-            Set set = outfiles.keySet();
-            Iterator iter = set.iterator();
-            while (iter.hasNext()) {
-                FpdModuleIdentification moduleId = (FpdModuleIdentification) iter.next();
-                String baseName = moduleId.getBaseName();
-                Element moduleEle = document.createElement("ant");
-                moduleEle.setAttribute("antfile", GlobalData
-                                .getModulePath(baseName)
-                                + File.separatorChar + "build.xml");
-                moduleEle.setAttribute("target", baseName);
-                //
-                // ARCH
-                //
-                Element property = document.createElement("property");
-                property.setAttribute("name", "ARCH");
-                property.setAttribute("value", moduleId.getArch());
-                moduleEle.appendChild(property);
-                //
-                // PACKAGE_DIR
-                //
-                property = document.createElement("property");
-                property.setAttribute("name", "PACKAGE_DIR");
-                property.setAttribute("value", "${WORKSPACE_DIR}" + File.separatorChar
-                                + GlobalData.getPackagePathForModule(baseName));
-                moduleEle.appendChild(property);
-                //
-                // PACKAGE
-                //
-                property = document.createElement("property");
-                property.setAttribute("name", "PACKAGE");
-                property.setAttribute("value", GlobalData
-                                .getPackageNameForModule(baseName));
-                moduleEle.appendChild(property);
-                ele.appendChild(moduleEle);
-            }
-            root.appendChild(ele);
-            //
-            // FVS Target
-            //
-            root.appendChild(document.createComment("FVs target"));
-            ele = document.createElement("target");
-            ele.setAttribute("name", "fvs");
-
-            String[] validFv = SurfaceAreaQuery.getFpdValidImageNames();
-            for (int i = 0; i < validFv.length; i++) {
-                String inputFile = FV_OUTPUT_DIR + "" + File.separatorChar
-                                + validFv[i].toUpperCase() + ".inf";
-                Element fvEle = document.createElement("genfvimage");
-                fvEle.setAttribute("infFile", inputFile);
-                ele.appendChild(fvEle);
-                Element moveEle = document.createElement("move");
-                moveEle.setAttribute("file", validFv[i].toUpperCase() + ".fv");
-                moveEle.setAttribute("todir", FV_OUTPUT_DIR);
-                ele.appendChild(moveEle);
-            }
-            root.appendChild(ele);
-            
-            boolean isUnified = false;
-            BuildOptionsDocument.BuildOptions buildOptions = (BuildOptionsDocument.BuildOptions)platformBuildOptions;
-            if (buildOptions.getOutputDirectory() != null){
-                if (buildOptions.getOutputDirectory().getIntermediateDirectories() != null){
-                    if (buildOptions.getOutputDirectory().getIntermediateDirectories().toString().equalsIgnoreCase("UNIFIED")){
-                        isUnified = true;
-                    }
-                }
-            }
-            //
-            // Clean Target
-            //
-            root.appendChild(document.createComment("Clean target"));
-            ele = document.createElement("target");
-            ele.setAttribute("name", "clean");
-            
-            if (isUnified) {
-                Element cleanEle = document.createElement("delete");
-                cleanEle.setAttribute("includeemptydirs", "true");
-                Element filesetEle = document.createElement("fileset");
-                filesetEle.setAttribute("dir", getProject().getProperty("PLATFORM_DIR") + File.separatorChar + "Build" + File.separatorChar + "${TARGET}");
-                filesetEle.setAttribute("includes", "**/OUTPUT/**");
-                cleanEle.appendChild(filesetEle);
-                ele.appendChild(cleanEle);
-            }
-            else {
-                set = outfiles.keySet();
-                iter = set.iterator();
-                while (iter.hasNext()) {
-                    FpdModuleIdentification moduleId = (FpdModuleIdentification) iter.next();
-                    String baseName = moduleId.getBaseName();
-    
-                    Element ifEle = document.createElement("if");
-                    Element availableEle = document.createElement("available");
-                    availableEle.setAttribute("file", GlobalData
-                                    .getModulePath(baseName)
-                                    + File.separatorChar + "build.xml");
-                    ifEle.appendChild(availableEle);
-                    Element elseEle = document.createElement("then");
-    
-                    Element moduleEle = document.createElement("ant");
-                    moduleEle.setAttribute("antfile", GlobalData
-                                    .getModulePath(baseName)
-                                    + File.separatorChar + "build.xml");
-                    moduleEle.setAttribute("target", baseName + "_clean");
-                    //
-                    // ARCH
-                    //
-                    Element property = document.createElement("property");
-                    property.setAttribute("name", "ARCH");
-                    property.setAttribute("value", moduleId.getArch());
-                    moduleEle.appendChild(property);
-                    //
-                    // PACKAGE_DIR
-                    //
-                    property = document.createElement("property");
-                    property.setAttribute("name", "PACKAGE_DIR");
-                    property.setAttribute("value", "${WORKSPACE_DIR}" + File.separatorChar
-                                    + GlobalData.getPackagePathForModule(baseName));
-                    moduleEle.appendChild(property);
-                    //
-                    // PACKAGE
-                    //
-                    property = document.createElement("property");
-                    property.setAttribute("name", "PACKAGE");
-                    property.setAttribute("value", GlobalData
-                                    .getPackageNameForModule(baseName));
-                    moduleEle.appendChild(property);
-                    elseEle.appendChild(moduleEle);
-                    ifEle.appendChild(elseEle);
-                    ele.appendChild(ifEle);
-                }
-            }
-            root.appendChild(ele);
-            //
-            // Deep Clean Target
-            //
-            root.appendChild(document.createComment("Clean All target"));
-            ele = document.createElement("target");
-            ele.setAttribute("name", "cleanall");
-
-            if (isUnified) {
-                Element cleanAllEle = document.createElement("delete");
-                cleanAllEle.setAttribute("dir", getProject().getProperty("PLATFORM_DIR") + File.separatorChar + "Build" + File.separatorChar + "${TARGET}");
-                ele.appendChild(cleanAllEle);
-            }
-            else {
-                set = outfiles.keySet();
-                iter = set.iterator();
-                while (iter.hasNext()) {
-                    FpdModuleIdentification moduleId = (FpdModuleIdentification) iter.next();
-                    String baseName = moduleId.getBaseName();
-    
-                    Element ifEle = document.createElement("if");
-                    Element availableEle = document.createElement("available");
-                    availableEle.setAttribute("file", GlobalData
-                                    .getModulePath(baseName)
-                                    + File.separatorChar + "build.xml");
-                    ifEle.appendChild(availableEle);
-                    Element elseEle = document.createElement("then");
-    
-                    Element moduleEle = document.createElement("ant");
-                    moduleEle.setAttribute("antfile", GlobalData
-                                    .getModulePath(baseName)
-                                    + File.separatorChar + "build.xml");
-                    moduleEle.setAttribute("target", baseName + "_cleanall");
-                    //
-                    // ARCH
-                    //
-                    Element property = document.createElement("property");
-                    property.setAttribute("name", "ARCH");
-                    property.setAttribute("value", moduleId.getArch());
-                    moduleEle.appendChild(property);
-                    //
-                    // PACKAGE_DIR
-                    //
-                    property = document.createElement("property");
-                    property.setAttribute("name", "PACKAGE_DIR");
-                    property.setAttribute("value", "${WORKSPACE_DIR}" + File.separatorChar
-                                    + GlobalData.getPackagePathForModule(baseName));
-                    moduleEle.appendChild(property);
-                    //
-                    // PACKAGE
-                    //
-                    property = document.createElement("property");
-                    property.setAttribute("name", "PACKAGE");
-                    property.setAttribute("value", GlobalData
-                                    .getPackageNameForModule(baseName));
-                    moduleEle.appendChild(property);
-                    elseEle.appendChild(moduleEle);
-                    ifEle.appendChild(elseEle);
-                    ele.appendChild(ifEle);
-                }
-            }
-            root.appendChild(ele);
-            
-            document.appendChild(rootComment);
-            document.appendChild(root);
-            //
-            // Prepare the DOM document for writing
-            //
-            Source source = new DOMSource(document);
-            //
-            // Prepare the output file
-            //
-            File file = new File(getProject().getProperty("PLATFORM_DIR")
-                            + File.separatorChar + "build.out.xml");
-            //
-            // generate all directory path
-            //
-            (new File(file.getParent())).mkdirs();
-            Result result = new StreamResult(file);
-            //
-            // Write the DOM document to the file
-            //
-            Transformer xformer = TransformerFactory.newInstance()
-                            .newTransformer();
-            xformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
-            xformer.setOutputProperty(OutputKeys.INDENT, "yes");
-            xformer.transform(source, result);
-        } catch (Exception ex) {
-            throw new BuildException("Generate build.out.xml failed. \n" + ex.getMessage());
-        }
-    }
-
-    /**
-      Add a property. 
-      
-      @param p property
-    **/
+     Add a property. 
+     
+     @param p property
+     **/
     public void addProperty(Property p) {
         properties.addElement(p);
     }
 
-    /**
-      Get FPD file name.
-       
-      @return FPD file name.
-    **/
-    public File getFpdFilename() {
-        return fpdFilename;
+    public void setPlatformName(String platformName) {
+        this.platformName = platformName;
     }
 
-    /**
-      Set FPD file name.
-      
-      @param fpdFilename FPD file name
-    **/
-    public void setFpdFilename(File fpdFilename) {
-        this.fpdFilename = fpdFilename;
+    public void setFpdFile(File fpdFile) {
+        this.fpdFile = fpdFile;
     }
 
-    public File getGuiddatabase() {
-        return guiddatabase;
+    public void setType(String type) {
+        this.type = type;
     }
+    
 
-    public void setGuiddatabase(File guiddatabase) {
-        this.guiddatabase = guiddatabase;
-    }
-
-    public void collectPCDInformation() {
-        String           exceptionString = null;
-        CollectPCDAction collectAction   = new CollectPCDAction ();
-        //
-        // Collect all PCD information from FPD to MSA, and get help information from SPD.
-        // These all information will be stored into memory database for future usage such 
-        // as autogen.
-        //
-        try {
-            collectAction.perform (getProject().getProperty("WORKSPACE_DIR"),
-                                   fpdFilename.getPath(),
-                                   ActionMessage.MAX_MESSAGE_LEVEL
-                                   );
-        } catch (Exception exp) {
-            exceptionString = exp.getMessage();
-            if (exceptionString == null) {
-                exceptionString = "[Internal Error]Pcd tools catch a internel errors, Please report this bug into TianoCore or send email to Wang, scott or Lu, ken!";
-            }
-            throw new BuildException (String.format("Fail to do PCD preprocess from FPD file: %s", exceptionString));
-        }
-    }
 }
diff --git a/Tools/Source/GenBuild/org/tianocore/build/fpd/PlatformBuildFileGenerator.java b/Tools/Source/GenBuild/org/tianocore/build/fpd/PlatformBuildFileGenerator.java
new file mode 100644
index 0000000000..b41ea211d2
--- /dev/null
+++ b/Tools/Source/GenBuild/org/tianocore/build/fpd/PlatformBuildFileGenerator.java
@@ -0,0 +1,479 @@
+/** @file
+ 
+ Copyright (c) 2006, Intel Corporation
+ All rights reserved. This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution.  The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+ **/
+package org.tianocore.build.fpd;
+
+import java.io.File;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Result;
+import javax.xml.transform.Source;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.tianocore.build.global.GlobalData;
+import org.tianocore.build.global.SurfaceAreaQuery;
+import org.tianocore.build.id.FpdModuleIdentification;
+import org.tianocore.build.id.ModuleIdentification;
+import org.w3c.dom.Comment;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+public class PlatformBuildFileGenerator {
+
+    private String platformName;
+    
+    ///
+    /// Mapping from modules identification to out put file name
+    ///
+    private Map<FpdModuleIdentification, String> outfiles;
+
+    ///
+    /// Mapping from FV name to its modules
+    ///
+    private Map<String, Set<FpdModuleIdentification>> fvs;
+
+    ///
+    /// Mapping from sequence number to FV names
+    ///
+    private Map<String, Set<String>> sequences;
+    
+    private boolean isUnified = true;
+    
+    private Project project;
+    
+    private String info = "DO NOT EDIT \n" 
+        + "File auto-generated by build utility\n" 
+        + "\n" 
+        + "Abstract:\n"
+        + "Auto-generated ANT build file for building of EFI Modules/Platforms\n";
+
+    public PlatformBuildFileGenerator(Project project, Map<FpdModuleIdentification, String> outfiles, Map<String, Set<FpdModuleIdentification>> fvs, Map<String, Set<String>> sequences, boolean isUnified){
+        this.project = project;
+        this.outfiles = outfiles;
+        this.fvs = fvs;
+        this.sequences = sequences;
+        this.isUnified = isUnified;
+        this.platformName = project.getProperty("PLATFORM");
+    }
+    
+    /**
+      Generate build.out.xml file.
+     
+      @throws BuildException
+                  build.out.xml XML document create error
+    **/
+    public void genBuildFile() throws BuildException {
+        DocumentBuilderFactory domfac = DocumentBuilderFactory.newInstance();
+        try {
+            DocumentBuilder dombuilder = domfac.newDocumentBuilder();
+            Document document = dombuilder.newDocument();
+            Comment rootComment = document.createComment(info);
+            //
+            // create root element and its attributes
+            //
+            Element root = document.createElement("project");
+            root.setAttribute("name", project.getProperty("PLATFORM"));
+            root.setAttribute("default", "all");
+            root.setAttribute("basedir", ".");
+            
+            //
+            // element for External ANT tasks
+            //
+            root.appendChild(document.createComment("Apply external ANT tasks"));
+            Element ele = document.createElement("taskdef");
+            ele.setAttribute("resource", "GenBuild.tasks");
+            root.appendChild(ele);
+
+            ele = document.createElement("taskdef");
+            ele.setAttribute("resource", "frameworktasks.tasks");
+            root.appendChild(ele);
+
+            ele = document.createElement("property");
+            ele.setAttribute("environment", "env");
+            root.appendChild(ele);
+            
+            Set<String> sequenceKeys = sequences.keySet();
+            Iterator sequenceIter = sequenceKeys.iterator();
+            String dependsStr = "";
+            while (sequenceIter.hasNext()) {
+                String num = (String)sequenceIter.next();
+                if (dependsStr.length() > 0) {
+                    dependsStr += " , ";
+                }
+                dependsStr += "modules" + num + ", fvs" + num;
+            }
+            
+            //
+            // Default Target
+            //
+            root.appendChild(document.createComment("Default target"));
+            ele = document.createElement("target");
+            ele.setAttribute("name", "all");
+            ele.setAttribute("depends", dependsStr + ", userextensions");
+            root.appendChild(ele);
+            
+            //
+            // Modules and Fvs Target
+            //
+            sequenceIter = sequenceKeys.iterator();
+            while (sequenceIter.hasNext()) {
+                String num = (String)sequenceIter.next();
+                applyModules(document, root, num);
+                applyFvs(document, root, num);
+            }
+
+            //
+            // Clean Target
+            //
+            applyClean(document, root);
+            
+            //
+            // Deep Clean Target
+            //
+            applyCleanall(document, root);
+            
+            //
+            // User Extension
+            //
+            applyUserExtensions(document, root);
+            
+            document.appendChild(rootComment);
+            document.appendChild(root);
+            //
+            // Prepare the DOM document for writing
+            //
+            Source source = new DOMSource(document);
+            //
+            // Prepare the output file
+            //
+            File file = new File(project.getProperty("PLATFORM_DIR") + File.separatorChar + platformName + "_build.xml");
+            //
+            // generate all directory path
+            //
+            (new File(file.getParent())).mkdirs();
+            Result result = new StreamResult(file);
+            //
+            // Write the DOM document to the file
+            //
+            Transformer xformer = TransformerFactory.newInstance().newTransformer();
+            xformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
+            xformer.setOutputProperty(OutputKeys.INDENT, "yes");
+            xformer.transform(source, result);
+        } catch (Exception ex) {
+            ex.printStackTrace();
+            throw new BuildException("Generate " + platformName + "_build.xml failed. \n" + ex.getMessage());
+        }
+    }
+    private void applyModules(Document document, Node root, String num) {
+        root.appendChild(document.createComment("Modules target"));
+        Element ele = document.createElement("target");
+        ele.setAttribute("name", "modules" + num);
+        
+        Set<String> fvNameSet = sequences.get(num);
+
+        Iterator fvNameIter = fvNameSet.iterator();
+        while (fvNameIter.hasNext()) {
+            String fvName = (String)fvNameIter.next();
+            Set<FpdModuleIdentification> set = fvs.get(fvName);
+            Iterator iter = set.iterator();
+            while (iter.hasNext()) {
+                FpdModuleIdentification fpdModuleId = (FpdModuleIdentification) iter.next();
+                ModuleIdentification moduleId = fpdModuleId.getModule();
+                Element moduleEle = document.createElement("GenBuild");
+                moduleEle.setAttribute("type", "build");
+                //
+                // Inherit Properties.
+                //{"ARCH", "PACKAGE", "PACKAGE_GUID", "PACKAGE_VERSION", "MODULE_DIR"}
+                //
+                
+                //
+                // ARCH
+                //
+                Element property = document.createElement("property");
+                property.setAttribute("name", "ARCH");
+                property.setAttribute("value", fpdModuleId.getArch());
+                moduleEle.appendChild(property);
+
+                //
+                // MODULE_GUID
+                //
+                property = document.createElement("property");
+                property.setAttribute("name", "MODULE_GUID");
+                property.setAttribute("value", moduleId.getGuid());
+                moduleEle.appendChild(property);
+                
+                //
+                // MODULE_VERSION
+                //
+                property = document.createElement("property");
+                property.setAttribute("name", "MODULE_VERSION");
+                property.setAttribute("value", moduleId.getVersion());
+                moduleEle.appendChild(property);
+                
+                //
+                // PACKAGE_GUID
+                //
+                property = document.createElement("property");
+                property.setAttribute("name", "PACKAGE_GUID");
+                property.setAttribute("value", moduleId.getPackage().getGuid());
+                moduleEle.appendChild(property);
+                
+                //
+                // PACKAGE_VERSION
+                //
+                property = document.createElement("property");
+                property.setAttribute("name", "PACKAGE_VERSION");
+                property.setAttribute("value", moduleId.getPackage().getVersion());
+                moduleEle.appendChild(property);
+                
+                ele.appendChild(moduleEle);
+            }
+        }
+        root.appendChild(ele);
+    }
+    
+    private void applyFvs(Document document, Node root, String num) {
+        Set<String> fvNameSet = sequences.get(num);
+        //
+        // FVS Target
+        //
+        root.appendChild(document.createComment("FVs target"));
+        Element ele = document.createElement("target");
+        ele.setAttribute("name", "fvs" + num);
+
+        //
+        // For every Target and ToolChain
+        //
+        String[] targetList = GlobalData.getToolChainInfo().getTargets();
+        for (int i = 0; i < targetList.length; i++){
+            String[] toolchainList = GlobalData.getToolChainInfo().getTagnames();
+            for(int j = 0; j < toolchainList.length; j++){
+                String fvOutputDir = project.getProperty("BUILD_DIR") + File.separatorChar 
+                                        + targetList[i] + File.separatorChar 
+                                        + toolchainList[i] + File.separatorChar + "FV";
+                String[] validFv = SurfaceAreaQuery.getFpdValidImageNames();
+                for (int k = 0; k < validFv.length; k++) {
+                    if (fvNameSet.contains(validFv[k]) || ! isListInSequence(validFv[k])) {
+                        String inputFile = fvOutputDir + "" + File.separatorChar + validFv[k].toUpperCase() + ".inf";
+                        Element fvEle = document.createElement("genfvimage");
+                        fvEle.setAttribute("infFile", inputFile);
+                        fvEle.setAttribute("outputDir", fvOutputDir);
+                        ele.appendChild(fvEle);
+                    }
+                }
+            }
+        }
+        root.appendChild(ele);
+    }
+    
+    private void applyClean(Document document, Node root) {
+        //
+        // Clean Target
+        //
+        root.appendChild(document.createComment("Clean target"));
+        Element ele = document.createElement("target");
+        ele.setAttribute("name", "clean");
+
+        if (isUnified) {
+            Element cleanEle = document.createElement("delete");
+            cleanEle.setAttribute("includeemptydirs", "true");
+            Element filesetEle = document.createElement("fileset");
+            filesetEle.setAttribute("dir", project.getProperty("BUILD_DIR"));
+            filesetEle.setAttribute("includes", "**\\OUTPUT\\**");
+            cleanEle.appendChild(filesetEle);
+            ele.appendChild(cleanEle);
+        } else {
+            Set set = outfiles.keySet();
+            Iterator iter = set.iterator();
+            while (iter.hasNext()) {
+                FpdModuleIdentification fpdModuleId = (FpdModuleIdentification) iter.next();
+                ModuleIdentification moduleId = fpdModuleId.getModule();
+
+                Element ifEle = document.createElement("if");
+                Element availableEle = document.createElement("available");
+                availableEle.setAttribute("file", moduleId.getMsaFile().getParent() + File.separatorChar
+                                                  + "build.xml");
+                ifEle.appendChild(availableEle);
+                Element elseEle = document.createElement("then");
+
+                Element moduleEle = document.createElement("ant");
+                moduleEle.setAttribute("antfile", moduleId.getMsaFile().getParent() + File.separatorChar
+                                                  + "build.xml");
+                moduleEle.setAttribute("target", "clean");
+                //
+                // Inherit Properties.
+                //{"ARCH", "PACKAGE", "PACKAGE_GUID", "PACKAGE_VERSION", "MODULE_DIR"}
+                //
+                
+                //
+                // ARCH
+                //
+                Element property = document.createElement("property");
+                property.setAttribute("name", "ARCH");
+                property.setAttribute("value", fpdModuleId.getArch());
+                moduleEle.appendChild(property);
+
+                //
+                // PACKAGE
+                //
+                property = document.createElement("property");
+                property.setAttribute("name", "PACKAGE");
+                property.setAttribute("value", moduleId.getPackage().getName());
+                moduleEle.appendChild(property);
+                
+                //
+                // PACKAGE_GUID
+                //
+                property = document.createElement("property");
+                property.setAttribute("name", "PACKAGE_GUID");
+                property.setAttribute("value", moduleId.getPackage().getGuid());
+                moduleEle.appendChild(property);
+                
+                //
+                // PACKAGE_VERSION
+                //
+                property = document.createElement("property");
+                property.setAttribute("name", "PACKAGE_VERSION");
+                property.setAttribute("value", moduleId.getPackage().getVersion());
+                moduleEle.appendChild(property);
+                
+                //
+                // MODULE_DIR
+                //
+                property = document.createElement("property");
+                property.setAttribute("name", "MODULE_DIR");
+                property.setAttribute("value", moduleId.getMsaFile().getParent());
+                moduleEle.appendChild(property);
+                elseEle.appendChild(moduleEle);
+                ifEle.appendChild(elseEle);
+                ele.appendChild(ifEle);
+            }
+        }
+        root.appendChild(ele);
+    }
+    
+    private void applyCleanall(Document document, Node root) {
+        //
+        // Deep Clean Target
+        //
+        root.appendChild(document.createComment("Clean All target"));
+        Element ele = document.createElement("target");
+        ele.setAttribute("name", "cleanall");
+
+        if (isUnified) {
+            Element cleanAllEle = document.createElement("delete");
+            cleanAllEle.setAttribute("dir", project.getProperty("BUILD_DIR"));
+            ele.appendChild(cleanAllEle);
+        } else {
+            Set set = outfiles.keySet();
+            Iterator iter = set.iterator();
+            while (iter.hasNext()) {
+                FpdModuleIdentification fpdModuleId = (FpdModuleIdentification) iter.next();
+                ModuleIdentification moduleId = fpdModuleId.getModule();
+
+                Element ifEle = document.createElement("if");
+                Element availableEle = document.createElement("available");
+                availableEle.setAttribute("file", moduleId.getMsaFile().getParent() + File.separatorChar
+                                                  + "build.xml");
+                ifEle.appendChild(availableEle);
+                Element elseEle = document.createElement("then");
+
+                Element moduleEle = document.createElement("ant");
+                moduleEle.setAttribute("antfile", moduleId.getMsaFile().getParent() + File.separatorChar
+                                                  + "build.xml");
+                moduleEle.setAttribute("target", "cleanall");
+                //
+                // Inherit Properties.
+                //{"ARCH", "PACKAGE", "PACKAGE_GUID", "PACKAGE_VERSION", "MODULE_DIR"}
+                //
+                
+                //
+                // ARCH
+                //
+                Element property = document.createElement("property");
+                property.setAttribute("name", "ARCH");
+                property.setAttribute("value", fpdModuleId.getArch());
+                moduleEle.appendChild(property);
+
+                //
+                // PACKAGE
+                //
+                property = document.createElement("property");
+                property.setAttribute("name", "PACKAGE");
+                property.setAttribute("value", moduleId.getPackage().getName());
+                moduleEle.appendChild(property);
+                
+                //
+                // PACKAGE_GUID
+                //
+                property = document.createElement("property");
+                property.setAttribute("name", "PACKAGE_GUID");
+                property.setAttribute("value", moduleId.getPackage().getGuid());
+                moduleEle.appendChild(property);
+                
+                //
+                // PACKAGE_VERSION
+                //
+                property = document.createElement("property");
+                property.setAttribute("name", "PACKAGE_VERSION");
+                property.setAttribute("value", moduleId.getPackage().getVersion());
+                moduleEle.appendChild(property);
+                
+                //
+                // MODULE_DIR
+                //
+                property = document.createElement("property");
+                property.setAttribute("name", "MODULE_DIR");
+                property.setAttribute("value", moduleId.getMsaFile().getParent());
+                moduleEle.appendChild(property);
+                elseEle.appendChild(moduleEle);
+                ifEle.appendChild(elseEle);
+                ele.appendChild(ifEle);
+            }
+        }
+        root.appendChild(ele);
+    }
+    
+    private void applyUserExtensions(Document document, Node root) {
+        //
+        // User Extensions
+        //
+        root.appendChild(document.createComment("User Extensions"));
+        Element ele = document.createElement("target");
+        ele.setAttribute("name", "userextensions");
+        
+        root.appendChild(ele);
+    }
+    
+    
+    private boolean isListInSequence(String fvName) {
+        Set<String> numbers = sequences.keySet();
+        Iterator<String> iter = numbers.iterator();
+        while (iter.hasNext()) {
+            Set<String> fvNameSet = sequences.get(iter.next());
+            if (fvNameSet.contains(fvName)) {
+                return true;
+            }
+        }
+        return false;
+    }
+}
diff --git a/Tools/Source/GenBuild/org/tianocore/build/global/GlobalData.java b/Tools/Source/GenBuild/org/tianocore/build/global/GlobalData.java
index 97096f6b4f..99cccc364c 100644
--- a/Tools/Source/GenBuild/org/tianocore/build/global/GlobalData.java
+++ b/Tools/Source/GenBuild/org/tianocore/build/global/GlobalData.java
@@ -16,29 +16,34 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 **/
 package org.tianocore.build.global;
 
+import org.apache.tools.ant.BuildException;
+import org.apache.xmlbeans.XmlObject;
+import org.tianocore.DbPathAndFilename;
+import org.tianocore.FrameworkDatabaseDocument;
+import org.tianocore.ModuleSurfaceAreaDocument;
+import org.tianocore.ModuleSurfaceAreaDocument.ModuleSurfaceArea;
+import org.tianocore.build.exception.EdkException;
+import org.tianocore.build.id.FpdModuleIdentification;
+import org.tianocore.build.id.ModuleIdentification;
+import org.tianocore.build.id.PackageIdentification;
+import org.tianocore.build.id.PlatformIdentification;
+import org.tianocore.build.toolchain.ToolChainAttribute;
+import org.tianocore.build.toolchain.ToolChainConfig;
+import org.tianocore.build.toolchain.ToolChainElement;
+import org.tianocore.build.toolchain.ToolChainInfo;
+import org.tianocore.build.toolchain.ToolChainKey;
+import org.tianocore.build.toolchain.ToolChainMap;
+//import org.tianocore.build.pcd.entity.MemoryDatabaseManager;
+//import org.tianocore.logger.EdkLog;
+
 import java.io.File;
-import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
-
-import org.apache.tools.ant.BuildException;
-import org.apache.xmlbeans.XmlObject;
-import org.tianocore.FilenameDocument;
-import org.tianocore.FilenameDocument.Filename;
-import org.tianocore.FrameworkDatabaseDocument;
-import org.tianocore.MsaFilesDocument;
-import org.tianocore.MsaFilesDocument.MsaFiles.MsaFile;
-import org.tianocore.MsaHeaderDocument.MsaHeader;
-import org.tianocore.MsaLibHeaderDocument.MsaLibHeader;
-import org.tianocore.PackageListDocument;
-import org.tianocore.PackageSurfaceAreaDocument;
-import org.tianocore.build.autogen.CommonDefinition;
-import org.tianocore.build.fpd.FpdParserTask;
-import org.tianocore.build.pcd.entity.MemoryDatabaseManager;
+import java.util.logging.Logger;
 
 /**
   GlobalData provide initializing, instoring, querying and update global data.
@@ -46,408 +51,321 @@ import org.tianocore.build.pcd.entity.MemoryDatabaseManager;
   PCD and so on. 
   
   <p>Note that all global information are initialized incrementally. All data will 
-  parse and record only it is necessary during build time. </p>
+  parse and record only of necessary during build time. </p>
   
   @since GenBuild 1.0
 **/
 public class GlobalData {
 
-    ///
-    /// means no surface area information for module
-    ///
-    public static final int NO_SA = 0;
-
-    ///
-    /// means only MSA
-    ///
-    public static final int ONLY_MSA = 1;
-
-    ///
-    /// means only Library MSA
-    ///
-    public static final int ONLY_LIBMSA = 2;
-
-    ///
-    /// means both MSA and MBD
-    ///
-    public static final int MSA_AND_MBD = 3;
-
-    ///
-    /// means both Library MSA and Library MBD
-    ///
-    public static final int LIBMSA_AND_LIBMBD = 4;
-
-    ///
-    /// Be used to ensure Global data will be initialized only once.
-    ///
-    public static boolean globalFlag = false;
-
+    public static Logger log = Logger.getAnonymousLogger();
+    
     ///
     /// Record current WORKSPACE Directory
     ///
     private static String workspaceDir = "";
+    
+    ///
+    /// Be used to ensure Global data will be initialized only once.
+    ///
+    private static boolean globalFlag = false;
+    
+    ///
+    /// Framework Database information: package list and platform list
+    ///
+    private static Set<PackageIdentification> packageList = new HashSet<PackageIdentification>();  
+
+    private static Set<PlatformIdentification> platformList = new HashSet<PlatformIdentification>();
 
     ///
-    /// Two columns: Package Name (Key), Package Path(ralative to WORKSPACE)
+    /// Every detail SPD informations: Module list, Library class definition,
+    ///   Package header file, GUID/PPI/Protocol definitions
     ///
-    private static final Map<String, String> packageInfo = new HashMap<String, String>();
+    private static final Map<PackageIdentification, Spd> spdTable = new HashMap<PackageIdentification, Spd>();
 
     ///
-    /// spdTable
-    /// Key: Package Name, Value: SPD detail info
+    /// Build informations are divided into three parts:
+    /// 1. From MSA 2. From FPD 3. From FPD' ModuleSA
     ///
-    private static final Map<String, Spd> spdTable = new HashMap<String, Spd>();
+    private static Map<ModuleIdentification, Map<String, XmlObject>> nativeMsa = new HashMap<ModuleIdentification, Map<String, XmlObject>>();
 
-    ///
-    /// Three columns:
-    /// 1. Module Name | BaseName (Key)
-    /// 2. Module Path + Msa file name (relative to Package)
-    /// 3. Package Name (This module belong to which package)
-    ///
-    private static final Map<String, String[]> moduleInfo = new HashMap<String, String[]>();
+    private static Map<FpdModuleIdentification, Map<String, XmlObject>> fpdModuleSA= new HashMap<FpdModuleIdentification, Map<String, XmlObject>>();
 
-    ///
-    /// List all libraries for current build module
-    /// Key: Library BaseName, Value: output library path+name
-    ///
-    private static final Map<String, String> libraries = new HashMap<String, String>();
+    private static XmlObject fpdBuildOptions;
 
+    private static XmlObject fpdDynamicPcds;
+    
     ///
-    /// Store every module's relative library instances BaseName
-    /// Key: Module BaseName, Value: All library instances module depends on.
+    /// Parsed modules list
     ///
-    private static final Map<String, Set<String> > moduleLibraryMap = new HashMap<String, Set<String> >();
-
+    private static Map<FpdModuleIdentification, Map<String, XmlObject>> parsedModules = new HashMap<FpdModuleIdentification, Map<String, XmlObject>>();
+    
     ///
-    /// Key: Module BaseName, Value: original MSA info
+    /// built modules list with ARCH, TARGET, TOOLCHAIN
     ///
-    private static final Map<String, Map<String, XmlObject> > nativeMsa = new HashMap<String, Map<String, XmlObject> >();
-
-    ///
-    /// Key: Module BaseName, Value: original MBD info
-    ///
-    private static final Map<String, Map<String, XmlObject> > nativeMbd = new HashMap<String, Map<String, XmlObject> >();
-
-    ///
-    /// Two columns: Module Name or Base Name as Key
-    /// Value is a HashMap with overridden data from MSA/MBD or/and Platform
-    ///
-    private static final Map<String, Map<String, XmlObject> > parsedModules = new HashMap<String, Map<String, XmlObject> >();
-
-    ///
-    /// List all built Module; Value is Module BaseName + Arch. TBD
-    ///
-    private static final Set<String> builtModules = new HashSet<String>();
-
-    ///
-    /// Library instance information table which recored the library and it's
-    /// constructor and distructor function
-    ///
-    private static final Map<String, String[]> libInstanceInfo = new HashMap<String, String[]>();
-
+    private static Set<FpdModuleIdentification> builtModules = new HashSet<FpdModuleIdentification>();
+    
     ///
     /// PCD memory database stored all PCD information which collected from FPD,MSA and SPD.
     ///
-    private static final MemoryDatabaseManager pcdDbManager = new MemoryDatabaseManager();
+//    private static final MemoryDatabaseManager pcdDbManager = new MemoryDatabaseManager();
 
-    /**
-      Query the module's absolute path with module base name. 
-      
-      @param moduleName the base name of the module
-      @return the absolute module path
-    **/
-    public synchronized static String getModulePath(String moduleName) {
-        String[] info = moduleInfo.get(moduleName);
-        String packagePath = (String) packageInfo.get(info[1]);
-        File convertFile = new File(workspaceDir + File.separatorChar + packagePath + File.separatorChar + info[0]);
-        return convertFile.getParent();
-    }
+    ///
+    /// build target + tool chain family/tag name + arch + command types + command options
+    ///
+    ///
+    /// Tool Chain Data
+    /// toolsDef - build tool program information
+    /// fpdBuildOption - all modules's build options for tool tag or tool chain families
+    /// moduleSaBuildOption - build options for a specific module
+    /// 
+    private static ToolChainConfig toolsDef;
+
+    private static ToolChainInfo toolChainInfo;
+    private static ToolChainInfo toolChainEnvInfo;
+    private static ToolChainInfo toolChainPlatformInfo;
+
+    private static ToolChainMap platformToolChainOption;
+    private static ToolChainMap platformToolChainFamilyOption;
+
+    private static Map<FpdModuleIdentification, ToolChainMap> moduleToolChainOption = new HashMap<FpdModuleIdentification, ToolChainMap>();
+    private static Map<FpdModuleIdentification, ToolChainMap> moduleToolChainFamilyOption = new HashMap<FpdModuleIdentification, ToolChainMap>();
+
+//    private static final MemoryDatabasseManager pcdDbManager = new MemoryDatabaseManager();
 
-    /**
-      Query the module's absolute MSA file path with module base name. 
     
-      @param moduleName the base name of the module
-      @return the absolute MSA file name
-      @throws BuildException
-              Base name is not registered in any SPD files
-    **/
-    private synchronized static String getMsaFilename(String moduleName) throws BuildException {
-        String[] info = moduleInfo.get(moduleName);
-        if (info == null) {
-            throw new BuildException("Module base name [" + moduleName + "] can't found in all SPD.");
-        }
-        String packagePath = (String) packageInfo.get(info[1]);
-        File convertFile = new File(workspaceDir + File.separatorChar + packagePath + File.separatorChar + info[0]);
-        return convertFile.getPath();
-    }
 
     /**
-      Query the module's absolute MBD file path with module base name. 
+      Parse framework database (DB) and all SPD files listed in DB to initialize
+      the environment for next build. This method will only be executed only once
+      in the whole build process.  
     
-      @param moduleName the base name of the module
-      @return the absolute MBD file name
+      @param workspaceDatabaseFile the file name of framework database
+      @param workspaceDir current workspace directory path
       @throws BuildException
-              Base name is not registered in any SPD files
+            Framework Dababase or SPD or MSA file is not valid
     **/
-    private synchronized static String getMbdFilename(String moduleName) throws BuildException {
-        String[] info = moduleInfo.get(moduleName);
-        if (info == null) {
-            throw new BuildException("Info: Module base name [" + moduleName + "] can't found in all SPD.");
+    public synchronized static void initInfo(String workspaceDatabaseFile, String workspaceDir, String toolsDefFilename) throws BuildException {
+        //
+        // ensure this method will be revoked only once
+        //
+        if (globalFlag) {
+            return;
         }
-        String packagePath = (String) packageInfo.get(info[1]);
-        File convertFile = new File(workspaceDir + File.separatorChar + packagePath + File.separatorChar + info[0]);
-        return convertFile.getPath().substring(0, convertFile.getPath().length() - 4) + ".mbd";
-    }
+        globalFlag = true;
+        
+        //
+        // Backup workspace directory. It will be used by other method
+        //
+        GlobalData.workspaceDir = workspaceDir.replaceAll("(\\\\)", "/");
+        
+        //
+        // Parse tools definition file
+        //
+        //
+        // If ToolChain has been set up before, do nothing.
+        // CONF dir + tools definition file name
+        //
+        String confDir = GlobalData.workspaceDir + File.separatorChar + "Tools" + File.separatorChar + "Conf";
+        File toolsDefFile = new File(confDir + File.separatorChar + toolsDefFilename);
+        System.out.println("Using file [" + toolsDefFile.getPath() + "] as tools definition file. ");
+        toolsDef = new ToolChainConfig(toolsDefFile);
+        
+        //
+        // Parse Framework Database
+        //
+        File dbFile = new File(workspaceDir + File.separatorChar + workspaceDatabaseFile);
+        try {
+            FrameworkDatabaseDocument db = (FrameworkDatabaseDocument) XmlObject.Factory.parse(dbFile);
+            //
+            // validate FrameworkDatabaseFile
+            //
+            if (! db.validate()) {
+                throw new BuildException("Framework Database file [" + dbFile.getPath() + "] is invalid.");
+            }
+            //
+            // Get package list
+            //
+            if (db.getFrameworkDatabase().getPackageList() != null ) {
+                List<DbPathAndFilename> packages = db.getFrameworkDatabase().getPackageList().getFilenameList();
+                Iterator<DbPathAndFilename> iter = packages.iterator();
+                while (iter.hasNext()) {
+                    String fileName = iter.next().getStringValue();
+                    Spd spd = new Spd(new File(workspaceDir + File.separatorChar + fileName));
+                    packageList.add(spd.getPackageId());
+                    spdTable.put(spd.getPackageId(), spd);
+                }
+            }
 
+            //
+            // Get platform list
+            //
+            if (db.getFrameworkDatabase().getPlatformList() != null) {
+                List<DbPathAndFilename> platforms = db.getFrameworkDatabase().getPlatformList().getFilenameList();
+                Iterator<DbPathAndFilename> iter = platforms.iterator();
+                while (iter.hasNext()) {
+                    String fileName = iter.next().getStringValue();
+                    File fpdFile = new File(workspaceDir + File.separatorChar + fileName);
+                    if ( ! fpdFile.exists() ) {
+                        throw new BuildException("Platform file [" + fpdFile.getPath() + "] not exists. ");
+                    }
+                    XmlObject fpdDoc = XmlObject.Factory.parse(fpdFile);
+                    //
+                    // Verify FPD file, if is invalid, throw Exception
+                    //
+                    if (! fpdDoc.validate()) {
+                        throw new BuildException("Framework Platform Surface Area file [" + fpdFile.getPath() + "] is invalid. ");
+                    }
+                    //
+                    // We can change Map to XmlObject
+                    //
+                    //
+                    // TBD check SPD or FPD is existed in FS
+                    //
+                    Map<String, XmlObject> fpdDocMap = new HashMap<String, XmlObject>();
+                    fpdDocMap.put("PlatformSurfaceArea", fpdDoc);
+                    SurfaceAreaQuery.setDoc(fpdDocMap);
+                    PlatformIdentification platformId = SurfaceAreaQuery.getFpdHeader();
+                    platformId.setFpdFile(fpdFile);
+                    platformList.add(platformId);
+                }
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+            throw new BuildException("Parse workspace Database [" + dbFile.getPath() + "] Error.\n" + e.getMessage());
+        }
+    }
+    
     /**
       Get the current WORKSPACE Directory. 
+      
       @return current workspace directory
     **/
     public synchronized static String getWorkspacePath() {
         return workspaceDir;
     }
 
-    /**
-      Query package relative path to WORKSPACE_DIR with package name. 
-      
-      @param packageName the name of the package
-      @return the path relative to WORKSPACE_DIR 
-    **/
-    public synchronized static String getPackagePath(String packageName) {
-        return (String) packageInfo.get(packageName);
-    }
 
     /**
-      Query package (which the module belongs to) relative path to WORSPACE_DIR.  
-    
-      @param moduleName the base name of the module
-      @return the relative path to WORKSPACE_DIR of the package which the module belongs to
-    **/
-    public synchronized static String getPackagePathForModule(String moduleName) {
-        String[] info = moduleInfo.get(moduleName);
-        String packagePath = (String) packageInfo.get(info[1]);
-        return packagePath;
-    }
-
-    /**
-      Query the package name which the module belongs to with the module's base name.
-    
-      @param moduleName the base name of the module
-      @return the package name which the module belongs to
-    **/
-    public synchronized static String getPackageNameForModule(String moduleName) {
-        return moduleInfo.get(moduleName)[1];
-    }
-
-    /**
-      Parse framework database (DB) and all SPD files listed in DB to initialize
-      the environment for next build. This method will only be executed only once
-      in the whole build process.  
-      
-      @param workspaceDatabaseFile the file name of framework database
-      @param workspaceDir current workspace directory path
-      @throws BuildException
-              Framework Dababase or SPD or MSA file is not valid
-    **/
-    public synchronized static void initInfo(String workspaceDatabaseFile, String workspaceDir) throws BuildException {
-        if (globalFlag) {
-            return;
-        }
-        globalFlag = true;
-        GlobalData.workspaceDir = workspaceDir;
-        File dbFile = new File(workspaceDir + File.separatorChar + workspaceDatabaseFile);
-        try {
-            FrameworkDatabaseDocument db = (FrameworkDatabaseDocument) XmlObject.Factory.parse(dbFile);
-            List<PackageListDocument.PackageList.Package> packages = db.getFrameworkDatabase().getPackageList()
-                                                                       .getPackageList();
-            Iterator iter = packages.iterator();
-            while (iter.hasNext()) {
-                PackageListDocument.PackageList.Package packageItem = (PackageListDocument.PackageList.Package) iter
-                                                                                                                    .next();
-                String name = packageItem.getPackageNameArray(0).getStringValue();
-                String path = packageItem.getPathArray(0).getStringValue();
-                packageInfo.put(name, path);
-                File spdFile = new File(workspaceDir + File.separatorChar + path + File.separatorChar + name + ".spd");
-                initPackageInfo(spdFile.getPath(), name);
-                // 
-                // SPD Parse.
-                //
-                PackageSurfaceAreaDocument spdDoc = (PackageSurfaceAreaDocument) XmlObject.Factory.parse(spdFile);
-                Spd spd = new Spd(spdDoc, path);
-                spdTable.put(name, spd);
-
+      Get the MSA file name with absolute path
+     */
+    public synchronized static File getMsaFile(ModuleIdentification moduleId) throws BuildException {
+        File msaFile = null;
+        //
+        // TBD. Do only when package is null. 
+        //
+        Iterator iter = packageList.iterator();
+        while (iter.hasNext()) {
+            PackageIdentification packageId = (PackageIdentification)iter.next();
+            Spd spd = spdTable.get(packageId);
+            msaFile = spd.getModuleFile(moduleId);
+            if (msaFile != null ) {
+                break ;
             }
-        } catch (Exception e) {
-            throw new BuildException("Parse workspace Database [" + dbFile.getPath() + "] Error.\n" + e.getMessage());
+        }
+        if (msaFile == null){
+            throw new BuildException("Can't find Module [" + moduleId.getName() + "] in all packages. ");
+        }
+        else {
+            return msaFile;
         }
     }
 
-    /**
-      Parse every MSA files, get base name from MSA Header. And record those
-      values to ModuleInfo.
-      
-      @param packageFilename the file name of the package
-      @param packageName the name of the package
-      @throws BuildException
-              SPD or MSA file is not valid
-    **/
-    private synchronized static void initPackageInfo(String packageFilename, String packageName) throws BuildException {
-        File packageFile = new File(packageFilename);
-        try {
-            PackageSurfaceAreaDocument spd = (PackageSurfaceAreaDocument) XmlObject.Factory.parse(packageFile);
-            List<String> msaFilenameList;
-
-            List<MsaFilesDocument.MsaFiles.MsaFile> msasList = spd.getPackageSurfaceArea().getMsaFiles()
-                                                                  .getMsaFileList();
-            if (msasList.size() == 0) {
-                msaFilenameList = spd.getPackageSurfaceArea().getMsaFiles().getFilenameList();
-            } else {
-                msaFilenameList = new ArrayList<String>(msasList.size());
-                Iterator msasIter = msasList.iterator();
-                while (msasIter.hasNext()) {
-                    MsaFilesDocument.MsaFiles.MsaFile msaFile = (MsaFilesDocument.MsaFiles.MsaFile)msasIter.next();
-                    msaFilenameList.add(msaFile.getFilename().getStringValue());
-                }
+    public synchronized static PackageIdentification getPackageForModule(ModuleIdentification moduleId) {
+        //
+        // If package already defined in module
+        //
+        if (moduleId.getPackage() != null) {
+            return moduleId.getPackage();
+        }
+        
+        PackageIdentification packageId = null;
+        Iterator iter = packageList.iterator();
+        while (iter.hasNext()) {
+            packageId = (PackageIdentification)iter.next();
+            moduleId.setPackage(packageId);
+            Spd spd = spdTable.get(packageId);
+            if (spd.getModuleFile(moduleId) != null ) {
+                break ;
             }
-
-            Iterator msaFilenameIter = msaFilenameList.iterator();
-            while (msaFilenameIter.hasNext()) {
-                String filename = (String)msaFilenameIter.next();
-                File msaFile = new File(workspaceDir + File.separatorChar + GlobalData.getPackagePath(packageName)
-                                        + File.separatorChar + filename);
-                SurfaceAreaParser surfaceAreaParser = new SurfaceAreaParser();
-                Map<String, XmlObject> map = surfaceAreaParser.parseFile(msaFile);
-                String baseName = "";
-                XmlObject header = null;
-                if ((header = map.get("MsaHeader")) != null) {
-                    if (((MsaHeader) header).isSetBaseName()) {
-                        baseName = ((MsaHeader) header).getBaseName().getStringValue();
-                    } else {
-                        baseName = ((MsaHeader) header).getModuleName();
-                    }
-                } else if ((header = map.get("MsaLibHeader")) != null) {
-                    baseName = ((MsaLibHeader) header).getBaseName().getStringValue();
-                } else {
-                    continue;
-                }
-                nativeMsa.put(baseName, map);
-                String[] info = { filename, packageName };
-                moduleInfo.put(baseName, info);
-            }
-        } catch (Exception e) {
-            throw new BuildException("Parse package description file [" + packageFile.getPath() + "] Error.\n"
-                                     + e.getMessage());
+        }
+        if (packageId == null){
+            throw new BuildException("Can't find Module [" + moduleId.getName() + "] in all packages. ");
+        }
+        else {
+            return packageId;
         }
     }
-
-    /**
-      Query the libraries which the module depends on.
     
-      @param moduleName the base name of the module
-      @return the libraries which the module depends on
-    **/
-    public synchronized static String[] getModuleLibrary(String moduleName, String arch) {
-        Set<String> set = moduleLibraryMap.get(moduleName + "-" + arch);
-        return set.toArray(new String[set.size()]);
-    }
-
     /**
-      Register module's library list which it depends on for later use. 
-      
-      @param moduleName the base name of the module
-      @param libraryList the libraries which the module depends on
+      Difference between build and parse: ToolChain and Target
     **/
-    public synchronized static void addModuleLibrary(String moduleName, String arch, Set<String> libraryList) {
-        moduleLibraryMap.put(moduleName + "-" + arch, libraryList);
+    public synchronized static boolean isModuleBuilt(FpdModuleIdentification moduleId) {
+        return builtModules.contains(moduleId);
     }
-
-    /**
-      Query the library absolute file name with library name. 
-      
-      @param library the base name of the library
-      @return the library absolute file name
-    **/
-    public synchronized static String getLibrary(String library, String arch) {
-        return libraries.get(library + "-" + arch);
-    }
-
-    /**
-      Register library absolute file name for later use.
-      
-      @param library the base name of the library
-      @param resultPath the library absolute file name
-    **/
-    public synchronized static void addLibrary(String library, String arch, String resultPath) {
-        libraries.put(library + "-" + arch, resultPath);
-    }
-
-    /**
-      Whether the module with ARCH has built in the previous build. 
-      
-      @param moduleName the base name of the module
-      @param arch current build ARCH
-      @return true if the module has built in previous, otherwise return false
-    **/
-    public synchronized static boolean isModuleBuilt(String moduleName, String arch) {
-        return builtModules.contains(moduleName + "-" + arch);
-    }
-
-    /**
-      Register the module with ARCH has built. 
     
-      @param moduleName the base name of the module
-      @param arch current build ARCH
-    **/
-    public synchronized static void registerBuiltModule(String moduleName, String arch) {
-        builtModules.add(moduleName + "-" + arch);
+    public synchronized static void registerBuiltModule(FpdModuleIdentification fpdModuleId) {
+        builtModules.add(fpdModuleId);
     }
 
-    /**
-      Whether the module's surface area has parsed in the previous build.
-      
-      @param moduleName the base name of the module
-      @return true if the module's surface area has parsed in previous, otherwise
-      return false
-    **/
-    public synchronized static boolean isModuleParsed(String moduleName) {
-        return parsedModules.containsKey(moduleName);
+    
+    public synchronized static void registerFpdModuleSA(FpdModuleIdentification fpdModuleId, Map<String, XmlObject> doc) {
+        Map<String, XmlObject> result = new HashMap<String, XmlObject>();
+        Set keySet = doc.keySet();
+        Iterator iter = keySet.iterator();
+        while (iter.hasNext()){
+            String key = (String)iter.next();
+            XmlObject item = cloneXmlObject(doc.get(key), true);
+            result.put(key, item);
+        }
+        fpdModuleSA.put(fpdModuleId, result);
     }
-
+    
     /**
       Query overrided module surface area information. If current is Package
       or Platform build, also include the information from FPD file. 
       
       <p>Note that surface area parsing is incremental. That means the method will 
-      only to parse the MSA and MBD files when never parsed before. </p>
+      only parse the MSA and MBD files if necessary. </p>
     
       @param moduleName the base name of the module
       @return the overrided module surface area information
       @throws BuildException
               MSA or MBD is not valid
     **/
-    public synchronized static Map<String, XmlObject> getDoc(String moduleName) throws BuildException {
-        if (parsedModules.containsKey(moduleName)) {
-            return parsedModules.get(moduleName);
+    public synchronized static Map<String, XmlObject> getDoc(FpdModuleIdentification fpdModuleId) throws BuildException {
+        if (parsedModules.containsKey(fpdModuleId)) {
+            return parsedModules.get(fpdModuleId);
         }
-        Map<String, XmlObject> msaMap = getNativeMsa(moduleName);
-        Map<String, XmlObject> mbdMap = getNativeMbd(moduleName);
-        OverrideProcess op = new OverrideProcess();
-        Map<String, XmlObject> map = op.override(mbdMap, msaMap);
+        Map<String, XmlObject> doc = new HashMap<String, XmlObject>();
+        ModuleIdentification moduleId = fpdModuleId.getModule();
         //
-        // IF IT IS A PALTFORM BUILD, OVERRIDE FROM PLATFORM
+        // First part: get the MSA files info
         //
-        if (FpdParserTask.platformBuildOptions != null) {
-            Map<String, XmlObject> platformMap = new HashMap<String, XmlObject>();
-            platformMap.put("BuildOptions", FpdParserTask.platformBuildOptions);
-            Map<String, XmlObject> overrideMap = op.override(platformMap, OverrideProcess.deal(map));
-            GlobalData.registerModule(moduleName, overrideMap);
-            return overrideMap;
-        } else {
-            parsedModules.put(moduleName, map);
-            return map;
+        doc = getNativeMsa(moduleId);
+        
+        //
+        // Second part: put build options
+        //
+        doc.put("BuildOptions", fpdBuildOptions);
+        
+        //
+        // Third part: get Module info from FPD, such as Library instances, PCDs
+        //
+        if (fpdModuleSA.containsKey(fpdModuleId)){
+            //
+            // merge module info in FPD to final Doc
+            // For Library Module, do nothing here
+            //
+            doc.putAll(fpdModuleSA.get(fpdModuleId));
         }
+        parsedModules.put(fpdModuleId, doc);
+        return doc;
     }
 
+    public synchronized static Map<String, XmlObject> getDoc(ModuleIdentification moduleId, String arch) throws BuildException {
+        FpdModuleIdentification fpdModuleId = new FpdModuleIdentification(moduleId, arch);
+        return getDoc(fpdModuleId);
+    }
     /**
       Query the native MSA information with module base name. 
       
@@ -459,200 +377,425 @@ public class GlobalData {
       @throws BuildException
               MSA file is not valid
     **/
-    public synchronized static Map<String, XmlObject> getNativeMsa(String moduleName) throws BuildException {
-        if (nativeMsa.containsKey(moduleName)) {
-            return nativeMsa.get(moduleName);
+    public synchronized static Map<String, XmlObject> getNativeMsa(ModuleIdentification moduleId) throws BuildException {
+        if (nativeMsa.containsKey(moduleId)) {
+            return nativeMsa.get(moduleId);
         }
-        String msaFilename = getMsaFilename(moduleName);
-        File msaFile = new File(msaFilename);
-        if (!msaFile.exists()) {
-            throw new BuildException("Info: Surface Area file [" + msaFile.getPath() + "] can't found.");
+        File msaFile = getMsaFile(moduleId);
+        Map<String, XmlObject> msaMap = getNativeMsa(msaFile);
+        nativeMsa.put(moduleId, msaMap);
+        return msaMap;
+    }
+    
+    public synchronized static Map<String, XmlObject> getNativeMsa(File msaFile) throws BuildException {
+        if (! msaFile.exists()) {
+            throw new BuildException("Surface Area file [" + msaFile.getPath() + "] can't found.");
         }
-        SurfaceAreaParser surfaceAreaParser = new SurfaceAreaParser();
-        Map<String, XmlObject> map = surfaceAreaParser.parseFile(msaFile);
-        nativeMsa.put(moduleName, map);
+        try {
+            ModuleSurfaceAreaDocument doc = (ModuleSurfaceAreaDocument)XmlObject.Factory.parse(msaFile);
+            //
+            // Validate File if they accord with XML Schema
+            //
+            if ( ! doc.validate()){
+                throw new BuildException("Module Surface Area file [" + msaFile.getPath() + "] is invalid.");
+            }
+            //
+            // parse MSA file
+            //
+            ModuleSurfaceArea msa= doc.getModuleSurfaceArea();
+            Map<String, XmlObject> msaMap = new HashMap<String, XmlObject>();
+            msaMap.put("MsaHeader", cloneXmlObject(msa.getMsaHeader(), true));
+            msaMap.put("ModuleDefinitions", cloneXmlObject(msa.getModuleDefinitions(), true));
+            msaMap.put("LibraryClassDefinitions", cloneXmlObject(msa.getLibraryClassDefinitions(), true));
+            msaMap.put("SourceFiles", cloneXmlObject(msa.getSourceFiles(), true));
+            msaMap.put("PackageDependencies", cloneXmlObject(msa.getPackageDependencies(), true));
+            msaMap.put("Protocols", cloneXmlObject(msa.getProtocols(), true));
+            msaMap.put("PPIs", cloneXmlObject(msa.getPPIs(), true));
+            msaMap.put("Guids", cloneXmlObject(msa.getGuids(), true));
+            msaMap.put("Externs", cloneXmlObject(msa.getExterns(), true));
+            return msaMap;
+        }
+        catch (Exception ex){
+            throw new BuildException(ex.getMessage());
+        }
+    }
+    
+    public static Map<String, XmlObject> getFpdBuildOptions() {
+        Map<String, XmlObject> map = new HashMap<String, XmlObject>();
+        map.put("BuildOptions", fpdBuildOptions);
         return map;
     }
     
-    /**
-      Query the native MBD information with module base name. 
-      
-      <p>Note that MBD parsing is incremental. That means the method will 
-      only to parse the MBD files when never parsed before. </p>
+    public static void setFpdBuildOptions(XmlObject fpdBuildOptions) {
+        GlobalData.fpdBuildOptions = cloneXmlObject(fpdBuildOptions, true);
+    }
+
+    public static XmlObject getFpdDynamicPcds() {
+        return fpdDynamicPcds;
+    }
+
+    public static void setFpdDynamicPcds(XmlObject fpdDynamicPcds) {
+        GlobalData.fpdDynamicPcds = fpdDynamicPcds;
+    }
+
+    //////////////////////////////////////////////
+    //////////////////////////////////////////////
     
-      @param moduleName the base name of the module
-      @return the native MBD information
-      @throws BuildException
-              MBD file is not valid
-    **/
-    public synchronized static Map<String, XmlObject> getNativeMbd(String moduleName) throws BuildException {
-        if (nativeMbd.containsKey(moduleName)) {
-            return nativeMbd.get(moduleName);
+    public static Set<ModuleIdentification> getModules(PackageIdentification packageId){
+        Spd spd = spdTable.get(packageId);
+        if (spd == null ) {
+            Set<ModuleIdentification> dummy = new HashSet<ModuleIdentification>();
+            return dummy;
         }
-        String mbdFilename = getMbdFilename(moduleName);
-        File mbdFile = new File(mbdFilename);
-        if (!mbdFile.exists()) {
-            return null;
-            //throw new BuildException("Info: Surface Area file [" + mbdFile.getPath() + "] can't found.");
+        else {
+            return spd.getModules();
         }
-        SurfaceAreaParser surfaceAreaParser = new SurfaceAreaParser();
-        Map<String, XmlObject> map = surfaceAreaParser.parseFile(mbdFile);
-        nativeMbd.put(moduleName, map);
-        return map;
     }
 
     /**
-      Register module overrided surface area information. If has existed, then update.
-      
-      @param moduleName the base name of the module
-      @param map the overrided surface area information
-    **/
-    public synchronized static void registerModule(String moduleName, Map<String, XmlObject> map) {
-        parsedModules.put(moduleName, map);
-    }
-
-    /**
-     * 
-     * @param protocolName
-     * @return
+     * The header file path is relative to workspace dir
      */
-    public synchronized static String[] getProtocolInfoGuid(String protocolName) {
-        Set set = spdTable.keySet();
-        Iterator iter = set.iterator();
-        String[] cNameGuid = null;
-
-        while (iter.hasNext()) {
-            Spd spd = (Spd) spdTable.get(iter.next());
-            cNameGuid = spd.getProtocolNameGuidArray(protocolName);
-            if (cNameGuid != null) {
-                break;
+    public static String[] getLibraryClassHeaderFiles(
+            PackageIdentification[] packages, String name)
+            throws BuildException {
+        if (packages == null) {
+            // throw Exception or not????
+            return new String[0];
+        }
+        String[] result = null;
+        for (int i = 0; i < packages.length; i++) {
+            Spd spd = spdTable.get(packages[i]);
+            //
+            // If find one package defined the library class
+            //
+            if ((result = spd.getLibClassIncluder(name)) != null) {
+                return result;
             }
         }
-        return cNameGuid;
+        //
+        // If can't find library class declaration in every package
+        //
+        throw new BuildException("Can not find library class [" + name
+                + "] declaration in every packages. ");
     }
 
-    public synchronized static String[] getPpiInfoGuid(String ppiName) {
-        Set set = spdTable.keySet();
-        Iterator iter = set.iterator();
-        String[] cNameGuid = null;
+    /**
+     * The header file path is relative to workspace dir
+     */
+    public static String getPackageHeaderFiles(PackageIdentification packages,
+            String moduleType) throws BuildException {
+        if (packages == null) {
+            return new String("");
+        }
+        Spd spd = spdTable.get(packages);
+        //
+        // If can't find package header file, skip it
+        //
+        String temp = null;
+        if (spd != null) {
+            if ((temp = spd.getPackageIncluder(moduleType)) != null) {
+                return temp;
+            } else {
+                temp = "";
+                return temp;
+            }
+        } else {
+            return null;
+        }
+    }
 
-        while (iter.hasNext()) {
-            Spd spd = (Spd) spdTable.get(iter.next());
-            cNameGuid = spd.getPpiCnameGuidArray(ppiName);
-
-            if (cNameGuid != null) {
-                break;
+    /**
+     * return two values: {cName, GuidValue}
+     */
+    public static String[] getGuid(PackageIdentification[] packages, String name)
+            throws BuildException {
+        if (packages == null) {
+            // throw Exception or not????
+            return new String[0];
+        }
+        String[] result = null;
+        for (int i = 0; i < packages.length; i++) {
+            Spd spd = spdTable.get(packages[i]);
+            //
+            // If find one package defined the GUID
+            //
+            if ((result = spd.getGuid(name)) != null) {
+                return result;
             }
         }
-        return cNameGuid;
+        return null;
     }
 
+    /**
+     * return two values: {cName, GuidValue}
+     */
+    public static String[] getPpiGuid(PackageIdentification[] packages,
+            String name) throws BuildException {
+        if (packages == null) {
+            return new String[0];
+        }
+        String[] result = null;
+        for (int i = 0; i < packages.length; i++) {
+            Spd spd = spdTable.get(packages[i]);
+            //
+            // If find one package defined the Ppi GUID
+            //
+            if ((result = spd.getPpi(name)) != null) {
+                return result;
+            }
+        }
+        return null;
+
+    }
+
+    /**
+     * return two values: {cName, GuidValue}
+     */
+    public static String[] getProtocolGuid(PackageIdentification[] packages,
+            String name) throws BuildException {
+        if (packages == null) {
+            return new String[0];
+        }
+        String[] result = null;
+        for (int i = 0; i < packages.length; i++) {
+            Spd spd = spdTable.get(packages[i]);
+            //
+            // If find one package defined the protocol GUID
+            //
+            if ((result = spd.getProtocol(name)) != null) {
+                return result;
+            }
+        }
+        return null;
+
+    }
+    
+    /////////////////////////// Update!! Update!! Update!!
+//    public synchronized static MemoryDatabaseManager getPCDMemoryDBManager() {
+//        return pcdDbManager;
+//    }
+    ///////////////////////////
+    public synchronized static PlatformIdentification getPlatform(String name) throws BuildException {
+        Iterator iter = platformList.iterator();
+        while(iter.hasNext()){
+            PlatformIdentification platformId = (PlatformIdentification)iter.next();
+            if (platformId.getName().equalsIgnoreCase(name)) {
+//                GlobalData.log.info("Platform: " + platformId + platformId.getFpdFile());
+                return platformId;
+            }
+        }
+        throw new BuildException("Can't find platform [" + name + "] in current workspace. ");
+    }
+    
+    public synchronized static PackageIdentification refreshPackageIdentification(PackageIdentification packageId) throws BuildException {
+        Iterator iter = packageList.iterator();
+        while(iter.hasNext()){
+            PackageIdentification packageItem = (PackageIdentification)iter.next();
+            if (packageItem.equals(packageId)) {
+                packageId.setName(packageItem.getName());
+                packageId.setSpdFile(packageItem.getSpdFile());
+                return packageId;
+            }
+        }
+        throw new BuildException("Can't find package GUID value " + packageId.getGuid() + " under current workspace. ");
+    }
+    
+    public synchronized static ModuleIdentification refreshModuleIdentification(ModuleIdentification moduleId) throws BuildException {
+//        System.out.println("1");
+//        System.out.println("##" + moduleId.getGuid());
+        PackageIdentification packageId = getPackageForModule(moduleId);
+//        System.out.println("" + packageId.getGuid());
+        moduleId.setPackage(packageId);
+        Spd spd = spdTable.get(packageId);
+        if (spd == null) {
+            throw new BuildException("Can't find package GUID value " + packageId.getGuid() + " under current workspace. ");
+        }
+        Set<ModuleIdentification> modules = spd.getModules();
+        Iterator<ModuleIdentification> iter = modules.iterator();
+        while (iter.hasNext()) {
+            ModuleIdentification item = iter.next();
+            if (item.equals(moduleId)) {
+                moduleId.setName(item.getName());
+                moduleId.setModuleType(item.getModuleType());
+                moduleId.setMsaFile(item.getMsaFile());
+                return moduleId;
+            }
+        }
+        throw new BuildException("Can't find module GUID value " + moduleId.getGuid() + " in " + packageId + " under current workspace. ");
+    }
+    
+    public synchronized static Set<PackageIdentification> getPackageList(){
+        return packageList;
+    }
+    ///// remove!!
+    private static XmlObject cloneXmlObject(XmlObject object, boolean deep) throws BuildException {
+        if ( object == null) {
+            return null;
+        }
+        XmlObject result = null;
+        try {
+            result = XmlObject.Factory.parse(object.getDomNode()
+                            .cloneNode(deep));
+        } catch (Exception ex) {
+            throw new BuildException(ex.getMessage());
+        }
+        return result;
+    }
+
+    ////// Tool Chain Related, try to refine and put some logic process to ToolChainFactory
+
+    public static ToolChainInfo getToolChainInfo() {
+//        GlobalData.log.info(toolsDef.getConfigInfo() + "" + toolChainEnvInfo + toolChainPlatformInfo);
+        if (toolChainInfo == null) {
+            toolChainInfo = toolsDef.getConfigInfo().intersection(toolChainEnvInfo);
+            if (toolChainPlatformInfo != null) {
+                toolChainInfo = toolChainInfo.intersection(toolChainPlatformInfo);
+            }
+            toolChainInfo.addCommands(toolsDef.getConfigInfo().getCommands());
+            toolChainInfo.normalize();
+            GlobalData.log.info(toolChainInfo + "");
+        }
+        return toolChainInfo;
+    }
+
+
+
+    public static void setPlatformToolChainFamilyOption(ToolChainMap map) {
+        platformToolChainFamilyOption = map;
+    }
+
+    public static void setPlatformToolChainOption(ToolChainMap map) {
+        platformToolChainOption = map;
+    }
+
+    public static void addModuleToolChainOption(FpdModuleIdentification fpdModuleId,
+        ToolChainMap toolChainOption) {
+        moduleToolChainOption.put(fpdModuleId, toolChainOption);
+    }
+
+    public static void addModuleToolChainFamilyOption(FpdModuleIdentification fpdModuleId,
+        ToolChainMap toolChainOption) {
+        moduleToolChainFamilyOption.put(fpdModuleId, toolChainOption);
+    }
+
+    public static String getCommandSetting(String[] commandDescription, FpdModuleIdentification fpdModuleId) throws EdkException {
+        ToolChainKey toolChainKey = new ToolChainKey(commandDescription);
+        ToolChainMap toolChainConfig = toolsDef.getConfig(); 
+        String setting = null;
+
+        if (!commandDescription[ToolChainElement.ATTRIBUTE.value].equals(ToolChainAttribute.FLAGS.toString())) {
+            setting = toolChainConfig.get(toolChainKey);
+            if (setting == null) {
+                setting = "";
+            }
+            return setting;
+        }
+
+        //
+        // get module specific options, if any
+        //
+        // tool tag first
+        ToolChainMap option = moduleToolChainOption.get(fpdModuleId);
+        ToolChainKey toolChainFamilyKey = null;
+
+        if ((option == null) || (option != null && (setting = option.get(toolChainKey)) == null)) {
+            //
+            // then tool chain family
+            //
+            toolChainFamilyKey = new ToolChainKey(commandDescription);
+            toolChainFamilyKey.setKey(ToolChainAttribute.FAMILY.toString(), ToolChainElement.ATTRIBUTE.value);
+            String family = toolChainConfig.get(toolChainFamilyKey);
+            toolChainFamilyKey.setKey(family, ToolChainElement.TOOLCHAIN.value);
+            toolChainFamilyKey.setKey(ToolChainAttribute.FLAGS.toString(), ToolChainElement.ATTRIBUTE.value);
+
+            option = moduleToolChainFamilyOption.get(fpdModuleId);
+            if (option != null) {                
+                setting = option.get(toolChainFamilyKey);
+            }
+        }
+
+        //
+        // get platform options, if any
+        //
+        if (setting == null) {
+            // tool tag first
+            if (platformToolChainOption == null || (setting = platformToolChainOption.get(toolChainKey)) == null) {
+                // then tool chain family
+                if (toolChainFamilyKey == null) {
+                    toolChainFamilyKey = new ToolChainKey(commandDescription);
+                    toolChainFamilyKey.setKey(ToolChainAttribute.FAMILY.toString(), ToolChainElement.ATTRIBUTE.value);
+                    String family = toolChainConfig.get(toolChainFamilyKey);
+                    toolChainFamilyKey.setKey(family, ToolChainElement.TOOLCHAIN.value);
+                    toolChainFamilyKey.setKey(ToolChainAttribute.FLAGS.toString(), ToolChainElement.ATTRIBUTE.value);
+                }
+
+                setting = platformToolChainFamilyOption.get(toolChainFamilyKey);
+            }
+        }
+
+        if (setting == null) {
+            setting = "";
+        }
+
+        return setting;
+    }
+    
+    public static void setToolChainEnvInfo(ToolChainInfo envInfo) {
+        toolChainEnvInfo = envInfo;
+    }
+    public static void setToolChainPlatformInfo(ToolChainInfo platformInfo) {
+        toolChainPlatformInfo = platformInfo;
+    }
+
+    //
+    // for PCD
+    //
+//    public synchronized static MemoryDatabaseManager getPCDMemoryDBManager() {
+//        return pcdDbManager;
+//    }
+
+    //
+    // For PCD
+    //
     /**
      * 
      * @param guidName
      * @return
      */
-    public synchronized static String[] getGuidInfoGuid(String guidName) {
-        String[] cNameGuid = null;
-        Set set = spdTable.keySet();
-        Iterator iter = set.iterator();
+//    public synchronized static String[] getGuidInfoGuid(String guidName) {
+//        String[] cNameGuid = null;
+//        Set set = spdTable.keySet();
+//        Iterator iter = set.iterator();
+//
+//        while (iter.hasNext()) {
+//            Spd spd = (Spd) spdTable.get(iter.next());
+//            cNameGuid = spd.getGuidNameArray(guidName);
+//            if (cNameGuid != null) {
+//                break;
+//            }
+//        }
+//        return cNameGuid;
+//    }
 
-        while (iter.hasNext()) {
-            Spd spd = (Spd) spdTable.get(iter.next());
-            cNameGuid = spd.getGuidNameArray(guidName);
-            if (cNameGuid != null) {
-                break;
-            }
-        }
-        return cNameGuid;
-    }
-
-    public synchronized static String getLibClassIncluder(String libName) {
-        String libIncluder = null;
-        Set set = spdTable.keySet();
-        Iterator iter = set.iterator();
-
-        while (iter.hasNext()) {
-            String packageName = (String) iter.next();
-            Spd spd = (Spd) spdTable.get(packageName);
-            libIncluder = spd.getLibClassIncluder(libName);
-            String packagePath = spd.packagePath;
-            if (packagePath != null) {
-                packagePath = packagePath.replace('\\', File.separatorChar);
-                packagePath = packagePath.replace('/', File.separatorChar);
-            } else {
-                packagePath = packageName;
-            }
-            if (libIncluder != null) {
-                libIncluder = libIncluder.replace('\\', File.separatorChar);
-                libIncluder = libIncluder.replace('/', File.separatorChar);
-                libIncluder = packageName + File.separatorChar + libIncluder;
-                break;
-            }
-        }
-        return libIncluder;
-    }
-
-    public synchronized static String getModuleInfoByPackageName(String packageName, String moduleType) {
-        Spd spd;
-        String includeFile = null;
-        String includeStr = "";
-        String cleanPath = "";
-
-        spd = (Spd) spdTable.get(packageName);
-        includeFile = spd.getModuleTypeIncluder(moduleType);
-        if (includeFile != null) {
-            includeFile = includeFile.replace('\\', File.separatorChar);
-            includeFile = includeFile.replace('/', File.separatorChar);
-            includeStr = CommonDefinition.include + " <" + includeStr;
-            cleanPath = spd.packagePath;
-            cleanPath = cleanPath.replace('\\', File.separatorChar);
-            cleanPath = cleanPath.replace('/', File.separatorChar);
-
-            if (cleanPath.charAt(spd.packagePath.length() - 1) != File.separatorChar) {
-                cleanPath = cleanPath + File.separatorChar;
-            }
-            includeStr = includeStr + cleanPath;
-            includeStr = includeStr + includeFile;
-            includeStr = includeStr + ">\r\n";
-        }
-
-        return includeStr;
-    }
-
-    public synchronized static void setLibInstanceInfo(String libName, String libConstructor, String libDesturctor) {
-        String[] libConsDes = new String[2];
-        libConsDes[0] = libConstructor;
-        libConsDes[1] = libDesturctor;
-
-        libInstanceInfo.put(libName, libConsDes);
-    }
-
-    public synchronized static boolean isHaveLibInstance(String libName) {
-        return libInstanceInfo.containsKey(libName);
-    }
-
-    public synchronized static String getLibInstanceConstructor(String libName) {
-        String[] libInstanceValue;
-        libInstanceValue = libInstanceInfo.get(libName);
-        if (libInstanceValue != null) {
-            return libInstanceValue[0];
-        } else {
-            return null;
-        }
-    }
-
-    public synchronized static String getLibInstanceDestructor(String libName) {
-        String[] libInstanceValue;
-        libInstanceValue = libInstanceInfo.get(libName);
-        if (libInstanceValue != null) {
-            return libInstanceValue[1];
-        } else {
-            return null;
-        }
-    }
-
-    public synchronized static MemoryDatabaseManager getPCDMemoryDBManager() {
-        return pcdDbManager;
-    }
+    //
+    // For PCD
+    //
+//    public synchronized static Map<FpdModuleIdentification, XmlObject> getFpdModuleSaXmlObject(
+//            String xmlObjectName) {
+//        Set<FpdModuleIdentification> fpdModuleSASet = fpdModuleSA.keySet();
+//        Iterator item = fpdModuleSASet.iterator();
+//
+//        Map<FpdModuleIdentification, XmlObject> SAPcdBuildDef = new HashMap<FpdModuleIdentification, XmlObject>();
+//        Map<String, XmlObject> SANode = new HashMap<String, XmlObject>();
+//        FpdModuleIdentification moduleId;
+//        while (item.hasNext()) {
+//            moduleId = (FpdModuleIdentification) item.next();
+//            SANode = fpdModuleSA.get(item.next());
+//            SAPcdBuildDef.put(moduleId,
+//                    (PcdBuildDefinitionDocument.PcdBuildDefinition) SANode
+//                            .get(xmlObjectName));
+//        }
+//        return SAPcdBuildDef;
+//    }
 }
+
diff --git a/Tools/Source/GenBuild/org/tianocore/build/global/GlobalShare.java b/Tools/Source/GenBuild/org/tianocore/build/global/GlobalShare.java
deleted file mode 100644
index 5912127a10..0000000000
--- a/Tools/Source/GenBuild/org/tianocore/build/global/GlobalShare.java
+++ /dev/null
@@ -1,178 +0,0 @@
-/*++
-
- Copyright (c) 2006, Intel Corporation
- All rights reserved. This program and the accompanying materials
- are licensed and made available under the terms and conditions of the BSD License
- which accompanies this distribution.  The full text of the license may be found at
- http://opensource.org/licenses/bsd-license.php
-
- THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
- WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
-
- Module Name:
- ShareObject.java
-
- Abstract:
-
- --*/
-package org.tianocore.build.global;
-
-import java.util.*;
-
-import org.apache.tools.ant.*;
-import org.apache.tools.ant.types.DataType;
-
-public class GlobalShare extends DataType implements DynamicConfigurator {
-    private static final HashMap<String, Object> objStorage = new HashMap<String, Object>();
-
-    private DataObjectOp op;
-
-    private String objName;
-
-    private Object objInst;
-
-    private String objClassPackage = "org.tianocore";
-
-    public GlobalShare () {
-
-    }
-
-    public GlobalShare (String objName) {
-        this.objName = objName;
-        this.objInst = objStorage.get(this.objName);
-    }
-
-    public GlobalShare (String objName, Object obj) {
-        this.objName = objName;
-        this.objInst = obj;
-        objStorage.put(this.objName, this.objInst);
-    }
-
-    public Object createDynamicElement(String name) throws BuildException {
-        String className = objClassPackage + "." + name;
-        log("GlobalShare.createDynamicElement(" + name + ")",
-                        Project.MSG_VERBOSE);
-        try {
-            objInst = Class.forName(className).newInstance();
-        } catch (ClassNotFoundException e) {
-            throw new BuildException("class name is not found");
-        } catch (InstantiationException e) {
-            throw new BuildException("the class cannnot be instantiated");
-        } catch (IllegalAccessException e) {
-            throw new BuildException("cannot access the class");
-        }
-
-        return objInst;
-    }
-
-    public void setDynamicAttribute(String name, String value)
-                    throws BuildException {
-        log("name = " + name + " value = " + value, Project.MSG_VERBOSE);
-        throw new BuildException();
-    }
-
-    public void setName(String name) {
-        this.objName = name;
-        if (this.op != null) {
-            issueOperation();
-        }
-    }
-
-    public String getName() {
-        return this.objName;
-    }
-
-    public void setPackage(String name) {
-        log("ShareObject.setPackage(" + name + ")", Project.MSG_VERBOSE);
-        this.objClassPackage = name;
-    }
-
-    public String getPackage() {
-        return this.objClassPackage;
-    }
-
-    public void setOperation(String opName) {
-        log("ShareObject.setOperation(" + opName + ")", Project.MSG_VERBOSE);
-        this.op = DataObjectOp.formString(opName);
-
-        if (this.objName != null) {
-            issueOperation();
-        }
-    }
-
-    public String getOperation() {
-        return this.op.toString();
-    }
-
-    public void issueOperation() {
-        if (this.op == DataObjectOp.ADD) {
-
-            log("ShareObject: adding ... " + this.objName, Project.MSG_VERBOSE);
-            objStorage.put(this.objName, this.objInst);
-
-        } else if (this.op == DataObjectOp.GET) {
-
-            log("ShareObject: fetching ... " + this.objName,
-                            Project.MSG_VERBOSE);
-            objInst = objStorage.get(objName);
-
-        } else if (this.op == DataObjectOp.DEL) {
-
-            log("ShareObject: removing ... " + this.objName,
-                            Project.MSG_VERBOSE);
-            objInst = objStorage.remove(objName);
-
-        } else {
-            throw new BuildException("not supported operation");
-        }
-    }
-
-    public Object get() {
-        return this.objInst;
-    }
-
-    public static int getObjectNum() {
-        return objStorage.size();
-    }
-
-    public static Object add(String objName, Object obj) {
-        return objStorage.put(objName, obj);
-    }
-
-    public static Object retrieve(String objName) {
-        return objStorage.get(objName);
-    }
-
-    public static Object remove(String objName) {
-        return objStorage.remove(objName);
-    }
-
-    public static void empty() {
-        objStorage.clear();
-    }
-}
-
-class DataObjectOp {
-    private static final HashMap<String, DataObjectOp> opMap = new HashMap<String, DataObjectOp>();
-
-    private final String opName;
-
-    private DataObjectOp (String name) {
-        this.opName = name;
-        opMap.put(this.opName, this);
-    }
-
-    public String toString() {
-        return opName;
-    }
-
-    public static DataObjectOp formString(String opName) {
-        return opMap.get(opName);
-    }
-
-    public static final DataObjectOp ADD = new DataObjectOp("ADD");
-
-    public static final DataObjectOp GET = new DataObjectOp("GET");
-
-    public static final DataObjectOp DEL = new DataObjectOp("DEL");
-}
diff --git a/Tools/Source/GenBuild/org/tianocore/build/global/LibBuildFileGenerator.java b/Tools/Source/GenBuild/org/tianocore/build/global/LibBuildFileGenerator.java
deleted file mode 100644
index 4d7e870587..0000000000
--- a/Tools/Source/GenBuild/org/tianocore/build/global/LibBuildFileGenerator.java
+++ /dev/null
@@ -1,412 +0,0 @@
-/** @file
-  This file is an ANT task.
-  
-  LibBuildFileGenerator task is used to generate module's build.xml file.
-
-Copyright (c) 2006, Intel Corporation
-All rights reserved. This program and the accompanying materials
-are licensed and made available under the terms and conditions of the BSD License
-which accompanies this distribution.  The full text of the license may be found at
-http://opensource.org/licenses/bsd-license.php
-
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
-
-**/
-package org.tianocore.build.global;
-
-import java.io.File;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Set;
-import java.util.Vector;
-
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.transform.OutputKeys;
-import javax.xml.transform.Result;
-import javax.xml.transform.Source;
-import javax.xml.transform.Transformer;
-import javax.xml.transform.TransformerFactory;
-import javax.xml.transform.dom.DOMSource;
-import javax.xml.transform.stream.StreamResult;
-
-import org.apache.tools.ant.BuildException;
-import org.apache.tools.ant.Task;
-import org.apache.xmlbeans.XmlObject;
-import org.tianocore.MsaHeaderDocument.MsaHeader;
-import org.tianocore.MsaLibHeaderDocument.MsaLibHeader;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-
-/**
-  This class <code>LibBuildFileGenerator</code> is an ANT task to generate 
-  build.xml for each module. Here are two usages. 
-  
-  <ul>
-    <li>
-      For one module (<b>bf</b> is LibBuildFileGenerator task name):
-      <pre>
-        &lt;bf buildFile="Application\HelloWorld\HelloWorld.msa" /&gt;
-      </pre>
-    </li>
-    <li>
-      For one package:
-      <pre>
-        &lt;bf recursive="true" /&gt;
-      </pre>
-    </li>
-  </ul>
-  
-  @since GenBuild 1.0
-**/
-public class LibBuildFileGenerator extends Task {
-
-    private File buildFile;
-
-    private boolean recursive = false;
-    
-    private String license = " Copyright (c) 2006, Intel Corporation \n"
-                    + "All rights reserved. This program and the accompanying materials \n"
-                    + "are licensed and made available under the terms and conditions of the BSD License \n"
-                    + "which accompanies this distribution.  The full text of the license may be found at  \n"
-                    + "http://opensource.org/licenses/bsd-license.php \n"
-                    + "\n"
-                    + "THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN \"AS IS\" BASIS, \n"
-                    + "WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.";
-
-    private String base_name;
-    
-    private String module_relative_path;
-    
-    private File base_file = new File(".");
-    
-    /**
-      Public construct method. It is necessary for ANT task.
-    **/
-    public LibBuildFileGenerator () {
-    }
-
-    /**
-      ANT task's entry point, will be called after init(). 
-      
-      @throws BuildException
-              buildFile do not specify while recursive set to false
-    **/
-    public void execute() throws BuildException {
-        if(recursive){
-            searchMsa(new File("."));
-        }
-        else {
-            Map<String,File> map = new HashMap<String,File>();
-            String basename = buildFile.getName();
-            int k = basename.lastIndexOf('.');
-            base_name = basename.substring(0, k);
-            map.put(base_name, buildFile);
-            genBuildFile(map);
-        }
-    }
-    
-    /**
-      Recursivly find all MSA files and record all modules. 
-      
-      @param path Package path
-    **/
-    private void searchMsa(File path){
-        File[] files = path.listFiles();
-        Vector<File> vec = new Vector<File>();
-        for(int i=0; i < files.length; i ++){
-            if (files[i].isFile()){
-                if(files[i].getName().endsWith(".msa")){
-                    System.out.println("#" + files[i].getPath());
-                    vec.add(files[i]);
-                }
-            }
-        }
-        Map<String,File> mapBasename = new HashMap<String,File>();
-        if (vec.size() > 0){
-            base_name = null;
-            for ( int j = 0 ; j < vec.size(); j++){
-                if ( vec.size() > 1){
-                  System.out.println("##" + vec.get(0));
-                }
-                File f = (File)vec.get(j);
-                SurfaceAreaParser surfaceAreaParser = new SurfaceAreaParser();
-                Map<String, XmlObject> map = surfaceAreaParser.parseFile(f);
-                String baseName = "";
-                XmlObject header = null;
-                if ( (header = map.get("MsaHeader")) != null ){
-                    baseName = ((MsaHeader)header).getBaseName().getStringValue();
-                }
-                else if ( (header = map.get("MsaLibHeader")) != null){
-                    baseName = ((MsaLibHeader)header).getBaseName().getStringValue();
-                } else {
-                    continue ;
-                }
-                if ( base_name == null || base_name.length() > baseName.length()){
-                    base_name = baseName;
-                    buildFile = f;
-                    try {
-                    module_relative_path = buildFile.getParent().substring(base_file.getPath().length() + 1);
-                    }
-                    catch(Exception e){
-                        module_relative_path = ".";
-                    }
-                }
-                mapBasename.put(baseName, f);
-            }
-            genBuildFile(mapBasename);
-        }
-
-        for(int i=0; i < files.length; i ++){
-            if (files[i].isDirectory()){
-                searchMsa(files[i]);
-            }
-        }
-    }
-    
-    /**
-      Generate build.xml.
-      
-      @param map All base name under one module directory
-    **/
-    private void genBuildFile(Map map) {
-        DocumentBuilderFactory domfac = DocumentBuilderFactory.newInstance();
-        try {
-            DocumentBuilder dombuilder = domfac.newDocumentBuilder();
-            Document document = dombuilder.newDocument();
-            //
-            // create root element and its attributes
-            //
-            document.appendChild(document.createComment(license));
-            Element root = document.createElement("project");
-            root.setAttribute("default", base_name);
-            root.setAttribute("basedir", ".");
-            //
-            // element for External ANT tasks
-            //
-            root.appendChild(document.createComment("Apply external ANT tasks"));
-            Element ele = document.createElement("taskdef");
-            ele.setAttribute("resource", "GenBuild.tasks");
-            root.appendChild(ele);
-            //
-            // <taskdef resource="net/sf/antcontrib/antlib.xml" />
-            //
-            ele = document.createElement("taskdef");
-            ele.setAttribute("resource", "net/sf/antcontrib/antlib.xml");
-            root.appendChild(ele);
-            
-            ele = document.createElement("property");
-            ele.setAttribute("environment", "env");
-            root.appendChild(ele);
-
-            ele = document.createElement("property");
-            ele.setAttribute("name", "WORKSPACE_DIR");
-            ele.setAttribute("value", "${env.WORKSPACE}");
-            root.appendChild(ele);
-            
-            ele = document.createElement("import");
-            ele.setAttribute("file", "${WORKSPACE_DIR}"+File.separatorChar+"Tools"+File.separatorChar+"Conf"+File.separatorChar+"BuildMacro.xml");
-            root.appendChild(ele);
-            
-            root.appendChild(document.createComment("MODULE_RELATIVE PATH is relative to PACKAGE_DIR"));
-            ele = document.createElement("property");
-            ele.setAttribute("name", "MODULE_RELATIVE_PATH");
-            ele.setAttribute("value", module_relative_path);
-            root.appendChild(ele);
-
-            ele = document.createElement("property");
-            ele.setAttribute("name", "MODULE_DIR");
-            ele.setAttribute("value", "${PACKAGE_DIR}" + File.separatorChar + "${MODULE_RELATIVE_PATH}");
-            root.appendChild(ele);
-
-            ele = document.createElement("property");
-            ele.setAttribute("name", "COMMON_FILE");
-            ele.setAttribute("value", "${WORKSPACE_DIR}" + File.separatorChar + "Tools"
-                            + File.separatorChar + "Conf" + File.separatorChar + "Common.xml");
-            root.appendChild(ele);
-            
-            //
-            // generate the buildfmd target
-            //
-            Set set = map.keySet();
-            Iterator iter = set.iterator();
-            while (iter.hasNext()){
-                String bName = (String)iter.next();
-                File msaFile = (File)map.get(bName);
-                String msaFilename = "${MODULE_DIR}" + File.separatorChar + msaFile.getName();
-                String mbdFilename = msaFilename.substring(0 , msaFilename.length() - 4) + ".mbd";
-                ele = document.createElement("target");
-                ele.setAttribute("name", bName);
-                Element target = document.createElement("GenBuild");
-                target.setAttribute("msaFilename", msaFilename);
-                target.setAttribute("mbdFilename", mbdFilename);
-                target.setAttribute("baseName", bName);
-                ele.appendChild(target);
-                root.appendChild(ele);
-            }
-
-            root.appendChild(ele);
-            //
-            // Default clean
-            //
-            ele = document.createElement("target");
-            ele.setAttribute("name", "clean");
-            ele.setAttribute("depends", base_name + "_clean");
-            root.appendChild(ele);
-            //
-            // Default Clean ALl
-            //
-            ele = document.createElement("target");
-            ele.setAttribute("name", "cleanall");
-            ele.setAttribute("depends", base_name + "_cleanall");
-            root.appendChild(ele);
-            //
-            // Every clean target for each BaseName
-            //
-            set = map.keySet();
-            iter = set.iterator();
-            while (iter.hasNext()){
-                String bName = (String)iter.next();
-                File msaFile = (File)map.get(bName);
-                String msaFilename = "${MODULE_DIR}" + File.separatorChar + msaFile.getName();
-                String mbdFilename = msaFilename.substring(0 , msaFilename.length() - 4) + ".mbd";
-                
-                ele = document.createElement("target");
-                ele.setAttribute("name", bName + "_clean");
-                //
-                // Output Dir
-                //
-                Element target = document.createElement("OutputDirSetup");
-                target.setAttribute("msaFilename", msaFilename);
-                target.setAttribute("mbdFilename", mbdFilename);
-                target.setAttribute("baseName", bName);
-                ele.appendChild(target);
-                //
-                // Call BaseName_build.xml clean
-                //
-                Element ifEle = document.createElement("if");
-                Element availableEle = document.createElement("available");
-                availableEle.setAttribute("file", "${DEST_DIR_OUTPUT}" + File.separatorChar + bName + "_build.xml");
-                ifEle.appendChild(availableEle);
-                Element elseEle = document.createElement("then");
-                
-                Element moduleEle = document.createElement("ant");
-                moduleEle.setAttribute("antfile", "${DEST_DIR_OUTPUT}" + File.separatorChar + bName + "_build.xml");
-                moduleEle.setAttribute("target", "clean");
-                
-                elseEle.appendChild(moduleEle);
-                ifEle.appendChild(elseEle);
-                ele.appendChild(ifEle);
-                //
-                // just delete
-                //
-                Element clean = document.createElement("delete");
-                clean.setAttribute("dir", "${DEST_DIR_OUTPUT}");
-                clean.setAttribute("excludes", "*.xml");
-                ele.appendChild(clean);
-                
-                root.appendChild(ele);
-            }
-            //
-            // Every Clean ALl target for each BaseName
-            //
-            set = map.keySet();
-            iter = set.iterator();
-            while (iter.hasNext()){
-                String bName = (String)iter.next();
-                File msaFile = (File)map.get(bName);
-                String msaFilename = "${MODULE_DIR}" + File.separatorChar + msaFile.getName();
-                String mbdFilename = msaFilename.substring(0 , msaFilename.length() - 4) + ".mbd";
-                
-                ele = document.createElement("target");
-                ele.setAttribute("name", bName + "_cleanall");
-                //
-                // Output Dir
-                //
-                Element target = document.createElement("OutputDirSetup");
-                target.setAttribute("msaFilename", msaFilename);
-                target.setAttribute("mbdFilename", mbdFilename);
-                target.setAttribute("baseName", bName);
-                ele.appendChild(target);
-                //
-                // Call BaseName_build.xml clean
-                //
-                Element ifEle = document.createElement("if");
-                Element availableEle = document.createElement("available");
-                availableEle.setAttribute("file", "${DEST_DIR_OUTPUT}" + File.separatorChar + bName + "_build.xml");
-                ifEle.appendChild(availableEle);
-                Element elseEle = document.createElement("then");
-                
-                Element moduleEle = document.createElement("ant");
-                moduleEle.setAttribute("antfile", "${DEST_DIR_OUTPUT}" + File.separatorChar + bName + "_build.xml");
-                moduleEle.setAttribute("target", "cleanall");
-                
-                elseEle.appendChild(moduleEle);
-                ifEle.appendChild(elseEle);
-                ele.appendChild(ifEle);
-                //
-                // just delete
-                //
-                Element clean = document.createElement("delete");
-                clean.setAttribute("dir", "${DEST_DIR_OUTPUT}");
-                ele.appendChild(clean);
-                
-                clean = document.createElement("delete");
-                clean.setAttribute("dir", "${DEST_DIR_DEBUG}");
-                ele.appendChild(clean);
-                
-                clean = document.createElement("delete");
-                Element fileset = document.createElement("fileset");
-                fileset.setAttribute("dir", "${BIN_DIR}");
-                fileset.setAttribute("includes", "**" + bName + "*");
-                clean.appendChild(fileset);
-                ele.appendChild(clean);
-                
-                root.appendChild(ele);
-            }
-            document.appendChild(root);
-            //
-            // Prepare the DOM document for writing
-            //
-            Source source = new DOMSource(document);
-            //
-            // Prepare the output file
-            //
-            String filename = buildFile.getParent() + File.separatorChar + "build.xml";
-            File file = new File(getProject().replaceProperties(filename));
-            //
-            // generate all directory path
-            //
-            Result result = new StreamResult(file);
-            //
-            // Write the DOM document to the file
-            //
-            Transformer xformer = TransformerFactory.newInstance()
-                            .newTransformer();
-            xformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
-            xformer.setOutputProperty(OutputKeys.INDENT, "yes");
-            xformer.transform(source, result);
-        } catch (Exception ex) {
-            System.out.println("##" + ex);
-        }
-    }
-    
-    
-    public File getBuildFile() {
-        return buildFile;
-    }
-
-    public void setBuildFile(File buildFile) {
-        this.buildFile = buildFile;
-    }
-
-    public boolean isRecursive() {
-        return recursive;
-    }
-
-    public void setRecursive(boolean recursive) {
-        this.recursive = recursive;
-    }
-}
diff --git a/Tools/Source/GenBuild/org/tianocore/build/global/ModuleIdentification.java b/Tools/Source/GenBuild/org/tianocore/build/global/ModuleIdentification.java
deleted file mode 100644
index 74311d4541..0000000000
--- a/Tools/Source/GenBuild/org/tianocore/build/global/ModuleIdentification.java
+++ /dev/null
@@ -1,55 +0,0 @@
-package org.tianocore.build.global;
-
-public class ModuleIdentification {
-
-    private String baseName;
-    
-    private String packageName;
-    
-    private String guid;
-    
-    private String version;
-    
-    public ModuleIdentification(String baseName, String packageName, String guid, String version){
-        this.baseName = baseName;
-        this.packageName = packageName;
-        this.guid = guid;
-        this.version = version;
-    }
-    
-    public boolean equals(Object obj) {
-        if (obj instanceof ModuleIdentification) {
-            ModuleIdentification moduleIdObj = (ModuleIdentification)obj;
-            if ( baseName.equalsIgnoreCase(moduleIdObj.baseName)) {
-                return true;
-            }
-            // TBD
-            return false;
-        }
-        else {
-            return super.equals(obj);
-        }
-    }
-    
-    public String toString(){
-        return packageName + ":" + guid + "_" + baseName + "_" + version;
-    }
-
-    public void setBaseName(String baseName) {
-        this.baseName = baseName;
-    }
-
-    public void setGuid(String guid) {
-        this.guid = guid;
-    }
-
-    public void setPackageName(String packageName) {
-        this.packageName = packageName;
-    }
-
-    public void setVersion(String version) {
-        this.version = version;
-    }
-    
-    
-}
diff --git a/Tools/Source/GenBuild/org/tianocore/build/global/OutputManager.java b/Tools/Source/GenBuild/org/tianocore/build/global/OutputManager.java
index 01e24e653f..773fe3e949 100644
--- a/Tools/Source/GenBuild/org/tianocore/build/global/OutputManager.java
+++ b/Tools/Source/GenBuild/org/tianocore/build/global/OutputManager.java
@@ -19,158 +19,180 @@ import java.io.File;
 
 /**
   OutputManager class is used to setup output directories (BIN_DIR, DEST_DIR_OUTPUT, 
-  DEST_DIR_DEBUG) according to BUILD_MODE. 
+  DEST_DIR_DEBUG). 
   
   @since GenBuild 1.0
 **/
 public class OutputManager {
-    
-    ///
-    /// Single Module build
-    ///
-    public static final String MODULE_BUILD = "MODULE";
 
-    ///
-    /// Package build
-    ///
-    public static final String PACKAGE_BUILD = "PACKAGE";
-
-    ///
-    /// Platform build
-    ///
-    public static final String PLATFORM_BUILD = "PLATFORM";
-    
-    public static String buildMode = MODULE_BUILD;
-    
-    ///
-    /// For Package build, PLATFORM represent PACKAGE
-    ///
-    public static String PLATFORM;
-    
-    ///
-    /// For Platform build, PLATFORM_DIR represent PACKAGE_DIR
-    ///
-    public static String PLATFORM_DIR;
-    
     ///
     /// means intermediate files will put under Module's dir
     ///
-    public static final String MODULE = "MODULE";
+    private String MODULE = "MODULE";
     
     ///
     /// mean intermediate files will put under a unify dir
     ///
-    public static final String UNIFIED = "UNIFIED";
+    private String UNIFIED = "UNIFIED";
     
-    ///
-    /// Flag to ensure the function <code>update</code> will be called only one in the whole build.
-    ///
-    private static boolean flag = true;
     
-    /**
-      If BUILD_MODE is PLATFORM or PACKAGE, record PLATFORM and PLARFORM_DIR.
-      Reminder that for PACKAGE build, here set value PACKAGE to PLATFORM and
-      PACKAGE_DIR to PLARFORM_DIR, and also update the ant properties. 
-      
-      <p>Note that this function will be called only once in the whole build.</p> 
-      
-      @param project current ANT build Project
-    **/
-    public synchronized static void update(Project project) {
-        if (flag){
-            flag = false;
-            String str = project.getProperty("BUILD_MODE");
-            if (str != null){
-                if (str.equals(PLATFORM_BUILD)) {
-                    buildMode = PLATFORM_BUILD;
-                    PLATFORM = project.getProperty("PLATFORM");
-                    PLATFORM_DIR = project.getProperty("PLATFORM_DIR");
-                }
-                else if (str.equals(PACKAGE_BUILD)) {
-                    buildMode = PACKAGE_BUILD;
-                    PLATFORM = project.getProperty("PACKAGE");
-                    PLATFORM_DIR = project.getProperty("PACKAGE_DIR");
-                    project.setProperty("PLATFORM", PLATFORM);
-                    project.setProperty("PLATFORM_DIR", PLATFORM_DIR);
-                }
-            }
+    private String userdir;
+    
+    private String type;
+    ///
+    /// Singleton Design Pattern
+    ///
+    private static OutputManager object;
+    
+    public synchronized static OutputManager getInstance() {
+        if ( object == null ) {
+            object = new OutputManager();
         }
+        return object;
+    }
+    
+    public void setup(String userdir, String type) {
+        this.userdir = userdir;
+        this.type = type;
     }
     
     /**
       Setup BIN_DIR, DEST_DIR_OUTPUT and DEST_DIR_OUTPUT, following are the rules:
       
-      <pre>
-        Those three variables are defined as following
-        DEST_DIR_OUTPUT (intermediate files)
-        DEST_DIR_DEBUG (intermediate debug files)
-        BIN_DIR (final files)
-        
-        Output Dir (MODULE or UNIFIED):
-        For <b>Module</b> build: 
-        All intermediate files are at ${MODULE_DIR}/Build/${TARGET}/${ARCH}/DEBUG|OUTPUT
-        All final files are at ${MODULE_DIR}/Build/${TARGET}/${ARCH}
-        
-        For <b>Platform</b> build:
-        If specified with MODULE
-        Intermediate files->${MODULE_DIR}/Build/${PLATFORM}/${TARGET}/${ARCH}/DEBUG|OUTPUT
-        Final files -> ${PLARFORM_DIR}/Build/${TARGET}/${ARCH}
-        
-        Else if specified with UNIFIED
-        Intermediate files->${PLARFORM_DIR}/Build/${TARGET}/${ARCH}/${PACKAGE}/${SOURCE_RELATIVE_PATH}/DEBUG|OUTPUT
-        Final files -> ${PLARFORM_DIR}/Build/${TARGET}/${ARCH}
-        
-        For <b>Package</b> build:
-        If specified with MODULE
-        Intermediate files->${MODULE_DIR}/Build/${PACKAGE}/${TARGET}/${ARCH}/DEBUG|OUTPUT
-        Final files -> ${PACKAGE_DIR}/Build/${TARGET}/${ARCH}
-        
-        Else if specified with UNIFIED
-        Intermediate files->${PACKAGE_DIR}/Build/${TARGET}/${ARCH}/${PACKAGE}/${SOURCE_RELATIVE_PATH}/DEBUG|OUTPUT
-        Final files -> ${PACKAGE_DIR}/Build/${TARGET}/${ARCH}
-      </pre>
+      <p>Divide all output files into two types: one is final files, such as FFS 
+      file for driver module while LIB file for library module; another is 
+      intermediate files, such AutoGen.c, OBJ files, Section files and so on. 
+      
+      <p>In FPD, OutputDirectory element is used to specify where to put the output 
+      files to. There are two mode (MODULE | UNIFIED). MODULE mode means that all 
+      output files will put to the module directory while UNIFIED mode means that 
+      all output files will put together. Default is UNIFIED mode. 
+      
+      <p>BUILD_DIR is the base directory for current module build. By default, 
+      BUILD_DIR is PLATFORM_DIR/Build in UNIFIED mode while is MODULE_DIR/Build 
+      in MODULE mode. Of course, user can customize BUILD_DIR. If user-defined 
+      BUILD_DIR is relative path, then look as related to WORKSPACE_DIR. 
+      
+      <p>Then, BIN_DIR is BUILD_DIR/TARGET/TOOLCHAIN/ARCH;
+      
+      <p>FV_DIR is BUILD_DIR/TARGET/TOOLCHAIN/FV;
+      
+      <p>DEST_DIR_DEBUG | DEST_DIR_OUTPUT is: 
+      BIN_DIR/PACKAGE_RELATIVE_DIR/MODULE_RELATIVE_DIR/DEBUG | OUTPUT
+
       
       @param project current ANT build Project
       @param userdir user-defined directory
       @param type the module build type (MODULE or UNIFIED)
     **/
-    public synchronized static void update(Project project, String userdir, String type) {
+    public void update(Project project) {
+//        GlobalData.log.info("" + userdir + ":" + type);
         //
-        // userdir TBD
+        // Default mode is UNIFIED. 
         //
-       if(  type == null || ! type.equals(MODULE)){
-           type = UNIFIED;
-       }
-       if (buildMode.equals(MODULE_BUILD)){
-           project.setProperty("DEST_DIR_OUTPUT", project.replaceProperties("${MODULE_DIR}"
-                        + File.separatorChar + "Build" + File.separatorChar + "${TARGET}"
-                        + File.separatorChar + "${ARCH}" + File.separatorChar + "OUTPUT"));
-           project.setProperty("DEST_DIR_DEBUG", project.replaceProperties("${MODULE_DIR}" + File.separatorChar + "Build" + File.separatorChar + "${TARGET}" + File.separatorChar + "${ARCH}" + File.separatorChar + "DEBUG"));
-           project.setProperty("BIN_DIR", project.replaceProperties("${MODULE_DIR}" + File.separatorChar + "Build" + File.separatorChar + "${TARGET}" + File.separatorChar + "${ARCH}"));
-       }
-       else if (buildMode.equals(PLATFORM_BUILD)) {
-           if (type.equals(MODULE)) {
-               project.setProperty("DEST_DIR_OUTPUT", project.replaceProperties("${MODULE_DIR}" + File.separatorChar + "Build" + File.separatorChar + "${PLATFORM}" + File.separatorChar + "${TARGET}" + File.separatorChar + "${ARCH}" + File.separatorChar + "OUTPUT"));
-               project.setProperty("DEST_DIR_DEBUG", project.replaceProperties("${MODULE_DIR}" + File.separatorChar + "Build" + File.separatorChar + "${PLATFORM}" + File.separatorChar + "${TARGET}" + File.separatorChar + "${ARCH}" + File.separatorChar + "DEBUG"));
-               project.setProperty("BIN_DIR", project.replaceProperties("${PLATFORM_DIR}" + File.separatorChar + "Build" + File.separatorChar + "${TARGET}" + File.separatorChar + "${ARCH}"));
-           }
-           else if (type.equals(UNIFIED)){
-               project.setProperty("DEST_DIR_OUTPUT", project.replaceProperties("${PLATFORM_DIR}" + File.separatorChar + "Build" + File.separatorChar + "${TARGET}" + File.separatorChar + "${ARCH}" + File.separatorChar + "${PACKAGE}" + File.separatorChar + "${MODULE_RELATIVE_PATH}" + File.separatorChar + "OUTPUT"));
-               project.setProperty("DEST_DIR_DEBUG", project.replaceProperties("${PLATFORM_DIR}" + File.separatorChar + "Build" + File.separatorChar + "${TARGET}" + File.separatorChar + "${ARCH}" + File.separatorChar + "${PACKAGE}" + File.separatorChar + "${MODULE_RELATIVE_PATH}" + File.separatorChar + "DEBUG"));
-               project.setProperty("BIN_DIR", project.replaceProperties("${PLATFORM_DIR}" + File.separatorChar + "Build" + File.separatorChar + "${TARGET}" + File.separatorChar + "${ARCH}"));
-           }
-       }
-       else if (buildMode.equals(PACKAGE_BUILD)) {
-           if (type.equals(MODULE)) {
-               project.setProperty("DEST_DIR_OUTPUT", project.replaceProperties("${MODULE_DIR}" + File.separatorChar + "Build" + File.separatorChar + "${PLATFORM}" + File.separatorChar + "${TARGET}" + File.separatorChar + "${ARCH}" + File.separatorChar + "OUTPUT"));
-               project.setProperty("DEST_DIR_DEBUG", project.replaceProperties("${MODULE_DIR}" + File.separatorChar + "Build" + File.separatorChar + "${PLATFORM}" + File.separatorChar + "${TARGET}" + File.separatorChar + "${ARCH}" + File.separatorChar + "DEBUG"));
-               project.setProperty("BIN_DIR", project.replaceProperties("${PLATFORM_DIR}" + File.separatorChar + "Build" + File.separatorChar + "${TARGET}" + File.separatorChar + "${ARCH}"));
-           }
-           else if (type.equals(UNIFIED)){
-               project.setProperty("DEST_DIR_OUTPUT", project.replaceProperties("${PLATFORM_DIR}" + File.separatorChar + "Build" + File.separatorChar + "${TARGET}" + File.separatorChar + "${ARCH}" + File.separatorChar + "${PACKAGE}" + File.separatorChar + "${MODULE_RELATIVE_PATH}" + File.separatorChar + "OUTPUT"));
-               project.setProperty("DEST_DIR_DEBUG", project.replaceProperties("${PLATFORM_DIR}" + File.separatorChar + "Build" + File.separatorChar + "${TARGET}" + File.separatorChar + "${ARCH}" + File.separatorChar + "${PACKAGE}" + File.separatorChar + "${MODULE_RELATIVE_PATH}" + File.separatorChar + "DEBUG"));
-               project.setProperty("BIN_DIR", project.replaceProperties("${PLATFORM_DIR}" + File.separatorChar + "Build" + File.separatorChar + "${TARGET}" + File.separatorChar + "${ARCH}"));
-           }
-       }
+        if (type != null && type.equalsIgnoreCase(MODULE)) {
+            type = MODULE;
+        }
+        else {
+            type = UNIFIED;
+        }
+        
+        //
+        // default BUILD_DIR value
+        //
+        String buildDir;
+        if(type.equals(MODULE)){
+            buildDir = project.getProperty("MODULE_DIR") + File.separatorChar + "Build";
+        }
+        else {
+            buildDir = project.getProperty("PLATFORM_DIR") + File.separatorChar + "Build";
+        }
+        
+        //
+        // If user define BUILD_DIR
+        //
+        if (userdir != null && ! userdir.equals("")) {
+            File buildFile = new File(userdir);
+            if (buildFile.isAbsolute()){
+                buildDir = userdir;
+            }
+            //
+            // If path is not absolute, then look as related to WORKSPACE_DIR
+            //
+            else {
+                buildDir = GlobalData.getWorkspacePath() + File.separatorChar + userdir;
+            }
+        }
+        
+        //
+        // Define BIN_DIR and FV_DIR
+        //
+        String binDir = buildDir + File.separatorChar + project.getProperty("TARGET")
+                                 + File.separatorChar + project.getProperty("TOOLCHAIN") 
+                                 + File.separatorChar + project.getProperty("ARCH") ;
+        
+        String fvDir = buildDir + File.separatorChar + project.getProperty("TARGET")
+                                + File.separatorChar + project.getProperty("TOOLCHAIN") 
+                                + File.separatorChar + "FV";
+        
+        //
+        // Define DEST_DIR_OUTPUT and DEST_DIR_DEBUG
+        //
+        String destDir = binDir + File.separatorChar + project.getProperty("PACKAGE_RELATIVE_DIR")
+                                + File.separatorChar + project.getProperty("MODULE_RELATIVE_DIR");
+        
+        //
+        // Set properties
+        //
+        project.setProperty("BUILD_DIR", buildDir.replaceAll("(\\\\)", "/"));
+        project.setProperty("FV_DIR", fvDir.replaceAll("(\\\\)", "/"));
+        project.setProperty("BIN_DIR", binDir.replaceAll("(\\\\)", "/"));
+        project.setProperty("DEST_DIR_DEBUG", (destDir + File.separatorChar + "DEBUG").replaceAll("(\\\\)", "/"));
+        project.setProperty("DEST_DIR_OUTPUT", (destDir + File.separatorChar + "OUTPUT").replaceAll("(\\\\)", "/"));
+        
+        //
+        // Create all directory if necessary
+        //
+        (new File(buildDir)).mkdirs();
+        (new File(fvDir)).mkdirs();
+        (new File(binDir)).mkdirs();
+        (new File(destDir + File.separatorChar + "DEBUG")).mkdirs();
+        (new File(destDir + File.separatorChar + "OUTPUT")).mkdirs();
     }
-}
+    
+    public boolean prepareBuildDir(Project project){
+        boolean isUnified = true;
+        
+        if (type.equalsIgnoreCase("MODULE")) {
+            isUnified = false;
+        }
+        
+        String buildDir = project.getProperty("PLATFORM_DIR") + File.separatorChar + "Build";
+        //
+        // If user define BUILD_DIR
+        //
+        if (userdir != null && ! userdir.equals("")) {
+            File buildFile = new File(userdir);
+            if (buildFile.isAbsolute()){
+                buildDir = userdir;
+            }
+            //
+            // If path is not absolute, then look as related to WORKSPACE_DIR
+            //
+            else {
+                buildDir = GlobalData.getWorkspacePath() + File.separatorChar + userdir;
+            }
+        }
+        //
+        // Set to property
+        //
+        project.setProperty("BUILD_DIR", buildDir.replaceAll("(\\\\)", "/"));
+        
+        //
+        // Create all directory if necessary
+        //
+        (new File(buildDir)).mkdirs();
+        return isUnified;
+    }
+
+}
\ No newline at end of file
diff --git a/Tools/Source/GenBuild/org/tianocore/build/global/OverrideProcess.java b/Tools/Source/GenBuild/org/tianocore/build/global/OverrideProcess.java
deleted file mode 100644
index 60f430f458..0000000000
--- a/Tools/Source/GenBuild/org/tianocore/build/global/OverrideProcess.java
+++ /dev/null
@@ -1,361 +0,0 @@
-/** @file
-  OverrideProcess class.
-  
-  OverrideProcess class is used to override surface area information. 
-
-Copyright (c) 2006, Intel Corporation
-All rights reserved. This program and the accompanying materials
-are licensed and made available under the terms and conditions of the BSD License
-which accompanies this distribution.  The full text of the license may be found at
-http://opensource.org/licenses/bsd-license.php
-
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
-
-**/
-package org.tianocore.build.global;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import javax.xml.namespace.QName;
-
-import org.apache.tools.ant.BuildException;
-import org.apache.xmlbeans.XmlCursor;
-import org.apache.xmlbeans.XmlObject;
-import org.tianocore.BootModesDocument;
-import org.tianocore.BuildOptionsDocument;
-import org.tianocore.DataHubsDocument;
-import org.tianocore.EventsDocument;
-import org.tianocore.ExternsDocument;
-import org.tianocore.FormsetsDocument;
-import org.tianocore.GuidsDocument;
-import org.tianocore.HobsDocument;
-import org.tianocore.IncludesDocument;
-import org.tianocore.LibrariesDocument;
-import org.tianocore.LibraryClassDefinitionsDocument;
-import org.tianocore.MsaHeaderDocument;
-import org.tianocore.MsaLibHeaderDocument;
-import org.tianocore.PcdCodedDocument;
-import org.tianocore.PPIsDocument;
-import org.tianocore.ProtocolsDocument;
-import org.tianocore.SourceFilesDocument;
-import org.tianocore.SystemTablesDocument;
-import org.tianocore.VariablesDocument;
-import org.tianocore.PackageDependenciesDocument;
-
-/**
-  This class is used to override surface area information. For example, MBD can
-  overried MSA, Platform can override all information of the module. 
-  
-  <p>Override will take effect if two element satisfy one of following two condition: </p>
-  <ul>
-    <li>Element name and its attribute OverrideID equal each other. </li>
-    <li>Element is defined as exclusive which mean such element can be
-    only appeared in the surface area. </li>
-  </ul>
-  
-  <p>For example, here OutputDirectory element is exclusive: </p>
-  
-  <pre>
-  Low priority Xml Document fragment:
-     &lt;Libraries&gt;
-       &lt;Arch ArchType="IA32"&gt;
-         &lt;Library OverrideID="8888"&gt;EdkPeCoffLoaderLib&lt;/Library&gt;
-         &lt;Library OverrideID="8888"&gt;BasePeCoffLib&lt;/Library&gt;
-       &lt;/Arch&gt;
-     &lt;/Libraries&gt; 
-     &lt;BuildOptions&gt;
-       &lt;OutputDirectory IntermediateDirectories="MODULE"/&gt;
-       &lt;Option&gt;CC_FLAGS = "/NOLOGO", "/C"&lt;/Option&gt;
-     &lt;BuildOptions&gt;
- 
-  High priority Xml Document fragment:
-     &lt;Libraries&gt;
-       &lt;Arch ArchType="IA32"&gt;
-         &lt;Library OverrideID="8888">Nt32PeCoffLoaderLib&lt;/Library&gt;
-       &lt;/Arch&gt;
-     &lt;/Libraries&gt;
-     &lt;BuildOptions&gt;
-       &lt;OutputDirectory IntermediateDirectories="UNIFIED"/&gt;
-       &lt;Option&gt;LIB_FLAGS = "/NOLOGO"&lt;/Option&gt;
-     &lt;BuildOptions&gt;
-     
-   The result is: 
-     &lt;Libraries&gt;
-       &lt;Arch ArchType="IA32"&gt;
-         &lt;Library OverrideID="8888"&gt;Nt32PeCoffLoaderLib&lt;/Library&gt;
-       &lt;/Arch&gt;
-     &lt;/Libraries&gt;
-     &lt;BuildOptions&gt;
-       &lt;OutputDirectory IntermediateDirectories="UNIFIED"/&gt;
-       &lt;Option&gt;CC_FLAGS = "/NOLOGO", "/C"&lt;/Option&gt;
-       &lt;Option&gt;LIB_FLAGS = "/NOLOGO"&lt;/Option&gt;
-     &lt;BuildOptions&gt;
-   
-  </pre>
-  
-  <p>Note that using XmlBeans to walk through the whole XML document tree.</p> 
-  
-  @since GenBuild 1.0
-  @see org.apache.xmlbeans.XmlBeans
-**/
-public class OverrideProcess {
-
-    ///
-    /// URI, the namespace of current XML schema
-    ///
-    public static String prefix = "http://www.TianoCore.org/2006/Edk2.0";
-
-    ///
-    /// list of top elements of surface area
-    ///
-    public static String[] topElements = { "LibraryClassDefinitions",
-                    "SourceFiles", "Includes", "PackageDependencies", "Libraries", "Protocols",
-                    "Events", "Hobs", "PPIs", "Variables", "BootModes",
-                    "SystemTables", "DataHubs", "Formsets", "Guids", "Externs",
-                    "PcdCoded", "BuildOptions" };
-
-    ///
-    /// list of exclusive elements
-    ///
-    public static String[] exclusiveElements = {"OutputDirectory"};
-    
-    /**
-      Recursively find out all elements specified with OverrideId attribute
-      and exclusive elements in current XML object. 
-      
-      @param o curent parsing XML object
-      @param map Map to list elements specified OverrideID attribute
-      @param execlusiveMap Map to list exclusive elements appeared in current XMl object
-      @param level the depth in XML document tree
-    **/
-    private void listOverrideID(XmlObject o, Map<String,Object> map, Map<String,Object> execlusiveMap, int level) {
-        XmlCursor cursor = o.newCursor();
-        String name = cursor.getName().getLocalPart();
-        for (int i = 0 ; i < exclusiveElements.length; i++){
-            if (name.equalsIgnoreCase(exclusiveElements[i])){
-                execlusiveMap.put(exclusiveElements[i], cursor.getObject());
-            }
-        }
-        String overrideID = cursor.getAttributeText(new QName("OverrideID"));
-        if (overrideID != null) {
-            map.put(name + ":" + overrideID, cursor.getObject());
-        }
-        if (cursor.toFirstChild()) {
-            do {
-                listOverrideID(cursor.getObject(), map, execlusiveMap, level + 1);
-            } while (cursor.toNextSibling());
-        }
-    }
-
-    /**
-      This function is used to prepare for overriding with changing data. 
-      
-      @param map original surface area information 
-      @return after normalize surface area information
-    **/
-    public synchronized static Map<String, XmlObject> deal(Map<String, XmlObject> map) {
-        Map<String, XmlObject> newMap = new HashMap<String, XmlObject>();
-        if (map.get("MsaHeader") != null) {
-            newMap.put("MsaHeader", ((MsaHeaderDocument) map.get("MsaHeader"))
-                            .getMsaHeader());
-        }
-        if (map.get("MsaLibHeader") != null) {
-            newMap.put("MsaLibHeader", ((MsaLibHeaderDocument) map
-                            .get("MsaLibHeader")).getMsaLibHeader());
-        }
-        if (map.get("LibraryClassDefinitions") != null) {
-            newMap.put("LibraryClassDefinitions",
-                            ((LibraryClassDefinitionsDocument) map
-                                            .get("LibraryClassDefinitions"))
-                                            .getLibraryClassDefinitions());
-        }
-        if (map.get("SourceFiles") != null) {
-            newMap.put("SourceFiles", ((SourceFilesDocument) map
-                            .get("SourceFiles")).getSourceFiles());
-        }
-        if (map.get("Includes") != null) {
-            newMap.put("Includes", ((IncludesDocument) map.get("Includes"))
-                            .getIncludes());
-        }
-        if (map.get("PackageDependencies") != null) {
-            newMap.put("PackageDependencies", ((PackageDependenciesDocument) map.get("PackageDependencies"))
-                            .getPackageDependencies());
-        }
-        if (map.get("Libraries") != null) {
-            newMap.put("Libraries", ((LibrariesDocument) map.get("Libraries"))
-                            .getLibraries());
-        }
-        if (map.get("Protocols") != null) {
-            newMap.put("Protocols", ((ProtocolsDocument) map.get("Protocols"))
-                            .getProtocols());
-        }
-        if (map.get("Events") != null) {
-            newMap.put("Events", ((EventsDocument) map.get("Events"))
-                            .getEvents());
-        }
-        if (map.get("Hobs") != null) {
-            newMap.put("Hobs", ((HobsDocument) map.get("Hobs")).getHobs());
-        }
-        if (map.get("PPIs") != null) {
-            newMap.put("PPIs", ((PPIsDocument) map.get("PPIs")).getPPIs());
-        }
-        if (map.get("Variables") != null) {
-            newMap.put("Variables", ((VariablesDocument) map.get("Variables"))
-                            .getVariables());
-        }
-        if (map.get("BootModes") != null) {
-            newMap.put("BootModes", ((BootModesDocument) map.get("BootModes"))
-                            .getBootModes());
-        }
-        if (map.get("SystemTables") != null) {
-            newMap.put("SystemTables", ((SystemTablesDocument) map
-                            .get("SystemTables")).getSystemTables());
-        }
-        if (map.get("DataHubs") != null) {
-            newMap.put("DataHubs", ((DataHubsDocument) map.get("DataHubs"))
-                            .getDataHubs());
-        }
-        if (map.get("Formsets") != null) {
-            newMap.put("Formsets", ((FormsetsDocument) map.get("Formsets"))
-                            .getFormsets());
-        }
-        if (map.get("Guids") != null) {
-            newMap.put("Guids", ((GuidsDocument) map.get("Guids")).getGuids());
-        }
-        if (map.get("Externs") != null) {
-            newMap.put("Externs", ((ExternsDocument) map.get("Externs"))
-                            .getExterns());
-        }
-        if (map.get("PcdCoded") != null) {
-            newMap.put("PcdCoded", ((PcdCodedDocument) map.get("PcdCoded")).getPcdCoded());
-        }
-        if (map.get("BuildOptions") != null) {
-            newMap.put("BuildOptions", ((BuildOptionsDocument) map
-                            .get("BuildOptions")).getBuildOptions());
-        }
-        return newMap;
-    }
-
-    /**
-      Recursively remove all subelement in Xml Object l (with low priority) 
-      based on OverrideID or exclusive elements. 
-    
-      @param l the XML object to process
-      @param map list of elements with OverrideID in high priority XML object
-      @param execusiveMap  list of exclusive elements in high priority XML object
-    **/
-    private void cut(XmlCursor l, Map map, Map execusiveMap) {
-        String name = l.getName().getLocalPart();
-        if (execusiveMap.containsKey(name)){
-            l.removeXml();
-            return;
-        }
-        String overrideID = l.getAttributeText(new QName("OverrideID"));
-        if (overrideID != null) {
-            if (map.containsKey(name + ":" + overrideID)) {
-                l.removeXml();
-                return;
-            }
-        }
-        if (l.toFirstChild()) {
-            do {
-                cut(l, map, execusiveMap);
-            } while (l.toNextSibling());
-        }
-    }
-
-    private XmlObject cloneXmlObject(XmlObject object, boolean deep) throws BuildException {
-        XmlObject result = null;
-        try {
-            result = XmlObject.Factory.parse(object.getDomNode()
-                            .cloneNode(deep));
-        } catch (Exception ex) {
-            throw new BuildException(ex.getMessage());
-        }
-        return result;
-    }
-
-    /**
-      Process every item list in h and l.
-    
-      @param h surface area info with high priority
-      @param l surface area info with low priority
-      @return surface area after override
-    **/
-    public Map<String, XmlObject> override(Map<String, XmlObject> h,
-                    Map<String, XmlObject> l) {
-        Map<String, XmlObject> result = new HashMap<String, XmlObject>();
-        result.put("MsaHeader", override(l.get("MsaHeader"), null));
-        result.put("MsaLibHeader", override(l.get("MsaLibHeader"), null));
-        for (int i = 0; i < topElements.length; i++) {
-            if (h != null) {
-                result.put(topElements[i], override(h.get(topElements[i]), l.get(topElements[i])));
-            } else {
-                result.put(topElements[i], override(l.get(topElements[i]), null));
-            }
-        }
-        return result;
-    }
-
-    /**
-      Recursively override two Xml Objects.
-      
-      @param h Xml Object info with high priority
-      @param l Xml Object info with low priority
-      @return Xml Object after area
-    **/
-    public XmlObject override(XmlObject h, XmlObject l) {
-        if (l == null && h == null) {
-            return null;
-        }
-        if (h == null) {
-            return cloneXmlObject(l, true);
-        }
-        if (l == null) {
-            return cloneXmlObject(h, true);
-        }
-        XmlCursor hc = h.newCursor();
-        if (h.getClass() != l.getClass()) {
-            System.out.println("Error: Two XmlObject does not with compliant format.");
-            return null;
-        }
-        if (!hc.toFirstChild()) {
-            return cloneXmlObject(l, true);
-        }
-
-        XmlCursor result = cloneXmlObject(h, true).newCursor();
-        XmlCursor lcursor = cloneXmlObject(l, true).newCursor();
-        result.push();
-        result.toNextToken();
-        result.insertNamespace("", prefix);
-        result.toFirstChild();
-        //
-        // found out all element specified a OverrideID
-        //
-        Map<String,Object> hmap = new HashMap<String,Object>();
-        Map<String,Object> execlusiveMap = new HashMap<String,Object>();
-        listOverrideID(h, hmap, execlusiveMap, 0);
-        lcursor.toNextToken();
-        lcursor.push();
-        //
-        // for every direct subelement of l, cut all element satisfied with
-        // override rule
-        //
-        if (lcursor.toFirstChild()) {
-            do {
-                cut(lcursor, hmap, execlusiveMap);
-            } while (lcursor.toNextSibling());
-        }
-        lcursor.pop();
-        if (lcursor.toFirstChild()) {
-            do {
-                lcursor.copyXml(result);
-                result.insertChars("\n");
-            } while (lcursor.toNextSibling());
-        }
-        result.pop();
-        return result.getObject();
-    }
-}
\ No newline at end of file
diff --git a/Tools/Source/GenBuild/org/tianocore/build/global/Spd.java b/Tools/Source/GenBuild/org/tianocore/build/global/Spd.java
index 72efa7eba7..ddc851dc70 100644
--- a/Tools/Source/GenBuild/org/tianocore/build/global/Spd.java
+++ b/Tools/Source/GenBuild/org/tianocore/build/global/Spd.java
@@ -14,40 +14,35 @@
 
  **/
 package org.tianocore.build.global;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
 
-import org.tianocore.GuidDeclarationsDocument.GuidDeclarations;
-import org.tianocore.IncludeHeaderDocument.IncludeHeader;
-import org.tianocore.LibraryClassDeclarationDocument.LibraryClassDeclaration;
-import org.tianocore.LibraryClassDeclarationsDocument.LibraryClassDeclarations;
-import org.tianocore.PackageHeadersDocument.PackageHeaders;
-import org.tianocore.PackageSurfaceAreaDocument;
-import org.tianocore.PackageSurfaceAreaDocument.PackageSurfaceArea;
-import org.tianocore.PpiDeclarationsDocument.PpiDeclarations;
-import org.tianocore.PpiDeclarationsDocument.PpiDeclarations.Entry;
-import org.tianocore.ProtocolDeclarationsDocument.ProtocolDeclarations;
+import java.io.File;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.xmlbeans.XmlObject;
+import org.tianocore.build.id.ModuleIdentification;
+import org.tianocore.build.id.PackageIdentification;
 
 /**
  
-  This class is to generate a global table for the content of spd file.
-  
-**/
+ This class is to generate a global table for the content of spd file.
+ 
+ **/
 public class Spd {
     ///
-    /// Map of module name and package it belongs to.
-    /// Key : Module BaseName
-    /// Value: Relative Path to Package
     ///
-    Map<String, String[]> msaInfo = new HashMap<String, String[]>();
+    ///
+    Map<ModuleIdentification, File> msaInfo = new HashMap<ModuleIdentification, File>();
 
     ///
     /// Map of module info. 
     /// Key : moduletype
     /// Value: moduletype related include file
     ///
-    Map<String, String> moduleInfo = new HashMap<String, String>();
+    Map<String, String> packageHeaderInfo = new HashMap<String, String>();
 
     ///
     /// Map of PPI info.
@@ -70,366 +65,198 @@ public class Spd {
     ///
     Map<String, String[]> guidInfo = new HashMap<String, String[]>();
 
-
     ///
     /// Map of library class and its exposed header file.
     /// Key : library class name
     /// value : library class corresponding header file
     ///
-    Map<String, String> libClassHeaderList = new HashMap<String, String>();
+    Map<String, String[]> libClassHeaderList = new HashMap<String, String[]>();
 
     ///
     /// Package path.
     ///
-    String packagePath = null;
+    PackageIdentification packageId;
 
     /**
-      Constructor function
-      
-      This function mainly initialize some member variables. 
-   
-      @param spdDoc      Handle of spd document.
-      @param spdPath     Path of spd file.
-     **/
-    Spd (PackageSurfaceAreaDocument spdDoc, String spdPath) {
-
-        PackageSurfaceArea spd = spdDoc.getPackageSurfaceArea();
-        this.packagePath = spdPath;
-
-        GuidDeclarations spdGuidInfo = spd.getGuidDeclarations();
-        genGuidInfoList(spdGuidInfo);
-
-        PpiDeclarations spdPpiInfo = spd.getPpiDeclarations();
-        genPpiInfoList(spdPpiInfo);
-
-        ProtocolDeclarations spdProtocolInfo = spd.getProtocolDeclarations();
-        genProtocolInfoList(spdProtocolInfo);
-
-        LibraryClassDeclarations spdLibClassDeclare = spd
-                        .getLibraryClassDeclarations();
-        genLibClassDeclare(spdLibClassDeclare);
-
-        PackageHeaders spdPackageHeaderInfo = spd.getPackageHeaders();
-        genModuleInfoList(spdPackageHeaderInfo);
-
-    }
-
-    /**
-      genModuleInfoList
-      
-      This function is to generate Module info map.
-      
-      @param packageHeader   The information of packageHeader which descripted
-                             in spd file.    
+     Constructor function
+     
+     This function mainly initialize some member variables. 
     **/
-    public void genModuleInfoList(PackageHeaders packageHeader) {
-
-        if (packageHeader != null) {
-            List<IncludeHeader> headerList = packageHeader.getIncludeHeaderList();
-            IncludeHeader       header;
-
-            for (int i = 0; i < headerList.size(); i++) {
-                header = (IncludeHeader)headerList.get(i);
-                try {
-                    this.moduleInfo.put(header.getModuleType().toString(), header.getStringValue());
-                } catch (Exception e) {
-                    System.out.print("can't find ModuleHeaders ModuleType & includeHeader!\n");
-                }
-            }
+    Spd(File packageFile) throws BuildException {
+        //
+        // If specified package file not exists
+        //
+        if ( ! packageFile.exists()) {
+            throw new BuildException("Package file [" + packageFile.getPath() + "] not exists. ");
         }
-    }
-
-  /**
-    genPpiInfoList
-    
-    This function is to generate Ppi info map.
-    
-    @param  ppiInfo           The information of PpiDeclarations which descripted
-                              in spd file.    
-  **/
-    public void genPpiInfoList(PpiDeclarations ppiInfo) {
-        String[] cNameGuid = new String[2];
-        String   guidString;
-
-        if (ppiInfo != null) {
-            List<PpiDeclarations.Entry> ppiEntryList = ppiInfo.getEntryList();
-            PpiDeclarations.Entry       ppiEntry;
-
-            for (int i = 0; i < ppiEntryList.size(); i++) {
-                ppiEntry = (PpiDeclarations.Entry)ppiEntryList.get(i);
-                try {
-                    if (ppiEntry.isSetGuidValue()) {
-                        guidString = ppiEntry.getGuidValue();
-                    } else {
-                        guidString = ppiEntry.getGuid().getStringValue();
-                    }
-
-                    cNameGuid[0] = ppiEntry.getCName();
-                    cNameGuid[1] = formatGuidName(guidString);
-                    this.ppiInfo.put(ppiEntry.getName(), new String[] { cNameGuid[0], cNameGuid[1] });
-                } catch (Exception e) {
-                    System.out.print("can't find GuidDeclarations C_Name & Guid!\n");
-                }
+        try {
+            XmlObject spdDoc = XmlObject.Factory.parse(packageFile);
+            //
+            // Verify SPD file, if is invalid, throw Exception
+            //
+            if (! spdDoc.validate()) {
+                throw new BuildException("Package Surface Area file [" + packageFile.getPath() + "] is invalid. ");
             }
-        }
-    }
-
-    /**
-      genProtocolInfoList 
-      
-      This function is to generate Protocol info map.
-      
-      @param   proInfo    The information of ProtocolDeclarations which 
-                          descripted in spd file.
-    **/
-    public void genProtocolInfoList(ProtocolDeclarations proInfo) {
-        String[] cNameGuid = new String[2];
-        String   guidString;
-
-        if (proInfo != null) {
-            List<ProtocolDeclarations.Entry> protocolEntryList = proInfo.getEntryList();
-            ProtocolDeclarations.Entry       protocolEntry;
-            for (int i = 0; i < protocolEntryList.size(); i++) {
-                protocolEntry = (ProtocolDeclarations.Entry)protocolEntryList.get(i);
-                try {
-                    if (protocolEntry.isSetGuidValue()) {
-                        guidString = protocolEntry.getGuidValue();
-                    } else {
-                        guidString = protocolEntry.getGuid().getStringValue();
-                    }
-                    cNameGuid[0] = protocolEntry.getCName();
-                    cNameGuid[1] = formatGuidName(guidString);
-
-                    String temp = new String(protocolEntry.getName());
-                    this.protocolInfo.put(temp, new String[] { cNameGuid[0], cNameGuid[1] });
-                } catch (Exception e) {
-                    System.out.print("can't find ProtocolDeclarations C_Name & Guid!\n");
-                }
-            }
-        }
-    }
-
-    /**
-      genGuidInfoList
-      
-      This function is to generate GUID inf map.
-      
-      @param guidInfo     The information of GuidDeclarations which descripted
-                          in spd file.
-      
-    **/
-    public void genGuidInfoList(GuidDeclarations guidInfo) {
-        String[] cNameGuid = new String[2];
-        String   guidString;
-
-        if (guidInfo != null) {
+            // We can change Map to XmlObject
+            Map<String, XmlObject> spdDocMap = new HashMap<String, XmlObject>();
+            spdDocMap.put("PackageSurfaceArea", spdDoc);
+            SurfaceAreaQuery.setDoc(spdDocMap);
+            //
+            //
+            //
+            packageId = SurfaceAreaQuery.getSpdHeader();
+            packageId.setSpdFile(packageFile);
             
-            List<GuidDeclarations.Entry>    guidEntryList = guidInfo.getEntryList();
-            GuidDeclarations.Entry          guidEntry;
-            for (int i = 0; i < guidEntryList.size(); i++) {
-                guidEntry = (GuidDeclarations.Entry)guidEntryList.get(i);
-                if (guidEntry.isSetGuidValue()) {
-                    guidString = guidEntry.getGuidValue();
-                } else {
-                    guidString = guidEntry.getGuid().getStringValue();
+            //
+            // initialize Msa Files
+            // MSA file is absolute file path
+            //
+            String[] msaFilenames = SurfaceAreaQuery.getSpdMsaFile();
+            for (int i = 0; i < msaFilenames.length; i++){
+                File msaFile = new File(packageId.getPackageDir() + File.separatorChar + msaFilenames[i]);
+                Map<String, XmlObject> msaDoc = GlobalData.getNativeMsa( msaFile );
+                SurfaceAreaQuery.push(msaDoc);
+                ModuleIdentification moduleId = SurfaceAreaQuery.getMsaHeader();
+                SurfaceAreaQuery.pop();
+                moduleId.setPackage(packageId);
+                moduleId.setMsaFile(msaFile);
+                if (msaInfo.containsKey(moduleId)) {
+                    throw new BuildException("Find two modules with the same GUID and Version in " + packageId + ". They are [" + msaInfo.get(moduleId) + "] and [" + msaFile + "] ");
                 }
+                msaInfo.put(moduleId, msaFile);
+            }
+            
+            //
+            // initialize Package header files
+            //
+            Map<String, String> packageHeaders = SurfaceAreaQuery.getSpdPackageHeaderFiles();
+            Set keys = packageHeaders.keySet();
+            Iterator iter = keys.iterator();
+            while (iter.hasNext()){
+                String moduleType = (String)iter.next();
+                String header = packageId.getPackageRelativeDir() + File.separatorChar + packageHeaders.get(moduleType);
+                
+                //
+                // Change path seperator to system-dependent path separator
+                //
+                File file = new File (header);
+                header = file.getParent();
+                packageHeaderInfo.put(moduleType, header);
+            }
+            
+            //
+            // initialize Guid Info
+            //
+            guidInfo.putAll(SurfaceAreaQuery.getSpdGuid());
+            
+            //
+            // initialize PPI info
+            //
+            ppiInfo.putAll(SurfaceAreaQuery.getSpdPpi());
+            
+            //
+            // initialize Protocol info
+            //
+            protocolInfo.putAll(SurfaceAreaQuery.getSpdProtocol());
+            
+            //
+            // initialize library class declaration
+            //
+            Map<String, String[]> libraryClassHeaders = SurfaceAreaQuery.getSpdLibraryClasses();
+            keys = libraryClassHeaders.keySet();
+            iter = keys.iterator();
+            while (iter.hasNext()){
+                String libraryClassName = (String)iter.next();
+                String[] headerFiles = libraryClassHeaders.get(libraryClassName);
+                for (int i = 0; i < headerFiles.length; i++){
+                    headerFiles[i] = packageId.getPackageRelativeDir() + File.separatorChar + headerFiles[i];
                     
-                cNameGuid[0] = guidEntry.getCName();
-                cNameGuid[1] = formatGuidName(guidString);
-                this.guidInfo.put(guidEntry.getName(), new String[] {cNameGuid[0], cNameGuid[1] });
-            }
-        }
-    }
-
-    /**
-      genLibClassDeclare
-      
-      This function is to generate the libClassHeader list.
-      
-      @param libClassDeclares  The information of LibraryClassDeclarations which
-                               descripted in spd file.
-    **/
-    public void genLibClassDeclare(LibraryClassDeclarations libClassDeclares) {
-        if (libClassDeclares != null && libClassDeclares.getLibraryClassDeclarationList() != null) {
-            if (libClassDeclares.getLibraryClassDeclarationList().size() > 0) {
-                List<LibraryClassDeclaration> libDeclareList = libClassDeclares.getLibraryClassDeclarationList();
-                for (int i = 0; i < libDeclareList.size(); i++) {
-                    libClassHeaderList.put(libDeclareList.get(i).getLibraryClass()
-                                    .getStringValue(), libDeclareList.get(i)
-                                    .getIncludeHeader().getStringValue());
+                    //
+                    // Change path separator to system system-dependent path separator. 
+                    //
+                    File file = new File (headerFiles[i]);
+                    headerFiles[i] = file.getPath();
                 }
+                libClassHeaderList.put(libraryClassName, headerFiles);
             }
         }
+        catch (Exception e) {
+            e.setStackTrace(e.getStackTrace());
+            throw new BuildException("Parse package description file [" + packageId.getSpdFile() + "] Error.\n"
+                                     + e.getMessage());
+        }
     }
 
-    /**
-      getPpiGuid
-      
-      This function is to get ppi GUID according ppi name.
+    public PackageIdentification getPackageId() {
+        return packageId;
+    }
+
+    public File getModuleFile(ModuleIdentification moduleId) {
+        return msaInfo.get(moduleId);
+    }
     
-      @param   ppiStr    Name of ppi.
-      @return            PPi's GUID.
-    **/
-    public String getPpiGuid(String ppiStr) {
-        if (ppiInfo.get(ppiStr) != null) {
-            return ppiInfo.get(ppiStr)[1];
-        } else {
-            return null;
-        }
-
+    public Set<ModuleIdentification> getModules(){
+        return msaInfo.keySet();
     }
 
     /**
-      getPpiCnameGuidArray
-      
-      This function is to get the ppi CName and it's GUID according to ppi name.
-      
-      @param   ppiName      Name of ppi.
-      @return               Ppi CName and it's GUID.
-    **/
-    public String[] getPpiCnameGuidArray(String ppiName) {
-        return this.ppiInfo.get(ppiName);
+       return two value {CName, Guid}. If not found, return null.
+     **/
+    public String[] getPpi(String ppiName) {
+        return ppiInfo.get(ppiName);
     }
 
     /**
-      getProtocolGuid
-      
-      This function is to get the protocol GUID according to protocol's name.
-      
-      @param   protocolStr    Name of protocol.
-      @return                 Protocol's GUID.
+        return two value {CName, Guid}. If not found, return null.
     **/
-    public String getProtocolGuid(String protocolStr) {
-        if (protocolInfo.get(protocolStr) != null) {
-            return this.protocolInfo.get(protocolStr)[0];
-        } else {
-            return null;
-        }
+    public String[] getProtocol(String protocolName) {
+        return protocolInfo.get(protocolName);
     }
 
     /**
-      getProtocolNameGuidArray
-      
-      This function is to get the protocol's CName ant it's GUID according to
-      protocol's namej.
-      
-      @param  protocolName   Name of protocl.
-      @return                Protocol's CName and it's GUID.
+      return two value {CName, Guid}. If not found, return null.
     **/
-    public String[] getProtocolNameGuidArray(String protocolName) {
-        return this.protocolInfo.get(protocolName);
+    public String[] getGuid(String guidName) {
+        return guidInfo.get(guidName);
     }
 
     /**
-      getGUIDGuid
-      
-      This function is to get the GUID according to GUID's name
-      
-      @param  guidStr        Name of GUID
-      @return                GUID.
+     getLibClassInclude 
+     
+     This function is to get the library exposed header file name according 
+     library class name.
+     
+     @param     libName    Name of library class   
+     @return               Name of header file
     **/
-    public String getGUIDGuid(String guidStr) {
-        if (guidInfo.get(guidStr) != null) {
-            return guidInfo.get(guidStr)[1];
-        } else {
-            return null;
-        }
-
-    }
-
-    /**
-      getGuidNameArray
-      
-      This function is to get the GUID's CName and it's GUID according to 
-      GUID's name
-      
-      @param   guidName     Name of GUID
-      @return               CName and GUID.
-    **/
-    public String[] getGuidNameArray(String guidName) {
-        return this.guidInfo.get(guidName);
-    }
-
-    /**
-      getLibClassInclude 
-      
-      This function is to get the library exposed header file name according 
-      library class name.
-      
-      @param     libName    Name of library class   
-      @return               Name of header file
-    **/
-    String getLibClassIncluder(String libName) {
+    String[] getLibClassIncluder(String libName) {
         return libClassHeaderList.get(libName);
     }
 
     /**
       getModuleTypeIncluder
-      
+    
       This function is to get the header file name from module info map 
       according to module type.
-     
+    
       @param   moduleType    Module type.
       @return                Name of header file.
     **/
-    String getModuleTypeIncluder(String moduleType) {
-        return moduleInfo.get(moduleType);
+    String getPackageIncluder(String moduleType) {
+        return packageHeaderInfo.get(moduleType);
     }
-
+    
     /**
-      formateGuidName
-      
-      This function is to formate GUID to ANSI c form.
-     
-      @param  guidNameCon      String of GUID.
-      @return                  Formated GUID.
-    **/
-    public static String formatGuidName (String guidNameConv) {
-        String[] strList;
-        String guid = "";
-        int index = 0;
-        if (guidNameConv
-                        .matches("[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}")) {
-            strList = guidNameConv.split("-");
-            guid = "0x" + strList[0] + ", ";
-            guid = guid + "0x" + strList[1] + ", ";
-            guid = guid + "0x" + strList[2] + ", ";
-            guid = guid + "{";
-            guid = guid + "0x" + strList[3].substring(0, 2) + ", ";
-            guid = guid + "0x" + strList[3].substring(2, 4);
+           getGuidNameArray
+    
+           This function is to get the GUID's CName and it's GUID according to
+           GUID's name
+    
+           @param   guidName     Name of GUID
+           @return               CName and GUID.
+         **/
+         public String[] getGuidNameArray(String guidName) {
+             return this.guidInfo.get(guidName);
+         }
 
-            while (index < strList[4].length()) {
-                guid = guid + ", ";
-                guid = guid + "0x" + strList[4].substring(index, index + 2);
-                index = index + 2;
-            }
-            guid = guid + "}";
-            return guid;
-        } else if (guidNameConv
-                        .matches("0x[a-fA-F0-9]{1,8},( )*0x[a-fA-F0-9]{1,4},( )*0x[a-fA-F0-9]{1,4}(,( )*\\{)?(,?( )*0x[a-fA-F0-9]{1,2}){8}( )*(\\})?")) {
-            strList = guidNameConv.split(",");
-            
-            //
-            // chang Microsoft specific form to ANSI c form
-            //
-            for (int i = 0; i < 3; i++){
-                guid = guid + strList[i] + ",";
-            }
-            guid = guid + "{";
-            
-            for (int i = 3; i < strList.length; i++){
-                if (i == strList.length - 1){
-                    guid = guid + strList[i];
-                } else {
-                    guid = guid + strList[i] + ",";
-                }
-            }
-            guid = guid + "}";            
-            return guid;
-        } else {
-            System.out.println("Check GUID Value, it don't conform to the schema!!!");
-            return "0";
-
-        }
-    }
 }
diff --git a/Tools/Source/GenBuild/org/tianocore/build/global/SurfaceAreaParser.java b/Tools/Source/GenBuild/org/tianocore/build/global/SurfaceAreaParser.java
deleted file mode 100644
index 229e16976d..0000000000
--- a/Tools/Source/GenBuild/org/tianocore/build/global/SurfaceAreaParser.java
+++ /dev/null
@@ -1,213 +0,0 @@
-/** @file
-  SurfaceAreaParser class.
-  
-  SurfaceAreaParser class is used to parse module surface area include both 
-  driver and library. 
-
-Copyright (c) 2006, Intel Corporation
-All rights reserved. This program and the accompanying materials
-are licensed and made available under the terms and conditions of the BSD License
-which accompanies this distribution.  The full text of the license may be found at
-http://opensource.org/licenses/bsd-license.php
-
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
-**/
-package org.tianocore.build.global;
-
-import java.io.File;
-import java.util.HashMap;
-import java.util.Map;
-
-import org.apache.tools.ant.BuildException;
-import org.apache.xmlbeans.XmlObject;
-import org.tianocore.LibraryModuleBuildDescriptionDocument;
-import org.tianocore.LibraryModuleSurfaceAreaDocument;
-import org.tianocore.ModuleBuildDescriptionDocument;
-import org.tianocore.ModuleSurfaceAreaDocument;
-
-/**
-  This class is used to parse module surface area (MSA & MBD) include both 
-  driver and library. 
-
-  @since GenBuild 1.0
-**/
-public class SurfaceAreaParser {
-
-    /**
-      Using XmlBeans to parse and valid surface area file. 
-    
-      @param surfaceAreaFile the surface area file to parse
-      @return top level elements and its value mapping information
-      @throws BuildException
-              If surface area is not well-formed or invalid
-    **/
-    public Map<String, XmlObject> parseFile(File surfaceAreaFile) throws BuildException {
-        Map<String, XmlObject> map = new HashMap<String, XmlObject>();
-        try {
-            XmlObject sadoc = XmlObject.Factory.parse(surfaceAreaFile);
-            // Validate File if they obey XML Schema
-            
-            if ( ! sadoc.validate()){
-                throw new BuildException("Surface Area file [" + surfaceAreaFile.getPath() + "] is invalid.");
-            }
-            if (sadoc instanceof ModuleSurfaceAreaDocument){
-                parseFile((ModuleSurfaceAreaDocument) sadoc, map);
-            }
-            else if(sadoc instanceof ModuleBuildDescriptionDocument){
-                parseFile((ModuleBuildDescriptionDocument) sadoc, map);
-            }
-            else if(sadoc instanceof LibraryModuleSurfaceAreaDocument){
-                parseFile((LibraryModuleSurfaceAreaDocument) sadoc, map);
-            }
-            else if(sadoc instanceof LibraryModuleBuildDescriptionDocument){
-                parseFile((LibraryModuleBuildDescriptionDocument) sadoc, map);
-            }
-        }
-        catch (Exception ex){
-            throw new BuildException(ex.getMessage());
-        }
-        return map;
-    }
-    
-    
-    /**
-      Parse MSA.
-    
-      @param doc top level surface area XML document
-      @param msaMap the map to store the result
-    **/
-    private void parseFile(ModuleSurfaceAreaDocument doc, Map<String, XmlObject> msaMap) {
-        msaMap.put("MsaHeader", doc.getModuleSurfaceArea().getMsaHeader());
-        msaMap.put("LibraryClassDefinitions", doc.getModuleSurfaceArea()
-                        .getLibraryClassDefinitions());
-        msaMap.put("SourceFiles", doc.getModuleSurfaceArea().getSourceFiles());
-        msaMap.put("Includes", doc.getModuleSurfaceArea().getIncludes());
-        msaMap.put("PackageDependencies", doc.getModuleSurfaceArea().getPackageDependencies());
-        msaMap.put("Protocols", doc.getModuleSurfaceArea().getProtocols());
-
-        msaMap.put("Events", doc.getModuleSurfaceArea().getEvents());
-        msaMap.put("Hobs", doc.getModuleSurfaceArea().getHobs());
-        msaMap.put("PPIs", doc.getModuleSurfaceArea().getPPIs());
-        msaMap.put("Variables", doc.getModuleSurfaceArea().getVariables());
-        msaMap.put("BootModes", doc.getModuleSurfaceArea().getBootModes());
-
-        msaMap.put("SystemTables", doc.getModuleSurfaceArea().getSystemTables());
-        msaMap.put("DataHubs", doc.getModuleSurfaceArea().getDataHubs());
-        msaMap.put("Formsets", doc.getModuleSurfaceArea().getFormsets());
-        msaMap.put("Guids", doc.getModuleSurfaceArea().getGuids());
-        msaMap.put("Externs", doc.getModuleSurfaceArea().getExterns());
-
-        msaMap.put("PcdCoded", doc.getModuleSurfaceArea().getPcdCoded());
-        msaMap.put("BuildOptions", doc.getModuleSurfaceArea().getBuildOptions());
-    }
-
-    /**
-      Parse MBD.
-  
-      @param doc top level surface area XML document
-      @param msaMap the map to store the result
-    **/
-    private void parseFile(ModuleBuildDescriptionDocument doc, Map<String, XmlObject> mbdMap) {
-        mbdMap.put("MbdHeader", doc.getModuleBuildDescription().getMbdHeader());
-        mbdMap.put("Libraries", doc.getModuleBuildDescription().getLibraries());
-        mbdMap.put("SourceFiles", doc.getModuleBuildDescription()
-                        .getSourceFiles());
-        mbdMap.put("Includes", doc.getModuleBuildDescription().getIncludes());
-        mbdMap.put("Protocols", doc.getModuleBuildDescription().getProtocols());
-
-        mbdMap.put("Events", doc.getModuleBuildDescription().getEvents());
-        mbdMap.put("Hobs", doc.getModuleBuildDescription().getHobs());
-        mbdMap.put("PPIs", doc.getModuleBuildDescription().getPPIs());
-        mbdMap.put("Variables", doc.getModuleBuildDescription().getVariables());
-        mbdMap.put("BootModes", doc.getModuleBuildDescription().getBootModes());
-
-        mbdMap.put("SystemTables", doc.getModuleBuildDescription()
-                        .getSystemTables());
-        mbdMap.put("DataHubs", doc.getModuleBuildDescription().getDataHubs());
-        mbdMap.put("Formsets", doc.getModuleBuildDescription().getFormsets());
-        mbdMap.put("Guids", doc.getModuleBuildDescription().getGuids());
-        mbdMap.put("Externs", doc.getModuleBuildDescription().getExterns());
-
-        mbdMap.put("BuildOptions", doc.getModuleBuildDescription()
-                        .getBuildOptions());
-    }
-    /**
-      Parse Library MSA.
-
-      @param doc top level surface area XML document
-      @param msaMap the map to store the result
-    **/
-    private void parseFile(LibraryModuleSurfaceAreaDocument doc, Map<String, XmlObject> msaMap) {
-        msaMap.put("MsaLibHeader", doc.getLibraryModuleSurfaceArea()
-                        .getMsaLibHeader());
-        msaMap.put("LibraryClassDefinitions", doc.getLibraryModuleSurfaceArea()
-                        .getLibraryClassDefinitions());
-        msaMap.put("SourceFiles", doc.getLibraryModuleSurfaceArea()
-                        .getSourceFiles());
-        msaMap.put("Includes", doc.getLibraryModuleSurfaceArea().getIncludes());
-        msaMap.put("Protocols", doc.getLibraryModuleSurfaceArea()
-                        .getProtocols());
-
-        msaMap.put("Events", doc.getLibraryModuleSurfaceArea().getEvents());
-        msaMap.put("Hobs", doc.getLibraryModuleSurfaceArea().getHobs());
-        msaMap.put("PPIs", doc.getLibraryModuleSurfaceArea().getPPIs());
-        msaMap.put("Variables", doc.getLibraryModuleSurfaceArea()
-                        .getVariables());
-        msaMap.put("BootModes", doc.getLibraryModuleSurfaceArea()
-                        .getBootModes());
-
-        msaMap.put("SystemTables", doc.getLibraryModuleSurfaceArea()
-                        .getSystemTables());
-        msaMap.put("DataHubs", doc.getLibraryModuleSurfaceArea().getDataHubs());
-        msaMap.put("Formsets", doc.getLibraryModuleSurfaceArea().getFormsets());
-        msaMap.put("Guids", doc.getLibraryModuleSurfaceArea().getGuids());
-        msaMap.put("Externs", doc.getLibraryModuleSurfaceArea().getExterns());
-
-        msaMap.put("PcdCoded", doc.getLibraryModuleSurfaceArea().getPcdCoded());
-        msaMap.put("BuildOptions", doc.getLibraryModuleSurfaceArea()
-                        .getBuildOptions());
-    }
-
-    /**
-      Parse Library MBD.
-
-      @param doc top level surface area XML document
-      @param msaMap the map to store the result
-    **/
-    private void parseFile(LibraryModuleBuildDescriptionDocument doc, Map<String, XmlObject> mbdMap) {
-        mbdMap.put("MbdLibHeader", doc.getLibraryModuleBuildDescription()
-                        .getMbdLibHeader());
-        mbdMap.put("Libraries", doc.getLibraryModuleBuildDescription()
-                        .getLibraries());
-        mbdMap.put("SourceFiles", doc.getLibraryModuleBuildDescription()
-                        .getSourceFiles());
-        mbdMap.put("Includes", doc.getLibraryModuleBuildDescription()
-                        .getIncludes());
-        mbdMap.put("Protocols", doc.getLibraryModuleBuildDescription()
-                        .getProtocols());
-
-        mbdMap
-                        .put("Events", doc.getLibraryModuleBuildDescription()
-                                        .getEvents());
-        mbdMap.put("Hobs", doc.getLibraryModuleBuildDescription().getHobs());
-        mbdMap.put("PPIs", doc.getLibraryModuleBuildDescription().getPPIs());
-        mbdMap.put("Variables", doc.getLibraryModuleBuildDescription()
-                        .getVariables());
-        mbdMap.put("BootModes", doc.getLibraryModuleBuildDescription()
-                        .getBootModes());
-
-        mbdMap.put("SystemTables", doc.getLibraryModuleBuildDescription()
-                        .getSystemTables());
-        mbdMap.put("DataHubs", doc.getLibraryModuleBuildDescription()
-                        .getDataHubs());
-        mbdMap.put("Formsets", doc.getLibraryModuleBuildDescription()
-                        .getFormsets());
-        mbdMap.put("Guids", doc.getLibraryModuleBuildDescription().getGuids());
-        mbdMap.put("Externs", doc.getLibraryModuleBuildDescription()
-                        .getExterns());
-
-        mbdMap.put("BuildOptions", doc.getLibraryModuleBuildDescription()
-                        .getBuildOptions());
-    }
-}
diff --git a/Tools/Source/GenBuild/org/tianocore/build/global/SurfaceAreaQuery.java b/Tools/Source/GenBuild/org/tianocore/build/global/SurfaceAreaQuery.java
index 35fd77833a..5eb14d4a45 100644
--- a/Tools/Source/GenBuild/org/tianocore/build/global/SurfaceAreaQuery.java
+++ b/Tools/Source/GenBuild/org/tianocore/build/global/SurfaceAreaQuery.java
@@ -14,7 +14,9 @@
 package org.tianocore.build.global;
 
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.Iterator;
+import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Stack;
@@ -25,99 +27,122 @@ import org.apache.xmlbeans.XmlNormalizedString;
 import org.apache.xmlbeans.XmlObject;
 import org.apache.xmlbeans.XmlString;
 import org.tianocore.BuildOptionsDocument;
-import org.tianocore.CName;
+import org.tianocore.DataIdDocument;
 import org.tianocore.ExternsDocument;
-import org.tianocore.FfsDocument;
 import org.tianocore.FileNameConvention;
-import org.tianocore.FrameworkComponentTypes;
-import org.tianocore.FvImageOptionsDocument;
-import org.tianocore.GuidDocument;
+import org.tianocore.FvAttributeDocument;
+import org.tianocore.FvImagesDocument;
+import org.tianocore.FvOptionDocument;
+import org.tianocore.GuidDeclarationsDocument;
 import org.tianocore.GuidsDocument;
 import org.tianocore.LibrariesDocument;
+import org.tianocore.LibraryClassDeclarationsDocument;
 import org.tianocore.LibraryClassDocument;
-import org.tianocore.LibraryUsage;
+import org.tianocore.ModuleDefinitionsDocument;
 import org.tianocore.ModuleSADocument;
+import org.tianocore.ModuleSaBuildOptionsDocument;
 import org.tianocore.ModuleTypeDef;
-import org.tianocore.NameValueDocument;
-import org.tianocore.OutputDirectoryDocument;
-import org.tianocore.PPIsDocument;
-import org.tianocore.PackageNameDocument;
-import org.tianocore.ProtocolsDocument;
-import org.tianocore.PcdCodedDocument.PcdCoded;
+import org.tianocore.MsaFilesDocument;
 import org.tianocore.MsaHeaderDocument;
+import org.tianocore.OptionDocument;
+import org.tianocore.PPIsDocument;
+import org.tianocore.PackageDependenciesDocument;
+import org.tianocore.PackageHeadersDocument;
+import org.tianocore.PlatformDefinitionsDocument;
+import org.tianocore.PpiDeclarationsDocument;
+import org.tianocore.ProtocolDeclarationsDocument;
+import org.tianocore.SpdHeaderDocument;
+import org.tianocore.SupportedArchitectures;
+import org.tianocore.FilenameDocument.Filename;
 import org.tianocore.MsaHeaderDocument.MsaHeader;
+import org.tianocore.ProtocolsDocument.Protocols.Protocol;
+import org.tianocore.ProtocolsDocument.Protocols.ProtocolNotify;
+import org.tianocore.PlatformHeaderDocument;
+import org.tianocore.build.id.FpdModuleIdentification;
+import org.tianocore.build.id.ModuleIdentification;
+import org.tianocore.build.id.PackageIdentification;
+import org.tianocore.build.id.PlatformIdentification;
+import org.tianocore.build.toolchain.ToolChainInfo;
 
 /**
-  SurfaceAreaQuery class is used to query Surface Area information from msa, mbd,
-  spd and fpd files. 
-  
-  This class should not instantiated. All the public interfaces is static.
-  
-  @since GenBuild 1.0
- **/
+ * SurfaceAreaQuery class is used to query Surface Area information from msa,
+ * mbd, spd and fpd files.
+ * 
+ * This class should not instantiated. All the public interfaces is static.
+ * 
+ * @since GenBuild 1.0
+ */
 public class SurfaceAreaQuery {
-    /// 
-    /// Contains name/value pairs of Surface Area document object. The name is
-    /// always the top level element name.
-    ///  
+
+    public static String prefix = "http://www.TianoCore.org/2006/Edk2.0";
+
+    // /
+    // / Contains name/value pairs of Surface Area document object. The name is
+    // / always the top level element name.
+    // /
     private static Map<String, XmlObject> map = null;
-    
-    ///
-    /// mapStack is used to do nested query
-    ///
-    private static Stack< Map<String, XmlObject> > mapStack = new Stack< Map<String, XmlObject> >();
-    
-    /// 
-    /// prefix of name space
-    /// 
+
+    // /
+    // / mapStack is used to do nested query
+    // /
+    private static Stack<Map<String, XmlObject>> mapStack = new Stack<Map<String, XmlObject>>();
+
+    // /
+    // / prefix of name space
+    // /
     private static String nsPrefix = "sans";
-    
-    ///
-    /// xmlbeans needs a name space for each Xpath element 
-    ///
+
+    // /
+    // / xmlbeans needs a name space for each Xpath element
+    // /
     private static String ns = null;
-    
-    ///
-    /// keep the namep declaration for xmlbeans Xpath query
-    ///
+
+    // /
+    // / keep the namep declaration for xmlbeans Xpath query
+    // /
     private static String queryDeclaration = null;
 
     /**
-     Set a Surface Area document for query later
-     
-     @param     map     A Surface Area document in TopLevelElementName/XmlObject format.
-     **/
+     * Set a Surface Area document for query later
+     * 
+     * @param map
+     *            A Surface Area document in TopLevelElementName/XmlObject
+     *            format.
+     */
     public static void setDoc(Map<String, XmlObject> map) {
-        ns = OverrideProcess.prefix;
+        ns = prefix;
         queryDeclaration = "declare namespace " + nsPrefix + "='" + ns + "'; ";
         SurfaceAreaQuery.map = map;
     }
 
     /**
-     Push current used Surface Area document into query stack. The given new 
-     document  will be used for any immediately followed getXXX() callings, 
-     untill pop() is called.
-     
-     @param     newMap  The TopLevelElementName/XmlObject format of a Surface Area document.
-     **/
+     * Push current used Surface Area document into query stack. The given new
+     * document will be used for any immediately followed getXXX() callings,
+     * untill pop() is called.
+     * 
+     * @param newMap
+     *            The TopLevelElementName/XmlObject format of a Surface Area
+     *            document.
+     */
     public static void push(Map<String, XmlObject> newMap) {
         mapStack.push(SurfaceAreaQuery.map);
         SurfaceAreaQuery.map = newMap;
     }
-    
+
     /**
-     Discard current used Surface Area document and use the top document in stack
-     instead.
-     **/
+     * Discard current used Surface Area document and use the top document in
+     * stack instead.
+     */
     public static void pop() {
         SurfaceAreaQuery.map = mapStack.pop();
     }
-    
-    ///
-    /// Convert xPath to be namespace qualified, which is necessary for XmlBeans
-    /// selectPath(). For example, converting /MsaHeader/ModuleType to
-    /// /ns:MsaHeader/ns:ModuleType
-    ///     
+
+    // /
+    // / Convert xPath to be namespace qualified, which is necessary for
+    // XmlBeans
+    // / selectPath(). For example, converting /MsaHeader/ModuleType to
+    // / /ns:MsaHeader/ns:ModuleType
+    // /
     private static String normalizeQueryString(String[] exp, String from) {
         StringBuffer normQueryString = new StringBuffer(4096);
 
@@ -128,10 +153,13 @@ public class SurfaceAreaQuery {
             Matcher matcher = pattern.matcher(newExp);
 
             while (matcher.find()) {
-                String starter = newExp.substring(matcher.start(1), matcher.end(1));
-                String seperator = newExp.substring(matcher.start(2), matcher.end(2));
-                String token = newExp.substring(matcher.start(3), matcher.end(3));
-                
+                String starter = newExp.substring(matcher.start(1), matcher
+                        .end(1));
+                String seperator = newExp.substring(matcher.start(2), matcher
+                        .end(2));
+                String token = newExp.substring(matcher.start(3), matcher
+                        .end(3));
+
                 normQueryString.append(starter);
                 normQueryString.append(seperator);
                 normQueryString.append(nsPrefix);
@@ -149,223 +177,361 @@ public class SurfaceAreaQuery {
     }
 
     /**
-      Search all XML documents stored in "map" for the specified xPath, using
-      relative path (starting with '$this')
-     
-     @param     xPath   xpath query string array
-     @returns   An array of XmlObject   if elements are found at the specified xpath
-     @returns   NULL                    if nothing is at the specified xpath
-     **/
-    public static XmlObject[] get(String[] xPath) {
+     * Search all XML documents stored in "map" for the specified xPath, using
+     * relative path (starting with '$this')
+     * 
+     * @param xPath
+     *            xpath query string array
+     * @returns An array of XmlObject if elements are found at the specified
+     *          xpath
+     * @returns NULL if nothing is at the specified xpath
+     */
+    public static Object[] get(String[] xPath) {
         if (map == null) {
             return null;
         }
-        
+
         String[] keys = (String[]) map.keySet().toArray(new String[map.size()]);
-        List<XmlObject> result = new ArrayList<XmlObject>();
+        List<Object> result = new ArrayList<Object>();
         for (int i = 0; i < keys.length; ++i) {
             XmlObject rootNode = (XmlObject) map.get(keys[i]);
             if (rootNode == null) {
                 continue;
             }
-            
-            String query = queryDeclaration + normalizeQueryString(xPath, "$this/" + keys[i]);
+
+            String query = queryDeclaration
+                    + normalizeQueryString(xPath, "$this/" + keys[i]);
             XmlObject[] tmp = rootNode.selectPath(query);
             for (int j = 0; j < tmp.length; ++j) {
-                result.add(tmp[j]);
+                result.add((Object)tmp[j]);
             }
         }
-        
+
         int size = result.size();
         if (size <= 0) {
             return null;
         }
-        
-        return (XmlObject[]) result.toArray(new XmlObject[size]);
+
+        return (Object[]) result.toArray(new Object[size]);
     }
 
     /**
-     Search XML documents named by "rootName" for the given xPath, using
-     relative path (starting with '$this')
-     
-     @param     rootName    The top level element name 
-     @param     xPath       The xpath query string array
-     @returns   An array of XmlObject   if elements are found at the given xpath
-     @returns   NULL                    if nothing is found at the given xpath
-     **/
-    public static XmlObject[] get(String rootName, String[] xPath) {
+     * Search XML documents named by "rootName" for the given xPath, using
+     * relative path (starting with '$this')
+     * 
+     * @param rootName
+     *            The top level element name
+     * @param xPath
+     *            The xpath query string array
+     * @returns An array of XmlObject if elements are found at the given xpath
+     * @returns NULL if nothing is found at the given xpath
+     */
+    public static Object[] get(String rootName, String[] xPath) {
         if (map == null) {
             return null;
         }
-        
+
         XmlObject root = (XmlObject) map.get(rootName);
         if (root == null) {
             return null;
         }
 
-        String query = queryDeclaration + normalizeQueryString(xPath, "$this/" + rootName);
+        String query = queryDeclaration
+                + normalizeQueryString(xPath, "$this/" + rootName);
         XmlObject[] result = root.selectPath(query);
         if (result.length > 0) {
-            return result;
+            return (Object[])result;
         }
 
         query = queryDeclaration + normalizeQueryString(xPath, "/" + rootName);
         result = root.selectPath(query);
         if (result.length > 0) {
-            return result;
+            return (Object[])result;
         }
 
         return null;
     }
 
     /**
-     Retrieve SourceFiles/Filename for specified ARCH type
-      
-     @param     arch        architecture name
-     @returns   An array of XmlObject   if elements are found at the known xpath
-     @returns   NULL                    if nothing is found at the known xpath
-     **/
-    public static XmlObject[] getSourceFiles(String arch) {
+     * Retrieve SourceFiles/Filename for specified ARCH type
+     * 
+     * @param arch
+     *            architecture name
+     * @returns An 2 dimension string array if elements are found at the known
+     *          xpath
+     * @returns NULL if nothing is found at the known xpath
+     */
+    public static String[][] getSourceFiles(String arch) {
         String[] xPath;
+        Object[] returns;
 
         if (arch == null || arch.equals("")) {
-            xPath = new String[] {
-                "/Filename",
-                "/Arch/Filename"
-                };
+            xPath = new String[] { "/Filename" };
         } else {
-            xPath = new String[] {
-                "/Filename[not(@SupArchList) and not(@ArchType) or @SupArchList='ALL' or @SupArchList='" + arch + "' or @ArchType='ALL' or @ArchType='" + arch + "']",
-                "/Filename[not(@SupArchList) and not(@ArchType) or @ArchType='ALL' or @ArchType='" + arch + "']",
-                "/Arch[@ArchType='ALL' or @ArchType='" + arch + "']/Filename"
-                };
+            xPath = new String[] { "/Filename[not(@SupArchList) or @SupArchList='"
+                    + arch + "']" };
         }
 
-        return get("SourceFiles", xPath);
+        returns = get("SourceFiles", xPath);
+
+        if (returns == null || returns.length == 0) {
+            return new String[0][0];
+        }
+
+        Filename[] sourceFileNames = (Filename[]) returns;
+        String[][] outputString = new String[sourceFileNames.length][2];
+        for (int i = 0; i < sourceFileNames.length; i++) {
+            outputString[i][0] = sourceFileNames[i].getToolCode();
+            outputString[i][1] = sourceFileNames[i].getStringValue();
+        }
+        return outputString;
     }
 
     /**
-     Retrieve BuildOptions/Ffs
+     * Retrieve /PlatformDefinitions/OutputDirectory from FPD
+     * 
+     * @returns Directory names array if elements are found at the known xpath
+     * @returns Empty if nothing is found at the known xpath
+     */
+    public static String getFpdOutputDirectory() {
+        String[] xPath = new String[] { "/PlatformDefinitions" };
 
-     @returns   FfsDocument.Ffs object  if elements are found at the known xpath
-     @returns   NULL                    if nothing is found at the known xpath
-     **/
-    public static FfsDocument.Ffs getFfs() {
-        String[] xPath = new String[] { "/Ffs" };
-
-        XmlObject[] returns = get("BuildOptions", xPath);
-        if (returns != null && returns.length > 0) {
-            return (FfsDocument.Ffs) returns[0];
+        Object[] returns = get("PlatformSurfaceArea", xPath);
+        if (returns == null || returns.length == 0) {
+            return null;
         }
-
-        return null;
+        PlatformDefinitionsDocument.PlatformDefinitions item = (PlatformDefinitionsDocument.PlatformDefinitions)returns[0];
+        return item.getOutputDirectory();
     }
 
-    /**
-     Retrieve BuildOptions/OutputDirectory
+    public static String getFpdIntermediateDirectories() {
+        String[] xPath = new String[] { "/PlatformDefinitions" };
 
-     @returns   Directory names array   if elements are found at the known xpath
-     @returns   Empty                   if nothing is found at the known xpath
-     **/
-    public static String[] getOutputDirectory() {
-        String[] xPath = new String[] { "/OutputDirectory" };
-
-        XmlObject[] returns = get("BuildOptions", xPath);
-        if (returns != null && returns.length > 0) {
-            String[] dirString = new String[2];
-
-            OutputDirectoryDocument.OutputDirectory[] dir = (OutputDirectoryDocument.OutputDirectory[]) returns;
-            dirString[0] = dir[0].getIntermediateDirectories().toString();
-            dirString[1] = dir[0].getStringValue();
-
-            return dirString;
+        Object[] returns = get("PlatformSurfaceArea", xPath);
+        if (returns == null || returns.length == 0) {
+            return "UNIFIED";
+        }
+        PlatformDefinitionsDocument.PlatformDefinitions item = (PlatformDefinitionsDocument.PlatformDefinitions)returns[0];
+        if(item.getIntermediateDirectories() == null) {
+            return null;     
+        }
+        else {
+            return item.getIntermediateDirectories().toString();
         }
-
-        return new String[] { "UNIFIED", null };
     }
 
-    /**
-     Retrieve BuildOptions/Option or Arch/Option
+    public static String getModuleFfsKeyword() {
+        String[] xPath = new String[] { "/" };
 
-     @param     arch    architecture name
-
-     @returns   name/value pairs of options if elements are found at the known xpath
-     @returns   Empty array                 if nothing is there
-     **/
-    public static String[][] getOptions(String arch){
-        String[] xPath;
-
-        if (arch == null || arch.equals("")) {
-            xPath = new String[] {
-                "/Option",
-                "/Arch/Option"
-                };
-        } else {
-            xPath = new String[] {
-                "/Option",
-                "/Option[@SupArchList='ALL' or @SupArchList='" + arch + "']",
-                "/Arch[@ArchType='ALL' or @ArchType='" + arch + "']/Option"
-                };
+        Object[] returns = get("ModuleSaBuildOptions", xPath);
+        if (returns == null || returns.length == 0) {
+            return null;
         }
-
-        XmlObject[] returns = get("BuildOptions", xPath);
-        if (returns == null){
-            return new String[0][2];
-        }
-        
-        String[][] result = new String[returns.length][2];
-        for (int i = 0; i < returns.length; i ++){
-            String str;
-            String name = null;
-            String value = null;
-
-            if (returns[i] instanceof BuildOptionsDocument.BuildOptions.Option) {
-                BuildOptionsDocument.BuildOptions.Option option = (BuildOptionsDocument.BuildOptions.Option)returns[i];
-                str = option.getStringValue();
-            } else if (returns[i] instanceof BuildOptionsDocument.BuildOptions.Arch.Option) {
-                BuildOptionsDocument.BuildOptions.Arch.Option archOption = (BuildOptionsDocument.BuildOptions.Arch.Option)returns[i];
-                str = archOption.getStringValue();
-            } else {
-                continue;
-            }
-            
-            int equalIndex = str.indexOf('=');
-            if ( equalIndex > 0) {
-                name = str.substring(0, equalIndex).trim();
-                value = str.substring(equalIndex + 1).trim();
-                // TBD remove some forbidden name: BASE_NAME, ARCH and so on
-                if (name.length() == 0){
-                    name = null;
-                }
-            }
-            result[i][0] = name;
-            result[i][1] = value;
-        }
-
-        return result;
+        ModuleSaBuildOptionsDocument.ModuleSaBuildOptions item = (ModuleSaBuildOptionsDocument.ModuleSaBuildOptions)returns[0];
+        return item.getFfsFormatKey();
     }
     
-    public static String getModuleName() {
-        String[] xPath = new String[] { "/ModuleName", "/BaseName" };
+    public static String getModuleFvBindingKeyword() {
+        String[] xPath = new String[] { "/" };
 
-        XmlObject[] returns = get(xPath);
-        if (returns != null && returns.length > 0) {
-            return returns[0].toString();
+        Object[] returns = get("ModuleSaBuildOptions", xPath);
+        if (returns == null || returns.length == 0) {
+            return null;
+        }
+        ModuleSaBuildOptionsDocument.ModuleSaBuildOptions item = (ModuleSaBuildOptionsDocument.ModuleSaBuildOptions)returns[0];
+        return item.getFvBinding();
+    }
+    
+    public static List getModuleSupportedArchs() {
+        String[] xPath = new String[] { "/" };
+
+        Object[] returns = get("ModuleDefinitions", xPath);
+        if (returns == null || returns.length == 0) {
+            return null;
+        }
+        ModuleDefinitionsDocument.ModuleDefinitions item = (ModuleDefinitionsDocument.ModuleDefinitions)returns[0];
+        return item.getSupportedArchitectures();
+    }
+    
+    public static BuildOptionsDocument.BuildOptions.Ffs[] getFpdFfs() {
+        String[] xPath = new String[] {"/Ffs"};
+        
+        Object[] returns = get("BuildOptions", xPath);
+        if (returns == null || returns.length == 0) {
+            return new BuildOptionsDocument.BuildOptions.Ffs[0];
+        }
+        return (BuildOptionsDocument.BuildOptions.Ffs[])returns;
+    }
+    
+    public static String getModuleOutputFileBasename() {
+        String[] xPath = new String[] { "/" };
+
+        Object[] returns = get("ModuleDefinitions", xPath);
+        if (returns == null || returns.length == 0) {
+            return null;
+        }
+        ModuleDefinitionsDocument.ModuleDefinitions item = (ModuleDefinitionsDocument.ModuleDefinitions)returns[0];
+        return item.getOutputFileBasename();
+    }
+    
+    /**
+     * Retrieve BuildOptions/Option or Arch/Option
+     * 
+     * @param toolChainFamilyFlag
+     *            if true, retrieve options for toolchain family; otherwise for
+     *            toolchain
+     * 
+     * @returns String[][5] name, target, toolchain, arch, coommand of options
+     *          if elements are found at the known xpath. String[0][] if dont
+     *          find element.
+     * 
+     * @returns Empty array if nothing is there
+     */
+    public static String[][] getOptions(String from, String[] xPath, boolean toolChainFamilyFlag) {
+        String target = null;
+        String toolchain = null;
+        String toolchainFamily = null;
+        List<String> archList = null;
+        String cmd = null;
+        String targetName = null;
+        String optionName = null;
+
+        Object[] returns = get(from, xPath);
+        if (returns == null) {
+            return new String[0][5];
         }
 
-        return null;
+        List<String[]> optionList = new ArrayList<String[]>();
+        OptionDocument.Option option;
+
+        for (int i = 0; i < returns.length; i++) {
+            option = (OptionDocument.Option) returns[i];
+
+            //
+            // Get Target, ToolChain(Family), Arch, Cmd, and Option from Option,
+            // then
+            // put to result[][5] array in above order.
+            //
+            String[] targetList;
+            if (option.getBuildTargets() == null) {
+                target = null;
+            }
+            else {
+                target = option.getBuildTargets().toString();
+            }
+            if (target != null) {
+                targetList = target.split(" ");
+            } else {
+                targetList = new String[1];
+                targetList[0] = null;
+            }
+
+            if (toolChainFamilyFlag) {
+                toolchainFamily = option.getToolChainFamily();
+                if (toolchainFamily != null) {
+                    toolchain = toolchainFamily.toString();
+                } else {
+                    toolchain = null;
+                }
+            } else {
+                toolchain = option.getTagName();
+            }
+
+            archList = new ArrayList<String>();
+            List<String> archEnumList = option.getSupArchList();            
+            if (archEnumList == null) {
+                archList.add(null);
+            } else {
+                archList.addAll(archEnumList);
+                /*
+                Iterator it = archEnumList.iterator();
+                while (it.hasNext()) {
+                    System.out.println(it.next().getClass().getName());
+                    SupportedArchitectures.Enum archType = it.next();
+                    archList.add(archType.toString());
+                }
+                */
+            }
+
+            cmd = option.getToolCode();
+
+            optionName = option.getStringValue();
+            for (int t = 0; t < targetList.length; t++) {
+                for (int j = 0; j < archList.size(); j++) {
+                    optionList.add(new String[] { targetList[t],
+                            toolchain, archList.get(j), cmd, optionName});
+                }
+            }
+        }
+
+        String[][] result = new String[optionList.size()][5];
+        for (int i = 0; i < optionList.size(); i++) {
+            result[i][0] = optionList.get(i)[0];
+            result[i][1] = optionList.get(i)[1];
+            result[i][2] = optionList.get(i)[2];
+            result[i][3] = optionList.get(i)[3];
+            result[i][4] = optionList.get(i)[4];
+        }
+        return result;
+    }
+
+    public static String[][] getModuleBuildOptions(boolean toolChainFamilyFlag) {
+        String[] xPath;
+        
+        if (toolChainFamilyFlag == true) {
+            xPath = new String[] {
+                    "/Options/Option[not(@ToolChainFamily) and not(@TagName)]",
+                    "/Options/Option[@ToolChainFamily]", };
+        } else {
+            xPath = new String[] {
+                    "/Options/Option[not(@ToolChainFamily) and not(@TagName)]",
+                    "/Options/Option[@TagName]", };
+        }
+        return getOptions("ModuleSaBuildOptions", xPath, toolChainFamilyFlag);
+    }   
+    
+    public static String[][] getPlatformBuildOptions(boolean toolChainFamilyFlag) {
+        String[] xPath;
+
+        if (toolChainFamilyFlag == true) {
+            xPath = new String[] {
+                    "/BuildOptions/Options/Option[not(@ToolChainFamily) and not(@TagName)]",
+                    "/BuildOptions/Options/Option[@ToolChainFamily]", };
+        } else {
+            xPath = new String[] {
+                    "/BuildOptions/Options/Option[not(@ToolChainFamily) and not(@TagName)]",
+                    "/BuildOptions/Options/Option[@TagName]", };
+        }
+
+        return getOptions("PlatformSurfaceArea", xPath, toolChainFamilyFlag);
+    }
+
+    public static ToolChainInfo getFpdToolChainInfo() {
+        String[] xPath = new String[] { "/PlatformDefinitions" };
+
+        Object[] returns = get("PlatformSurfaceArea", xPath);
+        if (returns == null || returns.length == 0) {
+            return null;
+        }
+        
+        PlatformDefinitionsDocument.PlatformDefinitions item = (PlatformDefinitionsDocument.PlatformDefinitions)returns[0];
+        ToolChainInfo toolChainInfo = new ToolChainInfo();
+        toolChainInfo.addTargets(item.getBuildTargets().toString());
+        toolChainInfo.addArchs(item.getSupportedArchitectures().toString());
+        toolChainInfo.addTagnames((String)null);
+        return toolChainInfo;
     }
 
     /**
-     Retrieve <xxxHeader>/ModuleType
-
-     @returns   The module type name    if elements are found at the known xpath
-     @returns   null                    if nothing is there
-     **/
+     * Retrieve <xxxHeader>/ModuleType
+     * 
+     * @returns The module type name if elements are found at the known xpath
+     * @returns null if nothing is there
+     */
     public static String getModuleType() {
         String[] xPath = new String[] { "/ModuleType" };
 
-        XmlObject[] returns = get(xPath);
+        Object[] returns = get(xPath);
         if (returns != null && returns.length > 0) {
             ModuleTypeDef type = (ModuleTypeDef) returns[0];
             return type.enumValue().toString();
@@ -375,107 +541,91 @@ public class SurfaceAreaQuery {
     }
 
     /**
-     Retrieve <xxxHeader>/ComponentType
-     
-     @returns   The component type name if elements are found at the known xpath
-     @returns   null                    if nothing is there
-     **/
-    public static String getComponentType() {
-        String[] xPath = new String[] { "/ComponentType" };
-
-        XmlObject[] returns = get(xPath);
-        if (returns != null && returns.length > 0) {
-            FrameworkComponentTypes type = (FrameworkComponentTypes) returns[0];
-            return type.enumValue().toString();
-        }
-
-        return null;
-    }
-
-    /**
-     Retrieve Includes/PackageName
-
-     @param     arch    Architecture name
-
-     @returns   package name list       if elements are found at the known xpath
-     @returns   null                    if nothing is there
-     **/
-    public static List<String> getIncludePackageName(String arch) {
+     * Retrieve PackageDependencies/Package
+     * 
+     * @param arch
+     *            Architecture name
+     * 
+     * @returns package name list if elements are found at the known xpath
+     * @returns null if nothing is there
+     */
+    public static PackageIdentification[] getDependencePkg(String arch) {
         String[] xPath;
+        String packageGuid = null;
+        String packageVersion = null;
 
         if (arch == null || arch.equals("")) {
-            xPath = new String[] {
-                "/PackageName",
-                "/Arch/PackageName"
-                };
+            xPath = new String[] { "/Package" };
         } else {
-            xPath = new String[] {
-                "/PackageName",
-                "/PackageName[@SupArchList='ALL' or @SupArchList='" + arch + "']",
-                "/PackageName[@Arch='ALL' or @Arch='" + arch + "']",
-                "/Arch[@ArchType='ALL' or @ArchType='" + arch + "']/PackageName"
-                };
-        }
-        
-        XmlObject[] returns = get("Includes", xPath);
-        if (returns == null || returns.length == 0) {
-            returns = get("PackageDependencies", xPath);
-            if (returns == null || returns.length == 0) {
-                return null;
-            }
+            xPath = new String[] { "/Package[not(@SupArchList) or @SupArchList='"
+                    + arch + "']" };
         }
 
-        List<String> packageNames = new ArrayList<String>();
-        PackageNameDocument.PackageName[] nameObj = (PackageNameDocument.PackageName[])returns;
-        for (int i = 0; i < returns.length; ++i) {
-            packageNames.add(nameObj[i].getStringValue());
+        Object[] returns = get("PackageDependencies", xPath);
+        if (returns == null) {
+            return new PackageIdentification[0];
         }
-        
-        return packageNames;
+        PackageIdentification[] packageIdList = new PackageIdentification[returns.length];
+        for (int i = 0; i < returns.length; i++) {
+            PackageDependenciesDocument.PackageDependencies.Package item = (PackageDependenciesDocument.PackageDependencies.Package) returns[i];
+            packageGuid = item.getPackageGuid();
+            packageVersion = item.getPackageVersion();
+            packageIdList[i] = (new PackageIdentification(null, packageGuid,
+                    packageVersion));
+        }
+        return packageIdList;
     }
 
     /**
-     Retrieve LibraryClassDefinitions/LibraryClass for specified usage
-
-     @param     usage   Library class usage
-
-     @returns   LibraryClass objects list   if elements are found at the known xpath
-     @returns   null                        if nothing is there
-     **/
-    public static LibraryClassDocument.LibraryClass[] getLibraryClassArray(String usage) {
+     * Retrieve LibraryClassDefinitions/LibraryClass for specified usage
+     * 
+     * @param usage
+     *            Library class usage
+     * 
+     * @returns LibraryClass objects list if elements are found at the known
+     *          xpath
+     * @returns null if nothing is there
+     */
+    public static String[] getLibraryClasses(String usage) {
         String[] xPath;
 
         if (usage == null || usage.equals("")) {
-            xPath = new String[] {"/LibraryClass"};
+            xPath = new String[] { "/LibraryClass" };
         } else {
-            xPath = new String[] {"/LibraryClass[@Usage='" + usage + "']"};
+            xPath = new String[] { "/LibraryClass[@Usage='" + usage + "']" };
         }
 
-        XmlObject[] returns = get("LibraryClassDefinitions", xPath);
-        if (returns != null && returns.length > 0) {
-            return (LibraryClassDocument.LibraryClass[]) returns;
+        Object[] returns = get("LibraryClassDefinitions", xPath);
+        if (returns == null || returns.length == 0) {
+            return new String[0];
         }
 
-        return null;
+        LibraryClassDocument.LibraryClass[] libraryClassList = (LibraryClassDocument.LibraryClass[]) returns;
+        String[] libraryClassName = new String[libraryClassList.length];
+        for (int i = 0; i < libraryClassList.length; i++) {
+            libraryClassName[i] = libraryClassList[i].getKeyword();
+        }
+        return libraryClassName;
     }
 
     /**
-     Retrieve ModuleEntryPoint names
-
-     @returns   ModuleEntryPoint name list  if elements are found at the known xpath
-     @returns   null                        if nothing is there
-     **/
+     * Retrieve ModuleEntryPoint names
+     * 
+     * @returns ModuleEntryPoint name list if elements are found at the known
+     *          xpath
+     * @returns null if nothing is there
+     */
     public static String[] getModuleEntryPointArray() {
         String[] xPath = new String[] { "/Extern/ModuleEntryPoint" };
 
-        XmlObject[] returns = get("Externs", xPath);
+        Object[] returns = get("Externs", xPath);
 
         if (returns != null && returns.length > 0) {
             String[] entryPoints = new String[returns.length];
 
             for (int i = 0; i < returns.length; ++i) {
                 entryPoints[i] = ((XmlNormalizedString) returns[i])
-                                .getStringValue();
+                        .getStringValue();
             }
 
             return entryPoints;
@@ -485,108 +635,162 @@ public class SurfaceAreaQuery {
     }
 
     /**
-     Retrieve module Guid string
- 
-     @returns   GUILD string            if elements are found at the known xpath
-     @returns   null                    if nothing is there
-     **/
-    public static String getModuleGuid() {
-        String[] xPath = new String[] { "" };
+     * retrieve Protocol for specified usage
+     * 
+     * @param usage
+     *            Protocol usage arch Architecture
+     * 
+     * @returns Protocol String list if elements are found at the known xpath
+     * @returns String[0] if nothing is there
+     */
+    public static String[] getProtocolArray(String arch, String usage) {
+        String[] xPath;
+        String usageXpath = "";
+        String archXpath = "";
 
-        XmlObject[] returns = get("MsaHeader", xPath);
-        if (returns != null && returns.length > 0) {
-            MsaHeaderDocument.MsaHeader moduleHeader = (MsaHeaderDocument.MsaHeader) returns[0];
-            if (moduleHeader.isSetGuid()) {
-                return moduleHeader.getGuid().getStringValue();
-            } else if (moduleHeader.isSetGuidValue()) {
-                return moduleHeader.getGuidValue();
+        if (arch == null || arch.equals("")) {
+            return new String[0];
+        } else {
+            archXpath = "/Protocol[@SupArchList='" + arch + "']";
+            if (usage != null && !usage.equals("")) {
+                usageXpath = "/Protocol[@Usage='" + usage + "']";
+                xPath = new String[] { usageXpath, archXpath };
+            } else {
+                return getProtocolArray(arch);
+            }
+
+        }
+
+        Object[] returns = get("Protocols", xPath);
+        if (returns == null) {
+            return new String[0];
+        }
+        Protocol[] protocolList = (Protocol[]) returns;
+
+        String[] protocolArray = new String[returns.length];
+        for (int i = 0; i < returns.length; i++) {
+            protocolArray[i] = protocolList[i].getProtocolCName();
+        }
+        return protocolArray;
+    }
+
+    /**
+     * retrieve Protocol for specified usage
+     * 
+     * @param arch
+     *            Architecture
+     * 
+     * @returns Protocol String list if elements are found at the known xpath
+     * @returns String[0] if nothing is there
+     */
+    public static String[] getProtocolArray(String arch) {
+        String[] xPath;
+
+        if (arch == null || arch.equals("")) {
+            return new String[0];
+        } else {
+            xPath = new String[] { "/Protocol[@SupArchList='" + arch + "']" };
+        }
+
+        Object[] returns = get("Protocols", xPath);
+        if (returns == null) {
+            return new String[0];
+        }
+        Protocol[] protocolList = (Protocol[]) returns;
+
+        String[] protocolArray = new String[returns.length];
+        for (int i = 0; i < returns.length; i++) {
+            protocolArray[i] = protocolList[i].getProtocolCName();
+        }
+        return protocolArray;
+    }
+
+    /**
+     * Retrieve ProtocolNotify for specified usage
+     * 
+     * @param usage
+     *            ProtocolNotify usage
+     * 
+     * @returns String[] if elements are found at the known xpath
+     * @returns String[0] if nothing is there
+     */
+    public static String[] getProtocolNotifyArray(String arch) {
+        String[] xPath;
+
+        if (arch == null || arch.equals("")) {
+            return new String[0];
+        } else {
+            xPath = new String[] { "/ProtocolNotify[@SupArchList='" + arch
+                    + "']" };
+        }
+
+        Object[] returns = get("Protocols", xPath);
+        if (returns == null) {
+            return new String[0];
+        }
+
+        String[] protocolNotifyList = new String[returns.length];
+        for (int i = 0; i < returns.length; i++) {
+            protocolNotifyList[i] = ((ProtocolNotify) returns[i]).getProtocolNotifyCName();
+        }
+
+        return protocolNotifyList;
+    }
+
+    /**
+     * Retrieve ProtocolNotify for specified usage
+     * 
+     * @param usage
+     *            ProtocolNotify usage
+     * 
+     * @returns String[] if elements are found at the known xpath
+     * @returns String[0] if nothing is there
+     */
+    public static String[] getProtocolNotifyArray(String arch, String usage) {
+
+        String[] xPath;
+        String usageXpath;
+        String archXpath;
+
+        if (arch == null || arch.equals("")) {
+            return new String[0];
+        } else {
+            archXpath = "/ProtocolNotify[@SupArchList='" + arch + "']";
+            if (usage != null && !usage.equals("")) {
+                usageXpath = "/ProtocolNotify[@Usage='" + arch + "']";
+                xPath = new String[] { archXpath, usageXpath };
+            } else {
+                return getProtocolNotifyArray(arch);
             }
         }
 
-        return null;
+        Object[] returns = get("Protocols", xPath);
+        if (returns == null) {
+            return new String[0];
+        }
+
+        String[] protocolNotifyList = new String[returns.length];
+
+        for (int i = 0; i < returns.length; i++) {
+            protocolNotifyList[i] = ((ProtocolNotify) returns[i]).getProtocolNotifyCName();
+        }
+        return protocolNotifyList;
     }
 
     /**
-     Retrieve module Guid string
- 
-     @returns   GUILD string            if elements are found at the known xpath
-     @returns   null                    if nothing is there
-     **/
-    public static String getModuleGuidValue() {
-        String[] xPath = new String[] { "" };
-
-        XmlObject[] returns = get("MsaHeader", xPath);
-        if (returns != null && returns.length > 0) {            
-            MsaHeaderDocument.MsaHeader moduleHeader = (MsaHeaderDocument.MsaHeader) returns[0];
-            return moduleHeader.getGuidValue();
-        }
-
-        return null;
-    }
-
-    /**
-     retrieve Protocol for specified usage
-
-     @param     usage   Protocol usage
-
-     @returns   Protocol objects list   if elements are found at the known xpath
-     @returns   null                    if nothing is there
-     **/
-    public static ProtocolsDocument.Protocols.Protocol[] getProtocolArray(String usage) {
-        String[] xPath;
-
-        if (usage == null || usage.equals("")) {
-            xPath = new String[] {"/Protocol"};
-        } else {
-            xPath = new String[] {"/Protocol[@Usage='" + usage + "']"};
-        }
-
-        XmlObject[] returns = get("Protocols", xPath);
-        if (returns != null && returns.length > 0) {
-            return (ProtocolsDocument.Protocols.Protocol[]) returns;
-        }
-
-        return null;
-    }
-
-    /**
-     Retrieve ProtocolNotify for specified usage
-    
-     @param     usage   ProtocolNotify usage
-
-     @returns   ProtocolNotify objects list     if elements are found at the known xpath
-     @returns   null                            if nothing is there
-     **/
-    public static ProtocolsDocument.Protocols.ProtocolNotify[] getProtocolNotifyArray(String usage) {
-        String[] xPath;
-
-        if (usage == null || usage.equals("")) {
-            xPath = new String[] {"/ProtocolNotify"};
-        } else {
-            xPath = new String[] {"/ProtocolNotify[@Usage='" + usage + "']"};
-        }
-
-        XmlObject[] returns = get("Protocols", xPath);
-        if (returns != null && returns.length > 0) {
-            return (ProtocolsDocument.Protocols.ProtocolNotify[]) returns;
-        }
-
-        return null;
-    }
-
-    /**
-     Retrieve ModuleUnloadImage names
-
-     @returns   ModuleUnloadImage name list     if elements are found at the known xpath
-     @returns   null                            if nothing is there
-     **/
+     * Retrieve ModuleUnloadImage names
+     * 
+     * @returns ModuleUnloadImage name list if elements are found at the known
+     *          xpath
+     * @returns null if nothing is there
+     */
     public static String[] getModuleUnloadImageArray() {
         String[] xPath = new String[] { "/Extern/ModuleUnloadImage" };
 
-        XmlObject[] returns = get("Externs", xPath);
+        Object[] returns = get("Externs", xPath);
         if (returns != null && returns.length > 0) {
             String[] stringArray = new String[returns.length];
-            XmlNormalizedString[] doc = (XmlNormalizedString[])returns;
+            XmlNormalizedString[] doc = (XmlNormalizedString[]) returns;
 
             for (int i = 0; i < returns.length; ++i) {
                 stringArray[i] = doc[i].getStringValue();
@@ -599,15 +803,15 @@ public class SurfaceAreaQuery {
     }
 
     /**
-     Retrieve Extern
-
-     @returns   Extern objects list     if elements are found at the known xpath
-     @returns   null                    if nothing is there
-     **/
+     * Retrieve Extern
+     * 
+     * @returns Extern objects list if elements are found at the known xpath
+     * @returns null if nothing is there
+     */
     public static ExternsDocument.Externs.Extern[] getExternArray() {
         String[] xPath = new String[] { "/Extern" };
 
-        XmlObject[] returns = get("Externs", xPath);
+        Object[] returns = get("Externs", xPath);
         if (returns != null && returns.length > 0) {
             return (ExternsDocument.Externs.Extern[]) returns;
         }
@@ -616,504 +820,1069 @@ public class SurfaceAreaQuery {
     }
 
     /**
-     Retrieve Ppi information
-
-     @param     usage   Ppi usage
-
-     @returns   Ppi objects list        if elements are found at the known xpath
-     @returns   null                    if nothing is there
-     **/
-    public static PPIsDocument.PPIs.Ppi[] getPpiArray(String usage) {
+     * Retrieve PpiNotify for specified arch
+     * 
+     * @param arch
+     *            PpiNotify arch
+     * 
+     * @returns String[] if elements are found at the known xpath
+     * @returns String[0] if nothing is there
+     */
+    public static String[] getPpiNotifyArray(String arch) {
         String[] xPath;
 
-        if (usage == null || usage.equals("")) {
-            xPath = new String[] { "/Ppi" };
+        if (arch == null || arch.equals("")) {
+            return new String[0];
         } else {
-            xPath = new String[] { "/Ppi[@Usage='" + usage + "']" };
+            xPath = new String[] { "/PpiNotify[@SupArchList='" + arch + "']" };
         }
 
-        XmlObject[] returns = get("PPIs", xPath);
-        if (returns != null && returns.length > 0) {
-            return (PPIsDocument.PPIs.Ppi[])returns;
+        Object[] returns = get("PPIs", xPath);
+        if (returns == null) {
+            return new String[0];
         }
 
-        return null;
+        String[] ppiNotifyList = new String[returns.length];
+        for (int i = 0; i < returns.length; i++) {
+            ppiNotifyList[i] = ((PPIsDocument.PPIs.PpiNotify) returns[i]).getPpiNotifyCName();
+        }
+
+        return ppiNotifyList;
     }
 
     /**
-     Retrive PpiNotify information
-    
-     @param usage
+     * Retrieve PpiNotify for specified usage and arch
+     * 
+     * @param arch
+     *            PpiNotify arch usage PpiNotify usage
+     * 
+     * 
+     * @returns String[] if elements are found at the known xpath
+     * @returns String[0] if nothing is there
+     */
+    public static String[] getPpiNotifyArray(String arch, String usage) {
 
-     @returns   PpiNotify objects list  if elements are found at the known xpath
-     @returns   null                    if nothing is there
-     **/
-    public static PPIsDocument.PPIs.PpiNotify[] getPpiNotifyArray(String usage) {
         String[] xPath;
+        String usageXpath;
+        String archXpath;
 
-        if (usage == null || usage.equals("")) {
-            xPath = new String[] { "/PpiNotify" };
+        if (arch == null || arch.equals("")) {
+            return new String[0];
         } else {
-            xPath = new String[] { "/PpiNotify[@Usage='" + usage + "']" };
-        }
-
-        XmlObject[] returns = get("PPIs", xPath);
-        if (returns != null && returns.length > 0) {
-            return (PPIsDocument.PPIs.PpiNotify[])returns;
-        }
-
-        return null;
-    }
-
-    /**
-     Retrieve GuidEntry information for specified usage
-
-     @param     usage   GuidEntry usage
-
-     @returns   GuidEntry objects list  if elements are found at the known xpath
-     @returns   null                    if nothing is there
-     **/
-    public static GuidsDocument.Guids.GuidEntry[] getGuidEntryArray(String usage) {
-        String[] xPath;
-
-        if (usage == null || usage.equals("")) {
-            xPath = new String[] { "/GuidEntry" };
-        } else {
-            xPath = new String[] { "/GuidEntry[@Usage='" + usage + "']" };
-        }
-
-        XmlObject[] returns = get("Guids", xPath);
-        if (returns != null && returns.length > 0) {
-            return (GuidsDocument.Guids.GuidEntry[])returns;
-        }
-
-        return null;
-    }
-
-    /**
-     Retrieve Library instance information
-
-     @param     arch    Architecture name
-     @param     usage   Library instance usage
-
-     @returns   library instance name list  if elements are found at the known xpath
-     @returns   null                        if nothing is there
-     **/
-    public static List<String> getLibraryInstance(String arch, String usage) {
-        String[] xPath;
-        String   archAttribute = "";
-        String   usageAttribute = "";
-
-        if ((arch != null) || (!arch.equals(""))) {
-            archAttribute = "[@ArchType='ALL' or @ArchType='" + arch + "']";
-        }
-        
-        if ((usage != null) || (!usage.equals(""))) {
-            // if no Usage attribute specified, default to ALWAYS_CONSUMED
-            if (usage.equals(LibraryUsage.ALWAYS_CONSUMED.toString())) {
-                usageAttribute = "[not(@Usage) or @Usage='" + usage + "']";
+            archXpath = "/PpiNotify[@SupArchList='" + arch + "']";
+            if (usage != null && !usage.equals("")) {
+                usageXpath = "/PpiNotify[@Usage='" + arch + "']";
+                xPath = new String[] { archXpath, usageXpath };
             } else {
-                usageAttribute = "[@Usage='" + usage + "']";
-            }
-        }
-        
-        xPath = new String[] {
-                "/Library" + archAttribute, //usageAttribute,
-                "/Library[not(@SupArchList) or @SupArchList='" + arch + "']",
-                "/Arch" + archAttribute + "/Library" + usageAttribute
-                };
-
-        XmlObject[] returns = get("Libraries", xPath);
-        if (returns == null || returns.length == 0) {
-            return null;
-        }
-        
-        List<String> instances = new ArrayList<String>();
-        for (int i = 0; i < returns.length; ++i) {
-            if (returns[i] instanceof LibrariesDocument.Libraries.Library) {
-                LibrariesDocument.Libraries.Library lib = (LibrariesDocument.Libraries.Library)returns[i];
-                instances.add(lib.getStringValue());
-            } else if (returns[i] instanceof LibrariesDocument.Libraries.Arch.Library) {
-                LibrariesDocument.Libraries.Arch.Library lib = (LibrariesDocument.Libraries.Arch.Library)returns[i];
-                instances.add(lib.getStringValue());
+                return getProtocolNotifyArray(arch);
             }
         }
 
-        return instances;
+        Object[] returns = get("PPIs", xPath);
+        if (returns == null) {
+            return new String[0];
+        }
+
+        String[] ppiNotifyList = new String[returns.length];
+
+        for (int i = 0; i < returns.length; i++) {
+            ppiNotifyList[i] = ((PPIsDocument.PPIs.PpiNotify) returns[i]).getPpiNotifyCName();
+        }
+        return ppiNotifyList;
     }
 
-    ///
-    /// This method is used for retrieving the elements information which has 
-    /// CName sub-element
-    ///
+    /**
+     * Retrieve Ppi for specified arch
+     * 
+     * @param arch
+     *            Ppi arch
+     * 
+     * @returns String[] if elements are found at the known xpath
+     * @returns String[0] if nothing is there
+     */
+    public static String[] getPpiArray(String arch) {
+        String[] xPath;
+
+        if (arch == null || arch.equals("")) {
+            return new String[0];
+        } else {
+            xPath = new String[] { "/Ppi[@SupArchList='" + arch + "']" };
+        }
+
+        Object[] returns = get("PPIs", xPath);
+        if (returns == null) {
+            return new String[0];
+        }
+
+        String[] ppiList = new String[returns.length];
+        for (int i = 0; i < returns.length; i++) {
+            ppiList[i] = ((PPIsDocument.PPIs.Ppi) returns[i]).getPpiCName();
+        }
+        return ppiList;
+    }
+
+    /**
+     * Retrieve PpiNotify for specified usage and arch
+     * 
+     * @param arch
+     *            PpiNotify arch usage PpiNotify usage
+     * 
+     * 
+     * @returns String[] if elements are found at the known xpath
+     * @returns String[0] if nothing is there
+     */
+    public static String[] getPpiArray(String arch, String usage) {
+
+        String[] xPath;
+        String usageXpath;
+        String archXpath;
+
+        if (arch == null || arch.equals("")) {
+            return new String[0];
+        } else {
+            archXpath = "/Ppi[@SupArchList='" + arch + "']";
+            if (usage != null && !usage.equals("")) {
+                usageXpath = "/Ppi[@Usage='" + arch + "']";
+                xPath = new String[] { archXpath, usageXpath };
+            } else {
+                return getProtocolNotifyArray(arch);
+            }
+        }
+
+        Object[] returns = get("PPIs", xPath);
+        if (returns == null) {
+            return new String[0];
+        }
+
+        String[] ppiList = new String[returns.length];
+
+        for (int i = 0; i < returns.length; i++) {
+            ppiList[i] = ((PPIsDocument.PPIs.Ppi) returns[i]).getPpiCName();
+        }
+        return ppiList;
+    }
+
+    /**
+     * Retrieve GuidEntry information for specified usage
+     * 
+     * @param arch
+     *            GuidEntry arch
+     * 
+     * @returns GuidEntry objects list if elements are found at the known xpath
+     * @returns null if nothing is there
+     */
+    public static String[] getGuidEntryArray(String arch) {
+        String[] xPath;
+
+        if (arch == null || arch.equals("")) {
+            xPath = new String[] { "/GuidName" };
+        } else {
+            xPath = new String[] { "/GuidName[@SupArchList='" + arch + "']" };
+        }
+
+        Object[] returns = get("Guids", xPath);
+        if (returns == null) {
+            return new String[0];
+        }
+        String[] guidList = new String[returns.length];
+        for (int i = 0; i < returns.length; i++) {
+            guidList[i] = ((GuidsDocument.Guids.GuidCNames) returns[i]).getGuidCName();
+        }
+        return guidList;
+
+    }
+
+    /**
+     * Retrieve GuidEntry information for specified usage
+     * 
+     * @param arch
+     *            GuidEntry arch usage GuidEntry usage
+     * 
+     * @returns GuidEntry objects list if elements are found at the known xpath
+     * @returns null if nothing is there
+     */
+    public static String[] getGuidEntryArray(String arch, String usage) {
+        String[] xPath;
+        String archXpath;
+        String usageXpath;
+
+        if (arch == null || arch.equals("")) {
+            return new String[0];
+        } else {
+            archXpath = "/GuidEntry[@SupArchList='" + arch + "']";
+            if (usage != null && !usage.equals("")) {
+                usageXpath = "/GuidEntry[@Usage='" + arch + "']";
+                xPath = new String[] { archXpath, usageXpath };
+            } else {
+                return getProtocolNotifyArray(arch);
+            }
+        }
+
+        Object[] returns = get("Guids", xPath);
+        if (returns == null) {
+            return new String[0];
+        }
+
+        String[] guidList = new String[returns.length];
+
+        for (int i = 0; i < returns.length; i++) {
+            guidList[i] = ((GuidsDocument.Guids.GuidCNames) returns[i]).getGuidCName();
+        }
+        return guidList;
+    }
+
+    /**
+     * Retrieve Library instance information
+     * 
+     * @param arch
+     *            Architecture name
+     * @param usage
+     *            Library instance usage
+     * 
+     * @returns library instance name list if elements are found at the known
+     *          xpath
+     * @returns null if nothing is there
+     */
+    public static ModuleIdentification[] getLibraryInstance(String arch) {
+        String[] xPath;
+        String saGuid = null;
+        String saVersion = null;
+        String pkgGuid = null;
+        String pkgVersion = null;
+
+        if (arch == null || arch.equalsIgnoreCase("")) {
+            xPath = new String[] { "/Instance" };
+        } else {
+            xPath = new String[] { "/Instance[not(@SupArchList) or @SupArchList='"
+                    + arch + "']" };
+        }
+
+        Object[] returns = get("Libraries", xPath);
+        if (returns == null || returns.length == 0) {
+            return new ModuleIdentification[0];
+        }
+
+        ModuleIdentification[] saIdList = new ModuleIdentification[returns.length];
+        for (int i = 0; i < returns.length; i++) {
+            LibrariesDocument.Libraries.Instance library = (LibrariesDocument.Libraries.Instance) returns[i];
+            saGuid = library.getModuleGuid();
+            saVersion = library.getModuleVersion();
+
+            pkgGuid = library.getPackageGuid();
+            pkgVersion = library.getPackageVersion();
+
+            ModuleIdentification saId = new ModuleIdentification(null, saGuid,
+                    saVersion);
+            PackageIdentification pkgId = new PackageIdentification(null,
+                    pkgGuid, pkgVersion);
+            saId.setPackage(pkgId);
+
+            saIdList[i] = saId;
+
+        }
+        return saIdList;
+    }
+
+    // /
+    // / This method is used for retrieving the elements information which has
+    // / CName sub-element
+    // /
     private static String[] getCNames(String from, String xPath[]) {
-        XmlObject[] returns = get(from, xPath);
+        Object[] returns = get(from, xPath);
         if (returns == null || returns.length == 0) {
             return null;
         }
-        
+
         String[] strings = new String[returns.length];
         for (int i = 0; i < returns.length; ++i) {
-            strings[i] = ((CName)returns[i]).getStringValue(); 
+            // TBD
+            // strings[i] = ((CName) returns[i]).getStringValue();
         }
-        
-        return strings;            
-    }
-    
-    /**
-     Retrive library's constructor name
 
-     @returns   constructor name list   if elements are found at the known xpath
-     @returns   null                    if nothing is there
-     **/
+        return strings;
+    }
+
+    /**
+     * Retrive library's constructor name
+     * 
+     * @returns constructor name list if elements are found at the known xpath
+     * @returns null if nothing is there
+     */
     public static String getLibConstructorName() {
-        String[] xPath = new String[] {"/Extern/Constructor"};
+        String[] xPath = new String[] { "/Extern/Constructor" };
 
-        XmlObject[] returns = get("Externs", xPath);
+        Object[] returns = get("Externs", xPath);
         if (returns != null && returns.length > 0) {
-            CName constructor = (CName)returns[0]; 
-            return constructor.getStringValue();            
+            // CName constructor = (CName) returns[0];
+            // return constructor.getStringValue();
         }
 
         return null;
     }
 
     /**
-     Retrive library's destructor name
-
-     @returns   destructor name list    if elements are found at the known xpath
-     @returns   null                    if nothing is there
-     **/
+     * Retrive library's destructor name
+     * 
+     * @returns destructor name list if elements are found at the known xpath
+     * @returns null if nothing is there
+     */
     public static String getLibDestructorName() {
-        String[] xPath = new String[] {"/Extern/Destructor"};
+        String[] xPath = new String[] { "/Extern/Destructor" };
 
-        XmlObject[] returns = get("Externs", xPath);
+        Object[] returns = get("Externs", xPath);
         if (returns != null && returns.length > 0) {
-            CName destructor = (CName)returns[0]; 
-            return destructor.getStringValue();            
+            // CName destructor = (CName) returns[0];
+            // return destructor.getStringValue();
         }
 
         return null;
     }
-    
-    /**
-     Retrive DriverBinding names
 
-     @returns   DriverBinding name list if elements are found at the known xpath
-     @returns   null                    if nothing is there
-     **/
+    /**
+     * Retrive DriverBinding names
+     * 
+     * @returns DriverBinding name list if elements are found at the known xpath
+     * @returns null if nothing is there
+     */
     public static String[] getDriverBindingArray() {
-        String[] xPath = new String[] {"/Extern/DriverBinding"};
+        String[] xPath = new String[] { "/Extern/DriverBinding" };
         return getCNames("Externs", xPath);
     }
-    
-    /**
-     Retrive ComponentName names
 
-     @returns   ComponentName name list if elements are found at the known xpath
-     @returns   null                    if nothing is there
-     **/
+    /**
+     * Retrive ComponentName names
+     * 
+     * @returns ComponentName name list if elements are found at the known xpath
+     * @returns null if nothing is there
+     */
     public static String[] getComponentNameArray() {
-        String[] xPath = new String[] {"/Extern/ComponentName"};
+        String[] xPath = new String[] { "/Extern/ComponentName" };
         return getCNames("Externs", xPath);
     }
-    
-    /**
-     Retrive DriverConfig names
 
-     @returns   DriverConfig name list  if elements are found at the known xpath
-     @returns   null                    if nothing is there
-     **/
+    /**
+     * Retrive DriverConfig names
+     * 
+     * @returns DriverConfig name list if elements are found at the known xpath
+     * @returns null if nothing is there
+     */
     public static String[] getDriverConfigArray() {
-        String[] xPath = new String[] {"/Extern/DriverConfig"};
+        String[] xPath = new String[] { "/Extern/DriverConfig" };
         return getCNames("Externs", xPath);
     }
-    
-    /**
-     Retrive DriverDiag names
 
-     @returns   DriverDiag name list    if elements are found at the known xpath
-     @returns   null                    if nothing is there
-     **/
+    /**
+     * Retrive DriverDiag names
+     * 
+     * @returns DriverDiag name list if elements are found at the known xpath
+     * @returns null if nothing is there
+     */
     public static String[] getDriverDiagArray() {
-        String[] xPath = new String[] {"/Extern/DriverDiag"};
+        String[] xPath = new String[] { "/Extern/DriverDiag" };
         return getCNames("Externs", xPath);
     }
 
     /**
-     Retrive SetVirtualAddressMapCallBack names
-
-     @returns   SetVirtualAddressMapCallBack name list  
-                                        if elements are found at the known xpath
-     @returns   null                    if nothing is there
-     **/
+     * Retrive SetVirtualAddressMapCallBack names
+     * 
+     * @returns SetVirtualAddressMapCallBack name list if elements are found at
+     *          the known xpath
+     * @returns null if nothing is there
+     */
     public static String[] getSetVirtualAddressMapCallBackArray() {
-        String[] xPath = new String[] {"/Extern/SetVirtualAddressMapCallBack"};
+        String[] xPath = new String[] { "/Extern/SetVirtualAddressMapCallBack" };
         return getCNames("Externs", xPath);
     }
-    
-    /**
-     Retrive ExitBootServicesCallBack names
 
-     @returns   ExitBootServicesCallBack name list  
-                                        if elements are found at the known xpath
-     @returns   null                    if nothing is there
-     **/
+    /**
+     * Retrive ExitBootServicesCallBack names
+     * 
+     * @returns ExitBootServicesCallBack name list if elements are found at the
+     *          known xpath
+     * @returns null if nothing is there
+     */
     public static String[] getExitBootServicesCallBackArray() {
-        String[] xPath = new String[] {"/Extern/ExitBootServicesCallBack"};
+        String[] xPath = new String[] { "/Extern/ExitBootServicesCallBack" };
         return getCNames("Externs", xPath);
     }
 
     /**
-     Retrieve module surface area file information
+     * Retrieve module surface area file information
+     * 
+     * @returns ModuleSA objects list if elements are found at the known xpath
+     * @returns Empty ModuleSA list if nothing is there
+     */
+    public static Map<FpdModuleIdentification, Map<String, XmlObject>> getFpdModules() {
+        String[] xPath = new String[] { "/FrameworkModules/ModuleSA" };
+        Object[] result = get("PlatformSurfaceArea", xPath);
+        String arch = null;
+        String fvBinding = null;
+        String saGuid = null;
+        String saVersion = null;
+        String pkgGuid = null;
+        String pkgVersion = null;
 
-     @returns   ModuleSA objects list   if elements are found at the known xpath
-     @returns   Empty ModuleSA list     if nothing is there
-     **/
-    public static ModuleSADocument.ModuleSA[] getFpdModules() {
-        String[] xPath = new String[] { "/TianoImage/*/ModuleSA" };
+        Map<FpdModuleIdentification, Map<String, XmlObject>> fpdModuleMap = new LinkedHashMap<FpdModuleIdentification, Map<String, XmlObject>>();
 
-        XmlObject[] result = get("FrameworkPlatformDescription", xPath);
         if (result == null) {
-            xPath = new String[] { "/FrameworkModules/*/ModuleSA" };
-            result = get("FrameworkPlatformDescription", xPath);
-            if (result != null) {
-                return (ModuleSADocument.ModuleSA[]) result;
+            return fpdModuleMap;
+        }
+
+        for (int i = 0; i < result.length; i++) {
+            //
+            // Get Fpd SA Module element node and add to ObjectMap.
+            //
+            Map<String, XmlObject> ObjectMap = new HashMap<String, XmlObject>();
+            ModuleSADocument.ModuleSA moduleSA = (ModuleSADocument.ModuleSA) result[i];
+            if (((ModuleSADocument.ModuleSA) result[i]).getLibraries() != null) {
+                ObjectMap.put("Libraries", moduleSA.getLibraries());
+            }
+            if (((ModuleSADocument.ModuleSA) result[i]).getPcdBuildDefinition() != null) {
+                ObjectMap.put("PcdBuildDefinition", moduleSA
+                        .getPcdBuildDefinition());
+            }
+            if (((ModuleSADocument.ModuleSA) result[i])
+                    .getModuleSaBuildOptions() != null) {
+                ObjectMap.put("ModuleSaBuildOptions", moduleSA
+                        .getModuleSaBuildOptions());
             }
-            return new ModuleSADocument.ModuleSA[0];
-        }
 
-        return (ModuleSADocument.ModuleSA[]) result;
+            //
+            // Get Fpd SA Module attribute and create FpdMoudleIdentification.
+            //
+            arch = moduleSA.getSupArchList().toString();
+
+            // TBD
+            fvBinding = null;
+            saVersion = ((ModuleSADocument.ModuleSA) result[i])
+                    .getModuleVersion();
+
+            saGuid = moduleSA.getModuleGuid();
+            pkgGuid = moduleSA.getPackageGuid();
+            pkgVersion = moduleSA.getPackageVersion();
+
+            //
+            // Create Module Identification which have class member of package
+            // identification.
+            //
+            PackageIdentification pkgId = new PackageIdentification(null,
+                    pkgGuid, pkgVersion);
+            ModuleIdentification saId = new ModuleIdentification(null, saGuid,
+                    saVersion);
+
+            saId.setPackage(pkgId);
+
+            //
+            // Create FpdModule Identification which have class member of module
+            // identification
+            //
+            if (arch != null) {
+                String[] archList = arch.split(" ");
+                for (int j = 0; j < archList.length; j++) {
+                    FpdModuleIdentification fpdSaId = new FpdModuleIdentification(saId,    archList[j]);
+        
+                    if (fvBinding != null) {
+                        fpdSaId.setFvBinding(fvBinding);
+                    }
+        
+                    //
+                    // Put element to Map<FpdModuleIdentification, Map<String,
+                    // Object>>.
+                    //
+                    fpdModuleMap.put(fpdSaId, ObjectMap);
+                }
+            }
+        }
+        return fpdModuleMap;
     }
 
     /**
-     Retrieve all <ModuleSA> documents from FPD file.
+     * Retrieve valid image names
+     * 
+     * @returns valid iamges name list if elements are found at the known xpath
+     * @returns empty list if nothing is there
+     */
+    public static String[] getFpdValidImageNames() {
+        String[] xPath = new String[] { "/Flash/FvImages/FvImage[@Type='ImageName']/FvImageNames" };
 
-     @returns   ModuleSA objects list   if elements are found at the known xpath
-     @returns   Empty ModuleSA list     if nothing is there
-     **/
-    public static ModuleSADocument.ModuleSA[] getFpdModuleSAs() {
-        String[] xPath = new String[] { "/FrameworkModules/*/ModuleSA" };
-
-        XmlObject[] result = get("FrameworkPlatformDescription", xPath);
-        if (result != null) {
-            return (ModuleSADocument.ModuleSA[]) result;
-        }
-        return new ModuleSADocument.ModuleSA[0];
-    }
-
-    /**
-     Retrieve variables for FV images
-
-     @returns   name/value list        if elements are found at the known xpath
-     @returns   empty list             if nothing is there
-     **/
-    public static String[][] getFpdGlobalVariable() {
-        String[] xPath = new String[] { "/Flash/FvImages/NameValue" };
-
-        XmlObject[] queryResult = get("FrameworkPlatformDescription", xPath);
-        if (queryResult == null) {
-            return new String[0][];
-        }
-
-        String[][] result = new String[queryResult.length][2];
-        for (int i = 0; i < queryResult.length; i++){
-            result[i][0] = ((NameValueDocument.NameValue)queryResult[i]).getName();
-            result[i][1] = ((NameValueDocument.NameValue)queryResult[i]).getValue();
-        }
-
-        return result;
-    }
-    
-    /**
-     Retrieve valid image names
-
-     @returns   valid iamges name list  if elements are found at the known xpath
-     @returns   empty list              if nothing is there
-     **/
-    public static String[] getFpdValidImageNames(){
-        String[] xPath = new String[] { "/Flash/FvImages/FvImage[@Type='ValidImageNames']/FvImageNames" };
-
-        XmlObject[] queryResult = get("FrameworkPlatformDescription", xPath);
+        Object[] queryResult = get("PlatformSurfaceArea", xPath);
         if (queryResult == null) {
             return new String[0];
         }
 
         String[] result = new String[queryResult.length];
-        for (int i = 0; i < queryResult.length; i++){
-            result[i] = ((XmlString)queryResult[i]).getStringValue();
+        for (int i = 0; i < queryResult.length; i++) {
+            result[i] = ((XmlString) queryResult[i]).getStringValue();
         }
 
         return result;
     }
+    
+    public static XmlObject getFpdUserExtension() {
+        String[] xPath = new String[] { "" };
+
+        Object[] queryResult = get("PlatformSurfaceArea", xPath);
+        if (queryResult == null) {
+            return null;
+        }
+        return null;
+    }
 
     /**
-     Retrieve FV image option information
+     * Retrieve FV image option information
+     * 
+     * @param fvName
+     *            FV image name
+     * 
+     * @returns option name/value list if elements are found at the known xpath
+     * @returns empty list if nothing is there
+     */
+    public static String[][] getFpdOptions(String fvName) {
+           String[] xPath = new String[] { "/Flash/FvImages/FvImage[@Type='Options' and ./FvImageNames='"
+                      + fvName.toUpperCase() + "']/FvImageOptions" };
+           Object[] queryResult = get("PlatformSurfaceArea", xPath);
+           if (queryResult == null) {
+                 return new String[0][];
+           }
+           ArrayList<String[]> list = new ArrayList<String[]>();
+           for (int i = 0; i < queryResult.length; i++) {
+               FvImagesDocument.FvImages.FvImage.FvImageOptions item = (FvImagesDocument.FvImages.FvImage.FvImageOptions) queryResult[i];
+               List<FvImagesDocument.FvImages.FvImage.FvImageOptions.NameValue> namevalues = item
+               .getNameValueList();
+               Iterator iter = namevalues.iterator();
+               while (iter.hasNext()) {
+                   FvImagesDocument.FvImages.FvImage.FvImageOptions.NameValue nvItem = (FvImagesDocument.FvImages.FvImage.FvImageOptions.NameValue) iter
+                   .next();
+                   list.add(new String[] { nvItem.getName(), nvItem.getValue() });
+               }
+           }
+          String[][] result = new String[list.size()][2];
+          for (int i = 0; i < list.size(); i++) {
+              result[i][0] = list.get(i)[0];
+              result[i][1] = list.get(i)[1];
+          }
+          return result;
 
-     @param fvName  FV image name
+    }
 
-     @returns   option name/value list if elements are found at the known xpath
-     @returns   empty list             if nothing is there
-     **/
-    public static String[][] getFpdOptions(String fvName){
-        String[] xPath = new String[] {"/Flash/FvImages/FvImageName[@Name='" + fvName.toUpperCase() + "']/FvImageOptions/NameValue" };
+    public static XmlObject getFpdBuildOptions() {
+        String[] xPath = new String[] { "/BuildOptions" };
 
-        XmlObject[] queryResult = get("FrameworkPlatformDescription", xPath);
+        Object[] queryResult = get("PlatformSurfaceArea", xPath);
+
+        if (queryResult == null || queryResult.length == 0) {
+            return null;
+        }
+        return (XmlObject)queryResult[0];
+    }
+
+    public static PlatformIdentification getFpdHeader() {
+        String[] xPath = new String[] { "/PlatformHeader" };
+
+        Object[] returns = get("PlatformSurfaceArea", xPath);
+
+        if (returns == null || returns.length == 0) {
+            return null;
+        }
+        PlatformHeaderDocument.PlatformHeader header = (PlatformHeaderDocument.PlatformHeader) returns[0];
+
+        String name = header.getPlatformName();
+
+        String guid = header.getGuidValue();
+
+        String version = header.getVersion();
+
+        return new PlatformIdentification(name, guid, version);
+    }
+
+    /**
+     * Retrieve FV image attributes information
+     * 
+     * @param fvName
+     *            FV image name
+     * 
+     * @returns attribute name/value list if elements are found at the known
+     *          xpath
+     * @returns empty list if nothing is there
+     */
+    public static String[][] getFpdAttributes(String fvName) {
+        String[] xPath = new String[] { "/Flash/FvImages/FvImage[@Type='Attributes' and ./FvImageNames='"
+                         + fvName.toUpperCase() + "']/FvImageOptions" };
+        Object[] queryResult = get("PlatformSurfaceArea", xPath);
+        if (queryResult == null) {
+             return new String[0][];
+        }
+        ArrayList<String[]> list = new ArrayList<String[]>();
+        for (int i = 0; i < queryResult.length; i++) {
+            
+            FvImagesDocument.FvImages.FvImage.FvImageOptions item = (FvImagesDocument.FvImages.FvImage.FvImageOptions) queryResult[i];
+            List<FvImagesDocument.FvImages.FvImage.FvImageOptions.NameValue> namevalues = item.getNameValueList();
+            Iterator iter = namevalues.iterator();
+            while (iter.hasNext()) {
+                FvImagesDocument.FvImages.FvImage.FvImageOptions.NameValue nvItem = (FvImagesDocument.FvImages.FvImage.FvImageOptions.NameValue) iter
+                 .next();
+                 list.add(new String[] { nvItem.getName(), nvItem.getValue() });
+            }
+        }
+       String[][] result = new String[list.size()][2];
+       for (int i = 0; i < list.size(); i++) {
+             result[i][0] = list.get(i)[0];
+             result[i][1] = list.get(i)[1];
+       }
+       return result;
+    }
+
+    /**
+     * Retrieve flash definition file name
+     * 
+     * @returns file name if elements are found at the known xpath
+     * @returns null if nothing is there
+     */
+    public static String getFlashDefinitionFile() {
+        String[] xPath = new String[] { "/PlatformDefinitions/FlashDeviceDefinitions/FlashDefinitionFile" };
+
+        Object[] queryResult = get("PlatformSurfaceArea", xPath);
+        if (queryResult == null || queryResult.length == 0) {
+            return null;
+        }
+
+        FileNameConvention filename = (FileNameConvention) queryResult[queryResult.length - 1];
+        return filename.getStringValue();
+    }
+
+    public static String[][] getFpdGlobalVariable() {
+        String[] xPath = new String[] { "/Flash/FvImages/NameValue" };
+        Object[] queryResult = get("PlatformSurfaceArea", xPath);
         if (queryResult == null) {
             return new String[0][];
         }
 
         String[][] result = new String[queryResult.length][2];
-        for (int i = 0; i < queryResult.length; i++){
-            result[i][0] = ((NameValueDocument.NameValue)queryResult[i]).getName();
-            result[i][1] = ((NameValueDocument.NameValue)queryResult[i]).getValue();
-        }
-
-        return result;
-    }
-    
-    /**
-     Retrieve FV image attributes information
-
-     @param     fvName  FV image name
-
-     @returns   attribute name/value list   if elements are found at the known xpath
-     @returns   empty list                  if nothing is there
-     **/
-    public static String[][] getFpdAttributes(String fvName){
-        String[] xPath = new String[] {"/Flash/FvImages/FvImage[@Type='Attributes' and ./FvImageNames='" + fvName.toUpperCase() + "']/FvImageOptions" };
-
-        XmlObject[] queryResult = get("FrameworkPlatformDescription", xPath);
-        if (queryResult == null) {
-            return new String[0][];
-        }
-
-        ArrayList<String[]> list = new ArrayList<String[]>();
-        for (int i = 0 ; i < queryResult.length; i++){
-            FvImageOptionsDocument.FvImageOptions item = (FvImageOptionsDocument.FvImageOptions)queryResult[i];
-
-            List<NameValueDocument.NameValue> namevalues = item.getNameValueList();
-            Iterator iter = namevalues.iterator();
-            while (iter.hasNext()) {
-                NameValueDocument.NameValue nvItem = (NameValueDocument.NameValue)iter.next();
-                list.add(new String[]{nvItem.getName(), nvItem.getValue()});
-            }
-
-            List<String> enables = item.getEnableList();
-            iter = enables.iterator();
-            while (iter.hasNext()) {
-                String enableItem = (String)iter.next();
-                list.add(new String[]{enableItem, "TRUE"});
-            }
-
-            List<String> disables = item.getDisableList();
-            iter = disables.iterator();
-            while (iter.hasNext()) {
-                String disableItem = (String)iter.next();
-                list.add(new String[]{disableItem, "FALSE"});
-            }
-        }
-
-        String[][] result = new String[list.size()][2];
-        for (int i = 0; i < list.size(); i++){
-            result[i][0] = list.get(i)[0];
-            result[i][1] = list.get(i)[1];
-        }
-
-        return result;
-    }
-    
-    /**
-     Retrieve flash definition file name
-
-     @returns   file name               if elements are found at the known xpath
-     @returns   null                    if nothing is there
-     **/
-    public static String getFlashDefinitionFile(){
-        String[] xPath = new String[] {"/Flash/FlashDefinitionFile" };
-
-        XmlObject[] queryResult = get("FrameworkPlatformDescription", xPath);
-        if (queryResult == null || queryResult.length == 0) {
-            return null;
-        }
-
-        FileNameConvention filename = (FileNameConvention)queryResult[queryResult.length - 1];
-        return filename.getStringValue();
-    }
-    
-    /**
-     Retrieve FV image component options
-
-     @param     fvName  FV image name
-
-     @returns   name/value pairs list   if elements are found at the known xpath
-     @returns   empty list              if nothing is there
-     **/
-    public static String[][] getFpdComponents(String fvName){
-        String[] xPath = new String[] {"/Flash/FvImages/FvImage[@Type='Components' and ./FvImageNames='" + fvName.toUpperCase() + "']/FvImageOptions" };
-
-        XmlObject[] queryResult = get("FrameworkPlatformDescription", xPath);
-        if (queryResult == null) {
-            return new String[0][];
-        }
-
-        ArrayList<String[]> list = new ArrayList<String[]>();
-        for (int i = 0 ; i < queryResult.length; i++){
-            FvImageOptionsDocument.FvImageOptions item = (FvImageOptionsDocument.FvImageOptions)queryResult[i];
-
-            List<NameValueDocument.NameValue> namevalues = item.getNameValueList();
-            Iterator iter = namevalues.iterator();
-            while (iter.hasNext()) {
-                NameValueDocument.NameValue nvItem = (NameValueDocument.NameValue)iter.next();
-                list.add(new String[]{nvItem.getName(), nvItem.getValue()});
-            }
-
-            List<String> enables = item.getEnableList();
-            iter = enables.iterator();
-            while (iter.hasNext()) {
-                String enableItem = (String)iter.next();
-                list.add(new String[]{enableItem, "TRUE"});
-            }
-
-            List<String> disables = item.getDisableList();
-            iter = disables.iterator();
-            while (iter.hasNext()) {
-                String disableItem = (String)iter.next();
-                list.add(new String[]{disableItem, "FALSE"});
-            }
-        }
-
-        String[][] result = new String[list.size()][2];
-        for (int i = 0; i < list.size(); i++){
-            result[i][0] = list.get(i)[0];
-            result[i][1] = list.get(i)[1];
-        }
-
-        return result;
-    }
-    
-    /**
-       Get name array of PCD in a module. In one module, token space
-       is same, and token name should not be conflicted.
-       
-       @return String[]
-    **/
-    public static String[] getModulePcdEntryNameArray() {
-        PcdCoded.PcdEntry[] pcdEntries  = null;
-        String[]            results;
-        int                 index;
-        String[]            xPath       = new String[] {"/PcdEntry"};
-        XmlObject[]         returns     = get ("PcdCoded", xPath);
-        if (returns == null) {
-            return null;
-        }
-
-        pcdEntries = (PcdCoded.PcdEntry[])returns;
-        results    = new String[pcdEntries.length];
         
-        for (index = 0; index < pcdEntries.length; index ++) {
-            results[index] = pcdEntries[index].getCName();
+        for (int i = 0; i < queryResult.length; i++) {
+            FvImagesDocument.FvImages.NameValue item = (FvImagesDocument.FvImages.NameValue)queryResult[i];
+            result[i][0] = item.getName();
+            result[i][1] = item.getValue();
         }
-        return results;
+        return result;   
+    }
+    
+    /**
+     * Retrieve FV image component options
+     * 
+     * @param fvName
+     *            FV image name
+     * 
+     * @returns name/value pairs list if elements are found at the known xpath
+     * @returns empty list if nothing is there
+     */
+    public static String[][] getFpdComponents(String fvName) {
+        String[] xPath = new String[] { "/Flash/FvImages/FvImage[@Type='Components' and ./FvImageNames='"+ fvName.toUpperCase() + "']/FvImageOptions" };
+        Object[] queryResult = get("PlatformSurfaceArea", xPath);
+        if (queryResult == null) {
+            return new String[0][];
+        }
+
+        ArrayList<String[]> list = new ArrayList<String[]>();
+        for (int i = 0; i < queryResult.length; i++) {
+        FvImagesDocument.FvImages.FvImage.FvImageOptions item = (FvImagesDocument.FvImages.FvImage.FvImageOptions) queryResult[i];
+        List<FvImagesDocument.FvImages.FvImage.FvImageOptions.NameValue> namevalues = item.getNameValueList();
+        Iterator iter = namevalues.iterator();
+        while (iter.hasNext()) {
+            FvImagesDocument.FvImages.FvImage.FvImageOptions.NameValue nvItem = (FvImagesDocument.FvImages.FvImage.FvImageOptions.NameValue) iter
+                        .next();
+                   list.add(new String[] { nvItem.getName(), nvItem.getValue() });
+                 }
+                }
+         String[][] result = new String[list.size()][2];
+                for (int i = 0; i < list.size(); i++) {
+               result[i][0] = list.get(i)[0];
+             result[i][1] = list.get(i)[1];
+        }
+            return result;  
+    }
+
+    /**
+     * Retrieve PCD tokens
+     * 
+     * @returns CName/ItemType pairs list if elements are found at the known
+     *          xpath
+     * @returns null if nothing is there
+     */
+    public static String[][] getPcdTokenArray() {
+        String[] xPath = new String[] { "/PcdData" };
+
+        Object[] returns = get("PCDs", xPath);
+        if (returns == null || returns.length == 0) {
+            return null;
+        }
+
+        // PcdCoded.PcdData[] pcds = (PcdCoded.PcdData[]) returns;
+        // String[][] result = new String[pcds.length][2];
+        // for (int i = 0; i < returns.length; ++i) {
+        // if (pcds[i].getItemType() != null) {
+        // result[i][1] = pcds[i].getItemType().toString();
+        // } else {
+        // result[i][1] = null;
+        // }
+        // result[i][0] = pcds[i].getCName();
+        // }
+
+        return null;
+    }
+
+    /**
+     * Get the PcdToken array from module's surface area document. The array
+     * should contains following data:
+     * <p>
+     * -------------------------------------------------------------------
+     * </p>
+     * <p>
+     * CName | ItemType | TokenspaceName | DefaultValue | Usage | HelpText
+     * </p>
+     * <p>
+     * -------------------------------------------------------------------
+     * </p>
+     * <p>
+     * Note: Until new schema applying, now we can only get CName, ItemType,
+     * </p>
+     * 
+     * @return 2-array table contains all information of PCD token retrieved
+     *         from MSA.
+     */
+    public static Object[][] etModulePCDTokenArray() {
+        return null;
+        // int index;
+        // Object[][] result;
+        // PCDs.PcdData[] pcds;
+        // String[] xPath = new String[] { "/PcdData" };
+        // Object[] returns = get("PCDs", xPath);
+        //
+        // if ((returns == null) || (returns.length == 0)) {
+        // return null;
+        // }
+        //
+        // pcds = (PCDs.PcdData[]) returns;
+        // result = new Object[pcds.length][6];
+        // for (index = 0; index < pcds.length; index++) {
+        // //
+        // // Get CName
+        // //
+        // result[index][0] = pcds[index].getCName();
+        // //
+        // // Get ItemType: FEATURE_FLAG, FIXED_AT_BUILD, PATCHABLE_IN_MODLE,
+        // // DYNAMIC, DYNAMIC_EX
+        // //
+        // if (pcds[index].getItemType() != null) {
+        // result[index][1] = pcds[index].getItemType().toString();
+        // } else {
+        // result[index][1] = null;
+        // }
+        //
+        // //
+        // // BUGBUG: following field can *not* be got from current MSA until
+        // // schema changed.
+        // //
+        // // result [index][2] = pcds[index].getTokenSpaceName();
+        // result[index][2] = null;
+        // result[index][3] = pcds[index].getDefaultValue();
+        // // result [index][4] = pcds[index].getUsage ();
+        // result[index][4] = null;
+        // // result [index][5] = pcds[index].getHelpText ();
+        // result[index][5] = null;
+        // }
+        // return result;
+    }
+
+    /**
+     * Retrieve MAS header
+     * 
+     * @return
+     * @return
+     */
+    public static ModuleIdentification getMsaHeader() {
+        String[] xPath = new String[] { "/" };
+        Object[] returns = get("MsaHeader", xPath);
+
+        if (returns == null || returns.length == 0) {
+            return null;
+        }
+
+        MsaHeader msaHeader = (MsaHeader) returns[0];
+        //
+        // Get BaseName, ModuleType, GuidValue, Version
+        // which in MsaHeader.
+        //
+        String name = msaHeader.getModuleName();
+        String moduleType = msaHeader.getModuleType().toString();
+        String guid = msaHeader.getGuidValue();
+        String version = msaHeader.getVersion();
+
+        ModuleIdentification moduleId = new ModuleIdentification(name, guid,
+                version);
+
+        moduleId.setModuleType(moduleType);
+
+        return moduleId;
+    }
+
+    /**
+     * Retrieve Extern Specification
+     * 
+     * @param
+     * 
+     * @return String[] If have specification element in the <extern> String[0]
+     *         If no specification element in the <extern>
+     * 
+     */
+
+    public static String[] getExternSpecificaiton() {
+        String[] xPath = new String[] { "/Specification" };
+
+        Object[] queryResult = get("Externs", xPath);
+        if (queryResult == null) {
+            return new String[0];
+        }
+
+        String[] specificationList = new String[queryResult.length];
+        for (int i = 0; i < queryResult.length; i++) {
+            // specificationList[i] = ((SpecificationDocument.Specification)
+            // queryResult[i])
+            // .getStringValue();
+        }
+        return specificationList;
+    }
+
+    /**
+     * Retreive MsaFile which in SPD
+     * 
+     * @param
+     * @return String[][3] The string sequence is ModuleName, ModuleGuid,
+     *         ModuleVersion, MsaFile String[0][] If no msafile in SPD
+     */
+    public static String[] getSpdMsaFile() {
+        String[] xPath = new String[] { "/MsaFiles" };
+
+        Object[] returns = get("PackageSurfaceArea", xPath);
+        if (returns == null) {
+            return new String[0];
+        }
+
+        List<String> filenameList = ((MsaFilesDocument.MsaFiles) returns[0])
+                .getFilenameList();
+        return filenameList.toArray(new String[filenameList.size()]);
+    }
+
+    /**
+     * Reteive
+     */
+    public static Map<String, String[]> getSpdLibraryClasses() {
+        String[] xPath = new String[] { "/LibraryClassDeclarations/LibraryClass" };
+
+        Object[] returns = get("PackageSurfaceArea", xPath);
+
+        //
+        // Create Map, Key - LibraryClass, String[] - LibraryClass Header file.
+        //
+        Map<String, String[]> libClassHeaderMap = new HashMap<String, String[]>();
+
+        if (returns == null) {
+            return libClassHeaderMap;
+        }
+
+        for (int i = 0; i < returns.length; i++) {
+            LibraryClassDeclarationsDocument.LibraryClassDeclarations.LibraryClass library = (LibraryClassDeclarationsDocument.LibraryClassDeclarations.LibraryClass) returns[i];
+            libClassHeaderMap.put(library.getName(), new String[] { library
+                    .getIncludeHeader() });
+        }
+        return libClassHeaderMap;
+    }
+
+    /**
+     * Reteive
+     */
+    public static Map<String, String> getSpdPackageHeaderFiles() {
+        String[] xPath = new String[] { "/PackageHeaders/IncludePkgHeader" };
+
+        Object[] returns = get("PackageSurfaceArea", xPath);
+
+        //
+        // Create Map, Key - ModuleType, String - PackageInclude Header file.
+        //
+        Map<String, String> packageIncludeMap = new HashMap<String, String>();
+
+        if (returns == null) {
+            return packageIncludeMap;
+        }
+//        GlobalData.log.info("" + returns[0].getClass().getName());
+        for (int i = 0; i < returns.length; i++) {
+            PackageHeadersDocument.PackageHeaders.IncludePkgHeader includeHeader = (PackageHeadersDocument.PackageHeaders.IncludePkgHeader) returns[i];
+            packageIncludeMap.put(includeHeader.getModuleType().toString(),
+                    includeHeader.getStringValue());
+        }
+        return packageIncludeMap;
+    }
+
+    public static PackageIdentification getSpdHeader() {
+        String[] xPath = new String[] { "/SpdHeader" };
+
+        Object[] returns = get("PackageSurfaceArea", xPath);
+
+        if (returns == null || returns.length == 0) {
+            return null;
+        }
+
+        SpdHeaderDocument.SpdHeader header = (SpdHeaderDocument.SpdHeader) returns[0];
+
+        String name = header.getPackageName();
+
+        String guid = header.getGuidValue();
+
+        String version = header.getVersion();
+
+        return new PackageIdentification(name, guid, version);
+    }
+
+    /**
+     * Reteive
+     */
+    public static Map<String, String[]> getSpdGuid() {
+        String[] xPath = new String[] { "/GuidDeclarations/Entry" };
+
+        Object[] returns = get("PackageSurfaceArea", xPath);
+
+        //
+        // Create Map, Key - GuidName, String[] - C_NAME & GUID value.
+        //
+        Map<String, String[]> guidDeclMap = new HashMap<String, String[]>();
+        if (returns == null) {
+            return guidDeclMap;
+        }
+
+        for (int i = 0; i < returns.length; i++) {
+            GuidDeclarationsDocument.GuidDeclarations.Entry entry = (GuidDeclarationsDocument.GuidDeclarations.Entry) returns[i];
+            String[] guidPair = new String[2];
+            guidPair[0] = entry.getCName();
+            guidPair[1] = entry.getGuidValue();
+            guidDeclMap.put(entry.getName(), guidPair);
+        }
+        return guidDeclMap;
+    }
+
+    /**
+     * Reteive
+     */
+    public static Map<String, String[]> getSpdProtocol() {
+        String[] xPath = new String[] { "/ProtocolDeclarations/Entry" };
+
+        Object[] returns = get("PackageSurfaceArea", xPath);
+
+        //
+        // Create Map, Key - protocolName, String[] - C_NAME & GUID value.
+        //
+        Map<String, String[]> protoclMap = new HashMap<String, String[]>();
+
+        if (returns == null) {
+            return protoclMap;
+        }
+
+        for (int i = 0; i < returns.length; i++) {
+            ProtocolDeclarationsDocument.ProtocolDeclarations.Entry entry = (ProtocolDeclarationsDocument.ProtocolDeclarations.Entry) returns[i];
+            String[] protocolPair = new String[2];
+
+            protocolPair[0] = entry.getCName();
+            protocolPair[1] = entry.getGuidValue();
+            protoclMap.put(entry.getName(), protocolPair);
+        }
+        return protoclMap;
+    }
+
+    /**
+     * getSpdPpi() Retrieve the SPD PPI Entry
+     * 
+     * @param
+     * @return Map<String, String[2]> if get the PPI entry from SPD. Key - PPI
+     *         Name String[0] - PPI CNAME String[1] - PPI Guid Null if no PPI
+     *         entry in SPD.
+     */
+    public static Map<String, String[]> getSpdPpi() {
+        String[] xPath = new String[] { "/PpiDeclarations/Entry" };
+
+        Object[] returns = get("PackageSurfaceArea", xPath);
+
+        //
+        // Create Map, Key - protocolName, String[] - C_NAME & GUID value.
+        //
+        Map<String, String[]> ppiMap = new HashMap<String, String[]>();
+
+        if (returns == null) {
+            return ppiMap;
+        }
+
+        for (int i = 0; i < returns.length; i++) {
+            PpiDeclarationsDocument.PpiDeclarations.Entry entry = (PpiDeclarationsDocument.PpiDeclarations.Entry) returns[i];
+            String[] ppiPair = new String[2];
+            ppiPair[0] = entry.getCName();
+            ppiPair[1] = entry.getGuidValue();
+            ppiMap.put(entry.getName(), ppiPair);
+        }
+        return ppiMap;
+    }
+
+    /**
+     * getToolChainFamily
+     * 
+     * This function is to retrieve ToolChainFamily attribute of FPD
+     * <BuildOptions>
+     * 
+     * @param
+     * @return toolChainFamily If find toolChainFamily attribute in
+     *         <BuildOptions> Null If don't have toolChainFamily in
+     *         <BuildOptions>.
+     */
+    public String getToolChainFamily() {
+        String toolChainFamily;
+        String[] xPath = new String[] { "/BuildOptions" };
+
+        Object[] result = get("PlatformSurfaceArea", xPath);
+        if (result == null) {
+            return null;
+        }
+        // toolChainFamily =
+        // ((BuildOptionsDocument.BuildOptions)result[0]).getToolChainFamilies();
+        // return toolChainFamily;
+        return null;
+    }
+
+    /**
+     * Retrieve module Guid string
+     * 
+     * @returns GUILD string if elements are found at the known xpath
+     * @returns null if nothing is there
+     */
+    public static String getModuleGuid() {
+        String[] xPath = new String[] { "" };
+
+        Object[] returns = get("MsaHeader", xPath);
+        if (returns != null && returns.length > 0) {
+            String guid = ((MsaHeaderDocument.MsaHeader) returns[0])
+                    .getGuidValue();
+            return guid;
+        }
+
+        return null;
+    }
+
+    //
+    // For new Pcd
+    //
+    public static ModuleSADocument.ModuleSA[] getFpdModuleSAs() {
+        String[] xPath = new String[] { "/FrameworkModules/ModuleSA" };
+        Object[] result = get("PlatformSurfaceArea", xPath);
+        if (result != null) {
+            return (ModuleSADocument.ModuleSA[]) result;
+        }
+        return new ModuleSADocument.ModuleSA[0];
+
     }
 }
diff --git a/Tools/Source/GenBuild/org/tianocore/build/fpd/FpdModuleIdentification.java b/Tools/Source/GenBuild/org/tianocore/build/id/FpdModuleIdentification.java
similarity index 57%
rename from Tools/Source/GenBuild/org/tianocore/build/fpd/FpdModuleIdentification.java
rename to Tools/Source/GenBuild/org/tianocore/build/id/FpdModuleIdentification.java
index 261cf58a35..add968f6db 100644
--- a/Tools/Source/GenBuild/org/tianocore/build/fpd/FpdModuleIdentification.java
+++ b/Tools/Source/GenBuild/org/tianocore/build/id/FpdModuleIdentification.java
@@ -11,7 +11,8 @@ http://opensource.org/licenses/bsd-license.php
 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 **/
-package org.tianocore.build.fpd;
+package org.tianocore.build.id;
+
 
 /**
   This class is used to identify a module with BaseName, GUID, Version, PackageName
@@ -23,30 +24,27 @@ public class FpdModuleIdentification {
     
     private String arch;
     
-    private String fvBinding;
+    private String fvBinding = "NULL"; // Optional
     
-    private String baseName;
+    private String sequence = "0"; // Optional
     
-    private String packageName;
+    private ModuleIdentification module;
     
-    private String guid;
+    private String target; // Optional
     
-    private String version;
+    private String toolchain; // Optional
     
-    private String sequence;
-    
-    /**
-      
-      @param baseName the base name of the module
-      @param guid the GUID of the module
-      @param arch the ARCH of the module
-    **/
-    public FpdModuleIdentification(String baseName, String guid, String arch){
-        this.baseName = baseName;
-        this.guid = guid;
+    public FpdModuleIdentification(String arch, String fvBinding, String sequence, ModuleIdentification module){
         this.arch = arch;
+        this.fvBinding = fvBinding;
+        this.sequence = sequence;
+        this.module = module;
     }
     
+    public FpdModuleIdentification(ModuleIdentification module, String arch){
+        this.arch = arch;
+        this.module = module;
+    }
     /**
       Override java.lang.Object#equals. 
       
@@ -58,20 +56,15 @@ public class FpdModuleIdentification {
     public boolean equals(Object obj) {
         if (obj instanceof FpdModuleIdentification) {
             FpdModuleIdentification moduleIdObj = (FpdModuleIdentification)obj;
-            if ( baseName.equalsIgnoreCase(moduleIdObj.baseName) && arch.equalsIgnoreCase(moduleIdObj.arch)) {
+            if ( module.equals(moduleIdObj.module) && arch.equalsIgnoreCase(moduleIdObj.arch)) {
                 return true;
             }
-            // TBD
             return false;
         }
         else {
-            return super.equals(obj);
+            return false;
         }
     }
-    
-    public void setArch(String arch) {
-        this.arch = arch;
-    }
 
     public void setFvBinding(String fvBinding) {
         this.fvBinding = fvBinding;
@@ -82,50 +75,34 @@ public class FpdModuleIdentification {
     }
 
     public String toString(){
-        return arch + ":" + guid + "_" + baseName;
-    }
-
-    public void setBaseName(String baseName) {
-        this.baseName = baseName;
-    }
-
-    public void setGuid(String guid) {
-        this.guid = guid;
-    }
-
-    public void setPackageName(String packageName) {
-        this.packageName = packageName;
-    }
-
-    public void setVersion(String version) {
-        this.version = version;
-    }
-
-    public String getArch() {
-        return arch;
-    }
-
-    public String getBaseName() {
-        return baseName;
+        return arch + ":" + module;
     }
 
     public String getFvBinding() {
         return fvBinding;
     }
 
-    public String getGuid() {
-        return guid;
-    }
-
-    public String getPackageName() {
-        return packageName;
-    }
-
     public String getSequence() {
         return sequence;
     }
 
-    public String getVersion() {
-        return version;
+    public ModuleIdentification getModule() {
+        return module;
+    }
+
+    public void setModule(ModuleIdentification module) {
+        this.module = module;
+    }
+
+    public String getArch() {
+        return arch;
+    }
+
+    public void setArch(String arch) {
+        this.arch = arch;
+    }
+    
+    public int hashCode(){
+        return module.hashCode();
     }
 }
diff --git a/Tools/Source/GenBuild/org/tianocore/build/id/Identification.java b/Tools/Source/GenBuild/org/tianocore/build/id/Identification.java
new file mode 100644
index 0000000000..abf5c1bade
--- /dev/null
+++ b/Tools/Source/GenBuild/org/tianocore/build/id/Identification.java
@@ -0,0 +1,74 @@
+package org.tianocore.build.id;
+
+import org.tianocore.build.global.GlobalData;
+
+public class Identification {
+
+    String name;
+    
+    String guid;
+    
+    String version;
+    
+    String type; // Optional
+    
+    Identification(String name, String guid, String version){
+        this.name = name;
+        this.guid = guid;
+        this.version = version;
+    }
+    
+    Identification(String guid, String version){
+        this.guid = guid;
+        this.version = version;
+    }
+    
+    public boolean equals(Object obj) {
+        if (obj instanceof Identification) {
+            Identification id = (Identification)obj;
+            if ( guid.equalsIgnoreCase(id.guid)) {
+                if (version == null || id.version == null) {
+                    return true;
+                }
+                else if (version.trim().equalsIgnoreCase("") || id.version.trim().equalsIgnoreCase("")){
+                    return true;
+                }
+                else if (version.equalsIgnoreCase(id.version)) {
+                    return true;
+                }
+            }
+            return false;
+        }
+        else {
+            return super.equals(obj);
+        }
+    }
+    
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public void setGuid(String guid) {
+        this.guid = guid;
+    }
+
+    public void setVersion(String version) {
+        this.version = version;
+    }
+
+    public String getGuid() {
+        return guid;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public String getVersion() {
+        return version;
+    }
+    
+    public int hashCode(){
+        return guid.toLowerCase().hashCode();
+    }
+}
diff --git a/Tools/Source/GenBuild/org/tianocore/build/id/ModuleIdentification.java b/Tools/Source/GenBuild/org/tianocore/build/id/ModuleIdentification.java
new file mode 100644
index 0000000000..5681251ec5
--- /dev/null
+++ b/Tools/Source/GenBuild/org/tianocore/build/id/ModuleIdentification.java
@@ -0,0 +1,124 @@
+package org.tianocore.build.id;
+
+import java.io.File;
+
+import org.tianocore.build.global.GlobalData;
+
+public class ModuleIdentification extends Identification {
+    
+    private PackageIdentification packageId;
+    
+    private File msaFile;
+    
+    private String moduleType;
+    
+    private boolean isLibrary = false;
+
+    public ModuleIdentification(String guid, String version){
+        super(guid, version);
+    }
+    
+    public ModuleIdentification(String guid, String version, PackageIdentification packageId){
+        super(guid, version);
+        this.packageId = packageId;
+    }
+    
+    public ModuleIdentification(String name, String guid, String version){
+        super(name, guid, version);
+    }
+    
+    public ModuleIdentification(String name, String guid, String version, PackageIdentification packageId){
+        super(name, guid, version);
+        this.packageId = packageId;
+    }
+    
+    public boolean isLibrary() {
+        return isLibrary;
+    }
+
+    public void setLibrary(boolean isLibrary) {
+        this.isLibrary = isLibrary;
+    }
+
+    public File getMsaFile() {
+        prepareMsaFile();
+        return msaFile;
+    }
+    
+    public String getModuleRelativePath() {
+        prepareMsaFile();
+        if (msaFile.getParent().length() == packageId.getPackageDir().length()) {
+            return ".";
+        }
+        return msaFile.getParent().substring(packageId.getPackageDir().length() + 1);
+    }
+
+    private void prepareMsaFile(){
+        if (msaFile == null) {
+            GlobalData.refreshModuleIdentification(this);
+        }
+    }
+
+    public void setMsaFile(File msaFile) {
+        this.msaFile = msaFile;
+    }
+   
+    public boolean equals(Object obj) {
+        if (obj instanceof ModuleIdentification) {
+            ModuleIdentification id = (ModuleIdentification)obj;
+            if (guid.equalsIgnoreCase(id.getGuid()) && packageId.equals(id.getPackage())) {
+                if (version == null || id.version == null) {
+                    return true;
+                }
+                else if (version.trim().equalsIgnoreCase("") || id.version.trim().equalsIgnoreCase("")){
+                    return true;
+                }
+                else if (version.equalsIgnoreCase(id.version)) {
+                    return true;
+                }
+            }
+            return false;
+        }
+        else {
+            return super.equals(obj);
+        }
+    }
+    
+    public String toString(){
+        if (name == null) {
+            GlobalData.refreshModuleIdentification(this);
+        }
+        if (version == null || version.trim().equalsIgnoreCase("")) {
+            return "Module [" + name + "] in " + packageId;
+        }
+        else {
+            return "Module [" + name + " " + version + "] in " + packageId; 
+        }
+    }
+
+    public void setPackage(PackageIdentification packageId) {
+        this.packageId = packageId;
+    }
+
+    public PackageIdentification getPackage() {
+        return packageId;
+    }
+
+    public String getModuleType() {
+        if (moduleType == null) {
+            GlobalData.refreshModuleIdentification(this);
+        }
+        return moduleType;
+    }
+
+    public void setModuleType(String moduleType) {
+        this.moduleType = moduleType;
+    }
+    
+    public String getName() {
+        if (name == null) {
+            GlobalData.refreshModuleIdentification(this);
+        }
+        return name;
+    }
+}
diff --git a/Tools/Source/GenBuild/org/tianocore/build/id/PackageIdentification.java b/Tools/Source/GenBuild/org/tianocore/build/id/PackageIdentification.java
new file mode 100644
index 0000000000..8d4994dd9b
--- /dev/null
+++ b/Tools/Source/GenBuild/org/tianocore/build/id/PackageIdentification.java
@@ -0,0 +1,73 @@
+package org.tianocore.build.id;
+import java.io.File;
+
+import org.tianocore.build.global.GlobalData;
+
+public class PackageIdentification extends Identification{
+    
+    //
+    // It is optional
+    //
+    private File spdFile;
+    
+    public PackageIdentification(String guid, String version){
+        super(guid, version);
+    }
+    
+    public PackageIdentification(String name, String guid, String version){
+        super(name, guid, version);
+    }
+    
+    public PackageIdentification(String name, String guid, String version, String spdFilename){
+        super(name, guid, version);
+        this.spdFile = new File(spdFilename);
+    }
+    
+    public PackageIdentification(String name, String guid, String version, File spdFile){
+        super(name, guid, version);
+        this.spdFile = spdFile;
+    }
+    
+    public void setSpdFile(File spdFile) {
+        this.spdFile = spdFile;
+    }
+
+    public File getSpdFile() {
+        return spdFile;
+    }
+
+    public String toString(){
+        if (name == null) {
+            GlobalData.refreshPackageIdentification(this);
+        }
+        if (version == null || version.trim().equalsIgnoreCase("")) {
+            return "package [" + name + "]";
+        }
+        else {
+            return "package [" + name + " " + version + "]";
+        }
+    }
+    
+    public String getPackageDir(){
+        prepareSpdFile();
+        return spdFile.getParent();
+    }
+    
+    public String getPackageRelativeDir(){
+        prepareSpdFile();
+        return spdFile.getParent().substring(GlobalData.getWorkspacePath().length() + 1);
+    }
+    
+    private void prepareSpdFile(){
+        if (spdFile == null) {
+            GlobalData.refreshPackageIdentification(this);
+        }
+    }
+    
+    public String getName() {
+        if (name == null) {
+            GlobalData.refreshPackageIdentification(this);
+        }
+        return name;
+    }
+}
diff --git a/Tools/Source/GenBuild/org/tianocore/build/id/PlatformIdentification.java b/Tools/Source/GenBuild/org/tianocore/build/id/PlatformIdentification.java
new file mode 100644
index 0000000000..8ee6cf04f3
--- /dev/null
+++ b/Tools/Source/GenBuild/org/tianocore/build/id/PlatformIdentification.java
@@ -0,0 +1,43 @@
+package org.tianocore.build.id;
+import java.io.File;
+
+import org.tianocore.build.global.GlobalData;
+
+public class PlatformIdentification extends Identification{
+    
+    private File fpdFile;
+    
+    public PlatformIdentification(String guid, String version){
+        super(guid, version);
+    }
+    
+    public PlatformIdentification(String name, String guid, String version){
+        super(name, guid, version);
+    }
+    
+    public PlatformIdentification(String name, String guid, String version, String fpdFilename){
+        super(name, guid, version);
+        this.fpdFile = new File(fpdFilename);
+    }
+    
+    public PlatformIdentification(String name, String guid, String version, File fpdFile){
+        super(name, guid, version);
+        this.fpdFile = fpdFile;
+    }
+    
+    public String toString(){
+        return "Platform " + name + "["+guid+"]";
+    }
+
+    public void setFpdFile(File fpdFile) {
+        this.fpdFile = fpdFile;
+    }
+
+    public File getFpdFile() {
+        return fpdFile;
+    }
+    
+    public String getPlatformRelativeDir(){
+        return fpdFile.getParent().substring(GlobalData.getWorkspacePath().length());
+    }
+}
\ No newline at end of file
diff --git a/Tools/Source/GenBuild/org/tianocore/build/toolchain/ConfigReader.java b/Tools/Source/GenBuild/org/tianocore/build/toolchain/ConfigReader.java
index f48735966e..0472265d39 100644
--- a/Tools/Source/GenBuild/org/tianocore/build/toolchain/ConfigReader.java
+++ b/Tools/Source/GenBuild/org/tianocore/build/toolchain/ConfigReader.java
@@ -14,16 +14,13 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 **/
 package org.tianocore.build.toolchain;
 
+import org.tianocore.build.exception.EdkException;
+
 import java.io.BufferedReader;
 import java.io.File;
 import java.io.FileReader;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Set;
-import java.util.Vector;
-
-import org.apache.tools.ant.BuildException;
+import java.util.ArrayList;
+import java.util.List;
 
 /**
   
@@ -36,6 +33,7 @@ public class ConfigReader {
 
     private static String confPath = ".";
 
+
     /**
       Public construct method. 
     **/
@@ -48,7 +46,7 @@ public class ConfigReader {
       @param filename the config file name like "target.txt"
       @return the variables defined in file
     **/
-    public static synchronized String[][] parse(String filename) {
+    public static synchronized String[][] parse(String filename) throws EdkException {
         return parse(confPath, filename);
     }
 
@@ -62,157 +60,77 @@ public class ConfigReader {
       @throws BuildException
               Config file's format is not valid
     **/
-    public static synchronized String[][] parse(String confPath, String filename) throws BuildException {
+    public static synchronized String[][] parse(String confPath, String filename) throws EdkException {
+        //Map<String, String> map = new TreeMap<String,String>(comparator);
+        List<String> keyList = new ArrayList<String>(256);
+        List<String> valueList = new ArrayList<String>(256);
+
         try {
-            Map<String, String> map = new HashMap<String, String>(20);
             File file = new File(confPath + File.separatorChar + filename);
             FileReader reader = new FileReader(file);
             BufferedReader in = new BufferedReader(reader);
             String str;
+
             while ((str = in.readLine()) != null) {
                 str = str.trim();
                 //
-                // if str is empty line or comments (start with '#')
+                // if str is empty line, comments (start with '#'),
+                // without '=', or start with '='
                 //
-                if (str.equalsIgnoreCase("") || str.startsWith("#")) {
-                    continue;
-                }
-                //
-                // if str without '=' or start with '='
-                //
-                if (str.indexOf('=') <= 0) {
+                int index;
+                if (str.length() == 0 || str.startsWith("#") || 
+                    (index = str.indexOf('=')) <= 0) {
                     continue;
                 }
                 //
                 // look as line "A = B"
                 //
-                int index = str.indexOf('=');
-                String key = str.substring(0, index).trim();
-                String value = str.substring(index + 1).trim();
-                //
-                // if key is existed, then update
-                //
-                if (map.containsKey(key)) {
-                    map.remove(key);
-                }
-                map.put(key, value);
+                keyList.add(str.substring(0, index).trim());
+                valueList.add(str.substring(index + 1).trim());
             }
-            Set keyset = map.keySet();
-            Iterator iter = keyset.iterator();
-            String[][] result = new String[map.size()][2];
-            int i = 0;
-            while (iter.hasNext()) {
-                String key = (String) iter.next();
-                result[i][0] = key;
-                result[i++][1] = (String) map.get(key);
-            }
-            return result;
         } catch (Exception e) {
-            throw new BuildException("Processor file [" + filename + "] error. \n" + e.getMessage());
+            throw new EdkException("Process file [" + filename + "] error. \n" + e.getMessage());
         }
+
+        String[][] definitions = new String[2][keyList.size()];
+        definitions[0] = (String[])keyList.toArray(definitions[0]);
+        definitions[1] = (String[])valueList.toArray(definitions[1]);
+
+        return definitions;
     }
 
-    /**
-      Parse global flags table. The format is like such(global flag name, value, 
-      vendor_arch_cmd, [add flags], [sub flags]): 
-      
-      <pre>
-        # EFI_DEBUG
-        EFI_DEBUG YES MSFT_IA32_ASM    ADD.["/Zi", "/DEBUG"]
-        EFI_DEBUG YES MSFT_IA32_CC     ADD.["/Zi", "/Gm", "/D EFI_DEBUG"] SUB.["/nologo", "/WX"]
-        EFI_DEBUG YES MSFT_IA32_LINK   ADD.["/DEBUG"]
-        EFI_DEBUG YES MSFT_NT32_CC     ADD.["/DEBUG"]
-      </pre>
-     
-      @param confPath the file path of config file
-      @param filename the file name of config file
-      @return the value list
-      @throws BuildException
-              Config file is not valid
-    **/
-    public static synchronized String[][] parseTable(String confPath,
-                    String filename) throws BuildException {
+    public static synchronized ToolChainMap parseToolChainConfig(File ConfigFile) throws EdkException {
+        ToolChainMap map = new ToolChainMap();
+    
         try {
-            Vector<String[]> vector = new Vector<String[]>(20);
-            File file = new File(confPath + File.separatorChar + filename);
-            FileReader reader = new FileReader(file);
+            FileReader reader = new FileReader(ConfigFile);
             BufferedReader in = new BufferedReader(reader);
             String str;
+
             while ((str = in.readLine()) != null) {
                 str = str.trim();
                 //
-                // if str is empty line or comments (start with '#')
+                // if str is empty line, comments (start with '#'),
+                // without '=', or start with '='
                 //
-                if (str.equalsIgnoreCase("") || str.startsWith("#")) {
+                int index;
+                if (str.length() == 0 || str.startsWith("#") || 
+                    (index = str.indexOf('=')) <= 0) {
                     continue;
                 }
-                String[] item = new String[5];
-                for(int i=0; i < item.length; i++){
-                    item[i] = "";
-                }
                 //
-                // EFI_DEBUG YES MSFT_IA32_ASM    ADD.["/Zi", "/DEBUG"]
-                // FLAGS: EFI_DEBUG
+                // look as line "A = B"
                 //
-                int index = str.indexOf(" ");
-                item[0] = str.substring(0, index);
-                str = str.substring(index + 1).trim();
-                //
-                // Setting: YES
-                //
-                index = str.indexOf(" ");
-                item[1] = str.substring(0, index);
-                str = str.substring(index + 1).trim();
-                //
-                // Vendor_Arch_Commandtype: MSFT_IA32_ASM
-                //
-                index = str.indexOf(" ");
-                item[2] = str.substring(0, index);
-                str = str.substring(index + 1).trim();
-                //
-                // Add or/and Sub
-                //
-                if (str.startsWith("ADD.")) {
-                    index = str.indexOf("]");
-                    if ( index > 0){
-                        item[3] = str.substring(5, index);
-                        str = str.substring(index + 1).trim();
-                    }
-                }
-                else if(str.startsWith("SUB.")){
-                    index = str.indexOf("]");
-                    if ( index > 0){
-                        item[4] = str.substring(5, index);
-                        str = str.substring(index + 1).trim();
-                    }
-                }
-                else {
-                    throw new BuildException("File [" + filename + "] never conform to Global Flags Table format.");
-                }
-                
-                if (str.startsWith("ADD.")) {
-                    index = str.indexOf("]");
-                    if ( index > 0){
-                        item[3] = str.substring(5, index);
-                        str = str.substring(index + 1).trim();
-                    }
-                }
-                else if(str.startsWith("SUB.")){
-                    index = str.indexOf("]");
-                    if ( index > 0){
-                        item[4] = str.substring(5, index);
-                        str = str.substring(index + 1).trim();
-                    }
-                }
-                vector.addElement(item);
+                String key = str.substring(0, index).trim().toUpperCase();
+                String value = str.substring(index + 1).trim();
+                map.put(key, value);
             }
-            String[][] result = new String[vector.size()][5];
-            for(int i=0; i < vector.size(); i++){
-                result[i] = (String[])vector.get(i);
-            }
-            return result;
         } catch (Exception e) {
-            throw new BuildException("Processor file [" + filename + "] error. \n" + e.getMessage());
+            throw new EdkException("Process file [" + ConfigFile.getAbsolutePath() + "] error. \n" + e.getMessage());
         }
+
+        return map;
     }
 }
+
+
diff --git a/Tools/Source/GenBuild/org/tianocore/build/toolchain/ToolChainAttribute.java b/Tools/Source/GenBuild/org/tianocore/build/toolchain/ToolChainAttribute.java
new file mode 100644
index 0000000000..7fa0bb3f7c
--- /dev/null
+++ b/Tools/Source/GenBuild/org/tianocore/build/toolchain/ToolChainAttribute.java
@@ -0,0 +1,37 @@
+package org.tianocore.build.toolchain;
+/**
+* TODO: Add class description
+* 
+* @author   jwang36
+*/
+public class ToolChainAttribute {
+    private static int nextValue = 0;
+
+    //"NAME", "PATH", "DPATH", "SPATH", "EXT", "FAMILY", "FLAGS"
+    public final static ToolChainAttribute NAME = new ToolChainAttribute("NAME");
+    public final static ToolChainAttribute PATH = new ToolChainAttribute("PATH");
+    public final static ToolChainAttribute DPATH = new ToolChainAttribute("DPATH");
+    public final static ToolChainAttribute SPATH = new ToolChainAttribute("SPATH");
+    public final static ToolChainAttribute EXT = new ToolChainAttribute("EXT");
+    public final static ToolChainAttribute FAMILY = new ToolChainAttribute("FAMILY");
+    public final static ToolChainAttribute FLAGS = new ToolChainAttribute("FLAGS");
+
+    private final String name;
+    public final int value = nextValue++;
+
+    /**
+     * Default constructor
+     */
+    private ToolChainAttribute(String name) {
+        this.name = name;
+    }
+
+    public String toString() {
+        return name;
+    }
+}
+
+
+
+
+
diff --git a/Tools/Source/GenBuild/org/tianocore/build/toolchain/ToolChainConfig.java b/Tools/Source/GenBuild/org/tianocore/build/toolchain/ToolChainConfig.java
new file mode 100644
index 0000000000..05d2124346
--- /dev/null
+++ b/Tools/Source/GenBuild/org/tianocore/build/toolchain/ToolChainConfig.java
@@ -0,0 +1,142 @@
+/** @file
+  ToolChainFactory class.
+  
+  ToolChainFactory class parse all config files and get STD_FLAGS, GLOBAL_FLAGS,
+  and also command path + name.
+  
+Copyright (c) 2006, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution.  The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+package org.tianocore.build.toolchain;
+
+import org.apache.tools.ant.BuildException;
+import org.tianocore.build.exception.EdkException;
+import org.tianocore.build.toolchain.ToolChainKey;
+import org.tianocore.build.toolchain.ToolChainMap;
+
+import java.io.File;
+import java.util.Iterator;
+import java.util.Set;
+
+
+/**
+  This class parse all config files and get STD_FLAGS, GLOBAL_FLAGS, and also 
+  command path + name.
+  
+  @since GenBuild 1.0
+**/
+public class ToolChainConfig {
+    ///
+    /// list of attributes
+    ///
+    private final static String[] attributes = {"NAME", "PATH", "DPATH", "SPATH", "EXT", "FAMILY", "FLAGS"};
+    ///
+    /// elements which are used to define one type of tool
+    ///
+    private final static String[] elements = {"TARGET", "TOOLCHAIN", "ARCH", "CMD", "ATTRIBUTE" };
+
+    ///
+    /// tool chain definitions
+    ///
+    private ToolChainMap config = null;
+    private ToolChainInfo info = new ToolChainInfo();
+
+    /**
+      Public construct method.
+    **/
+    public ToolChainConfig () {
+    }
+
+    /**
+      Public construct method.
+      
+      @param confPath the path of config files
+      @param toolChainTag TOOL_CHAIN name
+    **/
+    public ToolChainConfig (File toolChainFile) {
+        try {
+            config = ConfigReader.parseToolChainConfig(toolChainFile);
+            parseToolChainDefKey(config.keySet());
+        }
+        catch (EdkException ex) {
+            throw new BuildException(ex.getMessage());
+        }
+    }
+
+    /// 
+    /// 
+    /// 
+    public void parseToolChainDefKey (Set<ToolChainKey> toolChainDefKey) {
+        Iterator it = toolChainDefKey.iterator();
+        while (it.hasNext()) {
+            ToolChainKey key = (ToolChainKey)it.next();
+            String[] keySet = key.getKeySet();
+            info.addTargets(keySet[0]);
+            info.addTagnames(keySet[1]);
+            info.addArchs(keySet[2]);
+            info.addCommands(keySet[1], keySet[3]);
+        }
+    }
+
+/**
+     public Set<String> getTargets() {
+         return info.getTargets();
+     }
+
+     public Set<String> getTagnames() {
+         return info.getTagnames();
+     }
+
+     public Set<String> getArchs() {
+         return info.getArchs();
+     }
+
+     public Set<String> getCommands() {
+         return info.getCommands();
+     }
+
+     public String getValue(String key) {
+         return config.get(key);
+     }
+
+     public String getValue(String[] keySet) {
+         return config.get(keySet);
+     }
+
+     public String getValue(ToolChainKey key) {
+         return config.get(key);
+     }
+ **/
+
+    public ToolChainMap getConfig() {
+        return config;
+    }
+
+    public ToolChainInfo getConfigInfo() {
+        return info;
+    }
+
+    ///
+    /// override toString()
+    /// 
+    public String toString() {
+        StringBuffer ts = new StringBuffer(10240);
+
+        Iterator it = config.keySet().iterator();
+        while (it.hasNext()) {
+            ToolChainKey key = (ToolChainKey)it.next();
+            ts.append(key.toString() + " = ");
+//            ts.append(config.get(key) + "\n");
+        }
+
+        return ts.toString();
+    }
+}
+
diff --git a/Tools/Source/GenBuild/org/tianocore/build/toolchain/ToolChainElement.java b/Tools/Source/GenBuild/org/tianocore/build/toolchain/ToolChainElement.java
new file mode 100644
index 0000000000..a383cc8a84
--- /dev/null
+++ b/Tools/Source/GenBuild/org/tianocore/build/toolchain/ToolChainElement.java
@@ -0,0 +1,35 @@
+package org.tianocore.build.toolchain;
+/**
+* TODO: Add class description
+* 
+* @author   jwang36
+*/
+public class ToolChainElement {
+    private static int nextValue = 0;
+
+    //"NAME", "PATH", "DPATH", "SPATH", "EXT", "FAMILY", "FLAGS"
+    public final static ToolChainElement TARGET = new ToolChainElement("TARGET");
+    public final static ToolChainElement TOOLCHAIN = new ToolChainElement("TOOLCHAIN");
+    public final static ToolChainElement ARCH = new ToolChainElement("ARCH");
+    public final static ToolChainElement TOOLCODE = new ToolChainElement("TOOLCODE");
+    public final static ToolChainElement ATTRIBUTE = new ToolChainElement("ATTRIBUTE");
+
+    private final String name;
+    public final int value = nextValue++;
+
+    /**
+     * Default constructor
+     */
+    private ToolChainElement(String name) {
+        this.name = name;
+    }
+
+    public String toString() {
+        return name;
+    }
+}
+
+
+
+
+
diff --git a/Tools/Source/GenBuild/org/tianocore/build/toolchain/ToolChainFactory.java b/Tools/Source/GenBuild/org/tianocore/build/toolchain/ToolChainFactory.java
deleted file mode 100644
index ce8e93fbfb..0000000000
--- a/Tools/Source/GenBuild/org/tianocore/build/toolchain/ToolChainFactory.java
+++ /dev/null
@@ -1,529 +0,0 @@
-/** @file
-  ToolChainFactory class.
-  
-  ToolChainFactory class parse all config files and get STD_FLAGS, GLOBAL_FLAGS,
-  and also command path + name.
-  
-Copyright (c) 2006, Intel Corporation
-All rights reserved. This program and the accompanying materials
-are licensed and made available under the terms and conditions of the BSD License
-which accompanies this distribution.  The full text of the license may be found at
-http://opensource.org/licenses/bsd-license.php
-
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
-
-**/
-package org.tianocore.build.toolchain;
-
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Set;
-import java.util.StringTokenizer;
-import java.io.File;
-
-import org.apache.tools.ant.Project;
-
-
-/**
-  This class parse all config files and get STD_FLAGS, GLOBAL_FLAGS, and also 
-  command path + name.
-  
-  @since GenBuild 1.0
-**/
-public class ToolChainFactory {
-    ///
-    /// list of Arch: EBC, ARM, IA32, X64, IPF, PPC
-    ///
-    public final static String[] arch = { "EBC", "ARM", "IA32", "X64", "IPF",
-                    "PPC"};
-
-    ///
-    /// list of OS: Linux, Windows
-    ///
-    public final static String[] os = { "WINDOWS", "LINUX" };
-
-    ///
-    /// list of Command Type: CC, LIB, LINK, ASL, ASM, ASMLINK, PP
-    ///
-    public final static String[] commandType = { "CC", "LIB", "LINK", "ASL",
-                    "ASM", "ASMLINK", "PP" };
-
-    ///
-    /// default command name for every command
-    ///
-    public final static String[][] defaultCmdName = { { "CC", "cl" },
-                    { "LIB", "lib" }, { "LINK", "link" }, { "ASL", "iasl" },
-                    { "ASM", "ml" }, { "ASMLINK", "link" }, { "PP", "cl" } };
-
-    private String confPath = ".";
-    
-    private String toolChainName = "MSFT";
-
-    private String sTargetFilename = "target.txt";
-
-    private String sToolsdefFilename = "tools_def.txt";
-
-    private String sWorkspaceTarget = "WORKSPACE_TARGET";
-
-    private String sTargetArch = "TARGET_ARCH";
-
-    private HashMap<String,String[][]> filesMap = new HashMap<String,String[][]>();
-    
-    private HashMap<String,String> globalFlagsMap = new HashMap<String,String>();
-    
-    private String[][] globalFlagTable;
-    
-    private String currentTarget = "RELEASE";
-
-    ///
-    /// toolchain array list all results by parsing config files
-    ///
-    public static String[][] toolchain = null;
-    
-    /**
-      Public construct method.
-    **/
-    public ToolChainFactory () {
-    }
-
-    /**
-      Public construct method.
-      
-      @param project current ANT Project.
-    **/
-    public ToolChainFactory (Project project) {
-        this.confPath = project.replaceProperties("${WORKSPACE_DIR}" + File.separatorChar + "Tools" + File.separatorChar + "Conf");
-    }
-    
-    /**
-      Public construct method.
-      
-      @param confPath the path of config files
-      @param toolChainName TOOL_CHAIN name
-    **/
-    public ToolChainFactory (String confPath, String toolChainName) {
-        this.confPath = confPath;
-        //
-        // If set tool used the set one, otherwise use default one.
-        // toolChain used to define open tools define txt file.
-        //
-        if (toolChainName != null && toolChainName.length() > 0){
-            this.toolChainName = toolChainName;
-        }
-    }
-
-    /**
-      Parse all config files, following are the detail steps:
-      
-      <ul>
-        <li>Parse target.txt file. This file define the current build TARGET 
-        and supported ARCH list. </li>
-        <li>Parse tools_def.txt file. This file define every command name, path
-        and vendor. </li>
-        <li>For every supported ARCH and Command Type, find out STD_FLAGS, 
-        GLOBAL_ADD_FLAGS, GLOBAL_SUB_FLAGS. </li>
-      </ul>
-      
-      <p>Note that this method will be called only once during the whole build
-      process. </p>
-    **/
-    public void setupToolChain() {
-        if (toolchain != null) {
-            return ;
-        }
-        Map<String, String> map = new HashMap<String, String>(40);
-        //
-        // parse target.txt
-        //
-        String[][] target = ConfigReader.parse(confPath, sTargetFilename);
-        //
-        // get workspace_target and initialize global flags setting
-        //
-        currentTarget = getValue(sWorkspaceTarget, target);
-        parseGlobalSetting(currentTarget);
-        String[] archList = getArchs(getValue(sTargetArch, target));
-        
-        //
-        // If user write the ${toolChain}_Tools_Def.txt use this one,
-        // otherwise used "tools_def.txt" file.
-        //
-        File tempFile = new File (confPath + File.separator + toolChainName.toLowerCase() + "_tools_def.txt");
-        if (tempFile.exists()){
-            sToolsdefFilename = toolChainName.toLowerCase() + "_tools_def.txt";
-        }
-        
-        System.out.println("Tools definition file is: " + sToolsdefFilename);
-        //
-        // parse tools_def.txt
-        //
-        String[][] tools_def = ConfigReader.parse(confPath, sToolsdefFilename);
-        //
-        // for each arch find all command's path&name and flags
-        //
-        for (int i = 0; i < archList.length; i++) {
-            for (int j = 0; j < commandType.length; j++) {
-                //
-                // Path & Name
-                //
-                map.put(archList[i] + "_" + commandType[j], getAbsoluteCmdPath(
-                                archList[i], commandType[j], tools_def));
-                //
-                // Flags: CMD_STD_FLAGS + CMD_GLOBAL_FLAGS + CMD_PROJ_FLAGS
-                // ARCH_CMD_STD_FLAGS
-                //
-                map.put(archList[i] + "_" + commandType[j] + "_STD_FLAGS",
-                                getStdFlags(archList[i], commandType[j],
-                                                tools_def));
-                //
-                // Flags:ARCH_CMD_VENDOR or ARCH_VENDOR
-                //
-                map.put(archList[i]+ "_"+commandType[j]+"_VENDOR", getVendorFlag(archList[i],
-                        commandType[j], tools_def));
-                //
-                // ARCH_CMD_GLOBAL_FLAGS
-                //
-                String[] globalFlags = getGlobalFlags(archList[i], commandType[j],
-                                tools_def);
-                map.put(archList[i] + "_" + commandType[j] + "_GLOBAL_ADD_FLAGS",
-                                globalFlags[0]);
-                map.put(archList[i] + "_" + commandType[j] + "_GLOBAL_SUB_FLAGS",
-                                globalFlags[1]);
-                //
-                // ARCH_CMD_GLOBAL_FLAGS, default is "".
-                //
-                map.put(archList[i] + "_" + commandType[j] + "_PROJ_FLAGS", "");
-            }
-            map.put(archList[i]+"_VENDOR", getVendorFlag(archList[i], null, tools_def));
-        }
-        Set keyset = map.keySet();
-        Iterator iter = keyset.iterator();
-        String[][] result = new String[map.size()][2];
-        int i = 0;
-        while (iter.hasNext()) {
-            String key = (String) iter.next();
-            result[i][0] = key;
-            result[i++][1] = (String) map.get(key);
-        }
-        toolchain = result;
-    }
-
-    /**
-      Get the standard flags (STD_FLAGS) for specified arch and command type. 
-      
-      <ul>
-        <li>Find out Vendor that cmd Command Type with arch ARCH used. The 
-        search sequence is ARCH_CMD_VENDOR -> ARCH_VENDOR -> "MSFT". Here
-        we suppose default Vendor is MSFT.</li>
-        <li>Search ${Vendor}_tools.txt file, and get the corrsponding flags. 
-        </li>
-      </ul>
-      
-      @param arch the ARCH
-      @param cmd the command type
-      @param map detail flags information of tools_def.txt
-      @return the standard flags of arch ARCH and cmd Command Type 
-    **/
-    private String getStdFlags(String arch, String cmd, String[][] map) {
-        //
-        // first is to find out its Vendor in map
-        // ARCH_CMD_VENDOR -> ARCH_VENDOR -> "MSFT"
-        // Here we suppose default Vendor is MSFT.
-        //
-        String vendor = "MSFT";
-        String str;
-        if ((str = getValue(arch + "_" + cmd + "_VENDOR", map)) != null) {
-            vendor = str;
-        } else if ((str = getValue(arch + "_VENDOR", map)) != null) {
-            vendor = str;
-        }
-        //
-        // change to low letter
-        //
-        vendor = vendor.toLowerCase();
-        //
-        // parse the corresponding file and get arch_cmd value
-        //
-        String filename = vendor + "_tools.txt";
-        String[][] flagsMap;
-        if (filesMap.containsKey(filename)) {
-            flagsMap = (String[][]) filesMap.get(filename);
-        } else {
-            //
-            // read file and store in filesMap
-            //
-            flagsMap = ConfigReader.parse(confPath, vendor + "_tools.txt");
-            filesMap.put(filename, flagsMap);
-        }
-        if ((str = getValue(arch + "_" + cmd, flagsMap)) != null) {
-            return str;
-        }
-        return "";
-    }
-
-    /**
-      Get the global flags (GLOBAL_ADD_FLAGS & GLOBAL_SUB_FLAGS) for specified 
-      arch and command type. 
-      
-      <ul>
-        <li>Find out Vendor that cmd Command Type with arch ARCH used. The 
-        search sequence is ARCH_CMD_VENDOR -> ARCH_VENDOR -> "MSFT". Here
-        we suppose default Vendor is MSFT.</li>
-        <li>Search efi_flags_table.txt file, and get the corrsponding flags. 
-        </li>
-      </ul>
-      
-      @param arch the ARCH
-      @param cmd the command type
-      @param map detail flags information of tools_def.txt
-      @return two values, first is GLOBAL_ADD_FLAGS and another value is 
-      GLOBAL_SUB_FLAGS
-    **/
-    private String[] getGlobalFlags(String arch, String cmd, String[][] map) {
-        String addStr = "";
-        String subStr = "";
-        //
-        // first is to find out its Vendor in map
-        // ARCH_CMD_VENDOR -> ARCH_VENDOR -> "MSFT"
-        // Here we suppose default Vendor is MSFT.
-        //
-        String vendor = "MSFT";
-        String str;
-        if ((str = getValue(arch + "_" + cmd + "_VENDOR", map)) != null) {
-            vendor = str;
-        } else if ((str = getValue(arch + "_VENDOR", map)) != null) {
-            vendor = str;
-        }
-        //
-        // parse global flags table
-        //
-        if (globalFlagTable == null) {
-            globalFlagTable =  ConfigReader.parseTable(confPath, "efi_flags_table.txt");
-        }
-        for (int i=0; i < globalFlagTable.length; i++){
-            String[] item = globalFlagTable[i];
-            if (item[2].equalsIgnoreCase(vendor + "_" + arch + "_" + cmd)){
-                //
-                // if item[0] == item[1] is existed in globalFlagsMap
-                //
-                if (globalFlagsMap.containsKey(item[0])){
-                    if( item[1].equalsIgnoreCase((String)globalFlagsMap.get(item[0]))){
-                        addStr += item[3] + " ";
-                        subStr += item[4] + " ";
-                    }
-                }
-            }
-        }
-        
-        return new String[]{addStr, subStr};
-    }
-
-    /**
-      Find out command path and command name. 
-      
-      <pre>
-        Command path searching sequence in tools_def.txt file:
-        Path: ARCH_CMD_PATH -> ARCH_PATH -> Set to "".
-        
-        Command name searching sequence in tools_def.txt file:
-        Name: ARCH_CMD_NAME -> CMD_NAME -> Default Value.
-      </pre>
-      
-      @param arch the ARCH
-      @param cmd the Command Type
-      @param map detail flags information of tools_def.txt
-      @return the absolute command path and name
-    **/
-    private String getAbsoluteCmdPath(String arch, String cmd, String[][] map) {
-        String path = "";
-        String name = "";
-        String str;
-        //
-        // find Path
-        //
-        if ((str = getValue(arch + "_" + cmd + "_PATH", map)) != null) {
-            path = str;
-        } else if ((str = getValue(arch + "_PATH", map)) != null) {
-            path = str;
-        }
-        //
-        // find Name
-        //
-        if ((str = getValue(arch + "_" + cmd + "_NAME", map)) != null) {
-            name = str;
-        } else if ((str = getValue(cmd + "_NAME", map)) != null) {
-            name = str;
-        } else {
-            name = getValue(cmd, defaultCmdName);
-        }
-        if (path.equalsIgnoreCase("")) {
-            return name;
-        }
-        return path + File.separatorChar + name;
-    }
-
-    /**
-      Find out all global flags value, such as EFI_DEBUG equal YES or NO. Here 
-      are three type files: global_efi_flags.txt, ${TARGET}_efi_flags.txt, 
-      my_efi_flags.txt. global_efi_flags.txt with the highest priority while 
-      my_efi_flags.txt with the lowest priority. 
-      
-      <p>All global flags value will store in <code>globalFlagsMap</code> for 
-      getGlobalFlags using. </p> 
-      
-      @param target current build TARGET value
-    **/
-    private void parseGlobalSetting(String target){
-        //
-        // parse global_efi_flags -> ${TARGET}_efi_flags -> my_efi_flags
-        // parse global_efi_flags
-        //
-        String[][] map = ConfigReader.parse(confPath, "global_efi_flags.txt");
-        for (int i = 0; i < map.length; i++){
-            if(globalFlagsMap.containsKey(map[i][0])){
-                globalFlagsMap.remove(map[i][0]);
-            }
-            globalFlagsMap.put(map[i][0], map[i][1]);
-        }
-        //
-        // parse ${TARGET}_efi_flags
-        //
-        map = ConfigReader.parse(confPath, target.toLowerCase() + "_efi_flags.txt");
-        for (int i = 0; i < map.length; i++){
-            if(globalFlagsMap.containsKey(map[i][0])){
-                globalFlagsMap.remove(map[i][0]);
-            }
-            globalFlagsMap.put(map[i][0], map[i][1]);
-        }
-        //
-        // parse my_efi_flags.txt
-        //
-        map = ConfigReader.parse(confPath, "my_efi_flags.txt");
-        for (int i = 0; i < map.length; i++){
-            if(globalFlagsMap.containsKey(map[i][0])){
-                globalFlagsMap.remove(map[i][0]);
-            }
-            globalFlagsMap.put(map[i][0], map[i][1]);
-        }
-    }
-    
-    /**
-      Find value with key from map. If not found, return null. 
-      
-      <p>Note that default is case-insensitive</p>
-      
-      @param key key value
-      @param map mapping information
-      @return the related value of key
-    **/
-    private String getValue(String key, String[][] map) {
-        return getValue(key, map, false);
-    }
-
-    /**
-      Find value with key from map. If not found, return null. 
-      
-      @param key key value
-      @param map mapping information
-      @param caseSensitive whether case sesitive or not
-      @return the related value of key
-    **/
-    private String getValue(String key, String[][] map, boolean caseSensitive) {
-        for (int i = 0; i < map.length; i++) {
-            if (caseSensitive) {
-                if (key.compareTo(map[i][0]) == 0) {
-                    return map[i][1];
-                }
-            } else {
-                if (key.compareToIgnoreCase(map[i][0]) == 0) {
-                    return map[i][1];
-                }
-            }
-        }
-        return null;
-    }
-
-    /**
-      Find value with key from <code>toolchain</code>. If not found, return null. 
-    
-      @param key key value
-      @return the related value of key
-    **/
-    public static String getValue(String key){
-        for (int i = 0; i < toolchain.length; i++) {
-            if (key.compareToIgnoreCase(toolchain[i][0]) == 0) {
-                return toolchain[i][1];
-            }
-        }
-        return null;
-    }
-    
-    /**
-      Get Arch list from a string separated with comma. 
-      
-      <pre>
-        For example:
-          If the arch string is "IA32, X64, EBC".
-          Then the result is {"IA32", "X64", "EBC"}. 
-      </pre>
-    
-      @param arch string separated with comma
-      @return Arch list
-    **/
-    public String[] getArchs(String arch) {
-        if (arch == null) {
-            return new String[0];
-        }
-        StringTokenizer st = new StringTokenizer(arch, " \t,");
-        String[] archs = new String[st.countTokens()];
-        int i = 0;
-        while (st.hasMoreTokens()) {
-            archs[i++] = st.nextToken().toUpperCase();
-        }
-        return archs;
-    }
-
-    /**
-      Get current target value.
-    
-      @return current target value
-    **/
-    public String getCurrentTarget() {
-        return currentTarget;
-    }
-
-    /**
-      Find out Vendor that cmd Command Type with arch ARCH used. The 
-      search sequence is ARCH_CMD_VENDOR -> ARCH_VENDOR -> "MSFT". Here
-      we suppose default Vendor is MSFT.
-      
-      @param arch the ARCH
-      @param cmd the Command Type
-      @param map detail flags information of tools_def.txt
-      @return the related vendor name
-    **/
-    public String getVendorFlag (String arch, String cmdType, String[][] map){
-        //
-        // ARCH_CMD_VENDOR -> ARCH_VENDOR -> "MSFT"
-        // Here we suppose default Vendor is MSFT.
-        //
-        String str;
-        String vendor = "";
-        if (cmdType != null){
-            if ((str = getValue(arch + "_" + cmdType + "_VENDOR", map)) != null) {
-                vendor = str; 
-            }else {
-                vendor = "";
-            }
-        }else if (arch != null){
-            if ((str = getValue(arch + "_VENDOR", map)) != null) {
-                vendor = str; 
-            }else {
-                vendor = "";
-            }
-        }
-        return vendor;
-    }
-    
-}
diff --git a/Tools/Source/GenBuild/org/tianocore/build/toolchain/ToolChainInfo.java b/Tools/Source/GenBuild/org/tianocore/build/toolchain/ToolChainInfo.java
new file mode 100644
index 0000000000..146f6e5a13
--- /dev/null
+++ b/Tools/Source/GenBuild/org/tianocore/build/toolchain/ToolChainInfo.java
@@ -0,0 +1,219 @@
+package org.tianocore.build.toolchain;
+
+import java.util.HashMap;
+import java.util.LinkedHashSet;
+import java.util.Map;
+import java.util.Set;
+
+public class ToolChainInfo {
+
+    private Set<String> targets = new LinkedHashSet<String>();
+    
+    private Set<String> tagnames = new LinkedHashSet<String>();
+    
+    private Set<String> archs = new LinkedHashSet<String>();
+    
+    private Set<String> commands = new LinkedHashSet<String>();
+
+    private Map<String, Set<String>> commandMap = new HashMap<String, Set<String>>();
+    
+    public void addTargets(String targetList) {
+        //
+        // targetList some targets separated by space " "
+        //
+        if (targetList == null) {
+            targets.add("*");
+            return ;
+        }
+        addTargets(targetList.split(" "));
+    }
+    
+    public void addTargets(String[] targetArray) {
+        if (targetArray == null ) {
+            return ;
+        }
+        for (int i = 0; i < targetArray.length; i++) {
+            targets.add(targetArray[i]);
+        }
+    }
+    
+    public void addTargets(Set<String> targetSet) {
+        targets.addAll(targetSet);
+    }
+    
+    public void addTagnames(String tagnameList) {
+        //
+        // tagnameList some tagnames separated by space " "
+        //
+        if (tagnameList == null) {
+            tagnames.add("*");
+            return ;
+        }
+        addTagnames(tagnameList.split(" "));
+    }
+    
+    public void addTagnames(String[] tagnameArray) {
+        if (tagnameArray == null ) {
+            return ;
+        }
+        for (int i = 0; i < tagnameArray.length; i++) {
+            tagnames.add(tagnameArray[i]);
+        }
+    }
+    
+    public void addTagnames(Set<String> tagnameSet) {
+        tagnames.addAll(tagnameSet);
+    }
+    
+    public void addArchs(String archList) {
+        //
+        // archList some archs separated by space " "
+        //
+        if (archList == null) {
+            archs.add("*");
+            return ;
+        }
+        addArchs(archList.split(" "));
+    }
+    
+    public void addArchs(String[] archArray) {
+        if (archArray == null ) {
+            return ;
+        }
+        for (int i = 0; i < archArray.length; i++) {
+            archs.add(archArray[i]);
+        }
+    }
+    
+    public void addArchs(Set<String> archSet) {
+        archs.addAll(archSet);
+    }
+    
+    public void addCommands(String toolChain, String commandList) {
+        //
+        // archList some archs separated by space " "
+        //
+        if (commandList == null || commandList.length() == 0) {
+            return ;
+        }
+        addCommands(commandList.split(" "));
+    }
+    
+    public void addCommands(String[] commandArray) {
+        if (commandArray == null ) {
+            return ;
+        }
+        for (int i = 0; i < commandArray.length; i++) {
+            commands.add(commandArray[i]);
+        }
+    }
+    
+    public void addCommands(String toolChain, String[] commandArray) {
+        if (commandArray == null) {
+            return ;
+        }
+
+        Set<String> toolChainCommandSet = commandMap.get(toolChain);
+        if (toolChainCommandSet == null) {
+            toolChainCommandSet = new LinkedHashSet<String>();
+            commandMap.put(toolChain, toolChainCommandSet);
+        }
+        for (int i = 0; i < commandArray.length; i++) {
+            commands.add(commandArray[i]);
+            toolChainCommandSet.add(commandArray[i]);
+        }
+    }
+    
+    public void addCommands(String toolChain, Set<String> commandSet) {
+        if (commandSet == null) {
+            return;
+        }
+        Set<String> toolChainCommandSet = commandMap.get(toolChain);
+        if (toolChainCommandSet == null) {
+            toolChainCommandSet = new LinkedHashSet<String>();
+            commandMap.put(toolChain, toolChainCommandSet);
+        }
+        commands.addAll(commandSet);
+        toolChainCommandSet.addAll(commandSet);
+    }
+    
+    public ToolChainInfo union(ToolChainInfo info) {
+        ToolChainInfo result = new ToolChainInfo();
+        result.addTargets(union(this.targets, info.targets));
+        result.addTagnames(union(this.tagnames, info.tagnames));
+        result.addArchs(union(this.archs, info.archs));
+        //result.addCommands(union(this.getCommands(), info.getCommands()));
+        return result;
+    }
+    
+    public ToolChainInfo intersection(ToolChainInfo info) {
+//        System.out.println(this + "\n" + info);
+        ToolChainInfo result = new ToolChainInfo();
+        result.addTargets(intersection(this.targets, info.targets));
+        result.addTagnames(intersection(this.tagnames, info.tagnames));
+        result.addArchs(intersection(this.archs, info.archs));
+        // result.addCommands(union(this.commands, info.commands));
+//        System.out.println("result: " + result);
+        return result;
+    }
+    
+    private Set<String> union(Set<String> set1, Set<String> set2) {
+        Set<String> result = new LinkedHashSet<String>();
+        result.addAll(set1);
+        result.addAll(set2);
+        result.remove("*");
+        return result;
+    }
+    
+    private Set<String> intersection(Set<String> set1, Set<String> set2) {
+        Set<String> result = new LinkedHashSet<String>();
+        boolean set1HasWildcard = set1.contains("*");
+        boolean set2HasWildcard = set2.contains("*");
+
+        if (set1HasWildcard && set2HasWildcard) {
+            result.addAll(set1);
+            result.addAll(set2);
+        } else if (set1HasWildcard) {
+            result.addAll(set2);
+        } else if (set2HasWildcard) {
+            result.addAll(set1);
+        } else {
+            result.addAll(set1);
+            result.retainAll(set2);
+        }
+
+//        result.remove("*");
+        return result;
+    }
+    
+    public String[] getTargets() {
+        return (String[])targets.toArray(new String[targets.size()]);
+    }
+    
+    public String[] getTagnames() {
+        return (String[])tagnames.toArray(new String[tagnames.size()]);
+    }
+    
+    public String[] getArchs() {
+        return (String[])archs.toArray(new String[archs.size()]);
+    }
+
+    public String[] getCommands() {
+        return (String[])commands.toArray(new String[commands.size()]);
+    }
+
+    public Set<String> getCommands(String toolChain) {
+        return commandMap.get(toolChain);
+    }
+    
+    public String toString() {
+        return targets + "\n" + tagnames + "\n" + archs + "\n" + commands;
+    }
+    
+    public void normalize() {
+        targets.remove("*");
+        tagnames.remove("*");
+        archs.remove("*");
+        commands.remove("*");
+    }
+}
diff --git a/Tools/Source/GenBuild/org/tianocore/build/toolchain/ToolChainKey.java b/Tools/Source/GenBuild/org/tianocore/build/toolchain/ToolChainKey.java
new file mode 100644
index 0000000000..4804f15a74
--- /dev/null
+++ b/Tools/Source/GenBuild/org/tianocore/build/toolchain/ToolChainKey.java
@@ -0,0 +1,177 @@
+/*++
+
+Copyright (c) 2006, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution.  The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+  ToolChainKey.java
+
+Abstract:
+
+--*/
+
+package org.tianocore.build.toolchain;
+
+import java.io.Serializable;
+import java.util.AbstractMap;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.TreeMap;
+
+import org.tianocore.build.exception.EdkException;
+
+public class ToolChainKey implements java.io.Serializable, Comparable<ToolChainKey> {
+
+    private String delimiter = "_";
+
+    public final static int keyLength = 5;
+
+    private String[] keySet = null;
+
+    private String keyString = null;
+
+    private int hashValue = 0;
+
+    public ToolChainKey(String keyString, String delimiter) throws Exception {
+        setKey(keyString, delimiter);
+    }
+
+    public ToolChainKey(String keyString) throws EdkException {
+        setKey(keyString);
+    }
+
+    public ToolChainKey(String[] keySet) throws EdkException {
+        setKey(keySet);
+    }
+
+    public int hashCode() {
+        if (hashValue != 0) {
+            return hashValue;
+        }
+
+        for (int i = 0; i < keySet.length; ++i) {
+            char[] keyStringValue = new char[keySet[i].length()];
+            this.keySet[i].getChars(0, keyStringValue.length, keyStringValue, 0);
+
+            for (int j = 0; j < keyStringValue.length; ++j) {
+                hashValue = keyStringValue[j] + hashValue * 31;
+            }
+        }
+
+        return hashValue;
+    }
+
+    public int compareTo(ToolChainKey dstKey) {
+        String[] dstKeySet = dstKey.getKeySet();
+        int result = 0;
+        for (int i = 0; i < this.keyLength; ++i) {
+            result = this.keySet[i].compareToIgnoreCase(dstKeySet[i]);
+            if (result != 0) {
+                break;
+            }
+        }
+
+        return result;
+    }
+
+    public boolean equals(Object o) {
+        ToolChainKey dstKey = (ToolChainKey)o;
+        String[] dstKeySet = dstKey.getKeySet();
+
+        if (this == dstKey) {
+            return true;
+        }
+
+        if (dstKeySet.length != this.keyLength) {
+            return false;
+        }
+
+        for (int i = 0; i < this.keyLength; ++i) {
+            if (!this.keySet[i].equalsIgnoreCase(dstKeySet[i])) {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    public void setKey(String[] keySet) throws EdkException {
+        if (keySet.length != this.keyLength) {
+            throw new EdkException("Invalid ToolChain key");
+        }
+
+        this.keySet = new String[this.keyLength];
+        System.arraycopy(keySet, 0, this.keySet, 0, this.keyLength);
+        for (int i = 0; i < this.keyLength; ++i) {
+            if (this.keySet[i] == null || this.keySet[i].length() == 0) {
+                this.keySet[i] = "*";
+            }
+        }
+        this.keyString = null;
+        this.hashValue = 0;
+    }
+
+    public void setKey(String keySetString, int index) throws EdkException {
+        if (index >= this.keyLength) {
+            throw new EdkException("Invalid ToolChain key index");
+        }
+
+        if (keySetString == null || keySetString.length() == 0) {
+            keySetString = "*";
+        }
+        this.keySet[index] = keySetString;
+        this.keyString = null;
+        this.hashValue = 0;
+    }
+
+    public void setKey(String keyString) throws EdkException {
+        this.keySet = keyString.split(this.delimiter);
+
+        if (this.keySet.length != this.keyLength) {
+            throw new EdkException("Invalid ToolChain key");
+        }
+
+        this.keyString = keyString;
+        this.hashValue = 0;
+    }
+
+    public void setKey(String keyString, String delimiter) throws Exception {
+        this.keySet = keyString.split(delimiter);
+
+        if (this.keySet.length != this.keyLength) {
+            throw new Exception("Invalid ToolChain key");
+        }
+
+        this.keyString = keyString;
+        this.delimiter = delimiter;
+        this.hashValue = 0;
+    }
+
+    public String[] getKeySet() {
+        return keySet;
+    }
+
+    public String toString() {
+        if (this.keyString == null) {
+            StringBuffer keyStringBuf = new StringBuffer(64);
+            int i = 0;
+
+            keyStringBuf.append(this.keySet[i++]);
+            for (; i < this.keyLength; ++i) {
+                keyStringBuf.append(this.delimiter);
+                keyStringBuf.append(this.keySet[i]);
+            }
+
+            this.keyString = keyStringBuf.toString();
+        }
+
+        return this.keyString;
+    }
+}
+
diff --git a/Tools/Source/GenBuild/org/tianocore/build/toolchain/ToolChainMap.java b/Tools/Source/GenBuild/org/tianocore/build/toolchain/ToolChainMap.java
new file mode 100644
index 0000000000..da34e7ec7e
--- /dev/null
+++ b/Tools/Source/GenBuild/org/tianocore/build/toolchain/ToolChainMap.java
@@ -0,0 +1,165 @@
+/*++
+
+Copyright (c) 2006, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution.  The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+  ToolChainMap.java
+
+Abstract:
+
+--*/
+
+package org.tianocore.build.toolchain;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+import org.tianocore.build.exception.EdkException;
+
+public class ToolChainMap {
+
+    private int matchLevel = ToolChainKey.keyLength - 2;
+
+    private Map<ToolChainKey, String> map = null;
+
+    public ToolChainMap() {
+        //this.map = new TreeMap<ToolChainKey, String>();
+        this.map = new HashMap<ToolChainKey, String>();
+    }
+
+    public String put(String key, String delimiter, String value)throws EdkException {
+        ToolChainKey toolChainKey;
+
+        try {
+            toolChainKey = new ToolChainKey(key, delimiter);
+        } catch (Exception e) {
+            throw new EdkException(e.getMessage());
+        }
+        return (String)map.put(toolChainKey, value);
+    }
+
+    public String put(String key, String value) throws EdkException {
+        ToolChainKey toolChainKey;
+
+        try {
+            toolChainKey = new ToolChainKey(key);
+        } catch (Exception e) {
+            throw new EdkException(e.getMessage());
+        }
+        return (String)map.put(toolChainKey, value);
+    }
+
+    public String put(String[] key, String value) throws EdkException {
+        ToolChainKey toolChainKey;
+
+        try {
+            toolChainKey = new ToolChainKey(key);
+        } catch (Exception e) {
+            throw new EdkException(e.getMessage());
+        }
+        return (String)map.put(toolChainKey, value);
+    }
+
+    public String put(ToolChainKey key, String value) {
+        return (String)map.put(key, value);
+    }
+
+    public String get(String key) throws EdkException {
+        ToolChainKey toolChainKey;
+
+        try {
+            toolChainKey = new ToolChainKey(key);
+        } catch (Exception e) {
+            throw new EdkException(e.getMessage());
+        }
+        return get(toolChainKey);
+    }
+
+    public String get(String key, String delimiter) throws EdkException {
+        ToolChainKey toolChainKey;
+
+        try {
+            toolChainKey = new ToolChainKey(key, delimiter);
+        } catch (Exception e) {
+            throw new EdkException(e.getMessage());
+        }
+        return get(toolChainKey);
+    }
+
+    public String get(String[] key)  throws EdkException {
+        ToolChainKey toolChainKey;
+
+        try {
+            toolChainKey = new ToolChainKey(key);
+        } catch (Exception e) {
+            throw new EdkException(e.getMessage());
+        }
+        return get(toolChainKey);
+    }
+
+    public String get(ToolChainKey key)  throws EdkException {
+        String result = map.get(key);
+        if (result != null || map.containsKey(key)) {
+            return result;
+        }
+
+        String[] keySet = key.getKeySet();
+        ToolChainKey tmpKey;
+        try {
+            tmpKey = new ToolChainKey(keySet);
+        } catch (Exception e) {
+            throw new EdkException(e.getMessage());
+        }
+
+        int level = matchLevel;
+        while (level >= 0) {
+            int tmpLevel = level;
+            while (tmpLevel >= level) {
+                String[] tmpKeySet = tmpKey.getKeySet();
+                try {
+                    if (!tmpKeySet[tmpLevel].equals("*")) {
+                        tmpKey.setKey("*", tmpLevel);
+                        tmpLevel = matchLevel;
+                    } else {
+                        tmpKey.setKey(keySet[tmpLevel], tmpLevel);
+                        --tmpLevel;
+                        continue;
+                    }
+                } catch (Exception e) {
+                    throw new EdkException(e.getMessage());
+                }
+
+                result = map.get(tmpKey);
+                if (result != null) {
+                    map.put(key, result);
+                    return result;
+                }
+            }
+            --level;
+        }
+
+        map.put(key, result);
+        return result;
+    }
+
+    public int size() {
+        return map.size();
+    }
+
+    public Set<ToolChainKey> keySet() {
+        return (Set<ToolChainKey>)map.keySet();
+    }
+    
+//    public String toString() {
+//        return map.toString();
+//    }
+}
+
diff --git a/Tools/Source/GenBuild/org/tianocore/build/toolchain/ToolChainTask.java b/Tools/Source/GenBuild/org/tianocore/build/toolchain/ToolChainTask.java
index 04dab1c3e3..4b0577bea3 100644
--- a/Tools/Source/GenBuild/org/tianocore/build/toolchain/ToolChainTask.java
+++ b/Tools/Source/GenBuild/org/tianocore/build/toolchain/ToolChainTask.java
@@ -15,6 +15,8 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 **/
 package org.tianocore.build.toolchain;
 
+import java.io.File;
+
 import org.apache.tools.ant.BuildException;
 import org.apache.tools.ant.Task;
 
@@ -25,7 +27,13 @@ import org.apache.tools.ant.Task;
   @since GenBuild 1.0
 **/
 public class ToolChainTask extends Task{
-
+    ///
+    /// environment variable name of toolchain
+    ///
+    static private String toolsEnv = "env.TOOLS_DEF";
+    ///
+    /// configuration file path
+    ///
     private String confPath = ".";
     
     /**
@@ -43,10 +51,9 @@ public class ToolChainTask extends Task{
               Config files are invalid.
     **/
     public void execute() throws BuildException {
-        String toolChain = getProject().getProperty("env.TOOL_CHAIN");
-        ToolChainFactory toolchain = new ToolChainFactory(confPath, toolChain);
-        toolchain.setupToolChain();
-        getProject().setProperty("TARGET", toolchain.getCurrentTarget());
+        String toolChain = getProject().getProperty(toolsEnv);
+//        ToolChainConfig toolchain = new ToolChainConfig(new File(confPath + File.separatorChar + toolChain));
+        //getProject().setProperty("TARGET", toolchain.getCurrentTarget());
     }
 
     /**