diff --git a/cadquery/freecad_impl/exporters.py b/cadquery/freecad_impl/exporters.py
index 21768a7c..a774a844 100644
--- a/cadquery/freecad_impl/exporters.py
+++ b/cadquery/freecad_impl/exporters.py
@@ -2,7 +2,7 @@
     Copyright (C) 2011-2013  Parametric Products Intellectual Holdings, LLC
 
     This file is part of CadQuery.
-    
+
     CadQuery is free software; you can redistribute it and/or
     modify it under the terms of the GNU Lesser General Public
     License as published by the Free Software Foundation; either
@@ -15,14 +15,25 @@
 
     You should have received a copy of the GNU Lesser General Public
     License along with this library; If not, see 
-    
+
     An exporter should provide functionality to accept a shape, and return
     a string containing the model content.
 """
 import cadquery
 
-import FreeCAD,tempfile,os,StringIO
-from FreeCAD import Drawing
+from .verutil import fc_import
+FreeCAD = fc_import("FreeCAD")
+import tempfile,os,StringIO
+
+Drawing = fc_import("FreeCAD.Drawing")
+#_FCVER = freecad_version()
+#if _FCVER>=(0,13):
+    #import Drawing as FreeCADDrawing #It's in FreeCAD lib path
+#elif _FCVER>=(0,12):
+    #import FreeCAD.Drawing as FreeCADDrawing
+#else:
+    #raise RuntimeError, "Invalid freecad version: %s" % str(".".join(_FCVER))
+
 
 try:
     import xml.etree.cElementTree as ET
@@ -35,7 +46,7 @@ class ExportTypes:
     AMF = "AMF"
     SVG = "SVG"
     TJS = "TJS"
-    
+
 class UNITS:
     MM = "mm"
     IN = "in"
@@ -45,7 +56,7 @@ def toString(shape,exportType,tolerance=0.1):
 	s= StringIO.StringIO()
 	exportShape(shape,exportType,s,tolerance)
 	return s.getvalue()
-	
+
 def exportShape(shape,exportType,fileLike,tolerance=0.1):
     """
         :param shape:  the shape to export. it can be a shape object, or a cadquery object. If a cadquery
@@ -54,13 +65,13 @@ def exportShape(shape,exportType,fileLike,tolerance=0.1):
         :param tolerance: the tolerance, in model units
         :param fileLike: a file like object to which the content will be written.
         The object should be already open and ready to write. The caller is responsible
-        for closing the object 
+        for closing the object
     """
 
-    
+
     if isinstance(shape,cadquery.CQ):
         shape = shape.val()
-        
+
     if exportType == ExportTypes.TJS:
         #tessellate the model
         tess = shape.tessellate(tolerance)
@@ -78,9 +89,9 @@ def exportShape(shape,exportType,fileLike,tolerance=0.1):
         fileLike.write(getSVG(shape.wrapped))
     elif exportType == ExportTypes.AMF:
         tess = shape.tessellate(tolerance)
-        aw = AmfWriter(tess).writeAmf(fileLike)        
+        aw = AmfWriter(tess).writeAmf(fileLike)
     else:
-        
+
         #all these types required writing to a file and then
         #re-reading. this is due to the fact that FreeCAD writes these
         (h, outFileName) = tempfile.mkstemp()
@@ -130,8 +141,8 @@ def guessUnitOfMeasure(shape):
     if sum(dimList) < 10:
         return UNITS.IN
 
-    return UNITS.MM    
-    
+    return UNITS.MM
+
 
 class AmfWriter(object):
     def __init__(self,tessellation):
@@ -172,7 +183,7 @@ class AmfWriter(object):
         ET.ElementTree(amf).write(outFile,encoding='ISO-8859-1')
 
 """
-    Objects that represent 
+    Objects that represent
     three.js JSON object notation
     https://github.com/mrdoob/three.js/wiki/JSON-Model-format-3.0
 """
@@ -183,21 +194,21 @@ class JsonMesh(object):
         self.faces = [];
         self.nVertices = 0;
         self.nFaces = 0;
-        
+
     def addVertex(self,x,y,z):
         self.nVertices += 1;
         self.vertices.extend([x,y,z]);
-        
+
     #add triangle composed of the three provided vertex indices
     def addTriangleFace(self, i,j,k):
         #first position means justa simple triangle
         self.nFaces += 1;
         self.faces.extend([0,int(i),int(j),int(k)]);
-    
+
     """
         Get a json model from this model.
         For now we'll forget about colors, vertex normals, and all that stuff
-    """    
+    """
     def toJson(self):
         return JSON_TEMPLATE % {
             'vertices' : str(self.vertices),
@@ -249,7 +260,7 @@ def getSVG(shape,opts=None):
     """
 
     d = {'width':800,'height':240,'marginLeft':200,'marginTop':20}
-    
+
     if opts:
         d.update(opts)
 
@@ -314,14 +325,14 @@ def exportSVG(shape, fileName):
         TODO: should use file-like objects, not a fileName, and/or be able to return a string instead
         export a view of a part to svg
     """
-    
+
     svg = getSVG(shape.val().wrapped)
     f = open(fileName,'w')
     f.write(svg)
     f.close()
 
 
-        
+
 JSON_TEMPLATE= """\
 {
     "metadata" :
@@ -336,9 +347,9 @@ JSON_TEMPLATE= """\
         "materials"     : 1,
         "morphTargets"  : 0
     },
-    
+
     "scale" : 1.0,
-    
+
     "materials": [    {
     "DbgColor" : 15658734,
     "DbgIndex" : 0,
diff --git a/cadquery/freecad_impl/geom.py b/cadquery/freecad_impl/geom.py
index ae9ed518..a036d627 100644
--- a/cadquery/freecad_impl/geom.py
+++ b/cadquery/freecad_impl/geom.py
@@ -2,7 +2,7 @@
     Copyright (C) 2011-2013  Parametric Products Intellectual Holdings, LLC
 
     This file is part of CadQuery.
-    
+
     CadQuery is free software; you can redistribute it and/or
     modify it under the terms of the GNU Lesser General Public
     License as published by the Free Software Foundation; either
@@ -18,8 +18,10 @@
 """
 
 import math,sys
-import FreeCAD
-import FreeCAD.Part
+#import FreeCAD
+from .verutil import fc_import
+FreeCAD = fc_import("FreeCAD")
+#Turns out we don't need the Part module here.
 
 def sortWiresByBuildOrder(wireList,plane,result=[]):
     """
@@ -187,8 +189,8 @@ class Vector(object):
 
 class Matrix:
     """
-        A 3d , 4x4 transformation matrix.        
-        
+        A 3d , 4x4 transformation matrix.
+
         Used to move geometry in space.
     """
     def __init__(self,matrix=None):
@@ -196,14 +198,14 @@ class Matrix:
             self.wrapped = FreeCAD.Base.Matrix()
         else:
             self.wrapped = matrix
-            
+
     def rotateX(self,angle):
         self.wrapped.rotateX(angle)
-        
+
     def rotateY(self,angle):
         self.wrapped.rotateY(angle)
-    
-    
+
+
 class Plane:
     """
         A 2d coordinate system in space, with the x-y axes on the a plane, and a particular point as the origin.
@@ -321,7 +323,7 @@ class Plane:
 
         self.setOrigin3d(origin)
 
-        
+
     def setOrigin3d(self,originVector):
         """
             Move the origin of the plane, leaving its orientation and xDirection unchanged.
@@ -427,7 +429,7 @@ class Plane:
             v = Vector(tuplePoint[0],tuplePoint[1],tuplePoint[2])
         return Vector(self.rG.multiply(v.wrapped))
 
-        
+
     def rotated(self,rotate=(0,0,0)):
         """
         returns a copy of this plane, rotated about the specified axes, as measured from horizontal
@@ -445,7 +447,7 @@ class Plane:
         """
 
         if rotate.__class__.__name__ != 'Vector':
-            rotate = Vector(rotate)		
+            rotate = Vector(rotate)
         #convert to radians
         rotate = rotate.multiply(math.pi / 180.0 )
 
@@ -473,13 +475,13 @@ class Plane:
         #compute rotation matrix ( global --> local --> rotate  --> global )
         #rm = self.plane.fG.multiply(matrix).multiply(self.plane.rG)
         rm = self.computeTransform(rotationMatrix)
-        
+
 
         #There might be a better way, but to do this rotation takes 3 steps
         #transform geometry to local coordinates
         #then rotate about x
         #then transform back to global coordiante
-        
+
         resultWires = []
         for w in listOfShapes:
             mirrored = w.transformGeometry(rotationMatrix.wrapped)
@@ -487,7 +489,7 @@ class Plane:
 
         return resultWires
 
-        
+
     def _calcTransforms(self):
         """
             Computes transformation martrices to convert betwene local and global coordinates
@@ -507,12 +509,12 @@ class Plane:
         (invR.A14,invR.A24,invR.A34) = (self.origin.x,self.origin.y,self.origin.z)
 
         ( self.rG,self.fG ) = ( invR,invR.inverse() )
-        
+
     def computeTransform(self,tMatrix):
         """
             Computes the 2-d projection of the supplied matrix
         """
-        
+
         rm = self.fG.multiply(tMatrix.wrapped).multiply(self.rG)
         return Matrix(rm)
 
diff --git a/cadquery/freecad_impl/shapes.py b/cadquery/freecad_impl/shapes.py
index bcfc4c13..0f97b41b 100644
--- a/cadquery/freecad_impl/shapes.py
+++ b/cadquery/freecad_impl/shapes.py
@@ -2,7 +2,7 @@
 	Copyright (C) 2011-2013  Parametric Products Intellectual Holdings, LLC
 
 	This file is part of CadQuery.
-	
+
 	CadQuery is free software; you can redistribute it and/or
 	modify it under the terms of the GNU Lesser General Public
 	License as published by the Free Software Foundation; either
@@ -43,13 +43,15 @@
 
         5. allow changing interfaces when we'd like.  there are  few cases where the freecad api is not
            very userfriendly: we like to change those when necesary. As an example, in the freecad api,
-           all factory methods are on the 'Part' object, but it is very useful to know what kind of 
-           object each one returns, so these are better grouped by the type of object they return. 
+           all factory methods are on the 'Part' object, but it is very useful to know what kind of
+           object each one returns, so these are better grouped by the type of object they return.
            (who would know that Part.makeCircle() returns an Edge, but Part.makePolygon() returns a Wire ?
 """
 from cadquery import Vector,BoundBox
 import FreeCAD
-import FreeCAD.Part
+
+from .verutil import fc_import
+FreeCADPart = fc_import("FreeCAD.Part")
 
 class Shape(object):
     """
@@ -269,7 +271,7 @@ class Shape(object):
     def transformGeometry(self,tMatrix):
         """
 			tMatrix is a matrix object.
-			
+
             returns a copy of the object, but with geometry transformed insetad of just
             rotated.
 
@@ -316,9 +318,9 @@ class Edge(Shape):
         #self.endPoint = None
 
         self.edgetypes= {
-            FreeCAD.Part.Line : 'LINE',
-            FreeCAD.Part.ArcOfCircle : 'ARC',
-            FreeCAD.Part.Circle : 'CIRCLE'
+            FreeCADPart.Line : 'LINE',
+            FreeCADPart.ArcOfCircle : 'ARC',
+            FreeCADPart.Circle : 'CIRCLE'
         }
 
     def geomType(self):
@@ -368,7 +370,7 @@ class Edge(Shape):
 
     @classmethod
     def makeCircle(cls,radius,pnt=(0,0,0),dir=(0,0,1),angle1=360.0,angle2=360):
-        return Edge(FreeCAD.Part.makeCircle(radius,toVector(pnt),toVector(dir),angle1,angle2))
+        return Edge(FreeCADPart.makeCircle(radius,toVector(pnt),toVector(dir),angle1,angle2))
 
     @classmethod
     def makeSpline(cls,listOfVector):
@@ -380,7 +382,7 @@ class Edge(Shape):
         """
         vecs = [v.wrapped for v in listOfVector]
 
-        spline = FreeCAD.Part.BSplineCurve()
+        spline = FreeCADPart.BSplineCurve()
         spline.interpolate(vecs,False)
         return Edge(spline.toShape())
 
@@ -394,7 +396,7 @@ class Edge(Shape):
         :param v3: end vector
         :return: an edge object through the three points
         """
-        arc = FreeCAD.Part.Arc(v1.wrapped,v2.wrapped,v3.wrapped)
+        arc = FreeCADPart.Arc(v1.wrapped,v2.wrapped,v3.wrapped)
         e = Edge(arc.toShape())
         return e #arcane and undocumented, this creates an Edge object
 
@@ -406,7 +408,7 @@ class Edge(Shape):
             :param v2: Vector that represents the second point
             :return: A linear edge between the two provided points
         """
-        return Edge(FreeCAD.Part.makeLine(v1.toTuple(),v2.toTuple() ))
+        return Edge(FreeCADPart.makeLine(v1.toTuple(),v2.toTuple() ))
 
 
 class Wire(Shape):
@@ -425,7 +427,7 @@ class Wire(Shape):
         :param listOfWires:
         :return:
         """
-        return Shape.cast(FreeCAD.Part.Wire([w.wrapped for w in listOfWires]))
+        return Shape.cast(FreeCADPart.Wire([w.wrapped for w in listOfWires]))
 
     @classmethod
     def assembleEdges(cls,listOfEdges):
@@ -437,7 +439,7 @@ class Wire(Shape):
         """
         fCEdges = [a.wrapped for a in listOfEdges]
 
-        wa = Wire( FreeCAD.Part.Wire(fCEdges) )
+        wa = Wire( FreeCADPart.Wire(fCEdges) )
         return wa
 
     @classmethod
@@ -449,13 +451,13 @@ class Wire(Shape):
             :param normal: vector representing the direction of the plane the circle should lie in
             :return:
         """
-        w = Wire(FreeCAD.Part.Wire([FreeCAD.Part.makeCircle(radius,center.wrapped,normal.wrapped)]))
+        w = Wire(FreeCADPart.Wire([FreeCADPart.makeCircle(radius,center.wrapped,normal.wrapped)]))
         return w
 
     @classmethod
     def makePolygon(cls,listOfVertices,forConstruction=False):
         #convert list of tuples into Vectors.
-        w = Wire(FreeCAD.Part.makePolygon([i.wrapped for i in listOfVertices]))
+        w = Wire(FreeCADPart.makePolygon([i.wrapped for i in listOfVertices]))
         w.forConstruction = forConstruction
         return w
 
@@ -466,7 +468,7 @@ class Wire(Shape):
         By default a cylindrical surface is used to create the helix. If
         the fourth parameter is set (the apex given in degree) a conical surface is used instead'
         """
-        return Wire(FreeCAD.Part.makeHelix(pitch,height,radius,angle))
+        return Wire(FreeCADPart.makeHelix(pitch,height,radius,angle))
 
 
 class Face(Shape):
@@ -478,9 +480,9 @@ class Face(Shape):
 
         self.facetypes = {
             #TODO: bezier,bspline etc
-            FreeCAD.Part.Plane : 'PLANE',
-            FreeCAD.Part.Sphere : 'SPHERE',
-            FreeCAD.Part.Cone : 'CONE'
+            FreeCADPart.Plane : 'PLANE',
+            FreeCADPart.Sphere : 'SPHERE',
+            FreeCADPart.Cone : 'CONE'
         }
 
     def geomType(self):
@@ -506,7 +508,7 @@ class Face(Shape):
 
     @classmethod
     def makePlane(cls,length,width,basePnt=None,dir=None):
-        return Face(FreeCAD.Part.makePlan(length,width,toVector(basePnt),toVector(dir)))
+        return Face(FreeCADPart.makePlan(length,width,toVector(basePnt),toVector(dir)))
 
     @classmethod
     def makeRuledSurface(cls,edgeOrWire1,edgeOrWire2,dist=None):
@@ -515,7 +517,7 @@ class Face(Shape):
         Create a ruled surface out of two edges or wires. If wires are used then
         these must have the same
         """
-        return Shape.cast(FreeCAD.Part.makeRuledSurface(edgeOrWire1.obj,edgeOrWire2.obj,dist))
+        return Shape.cast(FreeCADPart.makeRuledSurface(edgeOrWire1.obj,edgeOrWire2.obj,dist))
 
     def cut(self,faceToCut):
         "Remove a face from another one"
@@ -541,7 +543,7 @@ class Shell(Shape):
 
     @classmethod
     def makeShell(cls,listOfFaces):
-        return Shell(FreeCAD.Part.makeShell([i.obj for i in listOfFaces]))
+        return Shell(FreeCADPart.makeShell([i.obj for i in listOfFaces]))
 
 
 class Solid(Shape):
@@ -568,7 +570,7 @@ class Solid(Shape):
             makeBox(length,width,height,[pnt,dir]) -- Make a box located\nin pnt with the d
             imensions (length,width,height)\nBy default pnt=Vector(0,0,0) and dir=Vector(0,0,1)'
         """
-        return Shape.cast(FreeCAD.Part.makeBox(length,width,height,pnt.wrapped,dir.wrapped))
+        return Shape.cast(FreeCADPart.makeBox(length,width,height,pnt.wrapped,dir.wrapped))
 
     @classmethod
     def makeCone(cls,radius1,radius2,height,pnt=Vector(0,0,0),dir=Vector(0,0,1),angleDegrees=360):
@@ -577,7 +579,7 @@ class Solid(Shape):
             Make a cone with given radii and height\nBy default pnt=Vector(0,0,0),
             dir=Vector(0,0,1) and angle=360'
         """
-        return Shape.cast(FreeCAD.Part.makeCone(radius1,radius2,height,pnt.wrapped,dir.wrapped,angleDegrees))
+        return Shape.cast(FreeCADPart.makeCone(radius1,radius2,height,pnt.wrapped,dir.wrapped,angleDegrees))
 
     @classmethod
     def makeCylinder(cls,radius,height,pnt=Vector(0,0,0),dir=Vector(0,0,1),angleDegrees=360):
@@ -586,7 +588,7 @@ class Solid(Shape):
             Make a cylinder with a given radius and height
             By default pnt=Vector(0,0,0),dir=Vector(0,0,1) and angle=360'
         """
-        return Shape.cast(FreeCAD.Part.makeCylinder(radius,height,pnt.wrapped,dir.wrapped,angleDegrees))
+        return Shape.cast(FreeCADPart.makeCylinder(radius,height,pnt.wrapped,dir.wrapped,angleDegrees))
 
     @classmethod
     def makeTorus(cls,radius1,radius2,pnt=None,dir=None,angleDegrees1=None,angleDegrees2=None):
@@ -596,7 +598,7 @@ class Solid(Shape):
             By default pnt=Vector(0,0,0),dir=Vector(0,0,1),angle1=0
             ,angle1=360 and angle=360'
         """
-        return Shape.cast(FreeCAD.Part.makeTorus(radius1,radius2,pnt,dir,angleDegrees1,angleDegrees2))
+        return Shape.cast(FreeCADPart.makeTorus(radius1,radius2,pnt,dir,angleDegrees1,angleDegrees2))
 
     @classmethod
     def sweep(cls,profileWire,pathWire):
@@ -615,11 +617,11 @@ class Solid(Shape):
         """
             makes a loft from a list of wires
             The wires will be converted into faces when possible-- it is presumed that nobody ever actually
-            wants to make an infinitely thin shell for a real FreeCAD.Part.
+            wants to make an infinitely thin shell for a real FreeCADPart.
         """
         #the True flag requests building a solid instead of a shell.
 
-        return Shape.cast(FreeCAD.Part.makeLoft([i.wrapped for i in listOfWire],True))
+        return Shape.cast(FreeCADPart.makeLoft([i.wrapped for i in listOfWire],True))
 
     @classmethod
     def makeWedge(cls,xmin,ymin,zmin,z2min,x2min,xmax,ymax,zmax,z2max,x2max,pnt=None,dir=None):
@@ -629,7 +631,7 @@ class Solid(Shape):
          Make a wedge located in pnt\nBy default pnt=Vector(0,0,0) and dir=Vec
         tor(0,0,1)'
         """
-        return Shape.cast(FreeCAD.Part.makeWedge(xmin,ymin,zmin,z2min,x2min,xmax,ymax,zmax,z2max,x2max,pnt,dir))
+        return Shape.cast(FreeCADPart.makeWedge(xmin,ymin,zmin,z2min,x2min,xmax,ymax,zmax,z2max,x2max,pnt,dir))
 
     @classmethod
     def makeSphere(cls,radius,pnt=None,angleDegrees1=None,angleDegrees2=None,angleDegrees3=None):
@@ -638,7 +640,7 @@ class Solid(Shape):
             Make a sphere with a giv
             en radius\nBy default pnt=Vector(0,0,0), dir=Vector(0,0,1), angle1=0, angle2=90 and angle3=360'
         """
-        return Solid(FreeCAD.Part.makeSphere(radius,pnt,angleDegrees1,angleDegrees2,angleDegrees3))
+        return Solid(FreeCADPart.makeSphere(radius,pnt,angleDegrees1,angleDegrees2,angleDegrees3))
 
     @classmethod
     def extrudeLinearWithRotation(cls,outerWire,innerWires,vecCenter, vecNormal,angleDegrees):
@@ -679,12 +681,12 @@ class Solid(Shape):
         #make a ruled surface for each set of wires
         sides = []
         for w1,w2 in zip(startWires,endWires):
-            rs = FreeCAD.Part.makeRuledSurface(w1,w2)
+            rs = FreeCADPart.makeRuledSurface(w1,w2)
             sides.append(rs)
 
         #make faces for the top and bottom
-        startFace = FreeCAD.Part.Face(startWires)
-        endFace = FreeCAD.Part.Face(endWires)
+        startFace = FreeCADPart.Face(startWires)
+        endFace = FreeCADPart.Face(endWires)
 
         #collect all the faces from the sides
         faceList = [ startFace]
@@ -692,8 +694,8 @@ class Solid(Shape):
             faceList.extend(s.Faces)
         faceList.append(endFace)
 
-        shell = FreeCAD.Part.makeShell(faceList)
-        solid = FreeCAD.Part.makeSolid(shell)
+        shell = FreeCADPart.makeShell(faceList)
+        solid = FreeCADPart.makeSolid(shell)
         return Shape.cast(solid)
 
     @classmethod
@@ -730,7 +732,7 @@ class Solid(Shape):
         for w in innerWires:
             freeCADWires.append(w.wrapped)
 
-        f = FreeCAD.Part.Face(freeCADWires)
+        f = FreeCADPart.Face(freeCADWires)
         result = f.extrude(vecNormal.wrapped)
 
         return Shape.cast(result)
@@ -794,11 +796,11 @@ class Compound(Shape):
         Create a compound out of a list of shapes
         """
         solids = [s.wrapped for s in listOfShapes]
-        c = FreeCAD.Part.Compound(solids)
+        c = FreeCADPart.Compound(solids)
         return Shape.cast( c)
 
     def fuse(self,toJoin):
         return Shape.cast(self.wrapped.fuse(toJoin.wrapped))
 
     def tessellate(self,tolerance):
-        return self.wrapped.tessellate(tolerance)
\ No newline at end of file
+        return self.wrapped.tessellate(tolerance)
diff --git a/cadquery/freecad_impl/verutil.py b/cadquery/freecad_impl/verutil.py
new file mode 100644
index 00000000..9b09d3d0
--- /dev/null
+++ b/cadquery/freecad_impl/verutil.py
@@ -0,0 +1,113 @@
+"""
+    This file is part of CadQuery.
+
+    CadQuery is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    CadQuery is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; If not, see 
+
+    An exporter should provide functionality to accept a shape, and return
+    a string containing the model content.
+"""
+
+import re
+from importlib import import_module
+import os
+import sys
+
+MEMO_VERSION = None
+SUBMODULES = None
+_PATH = None
+
+def _figure_out_version(freecadversion):
+    """Break this out for testability."""
+    return tuple(
+            ((int(re.sub("([0-9]*).*", "\\1", part) or 0))
+                for part in freecadversion[:3]))
+
+
+def _fc_path():
+    """Find FreeCAD"""
+    global _PATH
+    if _PATH:
+        return _PATH
+    if sys.platform.startswith('linux'):
+        #Make some dangerous assumptions...
+        for _PATH in [
+                os.path.join(os.path.expanduser("~"), "lib/freecad/lib"),
+                "/usr/local/lib/freecad/lib",
+                "/usr/lib/freecad/lib",
+                ]:
+            if os.path.exists(_PATH):
+                return _PATH
+
+    elif sys.platform.startswith('win'):
+        for _PATH in [
+                "c:/apps/FreeCAD0.12/bin",
+                "c:/apps/FreeCAD0.13/bin",
+                ]:
+            if os.path.exists(_PATH):
+                return _PATH
+
+def freecad_version():
+    """Determine the freecad version and return it as a simple
+    comparable tuple"""
+    #If we cannot find freecad, we append it to the path if possible
+    _pthtmp = _fc_path()
+    if not _pthtmp in sys.path:
+        sys.path.append(_pthtmp)
+    import FreeCAD
+    global MEMO_VERSION
+    if not MEMO_VERSION:
+        MEMO_VERSION = _figure_out_version(FreeCAD.Version())
+    return MEMO_VERSION
+
+def _find_submodules():
+    """Find the list of allowable submodules in fc13"""
+    global SUBMODULES
+    searchpath = _fc_path()
+    if not SUBMODULES:
+        SUBMODULES = [
+                re.sub("(.*)\\.(py|so)","\\1", filename)
+                for filename in os.listdir(searchpath)
+                if (
+                    filename.endswith(".so") or
+                    filename.endswith(".py") or
+                    filename.endswith(".dll") )] #Yes, complex. Sorry.
+    return SUBMODULES
+
+
+def fc_import(modulename):
+    """Intelligent import of freecad components.
+    If we are in 0.12, we can import FreeCAD.Drawing
+    If we are in 0.13, we need to set sys.path and import Drawing as toplevel.
+    This may or may not be a FreeCAD bug though.
+    This is ludicrously complex and feels awful. Kinda like a lot of OCC.
+    """
+    #Note that this also sets the path as a side effect.
+
+    _fcver = freecad_version()
+
+    if _fcver >= (0, 13):
+        if modulename in _find_submodules():
+            return import_module(modulename)
+        elif re.sub("^FreeCAD\\.", "", modulename) in _find_submodules():
+            return import_module(re.sub("^FreeCAD\\.", "", modulename))
+        else:
+            raise ImportError, "Module %s not found/allowed in %s" % (
+                    modulename, _PATH)
+    elif _fcver >= (0, 12):
+        return import_module(modulename)
+    else:
+        raise RuntimeError, "Invalid freecad version: %s" % \
+                str(".".join(_fcver))
+
+__ALL__ = ['fc_import', 'freecad_version']
diff --git a/setup.py b/setup.py
index 8e8c0da5..9d212cb1 100644
--- a/setup.py
+++ b/setup.py
@@ -1,4 +1,4 @@
-from distutils.core import setup
+from setuptools import setup
 
 setup(
     name='cadquery',
@@ -37,4 +37,4 @@ setup(
         'Topic :: Internet',
         'Topic :: Scientific/Engineering'
     ]
-)
\ No newline at end of file
+)
diff --git a/tests/TestCadObjects.py b/tests/TestCadObjects.py
index d1c9d860..7cb0863f 100644
--- a/tests/TestCadObjects.py
+++ b/tests/TestCadObjects.py
@@ -3,9 +3,15 @@ import sys
 
 import unittest
 from tests import BaseTest
-import FreeCAD
+
+from cadquery.freecad_impl.verutil import fc_import
+FreeCAD = fc_import("FreeCAD")
+if not hasattr(FreeCAD, 'Part'):
+    FreeCAD.Part = fc_import("FreeCAD.Part")
+
+
 from cadquery import *
-	
+
 class TestCadObjects(BaseTest):
 
     def testVectorConstructors(self):
@@ -57,6 +63,6 @@ class TestCadObjects(BaseTest):
     def testVertices(self):
         e = Shape.cast(FreeCAD.Part.makeLine((0,0,0),(1,1,0)))
         self.assertEquals(2,len(e.Vertices()))
-		
+
 if __name__ == '__main__':
-    unittest.main()		
\ No newline at end of file
+    unittest.main()
diff --git a/tests/TestCadQuery.py b/tests/TestCadQuery.py
index 6407bd3d..4c2c655c 100644
--- a/tests/TestCadQuery.py
+++ b/tests/TestCadQuery.py
@@ -11,7 +11,11 @@ from cadquery import exporters
 from tests import BaseTest,writeStringToFile,makeUnitCube,readFileAsString,makeUnitSquareWire,makeCube
 
 #where unit test output will be saved
-OUTDIR = "c:/temp"
+import sys
+if sys.platform.startswith("win"):
+    OUTDIR = "c:/temp"
+else:
+    OUTDIR = "/tmp"
 SUMMARY_FILE = os.path.join(OUTDIR,"testSummary.html")
 
 SUMMARY_TEMPLATE="""
@@ -422,13 +426,14 @@ class TestCadQuery(BaseTest):
 
     def testBasicLines(self):
         "Make a triangluar boss"
+        global OUTDIR
         s = Workplane(Plane.XY())
 
         #TODO:  extrude() should imply wire() if not done already
         #most users dont understand what a wire is, they are just drawing
 
         r = s.lineTo(1.0,0).lineTo(0,1.0).close().wire().extrude(0.25)
-        r.val().exportStep('c:/temp/testBasicLinesStep1.STEP')
+        r.val().exportStep(os.path.join(OUTDIR, 'testBasicLinesStep1.STEP'))
 
         self.assertEqual(0,s.faces().size()) #no faces on the original workplane
         self.assertEqual(5,r.faces().size() ) # 5 faces on newly created object
@@ -436,12 +441,12 @@ class TestCadQuery(BaseTest):
         #now add a circle through a side face
         r.faces("+XY").workplane().circle(0.08).cutThruAll()
         self.assertEqual(6,r.faces().size())
-        r.val().exportStep('c:/temp/testBasicLinesXY.STEP')
+        r.val().exportStep(os.path.join(OUTDIR, 'testBasicLinesXY.STEP'))
 
         #now add a circle through a top
         r.faces("+Z").workplane().circle(0.08).cutThruAll()
         self.assertEqual(9,r.faces().size())
-        r.val().exportStep('c:/temp/testBasicLinesZ.STEP')
+        r.val().exportStep(os.path.join(OUTDIR, 'testBasicLinesZ.STEP'))
 
         self.saveModel(r)
 
diff --git a/tests/TestImports.py b/tests/TestImports.py
new file mode 100644
index 00000000..2c7d04f1
--- /dev/null
+++ b/tests/TestImports.py
@@ -0,0 +1,30 @@
+"""
+    Tests basic workplane functionality
+"""
+#core modules
+
+#my modules
+from cadquery.freecad_impl import verutil
+from tests import BaseTest
+
+class TestVersionsForImport(BaseTest):
+    """Test version checks."""
+
+    def test_013_version(self):
+        """Make sure various 0.13 Version calls work correctly"""
+        self.assertEquals(verutil._figure_out_version(
+            ['0', '13', '2055 (Git)',
+                'git://git.code.sf.net/p/free-cad/code',
+                '2013/04/18 13:48:49', 'master',
+                '3511a807a30cf41909aaf12a1efe1db6c53db577']),
+            (0,13,2055))
+        self.assertEquals(verutil._figure_out_version(
+            ['0', '13', '12345']),
+            (0,13,12345))
+        self.assertEquals(verutil._figure_out_version(
+            ['0', '13', 'SOMETAGTHATBREAKSSTUFF']),
+            (0,13,0))
+
+
+
+
diff --git a/tests/__init__.py b/tests/__init__.py
index 7c6e8216..21b96464 100644
--- a/tests/__init__.py
+++ b/tests/__init__.py
@@ -1,12 +1,13 @@
 from cadquery import *
 import unittest
 import sys
-FREECAD_LIB = "c:/apps/FreeCAD0.12/bin";
-sys.path.append(FREECAD_LIB);
-import FreeCAD
+import os
 
-P = FreeCAD.Part
-V = FreeCAD.Base.Vector
+from cadquery.freecad_impl.verutil import fc_import
+FreeCAD = fc_import("FreeCAD")
+
+P = fc_import("FreeCAD.Part")
+V = fc_import("FreeCAD").Base.Vector
 
 def readFileAsString(fileName):
     f= open(fileName,'r')
@@ -18,7 +19,7 @@ def writeStringToFile(strToWrite,fileName):
     f = open(fileName,'w')
     f.write(strToWrite)
     f.close()
-	
+
 
 def makeUnitSquareWire():
     return Solid.cast(P.makePolygon([V(0,0,0),V(1,0,0),V(1,1,0),V(0,1,0),V(0,0,0)]))