diff --git a/src/services/formatting/rules.ts b/src/services/formatting/rules.ts
index b5470579787f4..320df83e35acf 100644
--- a/src/services/formatting/rules.ts
+++ b/src/services/formatting/rules.ts
@@ -35,9 +35,13 @@ module ts.formatting {
         // Space after keyword but not before ; or : or ?
         public NoSpaceBeforeSemicolon: Rule;
         public NoSpaceBeforeColon: Rule;
-        public NoSpaceBeforeQMark: Rule;
+        public NoSpaceBeforeQuestionMark: Rule;
         public SpaceAfterColon: Rule;
-        public SpaceAfterQMark: Rule;
+        // insert space after '?' only when it is used in conditional operator
+        public SpaceAfterQuestionMarkInConditionalOperator: Rule;
+        // in other cases there should be no space between '?' and next token
+        public NoSpaceAfterQuestionMark: Rule;
+
         public SpaceAfterSemicolon: Rule;
 
         // Space/new line after }.
@@ -215,9 +219,10 @@ module ts.formatting {
             // Space after keyword but not before ; or : or ?
             this.NoSpaceBeforeSemicolon = new Rule(RuleDescriptor.create2(Shared.TokenRange.Any, SyntaxKind.SemicolonToken), RuleOperation.create2(new RuleOperationContext(Rules.IsSameLineTokenContext), RuleAction.Delete));
             this.NoSpaceBeforeColon = new Rule(RuleDescriptor.create2(Shared.TokenRange.Any, SyntaxKind.ColonToken), RuleOperation.create2(new RuleOperationContext(Rules.IsSameLineTokenContext, Rules.IsNotBinaryOpContext), RuleAction.Delete));
-            this.NoSpaceBeforeQMark = new Rule(RuleDescriptor.create2(Shared.TokenRange.Any, SyntaxKind.QuestionToken), RuleOperation.create2(new RuleOperationContext(Rules.IsSameLineTokenContext, Rules.IsNotBinaryOpContext), RuleAction.Delete));
+            this.NoSpaceBeforeQuestionMark = new Rule(RuleDescriptor.create2(Shared.TokenRange.Any, SyntaxKind.QuestionToken), RuleOperation.create2(new RuleOperationContext(Rules.IsSameLineTokenContext, Rules.IsNotBinaryOpContext), RuleAction.Delete));
             this.SpaceAfterColon = new Rule(RuleDescriptor.create3(SyntaxKind.ColonToken, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsSameLineTokenContext, Rules.IsNotBinaryOpContext), RuleAction.Space));
-            this.SpaceAfterQMark = new Rule(RuleDescriptor.create3(SyntaxKind.QuestionToken, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsSameLineTokenContext, Rules.IsNotBinaryOpContext), RuleAction.Space));
+            this.SpaceAfterQuestionMarkInConditionalOperator = new Rule(RuleDescriptor.create3(SyntaxKind.QuestionToken, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsSameLineTokenContext, Rules.IsConditionalOperatorContext), RuleAction.Space));
+            this.NoSpaceAfterQuestionMark = new Rule(RuleDescriptor.create3(SyntaxKind.QuestionToken, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsSameLineTokenContext), RuleAction.Delete));
             this.SpaceAfterSemicolon = new Rule(RuleDescriptor.create3(SyntaxKind.SemicolonToken, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsSameLineTokenContext), RuleAction.Space));
 
             // Space after }.
@@ -341,7 +346,8 @@ module ts.formatting {
             this.HighPriorityCommonRules =
             [
                 this.IgnoreBeforeComment, this.IgnoreAfterLineComment,
-                this.NoSpaceBeforeColon, this.SpaceAfterColon, this.NoSpaceBeforeQMark, this.SpaceAfterQMark,
+                this.NoSpaceBeforeColon, this.SpaceAfterColon, this.NoSpaceBeforeQuestionMark, this.SpaceAfterQuestionMarkInConditionalOperator,
+                this.NoSpaceAfterQuestionMark,
                 this.NoSpaceBeforeDot, this.NoSpaceAfterDot,
                 this.NoSpaceAfterUnaryPrefixOperator,
                 this.NoSpaceAfterUnaryPreincrementOperator, this.NoSpaceAfterUnaryPredecrementOperator,
@@ -475,6 +481,10 @@ module ts.formatting {
             return !Rules.IsBinaryOpContext(context);
         }
 
+        static IsConditionalOperatorContext(context: FormattingContext): boolean {
+            return context.contextNode.kind === SyntaxKind.ConditionalExpression;
+        }
+
         static IsSameLineTokenOrBeforeMultilineBlockContext(context: FormattingContext): boolean {
             //// This check is mainly used inside SpaceBeforeOpenBraceInControl and SpaceBeforeOpenBraceInFunction.
             ////
diff --git a/tests/cases/fourslash/formattingConditionalOperator.ts b/tests/cases/fourslash/formattingConditionalOperator.ts
new file mode 100644
index 0000000000000..545adb572b152
--- /dev/null
+++ b/tests/cases/fourslash/formattingConditionalOperator.ts
@@ -0,0 +1,6 @@
+/// 
+
+////var x=true?1:2
+format.document();
+goTo.bof();
+verify.currentLineContentIs("var x = true ? 1 : 2");;
\ No newline at end of file
diff --git a/tests/cases/fourslash/formattingQMark.ts b/tests/cases/fourslash/formattingQMark.ts
new file mode 100644
index 0000000000000..83ca56a49f660
--- /dev/null
+++ b/tests/cases/fourslash/formattingQMark.ts
@@ -0,0 +1,12 @@
+/// 
+
+////interface A {
+/////*1*/    foo?     ();
+/////*2*/    foo?             ();
+////}
+
+format.document();
+goTo.marker("1");
+verify.currentLineContentIs("    foo?();");
+goTo.marker("2");
+verify.currentLineContentIs("    foo?();");
\ No newline at end of file
diff --git a/tests/cases/fourslash/genericsFormatting.ts b/tests/cases/fourslash/genericsFormatting.ts
index f6f1426316c64..36833cadd10a1 100644
--- a/tests/cases/fourslash/genericsFormatting.ts
+++ b/tests/cases/fourslash/genericsFormatting.ts
@@ -30,4 +30,4 @@ goTo.marker("inNewSignature");
 verify.currentLineContentIs("    new (a: T);");
 
 goTo.marker("inOptionalMethodSignature");
-verify.currentLineContentIs("    op? (a: T, b: M);");
\ No newline at end of file
+verify.currentLineContentIs("    op?(a: T, b: M);");
\ No newline at end of file