diff --git a/pykd/dbgclient.cpp b/pykd/dbgclient.cpp
index 899860a..5c8c3bc 100644
--- a/pykd/dbgclient.cpp
+++ b/pykd/dbgclient.cpp
@@ -251,4 +251,23 @@ void waitForEvent()
 
 ///////////////////////////////////////////////////////////////////////////////////
 
+ULONG DebugClient::ptrSize()
+{
+    HRESULT     hres;
+
+    hres = m_control->IsPointer64Bit();
+
+    if ( FAILED( hres ) )
+        throw  DbgException( "IDebugControl::IsPointer64Bit  failed" );
+    
+    return S_OK == hres ? 8 : 4;
+}
+
+ULONG ptrSize()
+{ 
+    return g_dbgClient->ptrSize();
+}
+
+///////////////////////////////////////////////////////////////////////////////////
+
 }; // end of namespace pykd
\ No newline at end of file
diff --git a/pykd/dbgclient.h b/pykd/dbgclient.h
index be399cb..4282d41 100644
--- a/pykd/dbgclient.h
+++ b/pykd/dbgclient.h
@@ -119,6 +119,28 @@ public:
 
     std::wstring loadWChars( ULONG64 offset, ULONG count, bool phyAddr = FALSE );
 
+    ULONG ptrSize();
+
+    LONG64 ptrByte();
+
+    LONG64 ptrWord();
+
+    LONG64 ptrDWord();
+
+    LONG64 ptrQWord();
+
+    LONG64 ptrMWord();
+
+    ULONG64 ptrSignByte();
+
+    ULONG64 ptrSignWord();
+
+    ULONG64 ptrSignDWord();
+
+    ULONG64 ptrSignQWord();
+
+    ULONG64 ptrSignMWord();
+
     void readMemory( ULONG64 address, PVOID buffer, ULONG length, bool phyAddr = FALSE );
 
     void setExecutionStatus( ULONG status );
@@ -184,6 +206,8 @@ bool isKernelDebugging();
 
 bool isDumpAnalyzing();
 
+ULONG ptrSize();
+
 void setExecutionStatus( ULONG status );
 
 void waitForEvent();
diff --git a/pykd/dbgext.cpp b/pykd/dbgext.cpp
index c8880e7..0a2600f 100644
--- a/pykd/dbgext.cpp
+++ b/pykd/dbgext.cpp
@@ -218,6 +218,8 @@ BOOST_PYTHON_MODULE( pykd )
             "Print out string. If dml = True string is printed with dml highlighting ( only for windbg )" )
         .def( "dprintln", &pykd::DebugClient::dprintln,
             "Print out string and insert end of line symbol. If dml = True string is printed with dml highlighting ( only for windbg )" )
+        .def( "ptrSize", &DebugClient::ptrSize,
+            "Return effective pointer size" )
         .def( "setExecutionStatus",  &pykd::DebugClient::setExecutionStatus,
             "Requests that the debugger engine enter an executable state" )
         .def( "step", &pykd::DebugClient::changeDebuggerStatus<DEBUG_STATUS_STEP_OVER>, 
@@ -281,6 +283,8 @@ BOOST_PYTHON_MODULE( pykd )
         "Print out string. If dml = True string is printed with dml highlighting ( only for windbg )" ) );
     python::def( "dprintln", &pykd::dprintln, dprintln_( boost::python::args( "str", "dml" ), 
         "Print out string and insert end of line symbol. If dml = True string is printed with dml highlighting ( only for windbg )" ) );
+    python::def( "ptrSize", &ptrSize,
+        "Return effective pointer size" );
     python::def( "setExecutionStatus",  &pykd::setExecutionStatus,
         "Requests that the debugger engine enter an executable state" );
     python::def( "step", &pykd::changeDebuggerStatus<DEBUG_STATUS_STEP_OVER>, 
@@ -290,7 +294,7 @@ BOOST_PYTHON_MODULE( pykd )
     python::def( "waitForEvent", &pykd::waitForEvent,
         "Wait for events that breaks into the debugger" );
     
-    python::class_<pykd::TypeInfo>("typeInfo", "Class representing typeInfo", python::no_init )
+    python::class_<TypeInfo, TypeInfoPtr, boost::noncopyable >("typeInfo", "Class representing typeInfo", python::no_init )
         .def( "name", &pykd::TypeInfo::getName )
         .def( "size", &pykd::TypeInfo::getSize )
         .def( "offset", &pykd::TypeInfo::getOffset )
@@ -300,7 +304,7 @@ BOOST_PYTHON_MODULE( pykd )
     python::class_<TypedVar, TypedVarPtr, python::bases<intBase> >("typedVar", 
         "Class of non-primitive type object, child class of typeClass. Data from target is copied into object instance", 
         python::no_init )
-        .def( python::init<const TypeInfo&, ULONG64>() )
+        .def( python::init<const TypeInfoPtr&, ULONG64>() )
         .def("getAddress", &TypedVar::getAddress, 
             "Return virtual address" )
         .def("sizeof", &TypedVar::getSize,
diff --git a/pykd/module.cpp b/pykd/module.cpp
index 77fe40b..5052306 100644
--- a/pykd/module.cpp
+++ b/pykd/module.cpp
@@ -153,24 +153,16 @@ Module::reloadSymbols()
 
 ///////////////////////////////////////////////////////////////////////////////////
 
-TypeInfo
-Module::getTypeByName( const std::string  &typeName )
-{
-    return TypeInfo( getDia(), typeName );
-}
-
-///////////////////////////////////////////////////////////////////////////////////
-
 TypedVar 
 Module::getTypedVarByTypeName( const std::string &typeName, ULONG64 addr )
 {
-   return TypedVar( TypeInfo( getDia(), typeName ), addr );
+   return TypedVar( getTypeByName(typeName), addr );
 }
 
 ///////////////////////////////////////////////////////////////////////////////////
 
 TypedVar 
-Module::getTypedVarByType( const TypeInfo &typeInfo, ULONG64 addr )
+Module::getTypedVarByType( const TypeInfoPtr &typeInfo, ULONG64 addr )
 {
    return TypedVar( typeInfo, addr );
 }
@@ -182,7 +174,7 @@ Module::getTypedVarByName( const std::string &symName )
 {
     pyDia::SymbolPtr  typeSym = getDia()->getChildByName( symName );
 
-    return TypedVar( TypeInfo( typeSym->getType() ), typeSym->getRva() + m_base );
+    return TypedVar( TypeInfo::getTypeInfo( typeSym->getType() ), typeSym->getRva() + m_base );
 }
 
 ///////////////////////////////////////////////////////////////////////////////////
@@ -201,7 +193,7 @@ Module::getTypedVarByAddr( ULONG64 addr )
     if (displacement)
         throw DbgException( "not exactly match by RVA" );
 
-    return TypedVar( TypeInfo( diaSym->getType() ), addr );
+    return TypedVar( TypeInfo::getTypeInfo( diaSym->getType() ), addr ); 
 }
 
 ///////////////////////////////////////////////////////////////////////////////////
diff --git a/pykd/module.h b/pykd/module.h
index bee7e00..a18b418 100644
--- a/pykd/module.h
+++ b/pykd/module.h
@@ -59,11 +59,13 @@ public:
         return sym->getRva();
     }
 
-    TypeInfo getTypeByName( const std::string &typeName );
+    TypeInfoPtr getTypeByName( const std::string &typeName ) {
+        return TypeInfo::getTypeInfo( boost::static_pointer_cast<pyDia::Symbol>( getDia() ), typeName);
+    }
 
     TypedVar getTypedVarByTypeName( const std::string &typeName, ULONG64 addr );
 
-    TypedVar getTypedVarByType( const TypeInfo  &typeInfo, ULONG64 addr );
+    TypedVar getTypedVarByType( const TypeInfoPtr  &typeInfo, ULONG64 addr );
 
     TypedVar getTypedVarByAddr( ULONG64 addr );
 
@@ -71,7 +73,7 @@ public:
 
 private:
 
-    pyDia::GlobalScopePtr getDia() {
+    pyDia::GlobalScopePtr& getDia() {
         if (!m_dia)
             m_dia = pyDia::GlobalScope::loadPdb( getPdbName() );
         return m_dia;
diff --git a/pykd/stdafx.h b/pykd/stdafx.h
index b1273e3..d1655a4 100644
--- a/pykd/stdafx.h
+++ b/pykd/stdafx.h
@@ -48,18 +48,5 @@
 #include <boost/python/module.hpp>
 #pragma warning(pop)
 namespace python = boost::python;
-//
-//#include <vector>
-//
-//template <typename TElem>
-//TElem *getVectorBuffer(std::vector<TElem> &vec)
-//{
-//    return vec.size() ? &vec[0] : NULL;
-//}
-//template <typename TElem>
-//const TElem *getVectorBuffer(const std::vector<TElem> &vec)
-//{
-//    return vec.size() ? &vec[0] : NULL;
-//}
-//
-//// TODO: reference additional headers your program requires here
+
+#include <boost/regex.hpp> 
diff --git a/pykd/typedvar.cpp b/pykd/typedvar.cpp
index fcc065b..c14fe1b 100644
--- a/pykd/typedvar.cpp
+++ b/pykd/typedvar.cpp
@@ -7,22 +7,22 @@ namespace pykd {
 
 ///////////////////////////////////////////////////////////////////////////////////
 
-TypedVar::TypedVar ( IDebugClient4 *client, const TypeInfo& typeInfo, ULONG64 offset ) :
+TypedVar::TypedVar ( IDebugClient4 *client, const TypeInfoPtr& typeInfo, ULONG64 offset ) :
     DbgObject( client ),
     m_typeInfo( typeInfo ),
     m_offset( offset )
 {
-    m_size = m_typeInfo.getSize();
+    m_size = m_typeInfo->getSize();
 }
 
 ///////////////////////////////////////////////////////////////////////////////////
 
-TypedVar::TypedVar( const TypeInfo& typeInfo, ULONG64 offset ) :
+TypedVar::TypedVar( const TypeInfoPtr& typeInfo, ULONG64 offset ) :
     DbgObject( g_dbgClient->client() ),
     m_typeInfo( typeInfo ),
     m_offset( offset )
 {
-    m_size = m_typeInfo.getSize();
+    m_size = m_typeInfo->getSize();
 }
 
 ///////////////////////////////////////////////////////////////////////////////////
@@ -30,25 +30,25 @@ TypedVar::TypedVar( const TypeInfo& typeInfo, ULONG64 offset ) :
 TypedVarPtr
 TypedVar::getField( const std::string &fieldName ) 
 {
-    TypeInfo fieldType = m_typeInfo.getField( fieldName );
+    TypeInfoPtr fieldType = m_typeInfo->getField( fieldName );
 
     TypedVarPtr     tv;
 
-    if ( fieldType.isBasicType() )
+    if ( fieldType->isBasicType() )
     {
-        tv.reset( new BasicTypedVar( m_client, fieldType, m_offset + fieldType.getOffset() ) );
+        tv.reset( new BasicTypedVar( m_client, fieldType, m_offset + fieldType->getOffset() ) );
         return tv;
     }
 
-    if ( fieldType.isPointer() )
+    if ( fieldType->isPointer() )
     {
-        tv.reset( new PtrTypedVar( m_client, fieldType, m_offset + fieldType.getOffset() ) );
+        tv.reset( new PtrTypedVar( m_client, fieldType, m_offset + fieldType->getOffset() ) );
         return tv;
     }
 
-    if ( fieldType.isUserDefined() )       
+    if ( fieldType->isUserDefined() )       
     {
-        tv.reset( new TypedVar( m_client, fieldType, m_offset + fieldType.getOffset() ) );
+        tv.reset( new TypedVar( m_client, fieldType, m_offset + fieldType->getOffset() ) );
         return tv;
     }
 
diff --git a/pykd/typedvar.h b/pykd/typedvar.h
index cdd59c7..03d4abe 100644
--- a/pykd/typedvar.h
+++ b/pykd/typedvar.h
@@ -17,10 +17,10 @@ class TypedVar : public intBase, protected DbgObject {
 
 public:
 
-    TypedVar ( const TypeInfo& typeInfo, ULONG64 offset );
+    TypedVar ( const TypeInfoPtr& typeInfo, ULONG64 offset );
 
 
-    TypedVar ( IDebugClient4 *client, const TypeInfo& typeInfo, ULONG64 offset );
+    TypedVar ( IDebugClient4 *client, const TypeInfoPtr& typeInfo, ULONG64 offset );
 
     ULONG64 getAddress() const {
         return m_offset;
@@ -31,10 +31,10 @@ public:
     }
 
     ULONG getOffset() {
-        return m_typeInfo.getOffset();
+        return m_typeInfo->getOffset();
     }
 
-    TypeInfo
+    TypeInfoPtr
     getType() const {
         return m_typeInfo;
     }
@@ -55,7 +55,7 @@ protected:
        throw DbgException("can not change");
     }
 
-    TypeInfo                m_typeInfo;
+    TypeInfoPtr             m_typeInfo;
 
     ULONG64                 m_offset;
 
@@ -68,7 +68,7 @@ class BasicTypedVar : public TypedVar {
 
 public:
 
-    BasicTypedVar ( IDebugClient4 *client, const TypeInfo& typeInfo, ULONG64 offset ) : TypedVar(client, typeInfo, offset){}
+    BasicTypedVar ( IDebugClient4 *client, const TypeInfoPtr& typeInfo, ULONG64 offset ) : TypedVar(client, typeInfo, offset){}
 
     TypedVarPtr
     virtual getField( const std::string &fieldName ) {
@@ -89,7 +89,7 @@ class PtrTypedVar : public TypedVar {
 
 public:
 
-    PtrTypedVar ( IDebugClient4 *client, const TypeInfo& typeInfo, ULONG64 offset ) : TypedVar(client, typeInfo, offset){}
+    PtrTypedVar ( IDebugClient4 *client, const TypeInfoPtr& typeInfo, ULONG64 offset ) : TypedVar(client, typeInfo, offset){}
 
     TypedVarPtr
     virtual getField( const std::string &fieldName ) {
diff --git a/pykd/typeinfo.cpp b/pykd/typeinfo.cpp
index 9724b9f..25e9c4c 100644
--- a/pykd/typeinfo.cpp
+++ b/pykd/typeinfo.cpp
@@ -4,90 +4,206 @@
 
 namespace pykd {
 
-///////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////
 
-TypeInfo::TypeInfo( pyDia::GlobalScopePtr &diaScope, const std::string &symName ) : 
-    m_offset( 0 )
+TypeInfoPtr  TypeInfo::getTypeInfo( pyDia::SymbolPtr &typeSym )
 {
-    pyDia::SymbolPtr  typeSym = diaScope->getChildByName( symName );
+    ULONG  tag = typeSym->getSymTag();
 
-    if ( typeSym->getSymTag() == SymTagData )
+    switch( typeSym->getSymTag() )
     {
-        m_dia = typeSym->getType();
-    }
-    else
-    {
-        m_dia = typeSym;
+    case SymTagBaseType:
+        return getBaseTypeInfo( typeSym );
+
+    case SymTagUDT:
+        return TypeInfoPtr( new UdtTypeInfo( typeSym ) );
+
+    case SymTagArrayType:
+        return TypeInfoPtr( new ArrayTypeInfo( typeSym ) );
+
+    case SymTagPointerType:
+        return TypeInfoPtr( new PointerTypeInfo( typeSym ) );
     }
+
+    throw DbgException( "type name invalid" );
 }
 
-///////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////
 
-std::string 
-TypeInfo::getName() 
+static const boost::regex arrayMatch("^(.*)\\[(\\d+)\\]$"); 
+
+TypeInfoPtr  TypeInfo::getTypeInfo( pyDia::SymbolPtr &symScope, const std::string &symName )
 {
-    std::stringstream    sstr;
+    size_t pos = symName.find_first_of( "*[" );
 
-    pyDia::SymbolPtr    diaptr = m_dia;
+    if ( pos == std::string::npos )
+    {
+        TypeInfoPtr    basePtr = getBaseTypeInfo( symName );
+        if ( basePtr != 0 )
+            return basePtr;
+
+        pyDia::SymbolPtr  typeSym = symScope->getChildByName( symName );
+
+        if ( typeSym->getSymTag() == SymTagData )
+            typeSym = typeSym->getType();
+
+        return getTypeInfo( typeSym );
+    }
     
-    int                 symtag = diaptr->getSymTag();
+    if ( symName[ symName.size() - 1 ] == '*' )
+        return TypeInfoPtr( new PointerTypeInfo( symScope,symName.substr( 0, symName.size() - 1 )  ) );
 
-    while( symtag == SymTagArrayType || symtag == SymTagPointerType )
+    boost::cmatch    matchResult;
+
+    if ( boost::regex_match( symName.c_str(), matchResult, arrayMatch ) )
     {
-        if ( symtag == SymTagArrayType )
-        {
-            sstr << '[' << diaptr->getCount() << ']';
-        }
-        else
-        {
-            sstr << '*';
-        }
+        std::string     sym = std::string( matchResult[1].first, matchResult[1].second );
 
-        diaptr = diaptr->getType();
-        symtag = diaptr->getSymTag();
+        return TypeInfoPtr( new ArrayTypeInfo( symScope, sym, std::atoi( matchResult[2].first ) ) );
     }
 
-    std::string    typeName = symtag == SymTagBaseType ?
-        diaptr->getBasicTypeName( diaptr->getBaseType() ) :
-        diaptr->getName();
 
-    typeName += sstr.str();
-
-    return typeName;
-};
-
-///////////////////////////////////////////////////////////////////////////////////
-
-bool
-TypeInfo::isBasicType()
-{
-    return  m_dia->getSymTag() == SymTagBaseType;  
+    throw DbgException( "type name invalid" );
 }
 
-///////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////
 
-bool
-TypeInfo::isArrayType()
+static const boost::regex baseMatch("^(Char)|(WChar)|(Int2B)|(UInt2B)|(Int4B)|(UInt4B)|(Int8B)|(UInt8B)|(Long)|(ULong)|(Float)|(Bool)$" );
+
+TypeInfoPtr 
+TypeInfo::getBaseTypeInfo( const std::string &symName )
 {
-    return m_dia->getSymTag() == SymTagArrayType;
+    boost::cmatch    baseMatchResult;
+
+    if ( boost::regex_match( symName.c_str(), baseMatchResult, baseMatch ) )
+    {
+        if ( baseMatchResult[1].matched )
+            return TypeInfoPtr( new TypeInfoWrapper<char>("Char") );
+
+        if ( baseMatchResult[2].matched )
+            return TypeInfoPtr( new TypeInfoWrapper<wchar_t>("WChar") );
+
+        if ( baseMatchResult[3].matched )
+            return TypeInfoPtr( new TypeInfoWrapper<short>("Int2B") );
+
+        if ( baseMatchResult[4].matched )
+            return TypeInfoPtr( new TypeInfoWrapper<unsigned short>("UInt2B") );
+
+        if ( baseMatchResult[5].matched )
+            return TypeInfoPtr( new TypeInfoWrapper<long>("Int4B") );
+
+        if ( baseMatchResult[6].matched )
+            return TypeInfoPtr( new TypeInfoWrapper<unsigned long>("UInt4B") );
+
+        if ( baseMatchResult[7].matched )
+            return TypeInfoPtr( new TypeInfoWrapper<__int64>("Int8B") );
+
+        if ( baseMatchResult[8].matched )
+            return TypeInfoPtr( new TypeInfoWrapper<unsigned __int64>("UInt8B") );
+
+        if ( baseMatchResult[9].matched )
+            return TypeInfoPtr( new TypeInfoWrapper<long>("Long") );
+
+        if ( baseMatchResult[10].matched )
+            return TypeInfoPtr( new TypeInfoWrapper<unsigned long>("ULong") );
+
+        if ( baseMatchResult[11].matched )
+            return TypeInfoPtr( new TypeInfoWrapper<float>("Float") );
+
+        if ( baseMatchResult[12].matched )
+            return TypeInfoPtr( new TypeInfoWrapper<bool>("Bool") );
+   }
+
+    return TypeInfoPtr();
 }
 
-///////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////
 
-bool
-TypeInfo::isPointer()
+TypeInfoPtr 
+TypeInfo::getBaseTypeInfo( pyDia::SymbolPtr &symbol )  
 {
-    return m_dia->getSymTag() == SymTagPointerType;
+    std::string     symName = symbol->getBasicTypeName( symbol->getBaseType() );
+
+    if ( symName == "Int" || symName == "UInt" ) 
+    {
+        std::stringstream   sstr;
+        sstr << symName << symbol->getSize() << "B";
+
+        return getBaseTypeInfo( sstr.str() );
+    }
+
+    TypeInfoPtr     ptr = getBaseTypeInfo( symName );
+
+    if ( ptr == 0 )
+        ptr = TypeInfoPtr( new BaseTypeInfo( symbol ) );
+
+    return ptr;
 }
 
-///////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////
 
-bool
-TypeInfo::isUserDefined()
+PointerTypeInfo::PointerTypeInfo( pyDia::SymbolPtr &symbol  ) 
 {
-    return m_dia->getSymTag() == SymTagUDT;
+    m_derefType = TypeInfo::getTypeInfo( symbol->getType() );
+    m_size = (ULONG)symbol->getSize();
 }
 
-///////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////
+
+PointerTypeInfo::PointerTypeInfo( pyDia::SymbolPtr &symScope, const std::string &symName ) 
+{
+    m_derefType = TypeInfo::getTypeInfo( symScope, symName );
+    m_size = symScope->getMachineType() == CV_CFL_X64  ? 8 : 4;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////
+
+std::string PointerTypeInfo::getName()
+{
+    return m_derefType->getName() + '*';
+}
+
+/////////////////////////////////////////////////////////////////////////////////////
+
+ULONG PointerTypeInfo::getSize()
+{
+    return m_size;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////
+
+ArrayTypeInfo::ArrayTypeInfo( pyDia::SymbolPtr &symbol  ) 
+{
+    m_derefType = TypeInfo::getTypeInfo( symbol->getType() );
+    m_count = symbol->getCount();
+}
+
+/////////////////////////////////////////////////////////////////////////////////////
+
+ArrayTypeInfo::ArrayTypeInfo( pyDia::SymbolPtr &symScope, const std::string &symName, ULONG count ) 
+{
+    m_derefType = TypeInfo::getTypeInfo( symScope, symName );
+    m_count = count;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////
+
+std::string ArrayTypeInfo::getName()
+{
+    std::stringstream       sstr;
+
+    sstr  << m_derefType->getName() << '[' << m_count << ']';
+
+    return sstr.str();
+}
+
+/////////////////////////////////////////////////////////////////////////////////////
+
+ULONG ArrayTypeInfo::getSize()
+{
+    return m_derefType->getSize() * m_count;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////
 
 }; // end namespace pykd
\ No newline at end of file
diff --git a/pykd/typeinfo.h b/pykd/typeinfo.h
index 5814ff4..95e7a93 100644
--- a/pykd/typeinfo.h
+++ b/pykd/typeinfo.h
@@ -8,57 +8,266 @@ namespace pykd {
 
 ///////////////////////////////////////////////////////////////////////////////////
 
-class TypeInfo {
+class TypeInfo;
+typedef boost::shared_ptr<TypeInfo>  TypeInfoPtr;
+
+///////////////////////////////////////////////////////////////////////////////////
+
+class TypeInfo : boost::noncopyable {
 
 public:
 
-    TypeInfo( pyDia::GlobalScopePtr &diaScope, const std::string &symName );
+    static 
+    TypeInfoPtr  getTypeInfo( pyDia::SymbolPtr &symScope, const std::string &symName );
 
-    TypeInfo( pyDia::SymbolPtr  &diaType ) :
-        m_offset( 0 ),
-        m_dia( diaType )
-        {}
+    static 
+    TypeInfoPtr  getTypeInfo( pyDia::SymbolPtr &symbol );
 
-    TypeInfo
-    getField( const std::string &fieldName ) {
-        pyDia::SymbolPtr  field = m_dia->getChildByName( fieldName );
-        TypeInfo ti( field->getType() );
-        ti.m_offset = field->getOffset();
-        return ti;
+    static
+    TypeInfoPtr  getBaseTypeInfo( const std::string &name );
+
+    static
+    TypeInfoPtr  getBaseTypeInfo( pyDia::SymbolPtr &symbol ); 
+
+public:
+
+    virtual std::string getName() = 0;
+
+    virtual ULONG getSize() = 0;
+
+    virtual TypeInfoPtr getField( const std::string &fieldName ) = 0;
+
+    virtual bool isBasicType() {
+        return false;
     }
 
-    std::string 
-    getName();
+    virtual bool isPointer() {
+        return false;
+    }
 
-    ULONG
-    getOffset() {
+    virtual bool isUserDefined() {
+        return false;
+    }
+
+    ULONG getOffset() {
         return m_offset;
     }
 
-    ULONG
-    getSize() {
-        return (ULONG)m_dia->getSize();
-    }  
+    void setOffset( ULONG offset ) {
+        m_offset = offset;
+    }
 
-    bool
-    isBasicType();
+protected:
 
-    bool
-    isArrayType();
-
-    bool
-    isPointer();
-
-    bool
-    isUserDefined();
-  
-private:
-
-    pyDia::SymbolPtr    m_dia;
-
-    ULONG               m_offset;
+    ULONG   m_offset;
 };
 
 ///////////////////////////////////////////////////////////////////////////////////
 
+class BaseTypeInfo : public TypeInfo 
+{
+public:
+
+    BaseTypeInfo( pyDia::SymbolPtr &symbol ) :
+      m_dia( symbol )
+      {}
+        
+protected:
+
+    virtual std::string getName() {
+        return m_dia->getBasicTypeName( m_dia->getBaseType() );
+    }
+
+    virtual ULONG getSize() {
+        return (ULONG)m_dia->getSize();
+    }
+
+    virtual TypeInfoPtr getField( const std::string &fieldName ) {
+        throw DbgException( "there is no such field" );
+    }
+
+    virtual bool isBasicType() {
+        return true;
+    }
+
+    pyDia::SymbolPtr    m_dia;
+
+};
+
+///////////////////////////////////////////////////////////////////////////////////
+
+template<typename T>
+class TypeInfoWrapper : public TypeInfo
+{
+public:    
+    TypeInfoWrapper( const std::string &name ) :
+      m_name(name)
+      {}
+
+private:
+
+    virtual std::string getName() {
+        return m_name;
+    }
+
+    virtual ULONG getSize() {
+        return sizeof(T);
+    }
+
+    virtual TypeInfoPtr getField( const std::string &fieldName ) {
+        throw DbgException( "there is no such field" );
+    }
+
+    virtual bool isBasicType() {
+        return true;
+    }
+
+    std::string     m_name;
+
+};
+
+///////////////////////////////////////////////////////////////////////////////////
+
+class UdtTypeInfo : public BaseTypeInfo 
+{
+public:
+
+    UdtTypeInfo ( pyDia::SymbolPtr &symbol ) :
+        BaseTypeInfo( symbol )
+        {}
+
+    virtual std::string getName() {
+        return m_dia->getName();
+    }
+
+    virtual TypeInfoPtr getField( const std::string &fieldName ) {
+        pyDia::SymbolPtr  field = m_dia->getChildByName( fieldName );
+        TypeInfoPtr  ti = TypeInfo::getTypeInfo( m_dia, fieldName );
+        ti->setOffset( field->getOffset() );
+        return ti;
+    }
+
+    virtual bool isUserDefined() {
+        return true;
+    }
+};
+  
+///////////////////////////////////////////////////////////////////////////////////
+
+class PointerTypeInfo : public TypeInfo {
+
+public:
+
+    PointerTypeInfo( pyDia::SymbolPtr &symbol  );
+
+    PointerTypeInfo( pyDia::SymbolPtr &symScope, const std::string &symName );
+
+    virtual std::string getName();
+
+    virtual ULONG getSize();
+
+    virtual TypeInfoPtr getField( const std::string &fieldName ) {
+        throw DbgException( "there is no such field" );
+    }
+
+    virtual bool isPointer() {
+        return true;
+    }
+
+private:
+    
+    TypeInfoPtr     m_derefType;
+
+    ULONG           m_size;
+};
+
+///////////////////////////////////////////////////////////////////////////////////
+
+class ArrayTypeInfo : public TypeInfo {
+
+public:
+
+    ArrayTypeInfo( pyDia::SymbolPtr &symbol  );
+
+    ArrayTypeInfo( pyDia::SymbolPtr &symScope, const std::string &symName, ULONG count );
+
+    virtual std::string getName();
+
+    virtual ULONG getSize();
+
+    virtual TypeInfoPtr getField( const std::string &fieldName ) {
+        throw DbgException( "there is no such field" );
+    }
+
+private:
+
+    TypeInfoPtr     m_derefType;
+
+    ULONG           m_count;
+};
+
+///////////////////////////////////////////////////////////////////////////////////
+
+
+
+
+
+
+
+
+//
+//class TypeInfo {
+//
+//public:
+//
+//    TypeInfo( pyDia::GlobalScopePtr &diaScope, const std::string &symName );
+//
+//    TypeInfo( pyDia::SymbolPtr  &diaType ) :
+//        m_offset( 0 ),
+//        m_dia( diaType )
+//        {}
+//
+//    TypeInfo
+//    getField( const std::string &fieldName ) {
+//        pyDia::SymbolPtr  field = m_dia->getChildByName( fieldName );
+//        TypeInfo ti( field->getType() );
+//        ti.m_offset = field->getOffset();
+//        return ti;
+//    }
+//
+//    std::string 
+//    getName();
+//
+//    ULONG
+//    getOffset() {
+//        return m_offset;
+//    }
+//
+//    ULONG
+//    getSize() {
+//        return (ULONG)m_dia->getSize();
+//    }  
+//
+//    bool
+//    isBasicType();
+//
+//    bool
+//    isArrayType();
+//
+//    bool
+//    isPointer();
+//
+//    bool
+//    isUserDefined();
+//  
+//private:
+//
+//    pyDia::SymbolPtr    m_dia;
+//
+//    ULONG               m_offset;
+//
+//};
+
+///////////////////////////////////////////////////////////////////////////////////
+
 }; // namespace pykd
diff --git a/test/scripts/pykdtest.py b/test/scripts/pykdtest.py
index ef0f5f2..5a480d2 100644
--- a/test/scripts/pykdtest.py
+++ b/test/scripts/pykdtest.py
@@ -52,6 +52,8 @@ if __name__ == "__main__":
     target.module.reload();
     
     suite = getTestSuite()
-    #suite = getTestSuite( "typedvar.TypedVarTest.testCtor" )
+    #suite = getTestSuite( "typeinfo.TypeInfoTest" )
    
     unittest.TextTestRunner(stream=sys.stdout, verbosity=2).run( suite )
+    
+    a = raw_input("\npress return\n")
\ No newline at end of file
diff --git a/test/scripts/typeinfo.py b/test/scripts/typeinfo.py
index ff14cf2..a300bc3 100644
--- a/test/scripts/typeinfo.py
+++ b/test/scripts/typeinfo.py
@@ -15,29 +15,46 @@ class TypeInfoTest( unittest.TestCase ):
 
     def testCreateByName( self ):
         """ creating typeInfo by the type name """
-        ti1 = target.module.type( "structTest" )
-        ti2 = target.module.type( "classChild" )
+        #self.assertEqual( "structTest", target.module.type( "structTest" ).name() )
+        #self.assertEqual( "structTest**", target.module.type( "structTest**" ).name() )
+        self.assertEqual( "Int4B[2][3]", target.module.type("Int4B[2][3]").name() )
 
     def testGetField( self ):
         """ get field of the complex type """
         ti1 = target.module.type( "structTest" )
         self.assertTrue( hasattr( ti1, "m_field0" ) )
         try: hasattr(ti1, "m_field4" )                        # non-exsisting field
-        except pykd.DiaException: pass   
+        except pykd.BaseException: pass   
+
+    def testBaseTypes( self ):
+        self.assertEqual( 1, target.module.type("Char").size() )
+        self.assertEqual( 2, target.module.type("WChar").size() )
+        self.assertEqual( 2, target.module.type("Int2B").size() )        
+        self.assertEqual( 2, target.module.type("UInt2B").size() )          
+        self.assertEqual( 4, target.module.type("Int4B").size() )        
+        self.assertEqual( 4, target.module.type("UInt4B").size() )          
+        self.assertEqual( 8, target.module.type("Int8B").size() )        
+        self.assertEqual( 8, target.module.type("UInt8B").size() )            
 
     def testName( self ):
         ti1 = target.module.type( "classChild" )
         self.assertEqual( "classChild", ti1.name() )
-        self.assertEqual( "Int", ti1.m_childField.name() )
+        self.assertEqual( "Int4B", ti1.m_childField.name() )
         self.assertEqual( "structTest", ti1.m_childField3.name() )
         self.assertEqual( "structTest", target.module.type("g_structTest").name() )
 
-    def testArrayName( self ):
-        self.assertEqual( "structTest[2]", target.module.type("g_testArray").name() )
-
     def testPtrName( self ):
         self.assertEqual( "structTest*", target.module.type("g_structTestPtr").name() )
-        self.assertEqual( "structTest**", target.module.type("g_structTestPtrPtr").name() )
+        self.assertEqual( "structTest**", target.module.type("g_structTestPtrPtr").name() )        
+        self.assertEqual( "structTest**", target.module.type("structTest**").name() )        
+
+    def testArrayName( self ):
+        self.assertEqual( "structTest[2]", target.module.type("g_testArray").name() )
+        self.assertEqual( "Int4B[2][3]", target.module.type("intMatrix").name() )
+        self.assertEqual( "Char*[2]", target.module.type("strArray").name() )
+        self.assertEqual( "Int4B[2][3]*",target.module.type("ptrIntMatrix").name() )
+        self.assertEqual( "Char*[2]*", target.module.type("ptrStrArray").name() )   
+        self.assertEqual( "Int4B[2][3]",  target.module.type("Int[2][3]").name() )
         
     def testOffset( self ):
         ti1 = target.module.type( "structTest" )
@@ -49,4 +66,5 @@ class TypeInfoTest( unittest.TestCase ):
     def testSize( self ):
         ti1 = target.module.type( "structTest" )
         self.assertEqual( 20, ti1.size() )
+        self.assertEqual( pykd.ptrSize(), target.module.type("structTest**").size() )
 
diff --git a/test/targetapp/targetapp.cpp b/test/targetapp/targetapp.cpp
index 1003ae0..940ec22 100644
--- a/test/targetapp/targetapp.cpp
+++ b/test/targetapp/targetapp.cpp
@@ -64,6 +64,11 @@ unsigned short ushortArray[] = {0, 10, 0xFF, 0x8000, 0xFFFF };
 unsigned long ulongArray[] = {0, 0xFF, 0x8000, 0x80000000, 0xFFFFFFFF };
 unsigned __int64 ulonglongArray[] = {0, 0xFF, 0xFFFFFFFF, 0x8000000000000000, 0xFFFFFFFFFFFFFFFF };
 
+int intMatrix[2][3] = { { 0, 1, 2}, { 3, 4, 5 } };
+char* strArray[] = { "hello", "bye" };
+int (*ptrIntMatrix)[2][3] = &intMatrix;
+char *(*ptrStrArray)[2] = &strArray;
+
 class classChild : public classBase {
 public:
     int m_childField;
@@ -105,6 +110,10 @@ void FuncWithName0()
     std::cout << ushortArray[2];
     std::cout << ulongArray[2];
     std::cout << ulonglongArray[2];
+
+    std::cout << intMatrix[1][1];
+    std::cout << strArray[0];
+    std::cout << (*ptrIntMatrix)[0][1];
 }
 
 void FuncWithName1(int a)