diff --git a/nac3core/src/top_level.rs b/nac3core/src/top_level.rs
index 1e181cc5..eaac3621 100644
--- a/nac3core/src/top_level.rs
+++ b/nac3core/src/top_level.rs
@@ -119,8 +119,8 @@ impl TopLevelComposer {
         (primitives, unifier)
     }
 
-    // return a composer and things to make a "primitive" symbol resolver, so that the symbol 
-    // resolver can later figure out primitive type definitions when passed a primitive type name
+    /// return a composer and things to make a "primitive" symbol resolver, so that the symbol 
+    /// resolver can later figure out primitive type definitions when passed a primitive type name
     pub fn new() -> (Vec<(String, DefinitionId, Type)>, Self) {
         let primitives = Self::make_primitives();
         // the def list including the entries of primitive info
@@ -199,11 +199,11 @@ impl TopLevelComposer {
         &mut self,
         ast: ast::Stmt<()>,
         resolver: Option<Arc<Mutex<dyn SymbolResolver + Send>>>,
-    ) -> Result<Vec<(String, DefinitionId, Type)>, String> {
+    ) -> Result<(String, DefinitionId, Type), String> {
         match &ast.node {
             ast::StmtKind::ClassDef { name, body, .. } => {
                 let class_name = name.to_string();
-                let def_list = self.definition_list.write();
+                let mut def_list = self.definition_list.write();
                 let class_def_id = def_list.len();
 
                 // add the class to the unifier
@@ -212,19 +212,16 @@ impl TopLevelComposer {
                     fields: Default::default(),
                     params: Default::default(),
                 });
-
-                let mut ret_vector: Vec<(String, DefinitionId, Type)> =
-                    vec![(class_name.clone(), DefinitionId(class_def_id), ty)];
+                
                 // parse class def body and register class methods into the def list
-                // NOTE: module's symbol resolver would not know the name of the class methods,
-                // thus cannot return their definition_id? so we have to manage it ourselves?
-                // or do we return the class method list of (method_name, def_id, type) to
-                // application to be used to build symbol resolver? <- current implementation
-                // FIXME: better do not return and let symbol resolver to manage the mangled name
+                // module's symbol resolver would not know the name of the class methods,
+                // thus cannot return their definition_id? so we have to manage it ourselves
+                // by using the field `class_method_to_def_id`
                 for b in body {
                     if let ast::StmtKind::FunctionDef { name, .. } = &b.node {
                         let fun_name = name_mangling(class_name.clone(), name);
-                        let def_id = self.definition_list.len();
+                        let def_id = def_list.len();
+                        
                         // add to unifier
                         let ty = self.unifier.add_ty(TypeEnum::TFunc(
                             crate::typecheck::typedef::FunSignature {
@@ -233,51 +230,61 @@ impl TopLevelComposer {
                                 vars: Default::default(),
                             },
                         ));
+
                         // add to the definition list
-                        self.definition_list.push(TopLevelDefInfo {
-                            def: Self::make_top_level_function_def(fun_name.clone(), ty, None), // FIXME:
+                        def_list.push(TopLevelDefInfo {
+                            def: Self::make_top_level_function_def(fun_name.clone(), ty, resolver.clone()),
                             ty,
-                            ast: None, // since it is inside the class def body statments
+                            // since it is inside the class def body statments, the ast is None
+                            ast: None,
                         });
-                        ret_vector.push((fun_name, DefinitionId(def_id), ty));
+
+                        // class method, do not let the symbol manager manage it, use our own map
+                        // FIXME: maybe not do name magling, use map to map instead
+                        self.class_method_to_def_id.insert(
+                            fun_name, 
+                            DefinitionId(def_id)
+                        );
 
                         // if it is the contructor, special handling is needed. In the above
                         // handling, we still add __init__ function to the class method
                         if name == "__init__" {
-                            self.definition_list.push(TopLevelDefInfo {
+                            def_list.push(TopLevelDefInfo {
                                 def: TopLevelDef::Initializer {
                                     class_id: DefinitionId(class_def_id),
                                 },
-                                ty: self.primitives.none, // arbitary picked one
-                                ast: None, // it is inside the class def body statments
+                                // arbitary picked one for the constructor
+                                ty: self.primitives.none,
+                                // it is inside the class def body statments, so None
+                                ast: None,
                             })
-                            // FIXME: should we return this to the symbol resolver?, should be yes
                         }
                     }
                 }
 
                 // add the class to the definition list
-                self.definition_list.push(TopLevelDefInfo {
+                def_list.push(TopLevelDefInfo {
                     def: Self::make_top_level_class_def(class_def_id, resolver),
                     ast: Some(ast),
                     ty,
                 });
 
-                Ok(ret_vector)
-            }
+                Ok((class_name, DefinitionId(class_def_id), ty))
+            },
 
             ast::StmtKind::FunctionDef { name, .. } => {
                 let fun_name = name.to_string();
-                let def_id = self.definition_list.len();
+                
                 // add to the unifier
-                let ty =
-                    self.unifier.add_ty(TypeEnum::TFunc(crate::typecheck::typedef::FunSignature {
-                        args: Default::default(),
-                        ret: self.primitives.none,
-                        vars: Default::default(),
-                    }));
+                let ty = self.unifier.add_ty(TypeEnum::TFunc(crate::typecheck::typedef::FunSignature {
+                    args: Default::default(),
+                    ret: self.primitives.none,
+                    vars: Default::default(),
+                }));
+                    
                 // add to the definition list
-                self.definition_list.push(TopLevelDefInfo {
+                let mut def_list = self.definition_list.write();
+                def_list.push(TopLevelDefInfo {
                     def: Self::make_top_level_function_def(
                         name.into(),
                         self.primitives.none,
@@ -287,7 +294,7 @@ impl TopLevelComposer {
                     ty,
                 });
 
-                Ok(vec![(fun_name, DefinitionId(def_id), ty)])
+                Ok((fun_name, DefinitionId(def_list.len() - 1), ty))
             }
 
             _ => Err("only registrations of top level classes/functions are supprted".into()),
@@ -296,7 +303,8 @@ impl TopLevelComposer {
 
     /// this should be called after all top level classes are registered, and will actually fill in those fields of the previous dummy one
     pub fn analyze_top_level(&mut self) -> Result<(), String> {
-        for mut d in &mut self.definition_list {
+        for d in self.definition_list.write().iter_mut() {
+            // only analyze those with ast, and class_method(ast in class def)
             if let Some(ast) = &d.ast {
                 match &ast.node {
                     ast::StmtKind::ClassDef {
@@ -310,23 +318,25 @@ impl TopLevelComposer {
                             fields,
                             methods,
                             type_vars,
-                            // resolver,
+                            resolver,
                         ) = if let TopLevelDef::Class {
                             object_id,
                             ancestors,
                             fields,
                             methods,
                             type_vars,
-                            resolver
+                            resolver: Some(resolver)
                         } = &mut d.def {
-                            (object_id, ancestors, fields, methods, type_vars) // FIXME: this unwrap is not safe
+                            (object_id, ancestors, fields, methods, type_vars, resolver.lock())
                         } else { unreachable!() };
 
                         // try to get mutable reference of the entry in the unification table, get the `TypeEnum`
                         let (params,
                             fields
                         ) = if let TypeEnum::TObj {
-                            params, // FIXME: this params is immutable, even if this is mutable, what should the key be, get the original typevar's var_id?
+                            // FIXME: this params is immutable, even if this is mutable, what 
+                            // should the key be, get the original typevar's var_id?
+                            params,
                             fields,
                             ..
                         } = self.unifier.get_ty(d.ty).borrow() {
@@ -337,7 +347,9 @@ impl TopLevelComposer {
                         // into the `bases` ast node
                         for b in bases {
                             match &b.node {
-                                // typevars bounded to the class, things like `class A(Generic[T, V, ImportedModule.T])`
+                                // typevars bounded to the class, only support things like `class A(Generic[T, V])`, 
+                                // things like `class A(Generic[T, V, ImportedModule.T])` is not supported
+                                // i.e. only simple names are allowed in the subscript
                                 // should update the TopLevelDef::Class.typevars and the TypeEnum::TObj.params
                                 ast::ExprKind::Subscript {value, slice, ..} if {
                                     if let ast::ExprKind::Name {id, ..} = &value.node {
@@ -345,22 +357,10 @@ impl TopLevelComposer {
                                     } else { false }
                                 } => {
                                     match &slice.node {
-                                        // `class Foo(Generic[T, V, P, ImportedModule.T]):`
+                                        // `class Foo(Generic[T, V, P]):`
                                         ast::ExprKind::Tuple {elts, ..} => {
                                             for e in elts {
-                                                // TODO: I'd better parse the node to get the Type of the type vars(can have things like: A.B.C.typevar?)
-                                                match &e.node {
-                                                    ast::ExprKind::Name {id, ..} => {
-                                                        // the def_list
-                                                        // type_vars.push(resolver.get_symbol_type(id).ok_or_else(|| "unknown type variable".to_string())?); FIXME:
-
-                                                        // the TypeEnum of the class
-                                                        // FIXME: the `params` destructed above is not mutable, even if this is mutable, what should the key be?
-                                                        unimplemented!()
-                                                    },
-
-                                                    _ => unimplemented!()
-                                                }
+                                                // resolver.parse_type_annotation(self.definition_list.) // FIXME:
                                             }
                                         },
 
@@ -374,17 +374,11 @@ impl TopLevelComposer {
                                             unimplemented!()
                                         },
 
-                                        // `class Foo(Generic[ImportedModule.T])`
-                                        ast::ExprKind::Attribute {value, attr, ..} => {
-                                            // TODO:
-                                            unimplemented!()
-                                        },
-
-                                        _ => return Err("not supported".into()) // NOTE: it is really all the supported cases?
+                                        _ => return Err("not supported, only simple names are allowed in the subscript".into())
                                     };
                                 },
 
-                                // base class, name directly available inside the
+                                /* // base class, name directly available inside the
                                 // module, can use this module's symbol resolver
                                 ast::ExprKind::Name {id, ..} => {
                                     // let def_id = resolver.get_identifier_def(id); FIXME:
@@ -407,7 +401,9 @@ impl TopLevelComposer {
                                 // `class Foo(ImportedModule.A[int, bool])`, A is a class with associated type variables
                                 ast::ExprKind::Subscript {value, slice, ..} => {
                                     unimplemented!()
-                                },
+                                }, */
+                                
+                                // base class is possible in other cases, we parse for thr base class
                                 _ => return Err("not supported".into())
                             }
                         }
@@ -444,7 +440,9 @@ impl TopLevelComposer {
                         unimplemented!()
                     }
 
-                    _ => return Err("only expect function and class definitions to be submitted here to be analyzed".into())
+                    node => {
+                        return Err("only expect function and class definitions to be submitted here to be analyzed".into())
+                    }
                 }
             }
         }