public TypeReference GetType(Expression ex, INode parent)
 {
     if (ex is IdentifierExpression)
     {
         return GetIdentifierType(ex, parent);
     }
     else if (ex is FieldReferenceExpression)
     {
         FieldReferenceExpression fieldReference = (FieldReferenceExpression) ex;
         Expression targetObject = fieldReference.TargetObject;
         TypeReference targetType = GetType(targetObject);
         if (targetType != null)
         {
             string fullName = TypeResolver.GetFullName(targetType);
             if (targetType.RankSpecifier != null && targetType.RankSpecifier.Length > 0 && !(ex.Parent is IndexerExpression))
                 fullName = "JavaArray";
             if (CodeBase.Types.Contains(fullName))
             {
                 TypeDeclaration typeDeclaration = (TypeDeclaration) CodeBase.Types[fullName];
                 if (typeDeclaration.Type == ClassType.Enum)
                     return AstUtil.GetTypeReference(typeDeclaration.Name, ex.Parent);
                 else
                     return GetTypeInMembers(typeDeclaration, fieldReference.FieldName);
             }
         }
         return null;
     }
     else if (ex is PrimitiveExpression)
     {
         return GetConstantType((PrimitiveExpression) ex);
     }
     else if (ex is InvocationExpression)
     {
         return GetType(((InvocationExpression) ex).TargetObject);
     }
     else if (ex is IndexerExpression)
     {
         return GetType(((IndexerExpression) ex).TargetObject);
     }
     else if (ex is BinaryOperatorExpression)
     {
         return GetType(((BinaryOperatorExpression) ex).Left);
     }
     else if (ex is ObjectCreateExpression)
     {
         return ((ObjectCreateExpression) ex).CreateType;
     }
     else if (ex is ThisReferenceExpression)
     {
         TypeDeclaration ty = (TypeDeclaration) AstUtil.GetParentOfType(ex, typeof(TypeDeclaration));
         return AstUtil.GetTypeReference(ty.Name, ex.Parent);
     }
     else if (ex is CastExpression)
     {
         CastExpression cast = (CastExpression) ex;
         return cast.CastTo;
     }
     else if (ex is ArrayCreateExpression)
     {
         return ((ArrayCreateExpression) ex).CreateType;
     }
     else if (ex is BaseReferenceExpression)
     {
         TypeDeclaration typeDeclaration = (TypeDeclaration) AstUtil.GetParentOfType(ex, typeof(TypeDeclaration));
         if (typeDeclaration.BaseTypes.Count > 0)
             return (TypeReference) typeDeclaration.BaseTypes[0];
         else
             return AstUtil.GetTypeReference("System.Object", parent);
     }
     else if (ex is ParenthesizedExpression)
     {
         return GetType(((ParenthesizedExpression) ex).Expression);
     }
     else if (ex is TypeReferenceExpression)
     {
         return ((TypeReferenceExpression) ex).TypeReference;
     }
     else if (ex is AssignmentExpression)
     {
         return GetType(((AssignmentExpression) ex).Left);
     }
     else if (ex is UnaryOperatorExpression)
     {
         return GetType(((UnaryOperatorExpression) ex).Expression);
     }
     else if (ex is TypeOfExpression)
     {
         TypeReference typeReference = new TypeReference("java.lang.Class");
         typeReference.Parent = parent;
         return typeReference;
     }
     else if (ex is TypeOfIsExpression)
     {
         return GetType(((TypeOfIsExpression) ex).Expression);
     }
     else if (ex is ConditionalExpression)
     {
         return GetType(((ConditionalExpression) ex).TrueExpression);
     }
     else if (ex is ParameterDeclarationExpression)
     {
         return ((ParameterDeclarationExpression) ex).TypeReference;
     }
     else if (ex == Expression.Null)
     {
         return null;
     }
     else
         throw new NotSupportedException(ex.GetType().Name);
 }