diff --git a/extras/soap-tools/runMutalyzer.py b/extras/soap-tools/runMutalyzer.py
index 852e467b5fe86e2809b9d3e9ef6eb633afcbcab2..0a2d1e7593db0eed2963cdd80606a015f1ec7a11 100755
--- a/extras/soap-tools/runMutalyzer.py
+++ b/extras/soap-tools/runMutalyzer.py
@@ -76,6 +76,12 @@ def main(description, verbosity=None):
         print 'Affected proteins:'
         print '\n'.join(result.proteinDescriptions.string)
 
+    if 'exons' in result:
+        print '\nExon table for selected transcript:'
+        print '\t'.join(['Number', 'Start (g.)', 'Stop (g.)', 'Start (c.)', 'Stop (c.)'])
+        for i, exon in enumerate(result.exons.ExonInfo, start=1):
+            print '\t'.join([str(i), str(exon.gStart), str(exon.gStop), exon.cStart, exon.cStop])
+
 
 if __name__ == '__main__':
     if len(sys.argv) < 2:
diff --git a/mutalyzer/models.py b/mutalyzer/models.py
index cd1a46374206cf6fb752dd8fa704ca06cf6300f9..1665d68dd7c5be8c23078846538e9f09fcc03713 100644
--- a/mutalyzer/models.py
+++ b/mutalyzer/models.py
@@ -123,6 +123,21 @@ class Allele(ComplexModel):
 #Allele
 
 
+class ExonInfo(ComplexModel):
+    """
+    Used in TranscriptInfo and MutalyzerOutput data types.
+    """
+    __namespace__ = SOAP_NAMESPACE
+
+    cStart = Mandatory.String
+    gStart = Mandatory.Integer
+    chromStart = Integer
+    cStop = Mandatory.String
+    gStop = Mandatory.Integer
+    chromStop = Integer
+#ExonInfo
+
+
 class MutalyzerOutput(ComplexModel):
     """
     Return type of SOAP method runMutalyzer.
@@ -158,6 +173,8 @@ class MutalyzerOutput(ComplexModel):
     transcriptDescriptions = Array(String)
     proteinDescriptions = Array(String)
 
+    exons = Array(ExonInfo)
+
     rawVariants = Array(RawVariant)
 
     messages = Array(SoapMessage)
@@ -175,21 +192,6 @@ class TranscriptNameInfo(ComplexModel):
 #TranscriptNameInfo
 
 
-class ExonInfo(ComplexModel):
-    """
-    Used in TranscriptInfo data type.
-    """
-    __namespace__ = SOAP_NAMESPACE
-
-    cStart = Mandatory.String
-    gStart = Mandatory.Integer
-    chromStart = Integer
-    cStop = Mandatory.String
-    gStop = Mandatory.Integer
-    chromStop = Integer
-#ExonInfo
-
-
 class ProteinTranscript(ComplexModel):
     """
     Used in TranscriptInfo data type.
diff --git a/mutalyzer/services/rpc.py b/mutalyzer/services/rpc.py
index 1866df350f0ca39d9c04aa2227993fd18d8765ec..9b676542938d8594e2e88bd07fc6bbf204991297 100644
--- a/mutalyzer/services/rpc.py
+++ b/mutalyzer/services/rpc.py
@@ -763,6 +763,12 @@ class MutalyzerService(ServiceBase):
                 represented by an object with fields:
                 - description: Description of the raw variant.
                 - visualisation: ASCII visualisation of the raw variant.
+            - exons: If a transcript is selected, array of ExonInfo objects
+                for each exon in the selected transcript with fields:
+                - cStart
+                - gStart
+                - cStop
+                - gStop
             - messages: List of (error) messages.
         """
         O = Output(__file__)
@@ -804,6 +810,13 @@ class MutalyzerService(ServiceBase):
         result.transcriptDescriptions = O.getOutput("descriptions")
         result.proteinDescriptions = O.getOutput("protDescriptions")
 
+        if O.getIndexedOutput('hasTranscriptInfo', 0, False):
+            result.exons = []
+            for e in O.getOutput('exonInfo'):
+                exon = ExonInfo()
+                exon.gStart, exon.gStop, exon.cStart, exon.cStop = e
+                result.exons.append(exon)
+
         raw_variants = []
         for v in O.getOutput("visualisation"):
             r = RawVariant()
diff --git a/tests/test_services_soap.py b/tests/test_services_soap.py
index c610645a2db04bdffd2ae7cf2427f3d784c8d1be..135983f0843b272a24e61a05ee0f77779e0a1424 100644
--- a/tests/test_services_soap.py
+++ b/tests/test_services_soap.py
@@ -28,7 +28,8 @@ logging.basicConfig(level=logging.INFO)
 for logger in ('suds.metrics', 'suds.wsdl', 'suds.xsd.schema',
                'suds.xsd.sxbasic', 'suds.xsd.sxbase', 'suds.xsd.query',
                'suds.transport.http', 'suds.xsd.deplist', 'suds.mx.core',
-               'suds.mx.literal', 'suds.resolver', 'suds.client'):
+               'suds.mx.literal', 'suds.resolver', 'suds.client',
+               'suds.umx.typed'):
     logging.getLogger(logger).setLevel(logging.ERROR)
 
 
@@ -59,8 +60,8 @@ class TestServicesSoap():
         @todo: Start the standalone server and stop it in self.tearDown
         instead of depending on some running instance at a fixed address.
         """
-        self.client = Client(WSDL_URL) #, cache=None)
-        self.client.options.cache.setduration(seconds=120)
+        self.client = Client(WSDL_URL, cache=None)
+        #self.client.options.cache.setduration(seconds=120)
 
     def test_checksyntax_valid(self):
         """
@@ -472,6 +473,24 @@ class TestServicesSoap():
         assert_equal(r.sourceGi, '256574794')
         assert_equal(r.molecule, 'g')
 
+    def test_runmutalyzer_exons(self):
+        """
+        Exon table in runMutalyzer output.
+        """
+        r = self.client.service.runMutalyzer('NM_004959.4:c.630_636del')
+        assert_equal(r.errors, 0)
+        expected_exons = [(1, 172, '-187', '-16'),
+                          (173, 289, '-15', '102'),
+                          (290, 431, '103', '244'),
+                          (432, 1057, '245', '870'),
+                          (1058, 1177, '871', '990'),
+                          (1178, 1325, '991', '1138'),
+                          (1326, 3095, '1139', '*1522')]
+        assert_equal(len(r.exons.ExonInfo), len(expected_exons))
+        for exon, expected_exon in zip(r.exons.ExonInfo, expected_exons):
+            assert_equal((exon.gStart, exon.gStop, exon.cStart, exon.cStop),
+                         expected_exon)
+
     def test_gettranscriptsandinfo_slice(self):
         """
         Running getTranscriptsAndInfo on a chromosomal slice should include