private static void WriteCommonType(CXType type, TextWriter tw, string outParam = "")
        {
            tw.Write(outParam);

            var canonical = clang.getCanonicalType(type);

            string spelling;
            switch (type.kind)
            {
                case CXTypeKind.CXType_Typedef:
                    var cursor = clang.getTypeDeclaration(type);
                    if (clang.Location_isInSystemHeader(clang.getCursorLocation(cursor)) != 0)
                    {
                        spelling = canonical.ToPlainTypeString();
                    }
                    else
                    {
                        spelling = type.ToStringEx();
                    }
                    break;
                case CXTypeKind.CXType_Record:
                case CXTypeKind.CXType_Enum:
                    spelling = canonical.ToPlainTypeString();
                    break;
                case CXTypeKind.CXType_IncompleteArray:
                    WriteCommonType(clang.getArrayElementType(type), tw);
                    spelling = @"*";
                    break;
                case CXTypeKind.CXType_ConstantArray:
                    tw.Write(@"[MarshalAs(UnmanagedType.LPArray, SizeConst={0})] ", clang.getArraySize(type));
                    WriteCommonType(clang.getArrayElementType(type), tw);
                    spelling = @"[]";
                    break;
                case CXTypeKind.CXType_Unexposed:
                    // Often these are enums and canonical type gets you the enum spelling
                    // unexposed decl which turns into a function proto seems to be an un-typedef'd fn pointer
                    spelling = canonical.kind == CXTypeKind.CXType_FunctionProto ? @"IntPtr" : canonical.ToPlainTypeString();
                    break;
                default:
                    spelling = canonical.ToPlainTypeString();
                    break;
            }

            tw.Write(spelling);
        }