diff --git a/src/main/java/org/anarres/cpp/LexerSource.java b/src/main/java/org/anarres/cpp/LexerSource.java
index 0b381b9..98e146b 100644
--- a/src/main/java/org/anarres/cpp/LexerSource.java
+++ b/src/main/java/org/anarres/cpp/LexerSource.java
@@ -510,11 +510,14 @@ private Token _number_suffix(StringBuilder text, NumericValue value, int d)
                 d = read();
             } // This should probably be isPunct() || isWhite().
             else if (Character.isLetter(d) || d == '_') {
+                // We've encountered something initially identified as a number.
+                // Read in the rest of this token as an identifer but return it as an invalid.
+                while(Character.isLetterOrDigit(d) || d == '_') {
+                    text.append((char)d);
+                    d = read();
+                }
                 unread(d);
-                value.setFlags(flags);
-                return invalid(text,
-                        "Invalid suffix \"" + (char) d
-                        + "\" on numeric constant");
+                return new Token(INVALID,text.toString());
             } else {
                 unread(d);
                 value.setFlags(flags);
diff --git a/src/main/java/org/anarres/cpp/Preprocessor.java b/src/main/java/org/anarres/cpp/Preprocessor.java
index 0ad1538..180684f 100644
--- a/src/main/java/org/anarres/cpp/Preprocessor.java
+++ b/src/main/java/org/anarres/cpp/Preprocessor.java
@@ -119,6 +119,9 @@ public String getName() {
     private VirtualFileSystem filesystem;
     private PreprocessorListener listener;
 
+    HashSet<String> quotedImports=new HashSet<String>();
+    HashSet<String> sysImports=new HashSet<String>();
+
     public Preprocessor() {
         this.inputs = new ArrayList<Source>();
 
@@ -737,6 +740,7 @@ private boolean macro(Macro m, Token orig)
                         case WHITESPACE:
                         case CCOMMENT:
                         case CPPCOMMENT:
+                        case NL:
                             /* Avoid duplicating spaces. */
                             space = true;
                             break;
@@ -1127,6 +1131,25 @@ private void include(
             }
             if (include(quoteincludepath, name))
                 return;
+        } else {
+            int forwardSlashPos=name.indexOf('/');
+            if (forwardSlashPos!=-1) {
+                String frameworkName=name.substring(0,forwardSlashPos);
+                String includeName=name.substring(forwardSlashPos+1);
+                for (String frameworkPath:frameworkspath) {
+                    File frameworkFile=new File(frameworkPath,frameworkName+".framework");
+                    if (!frameworkFile.exists() || !frameworkFile.isDirectory())
+                        continue;
+                    File frameworkHeadersFile=new File(frameworkFile,"Headers");
+                    if (!frameworkHeadersFile.exists() || !frameworkHeadersFile.isDirectory())
+                        continue;
+                    File includeFile=new File(frameworkHeadersFile,includeName);
+                    if (!includeFile.exists() || !includeFile.isFile())
+                        continue;
+                    if (include(filesystem.getFile(includeFile.getCanonicalPath())))
+                        return;
+                }
+            }
         }
 
         if (include(sysincludepath, name))
@@ -1146,7 +1169,7 @@ private void include(
     }
 
     @Nonnull
-    private Token include(boolean next)
+    private Token include(boolean next,boolean isImport)
             throws IOException,
             LexerException {
         LexerSource lexer = (LexerSource) source;
@@ -1196,13 +1219,20 @@ private Token include(boolean next)
                 }
             }
 
-            /* Do the inclusion. */
-            include(source.getPath(), tok.getLine(), name, quoted, next);
+            HashSet<String> importMap=quoted?quotedImports:sysImports;
+            if (!isImport || !importMap.contains(name)) {
+                /* Do the inclusion. */
+                include(source.getPath(), tok.getLine(), name, quoted, next);
+                
+                importMap.add(name);
 
-            /* 'tok' is the 'nl' after the include. We use it after the
-             * #line directive. */
-            if (getFeature(Feature.LINEMARKERS))
-                return line_token(1, source.getName(), " 1");
+                /* 'tok' is the 'nl' after the include. We use it after the
+                 * #line directive. */
+                if (getFeature(Feature.LINEMARKERS))
+                    return line_token(1, source.getName(), " 1");
+            } else {
+                warning(tok,"Already imported:"+name);
+            }
             return tok;
         } finally {
             lexer.setInclude(false);
@@ -1494,7 +1524,7 @@ private long expr(int priority)
                 tok = expr_token();
                 if (tok.getType() != ')') {
                     expr_untoken(tok);
-                    error(tok, "missing ) in expression");
+                    error(tok, "missing ) in expression at "+tok);
                     return 0;
                 }
                 break;
@@ -1609,7 +1639,17 @@ private long expr(int priority)
                     break;
 
                 case '?':
-                /* XXX Handle this? */
+                    {
+                        tok = expr_token();
+                        if (tok.getType() != ':') {
+                            expr_untoken(tok);
+                            error(tok, "missing : in conditional expression");
+                            return 0;
+                        }
+                        long falseResult=expr(0);
+                        lhs = (lhs!=0) ? rhs : falseResult;
+                    }
+                    break;
 
                 default:
                     error(op,
@@ -1781,6 +1821,7 @@ private Token _token()
                 case RSH:
                 case RSH_EQ:
                 case STRING:
+                case SQSTRING :
                 case XOR_EQ:
                     return tok;
 
@@ -1851,11 +1892,12 @@ private Token _token()
                                 return undef();
                         // break;
 
+                        case PP_IMPORT :
                         case PP_INCLUDE:
                             if (!isActive())
                                 return source_skipline(false);
                             else
-                                return include(false);
+                                return include(false,ppcmd==PP_IMPORT);
                         // break;
                         case PP_INCLUDE_NEXT:
                             if (!isActive())
@@ -1866,7 +1908,7 @@ private Token _token()
                                 );
                                 return source_skipline(false);
                             }
-                            return include(true);
+                            return include(true,false);
                         // break;
 
                         case PP_WARNING: